Browse Source

Optimization: rename Evaluation to ObjectiveFunction

pull/489/head
Christoph Ruegg 11 years ago
committed by Erik Ovegard
parent
commit
bf23e770de
  1. 5
      src/Numerics/Numerics.csproj
  2. 6
      src/Numerics/Optimization/BaseObjectiveFunction.cs
  3. 10
      src/Numerics/Optimization/Exceptions.cs
  4. 4
      src/Numerics/Optimization/IObjectiveFunction.cs
  5. 2
      src/Numerics/Optimization/IUnconstrainedMinimizer.cs
  6. 2
      src/Numerics/Optimization/Implementation/LineSearchOutput.cs
  7. 6
      src/Numerics/Optimization/Implementation/NullObjectiveFunction.cs
  8. 50
      src/Numerics/Optimization/Implementation/ObjectiveChecker.cs
  9. 14
      src/Numerics/Optimization/Implementation/WeakWolfeLineSearch.cs
  10. 4
      src/Numerics/Optimization/MinimizationOutput.cs
  11. 2
      src/Numerics/Optimization/MinimizationWithLineSearchOutput.cs
  12. 16
      src/Numerics/Optimization/NewtonMinimizer.cs
  13. 11
      src/UnitTests/OptimizationTests/RosenbrockFunction.cs
  14. 46
      src/UnitTests/OptimizationTests/TestNewtonMinimizer.cs

5
src/Numerics/Numerics.csproj

@ -116,10 +116,11 @@
<Compile Include="OdeSolvers\AdamsBashforth.cs" />
<Compile Include="OdeSolvers\RungeKutta.cs" />
<Compile Include="Optimization\BaseEvaluation.cs" />
<Compile Include="Optimization\BaseObjectiveFunction.cs" />
<Compile Include="Optimization\Exceptions.cs" />
<Compile Include="Optimization\IEvaluation.cs" />
<Compile Include="Optimization\IObjectiveFunction.cs" />
<Compile Include="Optimization\Implementation\LineSearchOutput.cs" />
<Compile Include="Optimization\Implementation\NullEvaluation.cs" />
<Compile Include="Optimization\Implementation\NullObjectiveFunction.cs" />
<Compile Include="Optimization\Implementation\ObjectiveChecker.cs" />
<Compile Include="Optimization\Implementation\WeakWolfeLineSearch.cs" />
<Compile Include="Optimization\IUnconstrainedMinimizer.cs" />

6
src/Numerics/Optimization/BaseEvaluation.cs → src/Numerics/Optimization/BaseObjectiveFunction.cs

