Browse Source

Optimization: tweak IObjectiveFunction interface

pull/489/head
Christoph Ruegg 11 years ago
committed by Erik Ovegard
parent
commit
38b68c3e28
  1. 17
      src/Numerics/Optimization/BaseObjectiveFunction.cs
  2. 20
      src/Numerics/Optimization/IObjectiveFunction.cs
  3. 16
      src/Numerics/Optimization/Implementation/CheckedObjectiveFunction.cs
  4. 3
      src/Numerics/Optimization/Implementation/NullObjectiveFunction.cs
  5. 4
      src/Numerics/Optimization/Implementation/WeakWolfeLineSearch.cs
  6. 10
      src/Numerics/Optimization/NewtonMinimizer.cs
  7. 2
      src/UnitTests/OptimizationTests/TestNewtonMinimizer.cs

17
src/Numerics/Optimization/BaseObjectiveFunction.cs

@ -11,14 +11,14 @@ namespace MathNet.Numerics.Optimization
protected Vector<double> GradientRaw { get; set; } protected Vector<double> GradientRaw { get; set; }
protected Matrix<double> HessianRaw { get; set; } protected Matrix<double> HessianRaw { get; set; }
public bool GradientSupported { get; private set; } public bool IsGradientSupported { get; private set; }
public bool HessianSupported { get; private set; } public bool IsHessianSupported { get; private set; }
protected BaseObjectiveFunction(bool gradientSupported, bool hessianSupported) protected BaseObjectiveFunction(bool gradientSupported, bool hessianSupported)
{ {
Status = EvaluationStatus.None; Status = EvaluationStatus.None;
GradientSupported = gradientSupported; IsGradientSupported = gradientSupported;
HessianSupported = hessianSupported; IsHessianSupported = hessianSupported;
} }
public Vector<double> Point public Vector<double> Point
@ -34,6 +34,12 @@ namespace MathNet.Numerics.Optimization
} }
} }
public void EvaluateAt(Vector<double> point)
{
PointRaw = point;
Status = EvaluationStatus.None;
}
public double Value public double Value
{ {
get get
@ -71,9 +77,10 @@ namespace MathNet.Numerics.Optimization
} }
} }
public abstract IObjectiveFunction Fork();
protected abstract void SetValue(); protected abstract void SetValue();
protected abstract void SetGradient(); protected abstract void SetGradient();
protected abstract void SetHessian(); protected abstract void SetHessian();
public abstract IObjectiveFunction CreateNew();
} }
} }

20
src/Numerics/Optimization/IObjectiveFunction.cs

@ -4,18 +4,26 @@ using MathNet.Numerics.LinearAlgebra;
namespace MathNet.Numerics.Optimization namespace MathNet.Numerics.Optimization
{ {
[Flags] [Flags]
public enum EvaluationStatus { None = 0, Value = 1, Gradient = 2, Hessian = 4 } public enum EvaluationStatus
{
None = 0,
Value = 1,
Gradient = 2,
Hessian = 4
}
public interface IObjectiveFunction public interface IObjectiveFunction
{ {
Vector<double> Point { get; set; } void EvaluateAt(Vector<double> point);
IObjectiveFunction CreateNew(); IObjectiveFunction Fork();
// Used by algorithm Vector<double> Point { get; }
bool GradientSupported { get; }
bool HessianSupported { get; }
double Value { get; } double Value { get; }
bool IsGradientSupported { get; }
Vector<double> Gradient { get; } Vector<double> Gradient { get; }
bool IsHessianSupported { get; }
Matrix<double> Hessian { get; } Matrix<double> Hessian { get; }
} }
} }

16
src/Numerics/Optimization/Implementation/CheckedObjectiveFunction.cs

@ -25,7 +25,11 @@ namespace MathNet.Numerics.Optimization.Implementation
public Vector<double> Point public Vector<double> Point
{ {
get { return InnerObjectiveFunction.Point; } get { return InnerObjectiveFunction.Point; }
set { InnerObjectiveFunction.Point = value; } }
public void EvaluateAt(Vector<double> point)
{
InnerObjectiveFunction.EvaluateAt(point);
} }
public double Value public double Value
@ -97,19 +101,19 @@ namespace MathNet.Numerics.Optimization.Implementation
} }
} }
public IObjectiveFunction CreateNew() public IObjectiveFunction Fork()
{ {
return new CheckedObjectiveFunction(InnerObjectiveFunction, ValueChecker, GradientChecker, HessianChecker); return new CheckedObjectiveFunction(InnerObjectiveFunction, ValueChecker, GradientChecker, HessianChecker);
} }
public bool GradientSupported public bool IsGradientSupported
{ {
get { return InnerObjectiveFunction.GradientSupported; } get { return InnerObjectiveFunction.IsGradientSupported; }
} }
public bool HessianSupported public bool IsHessianSupported
{ {
get { return InnerObjectiveFunction.HessianSupported; } get { return InnerObjectiveFunction.IsHessianSupported; }
} }
} }
} }

