/// <summary> /// Find vector x that minimizes the function f(x), constrained within bounds, using the Broyden–Fletcher–Goldfarb–Shanno Bounded (BFGS-B) algorithm. /// For more options and diagnostics consider to use <see cref="BfgsBMinimizer"/> directly. /// </summary> public static Vector <double> OfFunctionGradientConstrained(Func <Vector <double>, Tuple <double, Vector <double> > > functionGradient, Vector <double> lowerBound, Vector <double> upperBound, Vector <double> initialGuess, double gradientTolerance = 1e-5, double parameterTolerance = 1e-5, double functionProgressTolerance = 1e-5, int maxIterations = 1000) { var objective = ObjectiveFunction.Gradient(functionGradient); var algorithm = new BfgsBMinimizer(gradientTolerance, parameterTolerance, functionProgressTolerance, maxIterations); var result = algorithm.FindMinimum(objective, lowerBound, upperBound, initialGuess); return(result.MinimizingPoint); }
/// <summary> /// Find vector x that minimizes the function f(x), constrained within bounds, using the Broyden–Fletcher–Goldfarb–Shanno Bounded (BFGS-B) algorithm. /// The missing gradient is evaluated numerically (forward difference). /// For more options and diagnostics consider to use <see cref="BfgsBMinimizer"/> directly. /// </summary> public static Vector <double> OfFunctionConstrained(Func <Vector <double>, double> function, Vector <double> lowerBound, Vector <double> upperBound, Vector <double> initialGuess, double gradientTolerance = 1e-5, double parameterTolerance = 1e-5, double functionProgressTolerance = 1e-5, int maxIterations = 1000) { var objective = ObjectiveFunction.Value(function); var objectiveWithGradient = new Optimization.ObjectiveFunctions.ForwardDifferenceGradientObjectiveFunction(objective, lowerBound, upperBound); var algorithm = new BfgsBMinimizer(gradientTolerance, parameterTolerance, functionProgressTolerance, maxIterations); var result = algorithm.FindMinimum(objectiveWithGradient, lowerBound, upperBound, initialGuess); return(result.MinimizingPoint); }
public void Thurber_BfgsB_Dif() { var obj = ObjectiveFunction.NonlinearFunction(ThurberModel, ThurberX, ThurberY, accuracyOrder: 6); var solver = new BfgsBMinimizer(1e-10, 1e-10, 1e-10, 1000); var result = solver.FindMinimum(obj, ThurberLowerBound, ThurberUpperBound, ThurberStart); for (int i = 0; i < result.MinimizingPoint.Count; i++) { AssertHelpers.AlmostEqualRelative(ThurberPbest[i], result.MinimizingPoint[i], 6); } }
public void FindMinimum_Rosenbrock_Easy_OneBoundary() { var obj = ObjectiveFunction.Gradient(RosenbrockFunction.Value, RosenbrockFunction.Gradient); var solver = new BfgsBMinimizer(1e-5, 1e-5, 1e-5, maximumIterations: 1000); var lowerBound = new DenseVector(new[] { 1.0, -5.0 }); var upperBound = new DenseVector(new[] { 5.0, 5.0 }); var initialGuess = new DenseVector(new[] { 1.2, 1.2 }); var result = solver.FindMinimum(obj, lowerBound, upperBound, initialGuess); Assert.That(Math.Abs(result.MinimizingPoint[0] - RosenbrockFunction.Minimum[0]), Is.LessThan(1e-3)); Assert.That(Math.Abs(result.MinimizingPoint[1] - RosenbrockFunction.Minimum[1]), Is.LessThan(1e-3)); }
public void FindMinimum_Rosenbrock_MinimumLesserOrEqualToUpperBoundary() { var obj = ObjectiveFunction.Gradient(RosenbrockFunction.Value, RosenbrockFunction.Gradient); var solver = new BfgsBMinimizer(1e-5, 1e-5, 1e-5, maximumIterations: 1000); var lowerBound = new DenseVector(new[] { -2.0, -2.0 }); var upperBound = new DenseVector(new[] { 0.5, 0.5 }); var initialGuess = new DenseVector(new[] { -0.9, -0.5 }); var result = solver.FindMinimum(obj, lowerBound, upperBound, initialGuess); Assert.LessOrEqual(result.MinimizingPoint[0], upperBound[0]); Assert.LessOrEqual(result.MinimizingPoint[1], upperBound[1]); }
public void FindMinimum_Quadratic_TwoBoundaries() { var obj = ObjectiveFunction.Gradient( x => x[0] * x[0] + x[1] * x[1], x => new DenseVector(new[] { 2 * x[0], 2 * x[1] }) ); var solver = new BfgsBMinimizer(1e-5, 1e-5, 1e-5, maximumIterations: 1000); var lowerBound = new DenseVector(new[] { 1.0, 1.0 }); var upperBound = new DenseVector(new[] { 2.0, 2.0 }); var initialGuess = new DenseVector(new[] { 1.5, 1.5 }); var result = solver.FindMinimum(obj, lowerBound, upperBound, initialGuess); 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)); }
public void Mgh_Tests(TestFunctions.TestCase test_case) { var obj = new MghObjectiveFunction(test_case.Function, true, true); var solver = new BfgsBMinimizer(1e-8, 1e-8, 1e-8, 1000); var result = solver.FindMinimum(obj, test_case.LowerBound, test_case.UpperBound, test_case.InitialGuess); if (test_case.MinimizingPoint != null) { Assert.That((result.MinimizingPoint - test_case.MinimizingPoint).L2Norm(), Is.LessThan(1e-3)); } var val1 = result.FunctionInfoAtMinimum.Value; var val2 = test_case.MinimalValue; var abs_min = Math.Min(Math.Abs(val1), Math.Abs(val2)); var abs_err = Math.Abs(val1 - val2); var rel_err = abs_err / abs_min; var success = (abs_min <= 1 && abs_err < 1e-3) || (abs_min > 1 && rel_err < 1e-3); Assert.That(success, "Minimal function value is not as expected."); }
public void BfgsMinimizer_MinimizesProperlyWhenConstrainedInOneVariable() { // Test comes from github issue 510 // https://github.com/mathnet/mathnet-numerics/issues/510 Func <Vector <double>, double> function = (Vector <double> vectorArg) => { double x = vectorArg[0]; double y = -1.0 * Math.Exp(-x * x); return(y); }; double gradientTolerance = 1e-10; double parameterTolerance = 1e-10; double functionProgressTolerance = 1e-10; int maxIterations = 1000; var initialGuess = new DenseVector(new[] { -1.0 }); // Bad Bound var lowerBound = new DenseVector(new[] { -2.0 }); var upperBound = new DenseVector(new[] { 2.0 }); var objective = ObjectiveFunction.Value(function); var objectiveWithGradient = new ForwardDifferenceGradientObjectiveFunction(objective, lowerBound, upperBound); var algorithm = new BfgsBMinimizer(gradientTolerance, parameterTolerance, functionProgressTolerance, maxIterations); var result = algorithm.FindMinimum(objectiveWithGradient, lowerBound, upperBound, initialGuess); var resultVector = result.MinimizingPoint; double xResult = resultVector[0]; // (actual minimum at zero) var abs_err = Math.Abs(xResult); var success = abs_err < 1e-6; Assert.That(success, "Minimal function value is not as expected."); }