Browse Source

Optimization: Finish implementation of Golden Section minimum search

pull/489/head
Scott Stephens 13 years ago
committed by Erik Ovegard
parent
commit
59557c265d
  1. 1
      src/Numerics/Numerics.csproj
  2. 24
      src/Numerics/Optimization/GoldenSectionMinimizer.cs
  3. 17
      src/Numerics/Optimization/MinimizationResult1D.cs
  4. 6
      src/UnitTests/OptimizationTests/TestBfgsMinimizer.cs
  5. 1
      src/UnitTests/OptimizationTests/TestConjugateGradientMinimizer.cs
  6. 32
      src/UnitTests/OptimizationTests/TestGoldenSectionMinimizer.cs
  7. 1
      src/UnitTests/UnitTests.csproj

1
src/Numerics/Numerics.csproj

@ -264,6 +264,7 @@
<Compile Include="Optimization\BfgsMinimizer.cs" />
<Compile Include="Optimization\ConjugateGradientMinimizer.cs" />
<Compile Include="Optimization\GoldenSectionMinimizer.cs" />
<Compile Include="Optimization\MinimizationResult1D.cs" />
<Compile Include="Optimization\NewtonMinimizer.cs" />
<Compile Include="Optimization\ObjectiveFunction.cs" />
<Compile Include="Optimization\ObjectiveFunction1D.cs" />

24
src/Numerics/Optimization/GoldenSectionMinimizer.cs

@ -13,7 +13,7 @@ namespace MathNet.Numerics.Optimization
MaximumIterations = maxIterations;
}
public MinimizationResult FindMinimum(IObjectiveFunction1D objective, double lowerBound, double upperBound)
public MinimizationResult1D FindMinimum(IObjectiveFunction1D objective, double lowerBound, double upperBound)
{
double middlePointX = lowerBound + (upperBound - lowerBound) / (1 + Constants.GoldenRatio);
IEvaluation1D lower = objective.Evaluate(lowerBound);
@ -37,19 +37,29 @@ namespace MathNet.Numerics.Optimization
var test = objective.Evaluate(testX);
ValueChecker(test.Value, testX);
if (test.Value > middle.Value)
if (test.Point < middle.Point)
{
if (test.Point < middle.Point)
if (test.Value > middle.Value)
{
lower = test;
}
else
upper = test;
{
upper = middle;
middle = test;
}
}
else
{
if (test.Point < middle.Point)
upper = middle;
if (test.Value > middle.Value)
{
upper = test;
}
else
{
lower = middle;
middle = test;
}
}
iterations += 1;
@ -58,7 +68,7 @@ namespace MathNet.Numerics.Optimization
if (iterations == MaximumIterations)
throw new MaximumIterationsException("Max iterations reached.");
return null;
return new MinimizationResult1D(middle, iterations, MinimizationResult.ExitCondition.BoundTolerance);
}
private void ValueChecker(double value, double point)

17
src/Numerics/Optimization/MinimizationResult1D.cs

@ -0,0 +1,17 @@
namespace MathNet.Numerics.Optimization
{
public class MinimizationResult1D
{
public double MinimizingPoint { get { return FunctionInfoAtMinimum.Point; } }
public IEvaluation1D FunctionInfoAtMinimum { get; private set; }
public int Iterations { get; private set; }
public MinimizationResult.ExitCondition ReasonForExit { get; private set; }
public MinimizationResult1D(IEvaluation1D functionInfo, int iterations, MinimizationResult.ExitCondition reasonForExit)
{
FunctionInfoAtMinimum = functionInfo;
Iterations = iterations;
ReasonForExit = reasonForExit;
}
}
}

6
src/UnitTests/OptimizationTests/TestBfgsMinimizer.cs

@ -12,7 +12,7 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
public void FindMinimum_Rosenbrock_Easy()
{
var obj = ObjectiveFunction.Gradient(RosenbrockFunction.Value, RosenbrockFunction.Gradient);
var solver = new BfgsMinimizer(1e-5, 1000);
var solver = new BfgsMinimizer(1e-5, 1e-5, 1000);
var result = solver.FindMinimum(obj, new DenseVector(new[] { 1.2, 1.2 }));
Assert.That(Math.Abs(result.MinimizingPoint[0] - 1.0), Is.LessThan(1e-3));
@ -23,7 +23,7 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
public void FindMinimum_Rosenbrock_Hard()
{
var obj = ObjectiveFunction.Gradient(RosenbrockFunction.Value, RosenbrockFunction.Gradient);
var solver = new BfgsMinimizer(1e-5, 1000);
var solver = new BfgsMinimizer(1e-5, 1e-5, 1000);
var result = solver.FindMinimum(obj, new DenseVector(new[] { -1.2, 1.0 }));
Assert.That(Math.Abs(result.MinimizingPoint[0] - 1.0), Is.LessThan(1e-3));
@ -34,7 +34,7 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
public void FindMinimum_Rosenbrock_Overton()
{
var obj = ObjectiveFunction.Gradient(RosenbrockFunction.Value, RosenbrockFunction.Gradient);
var solver = new BfgsMinimizer(1e-5, 1000);
var solver = new BfgsMinimizer(1e-5, 1e-5, 1000);
var result = solver.FindMinimum(obj, new DenseVector(new[] { -0.9, -0.5 }));
Assert.That(Math.Abs(result.MinimizingPoint[0] - 1.0), Is.LessThan(1e-3));

1
src/UnitTests/OptimizationTests/TestConjugateGradientMinimizer.cs

@ -8,7 +8,6 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
[TestFixture]
public class TestConjugateGradientMinimizer
{
[Test]
public void FindMinimum_Rosenbrock_Easy()
{

32
src/UnitTests/OptimizationTests/TestGoldenSectionMinimizer.cs

@ -0,0 +1,32 @@
using System;
using MathNet.Numerics.Optimization;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.OptimizationTests
{
[TestFixture]
public class TestGoldenSectionMinimizer
{
[Test]
public void Test_Works()
{
var algorithm = new GoldenSectionMinimizer(1e-5, 1000);
var f1 = new Func<double, double>(x => (x - 3)*(x - 3));
var obj = new SimpleObjectiveFunction1D(f1);
var r1 = algorithm.FindMinimum(obj, -100, 100);
Assert.That(Math.Abs(r1.MinimizingPoint - 3.0), Is.LessThan(1e-4));
}
[Test]
public void Test_ExpansionWorks()
{
var algorithm = new GoldenSectionMinimizer(1e-5, 1000);
var f1 = new Func<double, double>(x => (x - 3) * (x - 3));
var obj = new SimpleObjectiveFunction1D(f1);
var r1 = algorithm.FindMinimum(obj, -5, 5);
Assert.That(Math.Abs(r1.MinimizingPoint - 3.0), Is.LessThan(1e-4));
}
}
}

1
src/UnitTests/UnitTests.csproj

@ -368,6 +368,7 @@
<Compile Include="Random\RandomSerializationTests.cs" />
<Compile Include="OptimizationTests\RosenbrockFunction.cs" />
<Compile Include="OptimizationTests\TestNewtonMinimizer.cs" />
<Compile Include="OptimizationTests\TestGoldenSectionMinimizer.cs" />
<Compile Include="Random\SystemRandomSourceTests.cs" />
<Compile Include="OptimizationTests\BfgsTest.cs" />
<Compile Include="RootFindingTests\BisectionTest.cs" />

Loading…
Cancel
Save