3
src/Numerics/Optimization/Implementation/NullObjectiveFunction.cs

@ -10,6 +10,7 @@ namespace MathNet.Numerics.Optimization.Implementation
{ {
Point = point; Point = point;
} }
protected override void SetValue() protected override void SetValue()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
@ -25,7 +26,7 @@ namespace MathNet.Numerics.Optimization.Implementation
throw new NotImplementedException(); throw new NotImplementedException();
} }
public override IObjectiveFunction CreateNew() public override IObjectiveFunction Fork()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

4
src/Numerics/Optimization/Implementation/WeakWolfeLineSearch.cs

@ -36,11 +36,11 @@ namespace MathNet.Numerics.Optimization.Implementation
double initialDd = searchDirection * initialGradient; double initialDd = searchDirection * initialGradient;
int ii; int ii;
IObjectiveFunction candidateEval = objective.CreateNew(); IObjectiveFunction candidateEval = objective.Fork();
MinimizationOutput.ExitCondition reasonForExit = MinimizationOutput.ExitCondition.None; MinimizationOutput.ExitCondition reasonForExit = MinimizationOutput.ExitCondition.None;
for (ii = 0; ii < _maximumIterations; ++ii) for (ii = 0; ii < _maximumIterations; ++ii)
{ {
candidateEval.Point = startingPoint.Point + searchDirection * step; candidateEval.EvaluateAt(startingPoint.Point + searchDirection * step);
double stepDd = searchDirection * candidateEval.Gradient; double stepDd = searchDirection * candidateEval.Gradient;

10
src/Numerics/Optimization/NewtonMinimizer.cs

@ -20,17 +20,17 @@ namespace MathNet.Numerics.Optimization
public MinimizationOutput FindMinimum(IObjectiveFunction objective, Vector<double> initialGuess) public MinimizationOutput FindMinimum(IObjectiveFunction objective, Vector<double> initialGuess)
{ {
if (!objective.GradientSupported) if (!objective.IsGradientSupported)
throw new IncompatibleObjectiveException("Gradient not supported in objective function, but required for Newton minimization."); throw new IncompatibleObjectiveException("Gradient not supported in objective function, but required for Newton minimization.");
if (!objective.HessianSupported) if (!objective.IsHessianSupported)
throw new IncompatibleObjectiveException("Hessian not supported in objective function, but required for Newton minimization."); throw new IncompatibleObjectiveException("Hessian not supported in objective function, but required for Newton minimization.");
if (!(objective is CheckedObjectiveFunction)) if (!(objective is CheckedObjectiveFunction))
objective = new CheckedObjectiveFunction(objective, ValidateObjective, ValidateGradient, ValidateHessian); objective = new CheckedObjectiveFunction(objective, ValidateObjective, ValidateGradient, ValidateHessian);
IObjectiveFunction initialEval = objective.CreateNew(); IObjectiveFunction initialEval = objective.Fork();
initialEval.Point = initialGuess; initialEval.EvaluateAt(initialGuess);
// Check that we're not already done // Check that we're not already done
if (ExitCriteriaSatisfied(initialGuess, initialEval.Gradient)) if (ExitCriteriaSatisfied(initialGuess, initialEval.Gradient))
@ -73,7 +73,7 @@ namespace MathNet.Numerics.Optimization
} }
else else
{ {
candidatePoint.Point = candidatePoint.Point + searchDirection; candidatePoint.EvaluateAt(candidatePoint.Point + searchDirection);
} }
tmpLineSearch = false; tmpLineSearch = false;

2
src/UnitTests/OptimizationTests/TestNewtonMinimizer.cs

@ -25,7 +25,7 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
HessianRaw = RosenbrockFunction.Hessian(Point); HessianRaw = RosenbrockFunction.Hessian(Point);
} }
public override IObjectiveFunction CreateNew() public override IObjectiveFunction Fork()
{ {
return new RosenbrockObjectiveFunction(); return new RosenbrockObjectiveFunction();
} }

Loading…
Cancel
Save