public void ConstructorTest2()
        {
            Function function = // min f(x) = 10 * (x+1)^2 + y^2
                x => 10.0 * Math.Pow(x[0] + 1.0, 2.0) + Math.Pow(x[1], 2.0);

            Gradient gradient = x => new[] { 20 * (x[0] + 1), 2 * x[1] };


            double[] start = new double[2];

            var target = new BoundedBroydenFletcherGoldfarbShanno(2,
                function.Invoke, gradient.Invoke);

            Assert.IsTrue(target.Minimize());
            double minimum = target.Value;

            double[] solution = target.Solution;

            Assert.AreEqual(0, minimum, 1e-10);
            Assert.AreEqual(-1, solution[0], 1e-5);
            Assert.AreEqual(0, solution[1], 1e-5);

            double expectedMinimum = function(target.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
        public OptimizationProgressEventArgs[] Actual(Specification problem)
        {
            ActualMessage = String.Empty;

            BoundedBroydenFletcherGoldfarbShanno target =
                new BoundedBroydenFletcherGoldfarbShanno(problem.Variables)
            {
                FunctionTolerance = factr,
                GradientTolerance = pgtol,
                Corrections = m,
                MaxIterations = max_iterations
            };

            for (int i = 0; i < target.LowerBounds.Length; i++)
            {
                if (l != null)
                    target.LowerBounds[i] = l[i];
                if (u != null)
                    target.UpperBounds[i] = u[i];
            }


            target.Function = problem.Function;
            target.Gradient = problem.Gradient;

            actual.Clear();
            target.Progress += new EventHandler<OptimizationProgressEventArgs>(target_Progress);

            target.Minimize((double[])problem.Start.Clone());

            if (target.Status == BoundedBroydenFletcherGoldfarbShannoStatus.GradientConvergence)
                ActualMessage = "CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL";
            else if (target.Status == BoundedBroydenFletcherGoldfarbShannoStatus.FunctionConvergence)
                ActualMessage = "CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH";
            else if (target.Status == BoundedBroydenFletcherGoldfarbShannoStatus.LineSearchFailed)
                ActualMessage = "ABNORMAL_TERMINATION_IN_LNSRCH";

            return actual.ToArray();
        }
        public void lbfgsTest()
        {
            Func<double[], double> f = rosenbrockFunction;
            Func<double[], double[]> g = rosenbrockGradient;

            Assert.AreEqual(104, f(new[] { -1.0, 2.0 }));


            int n = 2; // number of variables
            double[] initial = { -1.2, 1 };

            var lbfgs = new BoundedBroydenFletcherGoldfarbShanno(n, f, g);
            lbfgs.GradientTolerance = 1e-10;
            lbfgs.FunctionTolerance = 1e-10;

            double expected = 0;
            Assert.IsTrue(lbfgs.Minimize(initial));
            double actual = lbfgs.Value;


            Assert.AreEqual(expected, actual, 1e-10);

            double[] result = lbfgs.Solution;

            //Assert.AreEqual(49, lbfgs.Evaluations);
            //Assert.AreEqual(40, lbfgs.Iterations);
            Assert.AreEqual(1.0, result[0], 1e-6);
            Assert.AreEqual(1.0, result[1], 1e-6);

            double y = f(result);
            double[] d = g(result);

            Assert.AreEqual(0, y, 1e-10);
            Assert.AreEqual(0, d[0], 1e-6);
            Assert.AreEqual(0, d[1], 1e-6);
        }
        public void InvalidLineSearchTest2()
        {
            int n = 10;

            Func<double[], double> function = (parameters) =>
            {
                return -(n * Math.Log(0) - n * Math.Log(Math.PI));
            };

            Func<double[], double[]> gradient = (parameters) =>
            {
                return new[] { 2.0, Double.NegativeInfinity };
            };

            double[] start = { 0, 0 };

            var lbfgs = new BoundedBroydenFletcherGoldfarbShanno(2, function, gradient);

            lbfgs.Minimize(start);

            Assert.AreEqual(BoundedBroydenFletcherGoldfarbShannoStatus.LineSearchFailed, lbfgs.Status);
        }
Beispiel #5
0
        private unsafe ConjugateGradientCode cvsmod(ref double f, double[] s, ref double stp, ref int info,
                                                    ref int nfev, double[] wa, ref double dginit, ref double dgout)
        {
            int n = NumberOfVariables;

            double[] x = Solution;

            if (info == 1)
            {
                goto L321;
            }

            infoc = 1;

            if (stp <= 0) // Check the input parameters for errors
            {
                return(ConjugateGradientCode.StepSize);
            }

            // Compute the initial gradient in the search direction
            // and check that S is a descent direction.

            if (dginit >= 0)
            {
                throw new LineSearchFailedException(0, "The search direction is not a descent direction.");
            }

            // Initialize local variables
            brackt = false;
            stage1 = true;
            nfev   = 0;
            finit  = f;
            dgtest = ftol * dginit;
            width  = stpmax - stpmin;
            width1 = width / 0.5;

            for (int j = 0; j < x.Length; ++j)
            {
                wa[j] = x[j];
            }

            // The variables STX, FX, DGX contain the values of the step,
            //   function, and directional derivative at the best step.
            // The variables STY, FY, DGY contain the value of the step,
            //   function, and derivative at the other endpoint of the interval
            //   of uncertainty.
            // The variables STP, F, DG contain the values of the step,
            //   function, and derivative at the current step.

            stx = 0;
            fx  = finit;
            dgx = dginit;
            sty = 0;
            fy  = finit;
            dgy = dginit;


L30:        // Start of iteration.

            // Set the minimum and maximum steps to correspond
            // to the present interval of uncertainty.

            if (brackt)
            {
                stmin = Math.Min(stx, sty);
                stmax = Math.Max(stx, sty);
            }
            else
            {
                stmin = stx;
                stmax = stp + 4 * (stp - stx);
            }

            // Force the step to be within
            // the bounds STPMAX and STPMIN.

            stp = Math.Max(stp, stpmin);
            stp = Math.Min(stp, stpmax);

            // If an unusual termination is to occur then
            // let STP be the lowest point obtained so far.

            if (brackt && (stp <= stmin || stp >= stmax) || nfev >= maxfev - 1 ||
                infoc == 0 || brackt && stmax - stmin <= xtol * stmax)
            {
                stp = stx;
            }

            // Evaluate the function and gradient at STP
            // and compute the directional derivative.

            for (int j = 0; j < s.Length; ++j)
            {
                x[j] = wa[j] + stp * s[j];
            }

            // Fetch function and gradient
            f = Function(x);
            g = Gradient(x);

            info = 0;
            nfev++;
            dg2 = 0;

            for (int j = 0; j < g.Length; ++j)
            {
                dg2 += g[j] * s[j];
            }

            ftest1 = finit + stp * dgtest;

            if ((brackt && (stp <= stmin || stp >= stmax)) || infoc == 0)
            {
                return(ConjugateGradientCode.RoundingErrors);
            }

            if (stp == stpmax && f <= ftest1 && dg2 <= dgtest)
            {
                return(ConjugateGradientCode.StepHigh);
            }

            if (stp == stpmin && (f > ftest1 || dg2 >= dgtest))
            {
                return(ConjugateGradientCode.StepLow);
            }

            if (nfev >= maxfev)
            {
                return(ConjugateGradientCode.MaximumEvaluations);
            }

            if (brackt && stmax - stmin <= xtol * stmax)
            {
                return(ConjugateGradientCode.Precision);
            }


            // More's code has been modified so that at least one new
            //  function value is computed during the line search (enforcing
            //  at least one interpolation is not easy, since the code may
            //  override an interpolation)

            if (f <= ftest1 && Math.Abs(dg2) <= gtol * (-dginit) && nfev > 1)
            {
                info  = 1;
                dgout = dg2;
                return(ConjugateGradientCode.Success);
            }


L321:

            // In the first stage we seek a step for which the modified
            // function has a nonpositive value and nonnegative derivative.
            if (stage1 && f <= ftest1 && dg2 >= Math.Min(ftol, gtol) * dginit)
            {
                stage1 = false;
            }

            // A modified function is used to predict the step only if
            // we have not obtained a step for which the modified function
            // has a nonpositive function value and nonnegative derivative,
            // and if a lower function value has been obtained but the
            // decrease is not sufficient.

            if (stage1 && f <= fx && f > ftest1)
            {
                // Define the modified function and derivative values
                double fm   = f - stp * dgtest;
                double fxm  = fx - stx * dgtest;
                double fym  = fy - sty * dgtest;
                double dgm  = dg2 - dgtest;
                double dgxm = dgx - dgtest;
                double dgym = dgy - dgtest;

                // Call CSTEPM to update the interval of
                // uncertainty and to compute the new step.

                BoundedBroydenFletcherGoldfarbShanno.dcstep(ref stx, ref fxm, ref dgxm,
                                                            ref sty, ref fym, ref dgym, ref stp, fm, dgm, ref brackt, stpmin, stpmax);

                // Reset the function and gradient values for f.
                fx  = fxm + stx * dgtest;
                fy  = fym + sty * dgtest;
                dgx = dgxm + dgtest;
                dgy = dgym + dgtest;
            }
            else
            {
                // Call CSTEPM to update the interval of
                // uncertainty and to compute the new step.
                BoundedBroydenFletcherGoldfarbShanno.dcstep(ref stx, ref fx, ref dgx,
                                                            ref sty, ref fy, ref dgy, ref stp, f, dg2, ref brackt, stpmin, stpmax);
            }

            // Force a sufficient decrease in the
            // size of the interval of uncertainty.

            if (brackt)
            {
                if ((Math.Abs(sty - stx)) >= 0.66 * width1)
                {
                    stp = stx + 0.5 * (sty - stx);
                }

                width1 = width;
                width  = Math.Abs(sty - stx);
            }

            goto L30;
        }
        public void lbfgsTest2()
        {
            Accord.Math.Tools.SetupGenerator(0);

            // Suppose we would like to find the minimum of the function
            // 
            //   f(x,y)  =  -exp{-(x-1)²} - exp{-(y-2)²/2}
            //

            // First we need write down the function either as a named
            // method, an anonymous method or as a lambda function:

            Func<double[], double> f = (x) =>
                -Math.Exp(-Math.Pow(x[0] - 1, 2)) - Math.Exp(-0.5 * Math.Pow(x[1] - 2, 2));

            // Now, we need to write its gradient, which is just the
            // vector of first partial derivatives del_f / del_x, as:
            //
            //   g(x,y)  =  { del f / del x, del f / del y }
            // 

            Func<double[], double[]> g = (x) => new double[] 
            {
                // df/dx = {-2 e^(-    (x-1)^2) (x-1)}
                2 * Math.Exp(-Math.Pow(x[0] - 1, 2)) * (x[0] - 1),

                // df/dy = {-  e^(-1/2 (y-2)^2) (y-2)}
                Math.Exp(-0.5 * Math.Pow(x[1] - 2, 2)) * (x[1] - 2)
            };

            // Finally, we can create the L-BFGS solver, passing the functions as arguments
            var lbfgs = new BoundedBroydenFletcherGoldfarbShanno(numberOfVariables: 2, function: f, gradient: g);

            // And then minimize the function:
            Assert.IsTrue(lbfgs.Minimize());
            double minValue = lbfgs.Value;
            double[] solution = lbfgs.Solution;

            // The resultant minimum value should be -2, and the solution
            // vector should be { 1.0, 2.0 }. The answer can be checked on
            // Wolfram Alpha by clicking the following the link:

            // http://www.wolframalpha.com/input/?i=maximize+%28exp%28-%28x-1%29%C2%B2%29+%2B+exp%28-%28y-2%29%C2%B2%2F2%29%29

            double expected = -2;
            Assert.AreEqual(expected, minValue, 1e-10);

            Assert.AreEqual(1, solution[0], 1e-3);
            Assert.AreEqual(2, solution[1], 1e-3);

        }
        public void lbfgsTest3()
        {
            Accord.Math.Tools.SetupGenerator(0);

            Func<double[], double> f;
            Func<double[], double[]> g;
            createExpDiff(out f, out g);

            int errors = 0;

            for (int i = 0; i < 10000; i++)
            {
                double[] start = Accord.Math.Matrix.Random(2, -1.0, 1.0);

                var lbfgs = new BoundedBroydenFletcherGoldfarbShanno(numberOfVariables: 2,
                    function: f, gradient: g);

                lbfgs.FunctionTolerance = 1e3;

                Assert.IsTrue(lbfgs.Minimize(start));
                double minValue = lbfgs.Value;
                double[] solution = lbfgs.Solution;

                double expected = -2;

                if (Math.Abs(expected - minValue) > 1e-2)
                    errors++;
            }

            Assert.IsTrue(errors < 1000);
        }
        public void ConstructorTest1()
        {
            Func<double[], double> function = // min f(x) = 10 * (x+1)^2 + y^2
                x => 10.0 * Math.Pow(x[0] + 1.0, 2.0) + Math.Pow(x[1], 2.0);

            Func<double[], double[]> gradient = x => new[] { 20 * (x[0] + 1), 2 * x[1] };

            var target = new BoundedBroydenFletcherGoldfarbShanno(2)
            {
                Function = function,
                Gradient = gradient
            };

            bool success = target.Minimize();
            double minimum = target.Value;
            double[] solution = target.Solution;

            Assert.IsTrue(success);

            Assert.AreEqual(0, minimum, 1e-10);
            Assert.AreEqual(-1, solution[0], 1e-5);
            Assert.AreEqual(0, solution[1], 1e-5);

            double expectedMinimum = function(target.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
        public void MutableGradientSizeTest()
        {
            var target = new BoundedBroydenFletcherGoldfarbShanno(2)
            {
                Function = (x) => 0.0,
                Gradient = (x) => x
            };

            target.Minimize();
        }
        public void WrongGradientSizeTest()
        {
            var target = new BoundedBroydenFletcherGoldfarbShanno(2)
            {
                Function = (x) => 0.0,
                Gradient = (x) => new double[1]
            };

            target.Minimize();
        }
        public void NoGradientTest()
        {
            var target = new BoundedBroydenFletcherGoldfarbShanno(2)
            {
                Function = (x) => 0.0
            };

            target.Minimize();
        }
        public void NoFunctionTest()
        {
            var target = new BoundedBroydenFletcherGoldfarbShanno(2);

            target.Minimize();
        }