@ -2,7 +2,7 @@
namespace MathNet.Numerics.Optimization
{
public abstract class BaseEvaluation : IEvaluation
public abstract class BaseObjectiveFunction : IObjectiveFunction
{
public EvaluationStatus Status { get; protected set; }
@ -14,7 +14,7 @@ namespace MathNet.Numerics.Optimization
public bool GradientSupported { get; private set; }
public bool HessianSupported { get; private set; }
protected BaseEvaluation(bool gradientSupported, bool hessianSupported)
protected BaseObjectiveFunction(bool gradientSupported, bool hessianSupported)
{
Status = EvaluationStatus.None;
GradientSupported = gradientSupported;
@ -74,6 +74,6 @@ namespace MathNet.Numerics.Optimization
protected abstract void SetValue();
protected abstract void SetGradient();
protected abstract void SetHessian();
public abstract IEvaluation CreateNew();
public abstract IObjectiveFunction CreateNew();
}
}

10
src/Numerics/Optimization/Exceptions.cs

@ -19,18 +19,18 @@ namespace MathNet.Numerics.Optimization
public class EvaluationException : OptimizationException
{
public IEvaluation Evaluation { get; private set; }
public IObjectiveFunction ObjectiveFunction { get; private set; }
public EvaluationException(string message, IEvaluation eval)
public EvaluationException(string message, IObjectiveFunction eval)
: base(message)
{
this.Evaluation = eval;
this.ObjectiveFunction = eval;
}
public EvaluationException(string message, IEvaluation eval, Exception inner_exception)
public EvaluationException(string message, IObjectiveFunction eval, Exception inner_exception)
: base(message, inner_exception)
{
this.Evaluation = eval;
this.ObjectiveFunction = eval;
}
//public EvaluationException(string message, IEvaluation1D eval)

4
src/Numerics/Optimization/IEvaluation.cs → src/Numerics/Optimization/IObjectiveFunction.cs

@ -6,10 +6,10 @@ namespace MathNet.Numerics.Optimization
[Flags]
public enum EvaluationStatus { None = 0, Value = 1, Gradient = 2, Hessian = 4 }
public interface IEvaluation
public interface IObjectiveFunction
{
Vector<double> Point { get; set; }
IEvaluation CreateNew();
IObjectiveFunction CreateNew();
// Used by algorithm
bool GradientSupported { get; }

2
src/Numerics/Optimization/IUnconstrainedMinimizer.cs

@ -4,6 +4,6 @@ namespace MathNet.Numerics.Optimization
{
public interface IUnconstrainedMinimizer
{
MinimizationOutput FindMinimum(IEvaluation objective, Vector<double> initialGuess);
MinimizationOutput FindMinimum(IObjectiveFunction objective, Vector<double> initialGuess);
}
}

2
src/Numerics/Optimization/Implementation/LineSearchOutput.cs

@ -4,7 +4,7 @@
{
public double FinalStep { get; private set; }
public LineSearchOutput(IEvaluation functionInfo, int iterations, double finalStep, ExitCondition reasonForExit)
public LineSearchOutput(IObjectiveFunction functionInfo, int iterations, double finalStep, ExitCondition reasonForExit)
: base(functionInfo, iterations, reasonForExit)
{
FinalStep = finalStep;

6
src/Numerics/Optimization/Implementation/NullEvaluation.cs → src/Numerics/Optimization/Implementation/NullObjectiveFunction.cs

@ -3,9 +3,9 @@ using MathNet.Numerics.LinearAlgebra;
namespace MathNet.Numerics.Optimization.Implementation
{
public class NullEvaluation : BaseEvaluation
public class NullObjectiveFunction : BaseObjectiveFunction
{
public NullEvaluation(Vector<double> point)
public NullObjectiveFunction(Vector<double> point)
: base(false, false)
{
Point = point;
@ -25,7 +25,7 @@ namespace MathNet.Numerics.Optimization.Implementation
throw new NotImplementedException();
}
public override IEvaluation CreateNew()
public override IObjectiveFunction CreateNew()
{
throw new NotImplementedException();
}

50
src/Numerics/Optimization/Implementation/ObjectiveChecker.cs

@ -3,20 +3,20 @@ using MathNet.Numerics.LinearAlgebra;
namespace MathNet.Numerics.Optimization.Implementation
{
public class CheckedEvaluation : IEvaluation
public class CheckedObjectiveFunction : IObjectiveFunction
{
private bool _valueChecked;
private bool _gradientChecked;
private bool _hessianChecked;
public IEvaluation InnerEvaluation { get; private set; }
public Action<IEvaluation> ValueChecker { get; private set; }
public Action<IEvaluation> GradientChecker { get; private set; }
public Action<IEvaluation> HessianChecker { get; private set; }
public IObjectiveFunction InnerObjectiveFunction { get; private set; }
public Action<IObjectiveFunction> ValueChecker { get; private set; }
public Action<IObjectiveFunction> GradientChecker { get; private set; }
public Action<IObjectiveFunction> HessianChecker { get; private set; }
public CheckedEvaluation(IEvaluation objective, Action<IEvaluation> valueChecker, Action<IEvaluation> gradientChecker, Action<IEvaluation> hessianChecker)
public CheckedObjectiveFunction(IObjectiveFunction objective, Action<IObjectiveFunction> valueChecker, Action<IObjectiveFunction> gradientChecker, Action<IObjectiveFunction> hessianChecker)
{
InnerEvaluation = objective;
InnerObjectiveFunction = objective;
ValueChecker = valueChecker;
GradientChecker = gradientChecker;
HessianChecker = hessianChecker;
@ -24,8 +24,8 @@ namespace MathNet.Numerics.Optimization.Implementation
public Vector<double> Point
{
get { return InnerEvaluation.Point; }
set { InnerEvaluation.Point = value; }
get { return InnerObjectiveFunction.Point; }
set { InnerObjectiveFunction.Point = value; }
}
public double Value
@ -38,16 +38,16 @@ namespace MathNet.Numerics.Optimization.Implementation
double tmp;
try
{
tmp = InnerEvaluation.Value;
tmp = InnerObjectiveFunction.Value;
}
catch (Exception e)
{
throw new EvaluationException("Objective function evaluation failed.", InnerEvaluation, e);
throw new EvaluationException("Objective function evaluation failed.", InnerObjectiveFunction, e);
}
ValueChecker(InnerEvaluation);
ValueChecker(InnerObjectiveFunction);
_valueChecked = true;
}
return InnerEvaluation.Value;
return InnerObjectiveFunction.Value;
}
}
@ -61,16 +61,16 @@ namespace MathNet.Numerics.Optimization.Implementation
Vector<double> tmp;
try
{
tmp = InnerEvaluation.Gradient;
tmp = InnerObjectiveFunction.Gradient;
}
catch (Exception e)
{
throw new EvaluationException("Objective gradient evaluation failed.", InnerEvaluation, e);
throw new EvaluationException("Objective gradient evaluation failed.", InnerObjectiveFunction, e);
}
GradientChecker(InnerEvaluation);
GradientChecker(InnerObjectiveFunction);
_gradientChecked = true;
}
return InnerEvaluation.Gradient;
return InnerObjectiveFunction.Gradient;
}
}
@ -84,32 +84,32 @@ namespace MathNet.Numerics.Optimization.Implementation
Matrix<double> tmp;
try
{
tmp = InnerEvaluation.Hessian;
tmp = InnerObjectiveFunction.Hessian;
}
catch (Exception e)
{
throw new EvaluationException("Objective hessian evaluation failed.", InnerEvaluation, e);
throw new EvaluationException("Objective hessian evaluation failed.", InnerObjectiveFunction, e);
}
HessianChecker(InnerEvaluation);
HessianChecker(InnerObjectiveFunction);
_hessianChecked = true;
}
return InnerEvaluation.Hessian;
return InnerObjectiveFunction.Hessian;
}
}
public IEvaluation CreateNew()
public IObjectiveFunction CreateNew()
{
return new CheckedEvaluation(InnerEvaluation, ValueChecker, GradientChecker, HessianChecker);
return new CheckedObjectiveFunction(InnerObjectiveFunction, ValueChecker, GradientChecker, HessianChecker);
}
public bool GradientSupported
{
get { return InnerEvaluation.GradientSupported; }
get { return InnerObjectiveFunction.GradientSupported; }
}
public bool HessianSupported
{
get { return InnerEvaluation.HessianSupported; }
get { return InnerObjectiveFunction.HessianSupported; }
}
}
}

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

