/// <summary>
        /// Try to find a (local) minimum of a given function from a given starting point.
        /// </summary>
        /// <returns>Approximate local minimum.</returns>
        /// <param name="f">Function f:R^d -> R to be minimized.</param>
        /// <param name="grad_f">Exact gradient of f.</param>
        /// <param name="hessian_f">Exact Hessian of f.</param>
        /// <param name="x_0">X 0.</param>
        public Vector <double> Minimize(Func <Vector <double>, double> f,
                                        Func <Vector <double>, Vector <double> > grad_f,
                                        Func <Vector <double>, Matrix <double> > hessian_f, Vector <double> x_0)
        {
            Vector <double> x = Vector <double> .Build.Dense(x_0.Count);

            // need to create the functions for the solver
            if (grad_f != null)
            {
                x = solver.Solve(grad_f, hessian_f, x_0);
            }
            else
            {
                Func <Vector <double>, Vector <double> > grad_approx    = (point) => ApproximateGrad(f, point);
                Func <Vector <double>, Matrix <double> > hessian_approx = (point) => ApproximateHessian(f, point);
                x = solver.Solve(grad_approx, hessian_approx, x_0);
            }
            return(x);
        }
示例#2
0
        public static void Main(string[] args)
        {
            Func <double, double> normalDensity
                = (x) => Math.Exp(-x * x / 2.0) / Math.Sqrt(2 * Math.PI);
            CompositeIntegrator integrator = new CompositeIntegrator(4);
            double integral = integrator.Integrate(normalDensity, -4, 4, 100);

            Console.WriteLine("Integral is approximately {0}", integral);

            NewtonSolver newtonSolver = new NewtonSolver(1e-16, 100);

            // we want a function F(x,y)_1 = x^2 + y^2 - 2xy, F(x,y)_2 = x^2 - y^2
            // you can check that F(x,x)_1 = 0 and F(x,x)_2 = 0 i.e. uncountably many solutions
            Func <Vector <double>, Vector <double> > F = (x) => {
                Vector <double> y = Vector <double> .Build.Dense(x.Count);

                y[0] = x[0] * x[0] + x[1] * x[1] - 2 * x[0] * x[1];
                y[1] = x[0] * x[0] - x[1] * x[1];
                return(y);
            };

            Func <Vector <double>, Matrix <double> > J_F = (x) => {
                int             d        = x.Count;
                Matrix <double> J_F_vals = Matrix <double> .Build.Dense(d, d);

                J_F_vals[0, 0] = 2 * x[0] - 2 * x[1]; J_F_vals[0, 1] = 2 * x[1] - 2 * x[0];
                J_F_vals[1, 0] = 2 * x[0]; J_F_vals[1, 1] = -2 * x[1];
                return(J_F_vals);
            };

            Vector <double> x0 = Vector <double> .Build.Dense(2);

            x0[0] = 1; x0[1] = -1;
            Vector <double> x1;

            x1 = newtonSolver.Solve(F, J_F, x0);
            Console.WriteLine(x1.ToString());



            // we want a function F(x,y)_1 = x^2 + y^2 - 2xy - 1, F(x,y)_2 = x^2 - y^2 - 7
            // you can check that [F(4,3), F(4,3)] = [0,0]
            Func <Vector <double>, Vector <double> > F2 = (x) => {
                Vector <double> y = Vector <double> .Build.Dense(x.Count);

                y[0] = x[0] * x[0] + x[1] * x[1] - 2 * x[0] * x[1] - 1;
                y[1] = x[0] * x[0] - x[1] * x[1] - 7;
                return(y);
            };

            Func <Vector <double>, Matrix <double> > J_F2 = (x) => {
                int             d        = x.Count;
                Matrix <double> J_F_vals = Matrix <double> .Build.Dense(d, d);

                J_F_vals[0, 0] = 2 * x[0] - 2 * x[1]; J_F_vals[0, 1] = 2 * x[1] - 2 * x[0];
                J_F_vals[1, 0] = 2 * x[0]; J_F_vals[1, 1] = -2 * x[1];
                return(J_F_vals);
            };


            x1 = newtonSolver.Solve(F2, J_F2, x0);
            Console.WriteLine(x1.ToString());

            NewtonMnimizer minimizer         = new NewtonMnimizer(1e-5, 100);
            Func <Vector <double>, double> f = (x) => x [0] * x [0] + x [1] * x [1];

            Vector <double> startPt = Vector <double> .Build.Dense(2);

            startPt[0] = 1; startPt[1] = -1;

            Console.WriteLine("With approximate grad of f and hessian of f using f.d.");
            Console.WriteLine(minimizer.Minimize(f, null, null, startPt));

            Console.WriteLine("With exact grad_f and approximate hessian f using f.d.");
            Func <Vector <double>, Vector <double> > grad_f = (x) => {
                Vector <double> grad = Vector <double> .Build.Dense(x.Count);

                grad[0] = 2 * x[0]; grad[1] = 2 * x[1];
                return(grad);
            };

            Console.WriteLine(minimizer.Minimize(f, grad_f, null, startPt));

            Console.WriteLine("With exact grad of f and hessian of f.");
            Func <Vector <double>, Matrix <double> > hessian_f = (x) => {
                Matrix <double> hessian = Matrix <double> .Build.Dense(x.Count, x.Count);

                hessian[0, 0] = 2; hessian[0, 1] = 0;
                hessian[1, 0] = 0; hessian[1, 1] = 2;
                return(hessian);
            };

            Console.WriteLine(minimizer.Minimize(f, grad_f, hessian_f, startPt));
            Console.ReadKey();
        }