6 changed files with 186 additions and 187 deletions
@ -1,99 +0,0 @@ |
|||||
using System; |
|
||||
using MathNet.Numerics.LinearAlgebra; |
|
||||
|
|
||||
namespace MathNet.Numerics.Optimization |
|
||||
{ |
|
||||
public abstract class BaseObjectiveFunction : IObjectiveFunction |
|
||||
{ |
|
||||
[Flags] |
|
||||
enum EvaluationStatus |
|
||||
{ |
|
||||
None = 0, |
|
||||
Value = 1, |
|
||||
Gradient = 2, |
|
||||
Hessian = 4 |
|
||||
} |
|
||||
|
|
||||
EvaluationStatus Status { get; set; } |
|
||||
|
|
||||
protected Vector<double> PointRaw { get; set; } |
|
||||
protected double ValueRaw { get; set; } |
|
||||
protected Vector<double> GradientRaw { get; set; } |
|
||||
protected Matrix<double> HessianRaw { get; set; } |
|
||||
|
|
||||
public bool IsGradientSupported { get; private set; } |
|
||||
public bool IsHessianSupported { get; private set; } |
|
||||
|
|
||||
protected BaseObjectiveFunction(bool gradientSupported, bool hessianSupported) |
|
||||
{ |
|
||||
Status = EvaluationStatus.None; |
|
||||
IsGradientSupported = gradientSupported; |
|
||||
IsHessianSupported = hessianSupported; |
|
||||
} |
|
||||
|
|
||||
public Vector<double> Point |
|
||||
{ |
|
||||
get { return PointRaw; } |
|
||||
} |
|
||||
|
|
||||
public void EvaluateAt(Vector<double> point) |
|
||||
{ |
|
||||
PointRaw = point; |
|
||||
Status = EvaluationStatus.None; |
|
||||
} |
|
||||
|
|
||||
public double Value |
|
||||
{ |
|
||||
get |
|
||||
{ |
|
||||
if (!Status.HasFlag(EvaluationStatus.Value)) |
|
||||
{ |
|
||||
SetValue(); |
|
||||
Status |= EvaluationStatus.Value; |
|
||||
} |
|
||||
return ValueRaw; |
|
||||
} |
|
||||
} |
|
||||
public Vector<double> Gradient |
|
||||
{ |
|
||||
get |
|
||||
{ |
|
||||
if (!Status.HasFlag(EvaluationStatus.Gradient)) |
|
||||
{ |
|
||||
SetGradient(); |
|
||||
Status |= EvaluationStatus.Gradient; |
|
||||
} |
|
||||
return GradientRaw; |
|
||||
} |
|
||||
} |
|
||||
public Matrix<double> Hessian |
|
||||
{ |
|
||||
get |
|
||||
{ |
|
||||
if (!Status.HasFlag(EvaluationStatus.Hessian)) |
|
||||
{ |
|
||||
SetHessian(); |
|
||||
Status |= EvaluationStatus.Hessian; |
|
||||
} |
|
||||
return HessianRaw; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public abstract IObjectiveFunction CreateNew(); |
|
||||
|
|
||||
public virtual IObjectiveFunction Fork() |
|
||||
{ |
|
||||
BaseObjectiveFunction fork = (BaseObjectiveFunction)CreateNew(); |
|
||||
fork.PointRaw = PointRaw; |
|
||||
fork.ValueRaw = ValueRaw; |
|
||||
fork.GradientRaw = GradientRaw; |
|
||||
fork.HessianRaw = HessianRaw; |
|
||||
fork.Status = Status; |
|
||||
return fork; |
|
||||
} |
|
||||
|
|
||||
protected abstract void SetValue(); |
|
||||
protected abstract void SetGradient(); |
|
||||
protected abstract void SetHessian(); |
|
||||
} |
|
||||
} |
|
||||
@ -1,62 +0,0 @@ |
|||||
using MathNet.Numerics.LinearAlgebra; |
|
||||
|
|
||||
namespace MathNet.Numerics.Optimization.ObjectiveFunctions |
|
||||
{ |
|
||||
public abstract class InplaceObjectiveFunction : IObjectiveFunction |
|
||||
{ |
|
||||
Vector<double> _point; |
|
||||
double _functionValue; |
|
||||
Vector<double> _gradientValue; |
|
||||
Matrix<double> _hessianValue; |
|
||||
|
|
||||
protected InplaceObjectiveFunction(bool isGradientSupported, bool isHessianSupported) |
|
||||
{ |
|
||||
IsGradientSupported = isGradientSupported; |
|
||||
IsHessianSupported = isHessianSupported; |
|
||||
} |
|
||||
|
|
||||
public abstract IObjectiveFunction CreateNew(); |
|
||||
|
|
||||
public virtual IObjectiveFunction Fork() |
|
||||
{ |
|
||||
// no need to deep-clone values since they are replaced on evaluation
|
|
||||
InplaceObjectiveFunction objective = (InplaceObjectiveFunction)CreateNew(); |
|
||||
objective._point = _point == null ? null : _point.Clone(); |
|
||||
objective._functionValue = _functionValue; |
|
||||
objective._gradientValue = _gradientValue == null ? null : _gradientValue.Clone(); |
|
||||
objective._hessianValue = _hessianValue == null ? null : _hessianValue.Clone(); |
|
||||
return objective; |
|
||||
} |
|
||||
|
|
||||
public bool IsGradientSupported { get; private set; } |
|
||||
public bool IsHessianSupported { get; private set; } |
|
||||
|
|
||||
public void EvaluateAt(Vector<double> point) |
|
||||
{ |
|
||||
_point = point; |
|
||||
EvaluateAt(_point, ref _functionValue, ref _gradientValue, ref _hessianValue); |
|
||||
} |
|
||||
|
|
||||
protected abstract void EvaluateAt(Vector<double> point, ref double value, ref Vector<double> gradient, ref Matrix<double> hessian); |
|
||||
|
|
||||
public Vector<double> Point |
|
||||
{ |
|
||||
get { return _point; } |
|
||||
} |
|
||||
|
|
||||
public double Value |
|
||||
{ |
|
||||
get { return _functionValue; } |
|
||||
} |
|
||||
|
|
||||
public Vector<double> Gradient |
|
||||
{ |
|
||||
get { return _gradientValue; } |
|
||||
} |
|
||||
|
|
||||
public Matrix<double> Hessian |
|
||||
{ |
|
||||
get { return _hessianValue; } |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,119 @@ |
|||||
|
using MathNet.Numerics.LinearAlgebra; |
||||
|
|
||||
|
namespace MathNet.Numerics.Optimization.ObjectiveFunctions |
||||
|
{ |
||||
|
public abstract class LazyObjectiveFunctionBase : IObjectiveFunction |
||||
|
{ |
||||
|
Vector<double> _point; |
||||
|
|
||||
|
bool _hasFunctionValue; |
||||
|
double _functionValue; |
||||
|
|
||||
|
bool _hasGradientValue; |
||||
|
Vector<double> _gradientValue; |
||||
|
|
||||
|
bool _hasHessianValue; |
||||
|
Matrix<double> _hessianValue; |
||||
|
|
||||
|
protected LazyObjectiveFunctionBase(bool gradientSupported, bool hessianSupported) |
||||
|
{ |
||||
|
IsGradientSupported = gradientSupported; |
||||
|
IsHessianSupported = hessianSupported; |
||||
|
} |
||||
|
|
||||
|
public abstract IObjectiveFunction CreateNew(); |
||||
|
|
||||
|
public virtual IObjectiveFunction Fork() |
||||
|
{ |
||||
|
// we need to deep-clone values since they may be updated inplace on evaluation
|
||||
|
LazyObjectiveFunctionBase fork = (LazyObjectiveFunctionBase)CreateNew(); |
||||
|
fork._point = _point == null ? null : _point.Clone(); |
||||
|
fork._hasFunctionValue = _hasFunctionValue; |
||||
|
fork._functionValue = _functionValue; |
||||
|
fork._hasGradientValue = _hasGradientValue; |
||||
|
fork._gradientValue = _gradientValue == null ? null : _gradientValue.Clone(); ; |
||||
|
fork._hasHessianValue = _hasHessianValue; |
||||
|
fork._hessianValue = _hessianValue == null ? null : _hessianValue.Clone(); |
||||
|
return fork; |
||||
|
} |
||||
|
|
||||
|
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; |
||||
|
} |
||||
|
|
||||
|
protected abstract void EvaluateValue(); |
||||
|
|
||||
|
protected virtual void EvaluateGradient() |
||||
|
{ |
||||
|
Gradient = null; |
||||
|
} |
||||
|
|
||||
|
protected virtual void EvaluateHessian() |
||||
|
{ |
||||
|
Hessian = null; |
||||
|
} |
||||
|
|
||||
|
public Vector<double> Point |
||||
|
{ |
||||
|
get { return _point; } |
||||
|
} |
||||
|
|
||||
|
public double Value |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if (!_hasFunctionValue) |
||||
|
{ |
||||
|
EvaluateValue(); |
||||
|
} |
||||
|
return _functionValue; |
||||
|
} |
||||
|
protected set |
||||
|
{ |
||||
|
_functionValue = value; |
||||
|
_hasFunctionValue = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public Vector<double> Gradient |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if (!_hasGradientValue) |
||||
|
{ |
||||
|
EvaluateGradient(); |
||||
|
} |
||||
|
return _gradientValue; |
||||
|
} |
||||
|
protected set |
||||
|
{ |
||||
|
_gradientValue = value; |
||||
|
_hasGradientValue = true; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public Matrix<double> Hessian |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if (!_hasHessianValue) |
||||
|
{ |
||||
|
EvaluateHessian(); |
||||
|
} |
||||
|
return _hessianValue; |
||||
|
} |
||||
|
protected set |
||||
|
{ |
||||
|
_hessianValue = value; |
||||
|
_hasHessianValue = true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
using MathNet.Numerics.LinearAlgebra; |
||||
|
|
||||
|
namespace MathNet.Numerics.Optimization.ObjectiveFunctions |
||||
|
{ |
||||
|
public abstract class ObjectiveFunctionBase : IObjectiveFunction |
||||
|
{ |
||||
|
protected ObjectiveFunctionBase(bool isGradientSupported, bool isHessianSupported) |
||||
|
{ |
||||
|
IsGradientSupported = isGradientSupported; |
||||
|
IsHessianSupported = isHessianSupported; |
||||
|
} |
||||
|
|
||||
|
public abstract IObjectiveFunction CreateNew(); |
||||
|
|
||||
|
public virtual IObjectiveFunction Fork() |
||||
|
{ |
||||
|
// we need to deep-clone values since they may be updated inplace on evaluation
|
||||
|
ObjectiveFunctionBase objective = (ObjectiveFunctionBase)CreateNew(); |
||||
|
objective.Point = Point == null ? null : Point.Clone(); |
||||
|
objective.Value = Value; |
||||
|
objective.Gradient = Gradient == null ? null : Gradient.Clone(); |
||||
|
objective.Hessian = Hessian == null ? null : Hessian.Clone(); |
||||
|
return objective; |
||||
|
} |
||||
|
|
||||
|
public bool IsGradientSupported { get; private set; } |
||||
|
public bool IsHessianSupported { get; private set; } |
||||
|
|
||||
|
public void EvaluateAt(Vector<double> point) |
||||
|
{ |
||||
|
Point = point; |
||||
|
Evaluate(); |
||||
|
} |
||||
|
|
||||
|
protected abstract void Evaluate(); |
||||
|
|
||||
|
public Vector<double> Point { get; private set; } |
||||
|
public double Value { get; protected set; } |
||||
|
public Vector<double> Gradient { get; protected set; } |
||||
|
public Matrix<double> Hessian { get; protected set; } |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue