committed by
Erik Ovegard
8 changed files with 419 additions and 4 deletions
@ -0,0 +1,65 @@ |
|||||
|
using System; |
||||
|
using MathNet.Numerics.LinearAlgebra; |
||||
|
using MathNet.Numerics.Optimization.ObjectiveFunctions; |
||||
|
|
||||
|
namespace MathNet.Numerics.Optimization |
||||
|
{ |
||||
|
public static class ObjectiveFunction |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Objective function where neither Gradient nor Hessian is available.
|
||||
|
/// </summary>
|
||||
|
public static IObjectiveFunction Value(Func<Vector<double>, double> function) |
||||
|
{ |
||||
|
return new ValueObjectiveFunction(function); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Objective function where the Gradient is available. Greedy evaluation.
|
||||
|
/// </summary>
|
||||
|
public static IObjectiveFunction Gradient(Func<Vector<double>, Tuple<double, Vector<double>>> function) |
||||
|
{ |
||||
|
return new GradientObjectiveFunction(function); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Objective function where the Gradient is available. Lazy evaluation.
|
||||
|
/// </summary>
|
||||
|
public static IObjectiveFunction Gradient(Func<Vector<double>, double> function, Func<Vector<double>, Vector<double>> gradient) |
||||
|
{ |
||||
|
return new LazyObjectiveFunction(function, gradient: gradient); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Objective function where the Hessian is available. Greedy evaluation.
|
||||
|
/// </summary>
|
||||
|
public static IObjectiveFunction Hessian(Func<Vector<double>, Tuple<double, Matrix<double>>> function) |
||||
|
{ |
||||
|
return new HessianObjectiveFunction(function); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Objective function where the Hessian is available. Lazy evaluation.
|
||||
|
/// </summary>
|
||||
|
public static IObjectiveFunction Hessian(Func<Vector<double>, double> function, Func<Vector<double>, Matrix<double>> hessian) |
||||
|
{ |
||||
|
return new LazyObjectiveFunction(function, hessian: hessian); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Objective function where both Gradient and Hessian are available. Greedy evaluation.
|
||||
|
/// </summary>
|
||||
|
public static IObjectiveFunction GradientHessian(Func<Vector<double>, Tuple<double, Vector<double>, Matrix<double>>> function) |
||||
|
{ |
||||
|
return new GradientHessianObjectiveFunction(function); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Objective function where both Gradient and Hessian are available. Lazy evaluation.
|
||||
|
/// </summary>
|
||||
|
public static IObjectiveFunction GradientHessian(Func<Vector<double>, double> function, Func<Vector<double>, Vector<double>> gradient, Func<Vector<double>, Matrix<double>> hessian) |
||||
|
{ |
||||
|
return new LazyObjectiveFunction(function, gradient: gradient, hessian: hessian); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,57 @@ |
|||||
|
using System; |
||||
|
using MathNet.Numerics.LinearAlgebra; |
||||
|
|
||||
|
namespace MathNet.Numerics.Optimization.ObjectiveFunctions |
||||
|
{ |
||||
|
internal class GradientHessianObjectiveFunction : IObjectiveFunction |
||||
|
{ |
||||
|
readonly Func<Vector<double>, Tuple<double, Vector<double>, Matrix<double>>> _function; |
||||
|
|
||||
|
public GradientHessianObjectiveFunction(Func<Vector<double>, Tuple<double, Vector<double>, Matrix<double>>> function) |
||||
|
{ |
||||
|
_function = function; |
||||
|
} |
||||
|
|
||||
|
public IObjectiveFunction CreateNew() |
||||
|
{ |
||||
|
return new GradientHessianObjectiveFunction(_function); |
||||
|
} |
||||
|
|
||||
|
public IObjectiveFunction Fork() |
||||
|
{ |
||||
|
// no need to deep-clone values since they are replaced on evaluation
|
||||
|
return new GradientHessianObjectiveFunction(_function) |
||||
|
{ |
||||
|
Point = Point, |
||||
|
Value = Value, |
||||
|
Gradient = Gradient, |
||||
|
Hessian = Hessian |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public bool IsGradientSupported |
||||
|
{ |
||||
|
get { return true; } |
||||
|
} |
||||
|
|
||||
|
public bool IsHessianSupported |
||||
|
{ |
||||
|
get { return true; } |
||||
|
} |
||||
|
|
||||
|
public void EvaluateAt(Vector<double> point) |
||||
|
{ |
||||
|
Point = point; |
||||
|
|
||||
|
var result = _function(point); |
||||
|
Value = result.Item1; |
||||
|
Gradient = result.Item2; |
||||
|
Hessian = result.Item3; |
||||
|
} |
||||
|
|
||||
|
public Vector<double> Point { get; private set; } |
||||
|
public double Value { get; private set; } |
||||
|
public Vector<double> Gradient { get; private set; } |
||||
|
public Matrix<double> Hessian { get; private set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
using System; |
||||
|
using MathNet.Numerics.LinearAlgebra; |
||||
|
|
||||
|
namespace MathNet.Numerics.Optimization.ObjectiveFunctions |
||||
|
{ |
||||
|
internal class GradientObjectiveFunction : IObjectiveFunction |
||||
|
{ |
||||
|
readonly Func<Vector<double>, Tuple<double, Vector<double>>> _function; |
||||
|
|
||||
|
public GradientObjectiveFunction(Func<Vector<double>, Tuple<double, Vector<double>>> function) |
||||
|
{ |
||||
|
_function = function; |
||||
|
} |
||||
|
|
||||
|
public IObjectiveFunction CreateNew() |
||||
|
{ |
||||
|
return new GradientObjectiveFunction(_function); |
||||
|
} |
||||
|
|
||||
|
public IObjectiveFunction Fork() |
||||
|
{ |
||||
|
// no need to deep-clone values since they are replaced on evaluation
|
||||
|
return new GradientObjectiveFunction(_function) |
||||
|
{ |
||||
|
Point = Point, |
||||
|
Value = Value, |
||||
|
Gradient = Gradient |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public bool IsGradientSupported |
||||
|
{ |
||||
|
get { return true; } |
||||
|
} |
||||
|
|
||||
|
public bool IsHessianSupported |
||||
|
{ |
||||
|
get { return false; } |
||||
|
} |
||||
|
|
||||
|
public void EvaluateAt(Vector<double> point) |
||||
|
{ |
||||
|
Point = point; |
||||
|
|
||||
|
var result = _function(point); |
||||
|
Value = result.Item1; |
||||
|
Gradient = result.Item2; |
||||
|
} |
||||
|
|
||||
|
public Vector<double> Point { get; private set; } |
||||
|
public double Value { get; private set; } |
||||
|
public Vector<double> Gradient { get; private set; } |
||||
|
|
||||
|
public Matrix<double> Hessian |
||||
|
{ |
||||
|
get { throw new NotSupportedException(); } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
using System; |
||||
|
using MathNet.Numerics.LinearAlgebra; |
||||
|
|
||||
|
namespace MathNet.Numerics.Optimization.ObjectiveFunctions |
||||
|
{ |
||||
|
internal class HessianObjectiveFunction : IObjectiveFunction |
||||
|
{ |
||||
|
readonly Func<Vector<double>, Tuple<double, Matrix<double>>> _function; |
||||
|
|
||||
|
public HessianObjectiveFunction(Func<Vector<double>, Tuple<double, Matrix<double>>> function) |
||||
|
{ |
||||
|
_function = function; |
||||
|
} |
||||
|
|
||||
|
public IObjectiveFunction CreateNew() |
||||
|
{ |
||||
|
return new HessianObjectiveFunction(_function); |
||||
|
} |
||||
|
|
||||
|
public IObjectiveFunction Fork() |
||||
|
{ |
||||
|
// no need to deep-clone values since they are replaced on evaluation
|
||||
|
return new HessianObjectiveFunction(_function) |
||||
|
{ |
||||
|
Point = Point, |
||||
|
Value = Value, |
||||
|
Hessian = Hessian |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public bool IsGradientSupported |
||||
|
{ |
||||
|
get { return false; } |
||||
|
} |
||||
|
|
||||
|
public bool IsHessianSupported |
||||
|
{ |
||||
|
get { return true; } |
||||
|
} |
||||
|
|
||||
|
public void EvaluateAt(Vector<double> point) |
||||
|
{ |
||||
|
Point = point; |
||||
|
|
||||
|
var result = _function(point); |
||||
|
Value = result.Item1; |
||||
|
Hessian = result.Item2; |
||||
|
} |
||||
|
|
||||
|
public Vector<double> Point { get; private set; } |
||||
|
public double Value { get; private set; } |
||||
|
public Matrix<double> Hessian { get; private set; } |
||||
|
|
||||
|
public Vector<double> Gradient |
||||
|
{ |
||||
|
get { throw new NotSupportedException(); } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,112 @@ |
|||||
|
using System; |
||||
|
using MathNet.Numerics.LinearAlgebra; |
||||
|
|
||||
|
namespace MathNet.Numerics.Optimization.ObjectiveFunctions |
||||
|
{ |
||||
|
internal class LazyObjectiveFunction : IObjectiveFunction |
||||
|
{ |
||||
|
readonly Func<Vector<double>, double> _function; |
||||
|
readonly Func<Vector<double>, Vector<double>> _gradient; |
||||
|
readonly Func<Vector<double>, Matrix<double>> _hessian; |
||||
|
|
||||
|
Vector<double> _point; |
||||
|
|
||||
|
bool _hasFunctionValue; |
||||
|
double _functionValue; |
||||
|
|
||||
|
bool _hasGradientValue; |
||||
|
Vector<double> _gradientValue; |
||||
|
|
||||
|
bool _hasHessianValue; |
||||
|
Matrix<double> _hessianValue; |
||||
|
|
||||
|
public LazyObjectiveFunction(Func<Vector<double>, double> function, Func<Vector<double>, Vector<double>> gradient = null, Func<Vector<double>, Matrix<double>> hessian = null) |
||||
|
{ |
||||
|
_function = function; |
||||
|
_gradient = gradient; |
||||
|
_hessian = hessian; |
||||
|
|
||||
|
IsGradientSupported = gradient != null; |
||||
|
IsHessianSupported = hessian != null; |
||||
|
} |
||||
|
|
||||
|
public IObjectiveFunction CreateNew() |
||||
|
{ |
||||
|
return new LazyObjectiveFunction(_function, _gradient, _hessian); |
||||
|
} |
||||
|
|
||||
|
public IObjectiveFunction Fork() |
||||
|
{ |
||||
|
// no need to deep-clone values since they are replaced on evaluation
|
||||
|
return new LazyObjectiveFunction(_function, _gradient, _hessian) |
||||
|
{ |
||||
|
_point = _point, |
||||
|
_hasFunctionValue = _hasFunctionValue, |
||||
|
_functionValue = _functionValue, |
||||
|
_hasGradientValue = _hasGradientValue, |
||||
|
_gradientValue = _gradientValue, |
||||
|
_hasHessianValue = _hasHessianValue, |
||||
|
_hessianValue = _hessianValue |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public bool IsGradientSupported { get; private set; } |
||||
|
public bool IsHessianSupported { get; private set; } |
||||
|
|
||||
|
public void EvaluateAt(Vector<double> point) |
||||
|
{ |
||||
|
_point = point; |
||||
|
_hasFunctionValue = false; |
||||
|
_hasGradientValue = false; |
||||
|
_hasHessianValue = false; |
||||
|
|
||||
|
// don't keep references unnecessarily
|
||||
|
_gradientValue = null; |
||||
|
_hessianValue = null; |
||||
|
} |
||||
|
|
||||
|
public Vector<double> Point |
||||
|
{ |
||||
|
get { return _point; } |
||||
|
} |
||||
|
|
||||
|
public double Value |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if (!_hasFunctionValue) |
||||
|
{ |
||||
|
_functionValue = _function(_point); |
||||
|
_hasFunctionValue = true; |
||||
|
} |
||||
|
return _functionValue; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public Vector<double> Gradient |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if (!_hasGradientValue) |
||||
|
{ |
||||
|
_gradientValue = _gradient(_point); |
||||
|
_hasGradientValue = true; |
||||
|
} |
||||
|
return _gradientValue; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public Matrix<double> Hessian |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if (!_hasHessianValue) |
||||
|
{ |
||||
|
_hessianValue = _hessian(_point); |
||||
|
_hasHessianValue = true; |
||||
|
} |
||||
|
return _hessianValue; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
using System; |
||||
|
using MathNet.Numerics.LinearAlgebra; |
||||
|
|
||||
|
namespace MathNet.Numerics.Optimization.ObjectiveFunctions |
||||
|
{ |
||||
|
internal class ValueObjectiveFunction : IObjectiveFunction |
||||
|
{ |
||||
|
readonly Func<Vector<double>, double> _function; |
||||
|
|
||||
|
public ValueObjectiveFunction(Func<Vector<double>, double> function) |
||||
|
{ |
||||
|
_function = function; |
||||
|
} |
||||
|
|
||||
|
public IObjectiveFunction CreateNew() |
||||
|
{ |
||||
|
return new ValueObjectiveFunction(_function); |
||||
|
} |
||||
|
|
||||
|
public IObjectiveFunction Fork() |
||||
|
{ |
||||
|
// no need to deep-clone values since they are replaced on evaluation
|
||||
|
return new ValueObjectiveFunction(_function) |
||||
|
{ |
||||
|
Point = Point, |
||||
|
Value = Value, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public bool IsGradientSupported |
||||
|
{ |
||||
|
get { return false; } |
||||
|
} |
||||
|
|
||||
|
public bool IsHessianSupported |
||||
|
{ |
||||
|
get { return false; } |
||||
|
} |
||||
|
|
||||
|
public void EvaluateAt(Vector<double> point) |
||||
|
{ |
||||
|
Point = point; |
||||
|
Value = _function(point); |
||||
|
} |
||||
|
|
||||
|
public Vector<double> Point { get; private set; } |
||||
|
public double Value { get; private set; } |
||||
|
|
||||
|
public Matrix<double> Hessian |
||||
|
{ |
||||
|
get { throw new NotSupportedException(); } |
||||
|
} |
||||
|
|
||||
|
public Vector<double> Gradient |
||||
|
{ |
||||
|
get { throw new NotSupportedException(); } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue