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