public MinimizationResult FindMinimum(Func <Vector <double>, double> objectiveFunction, Vector <double> initialGuess)
        {
            var lowerBound = Vector <double> .Build.Dense(initialGuess.Count, Double.NegativeInfinity);

            var upperBound = Vector <double> .Build.Dense(initialGuess.Count, Double.PositiveInfinity);

            var objective = ObjectiveFunction.Value(objectiveFunction);
            var objectiveFunctionWithGradient = new ForwardDifferenceGradientObjectiveFunction(objective, lowerBound, upperBound, RelativeIncrement, MinimumIncrement);
            var bfgsMinimizer = new BfgsMinimizer(GradientTolerance, ParameterTolerance, FunctionProgressTolerance, MaximumIterations);

            return(bfgsMinimizer.FindMinimum(objectiveFunctionWithGradient, initialGuess));
        }
        public void Mgh_FiniteDifference_Tests(TestFunctions.TestCase test_case)
        {
            var obj1   = new MghObjectiveFunction(test_case.Function, true, true);
            var obj    = new ForwardDifferenceGradientObjectiveFunction(obj1, test_case.LowerBound, test_case.UpperBound, 1e-10, 1e-10);
            var solver = new BfgsBMinimizer(1e-8, 1e-8, 1e-8, 10000);

            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.");
        }