Browse Source

Very minimally tested ConjugateGradient minimizer is complete.

unified_optimization
Scott Stephens 14 years ago
committed by Christoph Ruegg
parent
commit
edbab552eb
  1. 26
      src/Numerics/Optimization/ConjugateGradientMinimizer.cs
  2. 24
      src/UnitTests/OptimizationTests/TestConjugateGradientMinimizer.cs
  3. 4
      src/UnitTests/UnitTests.csproj

26
src/Numerics/Optimization/ConjugateGradientMinimizer.cs

@ -34,25 +34,41 @@ namespace MathNet.Numerics.Optimization
// First step // First step
var steepestDirection = -gradient; var steepestDirection = -gradient;
var searchDirection = steepestDirection; var searchDirection = steepestDirection;
var result = lineSearcher.FindConformingStep(objective, searchDirection, 1.0); double initialStepSize = 100 * GradientTolerance / (gradient * gradient);
var result = lineSearcher.FindConformingStep(objective, searchDirection, initialStepSize);
objective = result.FunctionInfoAtMinimum; objective = result.FunctionInfoAtMinimum;
ValidateGradient(objective.Gradient, objective.Point); ValidateGradient(objective.Gradient, objective.Point);
double stepSize = (objective.Point - initialGuess).Norm(2.0);
// Subsequent steps // Subsequent steps
int iterations = 1; int iterations = 1;
int totalLineSearchSteps = result.Iterations;
int noLineSearchIterations = result.Iterations > 0 ? 0 : 1;
int steepestDescentResets = 0;
while (!ExitCriteriaSatisfied(objective.Point, objective.Gradient) && iterations < MaximumIterations) while (!ExitCriteriaSatisfied(objective.Point, objective.Gradient) && iterations < MaximumIterations)
{ {
var previousSteepestDirection = steepestDirection; var previousSteepestDirection = steepestDirection;
steepestDirection = -objective.Gradient; steepestDirection = -objective.Gradient;
var searchDirectionAdjuster = steepestDirection * (steepestDirection - previousSteepestDirection) / (previousSteepestDirection * previousSteepestDirection); var searchDirectionAdjuster = Math.Max(0, steepestDirection*(steepestDirection - previousSteepestDirection)/(previousSteepestDirection*previousSteepestDirection));
searchDirection = steepestDirection + searchDirectionAdjuster * previousSteepestDirection; searchDirection = steepestDirection + searchDirectionAdjuster * searchDirection;
result = lineSearcher.FindConformingStep(objective, searchDirection, 1.0); if (searchDirection * objective.Gradient >= 0)
{
searchDirection = steepestDirection;
steepestDescentResets += 1;
}
result = lineSearcher.FindConformingStep(objective, searchDirection, stepSize);
noLineSearchIterations += result.Iterations == 0 ? 1 : 0;
totalLineSearchSteps += result.Iterations;
stepSize = (result.FunctionInfoAtMinimum.Point - objective.Point).Norm(2.0);
objective = result.FunctionInfoAtMinimum; objective = result.FunctionInfoAtMinimum;
iterations += 1; iterations += 1;
} }
return new MinimizationResult(objective, iterations, MinimizationResult.ExitCondition.AbsoluteGradient); return new MinimizationWithLineSearchResult(objective, iterations, MinimizationResult.ExitCondition.AbsoluteGradient, totalLineSearchSteps, noLineSearchIterations);
} }
private bool ExitCriteriaSatisfied(Vector<double> candidatePoint, Vector<double> gradient) private bool ExitCriteriaSatisfied(Vector<double> candidatePoint, Vector<double> gradient)

24
src/UnitTests/OptimizationTests/TestConjugateGradientMinimizer.cs

@ -1,11 +1,7 @@
using System; using System;
using System.Collections.Generic; using MathNet.Numerics.LinearAlgebra.Double;
using System.Linq;
using System.Text;
using NUnit.Framework;
using MathNet.Numerics.Optimization; using MathNet.Numerics.Optimization;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.OptimizationTests namespace MathNet.Numerics.UnitTests.OptimizationTests
{ {
@ -16,17 +12,23 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
[Test] [Test]
public void FindMinimum_Rosenbrock_Easy() public void FindMinimum_Rosenbrock_Easy()
{ {
var obj = new SimpleObjectiveFunction(RosenbrockFunction.Value, RosenbrockFunction.Gradient); var obj = ObjectiveFunction.Gradient(RosenbrockFunction.Value, RosenbrockFunction.Gradient);
var solver = new ConjugateGradientMinimizer(1e-5, 100); var solver = new ConjugateGradientMinimizer(1e-5, 1000);
var result = solver.FindMinimum(obj, new MathNet.Numerics.LinearAlgebra.Double.DenseVector(new double[]{1.2,1.2})); var result = solver.FindMinimum(obj, new DenseVector(new[]{1.2,1.2}));
Assert.That(result.MinimizingPoint[0], Is.EqualTo(1.0));
Assert.That(result.MinimizingPoint[1], Is.EqualTo(1.0)); Assert.That(Math.Abs(result.MinimizingPoint[0]-1.0), Is.LessThan(1e-3));
Assert.That(Math.Abs(result.MinimizingPoint[1] - 1.0), Is.LessThan(1e-3));
} }
[Test] [Test]
public void FindMinimum_Rosenbrock_Hard() public void FindMinimum_Rosenbrock_Hard()
{ {
var obj = ObjectiveFunction.Gradient(RosenbrockFunction.Value, RosenbrockFunction.Gradient);
var solver = new ConjugateGradientMinimizer(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));
Assert.That(Math.Abs(result.MinimizingPoint[1] - 1.0), Is.LessThan(1e-3));
} }
} }
} }

4
src/UnitTests/UnitTests.csproj

@ -349,10 +349,6 @@
<Compile Include="Random\SystemRandomSourceTests.cs" /> <Compile Include="Random\SystemRandomSourceTests.cs" />
<Compile Include="OptimizationTests\BfgsTest.cs" /> <Compile Include="OptimizationTests\BfgsTest.cs" />
<Compile Include="RootFindingTests\BisectionTest.cs" /> <Compile Include="RootFindingTests\BisectionTest.cs" />
<Compile Include="MatrixHelpers.cs" />
<Compile Include="NumberTheoryTests\GcdRelatedTest.cs" />
<Compile Include="NumberTheoryTests\GcdRelatedTestBigInteger.cs" />
<Compile Include="NumberTheoryTests\IntegerTheoryTest.cs" />
<Compile Include="OptimizationTests\RosenbrockFunction.cs" /> <Compile Include="OptimizationTests\RosenbrockFunction.cs" />
<Compile Include="OptimizationTests\TestConjugateGradientMinimizer.cs" /> <Compile Include="OptimizationTests\TestConjugateGradientMinimizer.cs" />
<Compile Include="PermutationTest.cs" /> <Compile Include="PermutationTest.cs" />

Loading…
Cancel
Save