Browse Source

Optimization: InplaceObjectiveFunction

unified_optimization
Christoph Ruegg 12 years ago
parent
commit
7139108a19
  1. 1
      src/Numerics/Numerics.csproj
  2. 10
      src/Numerics/Optimization/BaseObjectiveFunction.cs
  3. 62
      src/Numerics/Optimization/ObjectiveFunctions/InplaceObjectiveFunction.cs
  4. 26
      src/UnitTests/OptimizationTests/TestNewtonMinimizer.cs

1
src/Numerics/Numerics.csproj

@ -104,6 +104,7 @@
<Compile Include="LinearRegression\Options.cs" />
<Compile Include="Optimization\BaseObjectiveFunction.cs" />
<Compile Include="Optimization\Exceptions.cs" />
<Compile Include="Optimization\ObjectiveFunctions\InplaceObjectiveFunction.cs" />
<Compile Include="Optimization\ObjectiveFunctions\LazyObjectiveFunction.cs" />
<Compile Include="Optimization\ObjectiveFunction.cs" />
<Compile Include="Optimization\ObjectiveFunctions\ValueObjectiveFunction.cs" />

10
src/Numerics/Optimization/BaseObjectiveFunction.cs

@ -33,15 +33,7 @@ namespace MathNet.Numerics.Optimization
public Vector<double> Point
{
get
{
return PointRaw;
}
set
{
PointRaw = value;
Status = EvaluationStatus.None;
}
get { return PointRaw; }
}
public void EvaluateAt(Vector<double> point)

62
src/Numerics/Optimization/ObjectiveFunctions/InplaceObjectiveFunction.cs

@ -0,0 +1,62 @@
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; }
}
}
}

26
src/UnitTests/OptimizationTests/TestNewtonMinimizer.cs

@ -1,14 +1,15 @@
using System;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.Optimization;
using MathNet.Numerics.Optimization.ObjectiveFunctions;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.OptimizationTests
{
public class RosenbrockObjectiveFunction : BaseObjectiveFunction
{
public RosenbrockObjectiveFunction()
: base(true, true) { }
public RosenbrockObjectiveFunction() : base(true, true) { }
protected override void SetValue()
{
@ -31,6 +32,25 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
}
}
public class InplaceRosenbrockObjectiveFunction : InplaceObjectiveFunction
{
public InplaceRosenbrockObjectiveFunction() : base(true, true) { }
public override IObjectiveFunction CreateNew()
{
return new InplaceRosenbrockObjectiveFunction();
}
protected override void EvaluateAt(Vector<double> point, ref double value, ref Vector<double> gradient, ref Matrix<double> hessian)
{
// here we could directly overwrite the existing matrices instead.
// note: values must then be initialized manually here first, if null.
value = RosenbrockFunction.Value(point);
gradient = RosenbrockFunction.Gradient(point);
hessian = RosenbrockFunction.Hessian(point);
}
}
[TestFixture]
public class TestNewtonMinimizer
{
@ -70,7 +90,7 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
[Test]
public void FindMinimum_Linesearch_Rosenbrock_Easy()
{
var obj = new RosenbrockObjectiveFunction();
var obj = new InplaceRosenbrockObjectiveFunction();
var solver = new NewtonMinimizer(1e-5, 1000, true);
var result = solver.FindMinimum(obj, new DenseVector(new[] { 1.2, 1.2 }));

Loading…
Cancel
Save