public void ItemGradientAtStart(TestFunctions.TestCase test_case)
        {
            for (var item_index = 0; item_index < test_case.Function.ItemDimension; ++item_index)
            {
                var a_grad  = test_case.Function.ItemGradient(test_case.InitialGuess, item_index);
                var h       = 1e-4;
                var fd_grad = Vector <double> .Build.Dense(test_case.Function.ParameterDimension, 0.0);

                for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii)
                {
                    var bump_up = test_case.InitialGuess.Clone();
                    bump_up[ii] += h;
                    var bump_down = test_case.InitialGuess.Clone();
                    bump_down[ii] -= h;

                    var up_val   = test_case.Function.ItemValue(bump_up, item_index);
                    var down_val = test_case.Function.ItemValue(bump_down, item_index);

                    fd_grad[ii] = 0.5 * (up_val - down_val) / h;
                }

                for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii)
                {
                    Assert.That(Math.Abs(fd_grad[ii] - a_grad[ii]) < 1e-3, $"Failed for parameter {ii}");
                }
            }
        }
        public void GradientAtStart(TestFunctions.TestCase test_case)
        {
            var a_grad  = test_case.Function.SsqGradient(test_case.InitialGuess);
            var fd_grad = Vector <double> .Build.Dense(test_case.Function.ParameterDimension, 0.0);

            for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii)
            {
                var h = 1e-6;

                var bump_up = test_case.InitialGuess.Clone();
                bump_up[ii] += h;
                var bump_down = test_case.InitialGuess.Clone();
                bump_down[ii] -= h;

                var up_val   = test_case.Function.SsqValue(bump_up);
                var down_val = test_case.Function.SsqValue(bump_down);

                fd_grad[ii] = 0.5 * (up_val - down_val) / h;
            }

            for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii)
            {
                var val1        = a_grad[ii];
                var val2        = fd_grad[ii];
                var min_abs_val = Math.Min(Math.Abs(val1), Math.Abs(val2));
                if (min_abs_val <= 1)
                {
                    Assert.That(Math.Abs(val1 - val2) < 1e-3, $"Problem with gradient value at start point.");
                }
                else
                {
                    Assert.That(Math.Abs(val1 - val2) / min_abs_val < 1e-3, $"Problem with gradient value at start point.");
                }
            }
        }
        public void ItemHessianAtStart(TestFunctions.TestCase test_case)
        {
            for (var item_index = 0; item_index < test_case.Function.ItemDimension; ++item_index)
            {
                var a_hess  = test_case.Function.ItemHessian(test_case.InitialGuess, item_index);
                var h       = 1e-4;
                var fd_hess = Matrix <double> .Build.Dense(test_case.Function.ParameterDimension, test_case.Function.ParameterDimension);

                for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii)
                {
                    for (int jj = 0; jj < test_case.Function.ParameterDimension; ++jj)
                    {
                        var bump_uu = test_case.InitialGuess.Clone();
                        bump_uu[ii] += h;
                        bump_uu[jj] += h;

                        var bump_dd = test_case.InitialGuess.Clone();
                        bump_dd[ii] -= h;
                        bump_dd[jj] -= h;

                        var bump_ud = test_case.InitialGuess.Clone();
                        bump_ud[ii] += h;
                        bump_ud[jj] -= h;

                        var bump_du = test_case.InitialGuess.Clone();
                        bump_du[ii] -= h;
                        bump_du[jj] += h;

                        var val_uu = test_case.Function.ItemValue(bump_uu, item_index);
                        var val_dd = test_case.Function.ItemValue(bump_dd, item_index);
                        var val_ud = test_case.Function.ItemValue(bump_ud, item_index);
                        var val_du = test_case.Function.ItemValue(bump_du, item_index);

                        fd_hess[ii, jj] = (val_uu - val_ud + val_dd - val_du) / (4 * h * h);
                    }
                }

                for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii)
                {
                    for (int jj = 0; jj < test_case.Function.ParameterDimension; ++jj)
                    {
                        var val1 = fd_hess[ii, jj];
                        var val2 = a_hess[ii, jj];

                        var abs_min = Math.Min(Math.Abs(val1), Math.Abs(val2));
                        if (abs_min <= 1)
                        {
                            Assert.That(Math.Abs(val1 - val2) < 1e-3, $"Problem with hessian at start point.");
                        }
                        else
                        {
                            Assert.That(Math.Abs(val1 - val2) / abs_min < 0.05, $"Problem with hessian at start point.");
                        }
                    }
                }
            }
        }
        public void HessianAtStart(TestFunctions.TestCase test_case)
        {
            var a_hess  = test_case.Function.SsqHessian(test_case.InitialGuess);
            var fd_hess = Matrix <double> .Build.Dense(test_case.Function.ParameterDimension, test_case.Function.ParameterDimension);

            for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii)
            {
                for (int jj = 0; jj < test_case.Function.ParameterDimension; ++jj)
                {
                    var h1 = 1e-3 * Math.Max(1.0, Math.Abs(test_case.InitialGuess[ii]));
                    var h2 = 1e-3 * Math.Max(1.0, Math.Abs(test_case.InitialGuess[jj]));

                    var bump_uu = test_case.InitialGuess.Clone();
                    bump_uu[ii] += h1;
                    bump_uu[jj] += h2;

                    var bump_dd = test_case.InitialGuess.Clone();
                    bump_dd[ii] -= h1;
                    bump_dd[jj] -= h2;

                    var bump_ud = test_case.InitialGuess.Clone();
                    bump_ud[ii] += h1;
                    bump_ud[jj] -= h2;

                    var bump_du = test_case.InitialGuess.Clone();
                    bump_du[ii] -= h1;
                    bump_du[jj] += h2;

                    var val_uu = test_case.Function.SsqValue(bump_uu);
                    var val_dd = test_case.Function.SsqValue(bump_dd);
                    var val_ud = test_case.Function.SsqValue(bump_ud);
                    var val_du = test_case.Function.SsqValue(bump_du);

                    fd_hess[ii, jj] = (val_uu - val_ud + val_dd - val_du) / (4 * h1 * h2);
                }
            }

            for (int ii = 0; ii < test_case.Function.ParameterDimension; ++ii)
            {
                for (int jj = 0; jj < test_case.Function.ParameterDimension; ++jj)
                {
                    var val1 = fd_hess[ii, jj];
                    var val2 = a_hess[ii, jj];

                    var abs_min = Math.Min(Math.Abs(val1), Math.Abs(val2));
                    if (abs_min <= 1)
                    {
                        Assert.That(Math.Abs(val1 - val2) < 1e-3, $"Problem with hessian at start point.");
                    }
                    else
                    {
                        Assert.That(Math.Abs(val1 - val2) / abs_min < 0.05, $"Problem with hessian at start point.");
                    }
                }
            }
        }
 public void ValueAtMinimum(TestFunctions.TestCase test_case)
 {
     if (test_case.MinimizingPoint != null)
     {
         var value_at_minimum = test_case.Function.SsqValue(test_case.MinimizingPoint);
         Assert.That(
             Math.Abs(value_at_minimum - test_case.MinimalValue) < 1e-3,
             $"Function value at minimum not as expected."
             );
     }
 }
        public void Mgh_Tests(TestFunctions.TestCase test_case)
        {
            var obj = new MghObjectiveFunction(test_case.Function, true, true);

            var result = NewtonMinimizer.Minimum(obj, test_case.InitialGuess, 1e-8, 1000, useLineSearch: false);

            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.");
        }
Beispiel #7
0
        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, 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.");
        }