@ -19,11 +19,11 @@ namespace MathNet.Numerics.Optimization.Implementation
}
// Implemented following http://www.math.washington.edu/~burke/crs/408/lectures/L9-weak-Wolfe.pdf
public LineSearchOutput FindConformingStep(IEvaluation objective, IEvaluation startingPoint, Vector<double> searchDirection, double initialStep)
public LineSearchOutput FindConformingStep(IObjectiveFunction objective, IObjectiveFunction startingPoint, Vector<double> searchDirection, double initialStep)
{
if (!(objective is CheckedEvaluation))
if (!(objective is CheckedObjectiveFunction))
{
objective = new CheckedEvaluation(objective, ValidateValue, ValidateGradient, null);
objective = new CheckedObjectiveFunction(objective, ValidateValue, ValidateGradient, null);
}
double lowerBound = 0.0;
@ -36,7 +36,7 @@ namespace MathNet.Numerics.Optimization.Implementation
double initialDd = searchDirection * initialGradient;
int ii;
IEvaluation candidateEval = objective.CreateNew();
IObjectiveFunction candidateEval = objective.CreateNew();
MinimizationOutput.ExitCondition reasonForExit = MinimizationOutput.ExitCondition.None;
for (ii = 0; ii < _maximumIterations; ++ii)
{
@ -89,7 +89,7 @@ namespace MathNet.Numerics.Optimization.Implementation
return new LineSearchOutput(candidateEval, ii, step, reasonForExit);
}
bool Conforms(IEvaluation startingPoint, Vector<double> searchDirection, double step, IEvaluation endingPoint)
bool Conforms(IObjectiveFunction startingPoint, Vector<double> searchDirection, double step, IObjectiveFunction endingPoint)
{
bool sufficientDecrease = endingPoint.Value <= startingPoint.Value + _c1 * step * (startingPoint.Gradient * searchDirection);
bool notTooSteep = endingPoint.Gradient * searchDirection >= _c2 * startingPoint.Gradient * searchDirection;
@ -97,7 +97,7 @@ namespace MathNet.Numerics.Optimization.Implementation
return step > 0 && sufficientDecrease && notTooSteep;
}
void ValidateValue(IEvaluation eval)
void ValidateValue(IObjectiveFunction eval)
{
if (!IsFinite(eval.Value))
{
@ -105,7 +105,7 @@ namespace MathNet.Numerics.Optimization.Implementation
}
}
void ValidateGradient(IEvaluation eval)
void ValidateGradient(IObjectiveFunction eval)
{
foreach (double x in eval.Gradient)
{

4
src/Numerics/Optimization/MinimizationOutput.cs

@ -7,11 +7,11 @@ namespace MathNet.Numerics.Optimization
public enum ExitCondition { None, RelativeGradient, LackOfProgress, AbsoluteGradient, WeakWolfeCriteria, BoundTolerance, StrongWolfeCriteria, LackOfFunctionImprovement }
public Vector<double> MinimizingPoint { get { return FunctionInfoAtMinimum.Point; } }
public IEvaluation FunctionInfoAtMinimum { get; private set; }
public IObjectiveFunction FunctionInfoAtMinimum { get; private set; }
public int Iterations { get; private set; }
public ExitCondition ReasonForExit { get; private set; }
public MinimizationOutput(IEvaluation functionInfo, int iterations, ExitCondition reasonForExit)
public MinimizationOutput(IObjectiveFunction functionInfo, int iterations, ExitCondition reasonForExit)
{
FunctionInfoAtMinimum = functionInfo;
Iterations = iterations;

2
src/Numerics/Optimization/MinimizationWithLineSearchOutput.cs

@ -5,7 +5,7 @@
public int TotalLineSearchIterations { get; private set; }
public int IterationsWithNonTrivialLineSearch { get; private set; }
public MinimizationWithLineSearchOutput(IEvaluation functionInfo, int iterations, ExitCondition reasonForExit, int totalLineSearchIterations, int iterationsWithNonTrivialLineSearch)
public MinimizationWithLineSearchOutput(IObjectiveFunction functionInfo, int iterations, ExitCondition reasonForExit, int totalLineSearchIterations, int iterationsWithNonTrivialLineSearch)
: base(functionInfo, iterations, reasonForExit)
{
TotalLineSearchIterations = totalLineSearchIterations;

16
src/Numerics/Optimization/NewtonMinimizer.cs

@ -18,7 +18,7 @@ namespace MathNet.Numerics.Optimization
UseLineSearch = useLineSearch;
}
public MinimizationOutput FindMinimum(IEvaluation objective, Vector<double> initialGuess)
public MinimizationOutput FindMinimum(IObjectiveFunction objective, Vector<double> initialGuess)
{
if (!objective.GradientSupported)
throw new IncompatibleObjectiveException("Gradient not supported in objective function, but required for Newton minimization.");
@ -26,10 +26,10 @@ namespace MathNet.Numerics.Optimization
if (!objective.HessianSupported)
throw new IncompatibleObjectiveException("Hessian not supported in objective function, but required for Newton minimization.");
if (!(objective is CheckedEvaluation))
objective = new CheckedEvaluation(objective, ValidateObjective, ValidateGradient, ValidateHessian);
if (!(objective is CheckedObjectiveFunction))
objective = new CheckedObjectiveFunction(objective, ValidateObjective, ValidateGradient, ValidateHessian);
IEvaluation initialEval = objective.CreateNew();
IObjectiveFunction initialEval = objective.CreateNew();
initialEval.Point = initialGuess;
// Check that we're not already done
@ -40,7 +40,7 @@ namespace MathNet.Numerics.Optimization
var lineSearcher = new WeakWolfeLineSearch(1e-4, 0.9, 1e-4, maxIterations: 1000);
// Declare state variables
IEvaluation candidatePoint = initialEval;
IObjectiveFunction candidatePoint = initialEval;
// Subsequent steps
int iterations = 0;
@ -92,7 +92,7 @@ namespace MathNet.Numerics.Optimization
return gradient.Norm(2.0) < GradientTolerance;
}
private void ValidateGradient(IEvaluation eval)
private void ValidateGradient(IObjectiveFunction eval)
{
foreach (var x in eval.Gradient)
{
@ -101,13 +101,13 @@ namespace MathNet.Numerics.Optimization
}
}
private void ValidateObjective(IEvaluation eval)
private void ValidateObjective(IObjectiveFunction eval)
{
if (Double.IsNaN(eval.Value) || Double.IsInfinity(eval.Value))
throw new EvaluationException("Non-finite objective function returned.", eval);
}
private void ValidateHessian(IEvaluation eval)
private void ValidateHessian(IObjectiveFunction eval)
{
for (int ii = 0; ii < eval.Hessian.RowCount; ++ii)
{

11
src/UnitTests/OptimizationTests/RosenbrockFunction.cs

@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
namespace MathNet.Numerics.UnitTests.OptimizationTests
{
@ -16,7 +13,7 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
public static Vector<double> Gradient(Vector<double> input)
{
Vector<double> output = new MathNet.Numerics.LinearAlgebra.Double.DenseVector(2);
Vector<double> output = new DenseVector(2);
output[0] = -2 * (1 - input[0]) + 200 * (input[1] - input[0] * input[0]) * (-2 * input[0]);
output[1] = 2 * 100 * (input[1] - input[0] * input[0]);
return output;
@ -24,8 +21,7 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
public static Matrix<double> Hessian(Vector<double> input)
{
Matrix<double> output = new MathNet.Numerics.LinearAlgebra.Double.DenseMatrix(2, 2);
Matrix<double> output = new DenseMatrix(2, 2);
output[0, 0] = 2 - 400 * input[1] + 1200 * input[0] * input[0];
output[1, 1] = 200;
output[0, 1] = -400 * input[0];
@ -50,6 +46,5 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
{
return 100.0 * RosenbrockFunction.Hessian(input / 100.0);
}
}
}

46
src/UnitTests/OptimizationTests/TestNewtonMinimizer.cs

@ -1,37 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.Optimization;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.OptimizationTests
{
public class RosenbrockEvaluation : BaseEvaluation
public class RosenbrockObjectiveFunction : BaseObjectiveFunction
{
public RosenbrockEvaluation()
public RosenbrockObjectiveFunction()
: base(true, true) { }
protected override void SetValue()
{
this.ValueRaw = RosenbrockFunction.Value(this.Point);
ValueRaw = RosenbrockFunction.Value(Point);
}
protected override void SetGradient()
{
this.GradientRaw = RosenbrockFunction.Gradient(this.Point);
GradientRaw = RosenbrockFunction.Gradient(Point);
}
protected override void SetHessian()
{
this.HessianRaw = RosenbrockFunction.Hessian(this.Point);
HessianRaw = RosenbrockFunction.Hessian(Point);
}
public override IEvaluation CreateNew()
public override IObjectiveFunction CreateNew()
{
return new RosenbrockEvaluation();
return new RosenbrockObjectiveFunction();
}
}
@ -42,10 +38,10 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
[Test]
public void FindMinimum_Rosenbrock_Easy()
{
var obj = new RosenbrockEvaluation();
var obj = new RosenbrockObjectiveFunction();
var solver = new NewtonMinimizer(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(Math.Abs(result.MinimizingPoint[0] - 1.0), Is.LessThan(1e-3));
Assert.That(Math.Abs(result.MinimizingPoint[1] - 1.0), Is.LessThan(1e-3));
@ -54,9 +50,9 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
[Test]
public void FindMinimum_Rosenbrock_Hard()
{
var obj = new RosenbrockEvaluation();
var obj = new RosenbrockObjectiveFunction();
var solver = new NewtonMinimizer(1e-5, 1000);
var result = solver.FindMinimum(obj, new MathNet.Numerics.LinearAlgebra.Double.DenseVector(new double[] { -1.2, 1.0 }));
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));
@ -65,9 +61,9 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
[Test]
public void FindMinimum_Rosenbrock_Overton()
{
var obj = new RosenbrockEvaluation();
var obj = new RosenbrockObjectiveFunction();
var solver = new NewtonMinimizer(1e-5, 1000);
var result = solver.FindMinimum(obj, new MathNet.Numerics.LinearAlgebra.Double.DenseVector(new double[] { -0.9, -0.5 }));
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));
Assert.That(Math.Abs(result.MinimizingPoint[1] - 1.0), Is.LessThan(1e-3));
@ -76,9 +72,9 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
[Test]
public void FindMinimum_Linesearch_Rosenbrock_Easy()
{
var obj = new RosenbrockEvaluation();
var obj = new RosenbrockObjectiveFunction();
var solver = new NewtonMinimizer(1e-5, 1000, true);
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(Math.Abs(result.MinimizingPoint[0] - 1.0), Is.LessThan(1e-3));
Assert.That(Math.Abs(result.MinimizingPoint[1] - 1.0), Is.LessThan(1e-3));
@ -87,9 +83,9 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
[Test]
public void FindMinimum_Linesearch_Rosenbrock_Hard()
{
var obj = new RosenbrockEvaluation();
var obj = new RosenbrockObjectiveFunction();
var solver = new NewtonMinimizer(1e-5, 1000, true);
var result = solver.FindMinimum(obj, new MathNet.Numerics.LinearAlgebra.Double.DenseVector(new double[] { -1.2, 1.0 }));
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));
@ -98,9 +94,9 @@ namespace MathNet.Numerics.UnitTests.OptimizationTests
[Test]
public void FindMinimum_Linesearch_Rosenbrock_Overton()
{
var obj = new RosenbrockEvaluation();
var obj = new RosenbrockObjectiveFunction();
var solver = new NewtonMinimizer(1e-5, 1000, true);
var result = solver.FindMinimum(obj, new MathNet.Numerics.LinearAlgebra.Double.DenseVector(new double[] { -0.9, -0.5 }));
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));
Assert.That(Math.Abs(result.MinimizingPoint[1] - 1.0), Is.LessThan(1e-3));

Loading…
Cancel
Save