Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        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.");
        }