Пример #1
0
        public void ConstructorTest4()
        {
            // Weak version of Rosenbrock's problem.
            var function = new NonlinearObjectiveFunction(2, x =>
                                                          Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

            Subplex solver = new Subplex(function);

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

            double[] solution = solver.Solution;

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

            double expectedMinimum = function.Function(solver.Solution);

            Assert.AreEqual(expectedMinimum, minimum);
        }
Пример #2
0
        private static void test_body(NonlinearObjectiveFunction function, NonlinearConstraint[] constraints)
        {
            Cobyla cobyla = new Cobyla(function, constraints);

            for (int i = 0; i < cobyla.Solution.Length; i++)
            {
                cobyla.Solution[i] = 1;
            }

            bool   success = cobyla.Minimize();
            double minimum = cobyla.Value;

            Assert.IsTrue(success);

            double[] solution = cobyla.Solution;

            double sqrthalf = Math.Sqrt(0.5);

            Assert.AreEqual(-0.5, minimum, 1e-10);
            Assert.AreEqual(sqrthalf, solution[0], 1e-5);
            Assert.AreEqual(-sqrthalf, solution[1], 1e-5);
        }
Пример #3
0
        public void ConstructorTest2()
        {
            var function = new NonlinearObjectiveFunction(2, x => x[0] * x[1]);

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(function, x => 1.0 - x[0] * x[0] - x[1] * x[1])
            };

            Cobyla cobyla = new Cobyla(function, constraints);

            for (int i = 0; i < cobyla.Solution.Length; i++)
            {
                cobyla.Solution[i] = 1;
            }

            bool success = cobyla.Minimize();

            double violation = constraints[0].GetViolation(cobyla.Solution);

            var status = cobyla.Status;


            Assert.IsTrue(success);
            double minimum = cobyla.Value;

            double[] solution = cobyla.Solution;

            double sqrthalf = Math.Sqrt(0.5);

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

            double expectedMinimum = function.Function(cobyla.Solution);

            Assert.AreEqual(expectedMinimum, minimum);
        }
Пример #4
0
        public void ConstructorTest2()
        {
            Accord.Math.Tools.SetupGenerator(0);

            var function = new NonlinearObjectiveFunction(2,
                                                          function: x => x[0] * x[1],
                                                          gradient: x => new[] { x[1], x[0] });

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(function,
                                        function: x => 1.0 - x[0] * x[0] - x[1] * x[1],
                                        gradient: x => new [] { -2 * x[0],         -2 * x[1] }),
                new NonlinearConstraint(function,
                                        function: x => x[0],
                                        gradient: x => new [] { 1.0,                     0.0 }),
            };

            var target = new ConjugateGradient(2);

            target.Tolerance = 0;
            AugmentedLagrangian solver = new AugmentedLagrangian(target, function, constraints);

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

            double[] solution = solver.Solution;

            double sqrthalf = Math.Sqrt(0.5);

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

            double expectedMinimum = function.Function(solver.Solution);

            Assert.AreEqual(expectedMinimum, minimum);
        }
Пример #5
0
        public void SubspaceTest1()
        {
            var function = new NonlinearObjectiveFunction(5, x =>
                                                          10.0 * Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

            NelderMead solver = new NelderMead(function);

            solver.NumberOfVariables = 2;

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

            double[] solution = solver.Solution;

            Assert.AreEqual(5, solution.Length);
            Assert.AreEqual(-0, minimum, 1e-6);
            Assert.AreEqual(-1, solution[0], 1e-3);
            Assert.AreEqual(+1, solution[1], 1e-3);

            double expectedMinimum = function.Function(solver.Solution);

            Assert.AreEqual(expectedMinimum, minimum);
        }
Пример #6
0
        // We don't use this at the moment
        static List <NonlinearConstraint> CreateConstraints(Parameter[] x, NonlinearObjectiveFunction f)
        {
            // Now we can start stating the constraints
            var nlConstraints = x.SelectMany((p, i) => {
                Func <double[], double> cfn = args => x [i].Value;
                return(new[] {
                    new NonlinearConstraint
                        (f
                        , function: cfn
                        , shouldBe: ConstraintType.GreaterThanOrEqualTo
                        , value: p.Min
                        , gradient: Grad(x.Length, cfn)),
                    new NonlinearConstraint
                        (f
                        , function: cfn
                        , shouldBe: ConstraintType.LesserThanOrEqualTo
                        , value: p.Max
                        , gradient: Grad(x.Length, cfn)),
                });
            }).ToList();

            return(nlConstraints);
        }
Пример #7
0
        public static void AugmentedLagrangianSolverConstructorTest4()
        {
            double x = 0, y = 0;

            var f = new NonlinearObjectiveFunction(

                function: () => 0.3 * x + 0.6 * y,

                gradient: () => new[]
            {
                0.3,     // df/dx
                0.6,     // df/dy
            }

                );



            var constraints = new List <NonlinearConstraint>();

            constraints.Add(new NonlinearConstraint(f,

                                                    function: () => 7 * x + 3 * y,
                                                    gradient: () => new[] { 7.0, 3.0 },

                                                    shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 2100
                                                    ));

            constraints.Add(new NonlinearConstraint(f,

                                                    function: () => y,
                                                    gradient: () => new[] { 0, 1.0 },

                                                    shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 1200
                                                    ));

            constraints.Add(new NonlinearConstraint(f,

                                                    function: () => x,
                                                    gradient: () => new[] { 1.0, 0 },

                                                    shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0
                                                    ));



            var solver = new AugmentedLagrangian(f, constraints);

            solver.Solution[0] = 1;
            solver.Solution[1] = 1;


            bool success = solver.Minimize();

            double[] solution = solver.Solution;


            double minValue = solver.Value;

            Console.WriteLine("Solver Value = " + solver.Value);
            Console.WriteLine("Solver Minize = " + solver.Minimize());
            Console.WriteLine("Solver Solution x = " + solver.Solution[0]);
            Console.WriteLine("Solver Solution y = " + solver.Solution[1]);
            Console.ReadKey();
        }
        public void ConstructorTest3()
        {
            // minimize f(x) = x*y*z,
            // s.t.
            //
            //    1 - x² - 2y² - 3z² > 0
            //    x > 0,
            //    y > 0
            //

            // Easy three dimensional minimization in ellipsoid.
            var function = new NonlinearObjectiveFunction(3,
                                                          function: x => x[0] * x[1] * x[2],
                                                          gradient: x => new[] { x[1] * x[2], x[0] * x[2], x[0] * x[1] });

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(3,
                                        function: x => 1.0 - x[0] * x[0] - 2.0 * x[1] * x[1] - 3.0 * x[2] * x[2],
                                        gradient: x => new[] { -2.0 * x[0],                               -4.0 * x[1], -6.0 * x[2] }),
                new NonlinearConstraint(3,
                                        function: x => x[0],
                                        gradient: x => new[] { 1.0,                                                 0,           0 }),
                new NonlinearConstraint(3,
                                        function: x => x[1],
                                        gradient: x => new[] { 0,                                                 1.0,           0 }),
                new NonlinearConstraint(3,
                                        function: x => - x[2],
                                        gradient: x => new[] { 0,                                                   0,        -1.0 }),
            };

            for (int i = 0; i < constraints.Length; i++)
            {
                Assert.AreEqual(ConstraintType.GreaterThanOrEqualTo, constraints[i].ShouldBe);
                Assert.AreEqual(0, constraints[i].Value);
            }

            var inner = new BroydenFletcherGoldfarbShanno(3);

            inner.LineSearch  = LineSearch.BacktrackingArmijo;
            inner.Corrections = 10;

            var solver = new AugmentedLagrangian(inner, function, constraints);

            Assert.AreEqual(inner, solver.Optimizer);

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

            double[] solution = solver.Solution;

            double[] expected =
            {
                1.0 / Math.Sqrt(3.0), 1.0 / Math.Sqrt(6.0), -1.0 / 3.0
            };


            for (int i = 0; i < expected.Length; i++)
            {
                Assert.AreEqual(expected[i], solver.Solution[i], 1e-3);
            }
            Assert.AreEqual(-0.078567420132031968, minimum, 1e-4);

            double expectedMinimum = function.Function(solver.Solution);

            Assert.AreEqual(expectedMinimum, minimum);
        }
        private static void test2(IGradientOptimizationMethod inner)
        {
            // maximize 2x + 3y, s.t. 2x² + 2y² <= 50
            //
            // http://www.wolframalpha.com/input/?i=max+2x+%2B+3y%2C+s.t.+2x%C2%B2+%2B+2y%C2%B2+%3C%3D+50

            // Max x' * c
            //  x

            // s.t. x' * A * x <= k
            //      x' * i     = 1
            // lower_bound < x < upper_bound

            double[] c = { 2, 3 };
            double[,] A = { { 2, 0 }, { 0, 2 } };
            double k = 50;

            // Create the objective function
            var objective = new NonlinearObjectiveFunction(2,
                                                           function: (x) => x.InnerProduct(c),
                                                           gradient: (x) => c
                                                           );

            // Test objective
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i * 2 + j * 3;
                    double actual   = objective.Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }


            // Create the optimization constraints
            var constraints = new List <NonlinearConstraint>();

            constraints.Add(new QuadraticConstraint(objective,
                                                    quadraticTerms: A,
                                                    shouldBe: ConstraintType.LesserThanOrEqualTo, value: k
                                                    ));


            // Test first constraint
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    var input = new double[] { i, j };

                    double expected = i * (2 * i + 0 * j) + j * (0 * i + 2 * j);
                    double actual   = constraints[0].Function(input);
                    Assert.AreEqual(expected, actual);
                }
            }


            // Create the solver algorithm
            AugmentedLagrangian solver =
                new AugmentedLagrangian(inner, objective, constraints);

            Assert.AreEqual(inner, solver.Optimizer);

            Assert.IsTrue(solver.Maximize());
            double maxValue = solver.Value;

            Assert.AreEqual(18.02, maxValue, 1e-2);
            Assert.AreEqual(2.77, solver.Solution[0], 1e-2);
            Assert.AreEqual(4.16, solver.Solution[1], 1e-2);
        }
        private static void test1(IGradientOptimizationMethod inner, double tol)
        {
            // maximize 2x + 3y, s.t. 2x² + 2y² <= 50 and x+y = 1

            // Max x' * c
            //  x

            // s.t. x' * A * x <= k
            //      x' * i     = 1
            // lower_bound < x < upper_bound

            double[] c = { 2, 3 };
            double[,] A = { { 2, 0 }, { 0, 2 } };
            double k = 50;

            // Create the objective function
            var objective = new NonlinearObjectiveFunction(2,
                                                           function: (x) => x.InnerProduct(c),
                                                           gradient: (x) => c
                                                           );

            // Test objective
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i * 2 + j * 3;
                    double actual   = objective.Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }


            // Create the optimization constraints
            var constraints = new List <NonlinearConstraint>();

            constraints.Add(new QuadraticConstraint(objective,
                                                    quadraticTerms: A,
                                                    shouldBe: ConstraintType.LesserThanOrEqualTo, value: k
                                                    ));

            constraints.Add(new NonlinearConstraint(objective,
                                                    function: (x) => x.Sum(),
                                                    gradient: (x) => new[] { 1.0, 1.0 },
                                                    shouldBe: ConstraintType.EqualTo, value: 1,
                                                    withinTolerance: 1e-10
                                                    ));


            // Test first constraint
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i * (2 * i + 0 * j) + j * (0 * i + 2 * j);
                    double actual   = constraints[0].Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }


            // Test second constraint
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i + j;
                    double actual   = constraints[1].Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }



            AugmentedLagrangian solver =
                new AugmentedLagrangian(inner, objective, constraints);

            Assert.AreEqual(inner, solver.Optimizer);

            Assert.IsTrue(solver.Maximize());
            double maxValue = solver.Value;

            Assert.AreEqual(6, maxValue, tol);
            Assert.AreEqual(-3, solver.Solution[0], tol);
            Assert.AreEqual(4, solver.Solution[1], tol);
        }
        public void AugmentedLagrangianSolverConstructorTest5()
        {
            // Suppose we would like to minimize the following function:
            //
            //    f(x,y) = min 100(y-x²)²+(1-x)²
            //
            // Subject to the constraints
            //
            //    x >= 0  (x must be positive)
            //    y >= 0  (y must be positive)
            //

            double x = 0, y = 0;


            // First, we create our objective function
            var f = new NonlinearObjectiveFunction(

                // This is the objective function:  f(x,y) = min 100(y-x²)²+(1-x)²
                function: () => 100 * Math.Pow(y - x * x, 2) + Math.Pow(1 - x, 2),

                // The gradient vector:
                gradient: () => new[]
            {
                2 * (200 * Math.Pow(x, 3) - 200 * x * y + x - 1),     // df/dx = 2(200x³-200xy+x-1)
                200 * (y - x * x)                                     // df/dy = 200(y-x²)
            }

                );


            // Now we can start stating the constraints
            var constraints = new List <NonlinearConstraint>();

            // Add the non-negativity constraint for x
            constraints.Add(new NonlinearConstraint(f,

                                                    // 1st constraint: x should be greater than or equal to 0
                                                    function: () => x, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0,

                                                    gradient: () => new[] { 1.0, 0.0 }
                                                    ));

            // Add the non-negativity constraint for y
            constraints.Add(new NonlinearConstraint(f,

                                                    // 2nd constraint: y should be greater than or equal to 0
                                                    function: () => y, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0,

                                                    gradient: () => new[] { 0.0, 1.0 }
                                                    ));


            // Finally, we create the non-linear programming solver
            var solver = new AugmentedLagrangian(f, constraints);

            // And attempt to solve the problem
            Assert.IsTrue(solver.Minimize());
            double minValue = solver.Value;

            Assert.AreEqual(0, minValue, 1e-10);
            Assert.AreEqual(1, solver.Solution[0], 1e-6);
            Assert.AreEqual(1, solver.Solution[1], 1e-6);

            Assert.IsFalse(Double.IsNaN(minValue));
            Assert.IsFalse(Double.IsNaN(solver.Solution[0]));
            Assert.IsFalse(Double.IsNaN(solver.Solution[1]));
        }
        public void AugmentedLagrangianSolverConstructorTest4()
        {
            // min x*y+ y*z
            //
            // s.t.  x^2 - y^2 + z^2 - 2  >= 0
            //       x^2 + y^2 + z^2 - 10 <= 0
            //       x   + y               = 1
            //

            double x = 0, y = 0, z = 0;

            var f = new NonlinearObjectiveFunction(

                function: () => x * y + y * z,

                gradient: () => new[]
            {
                y,         // df/dx
                x + z,     // df/dy
                y,         // df/dz
            }

                );


            var constraints = new List <NonlinearConstraint>();

            constraints.Add(new NonlinearConstraint(f,

                                                    function: () => x * x - y * y + z * z,
                                                    gradient: () => new[] { 2 * x, -2 * y, 2 * z },

                                                    shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 2
                                                    ));

            constraints.Add(new NonlinearConstraint(f,

                                                    function: () => x * x + y * y + z * z,
                                                    gradient: () => new[] { 2 * x, 2 * y, 2 * z },

                                                    shouldBe: ConstraintType.LesserThanOrEqualTo, value: 10
                                                    ));

            constraints.Add(new NonlinearConstraint(f,

                                                    function: () => x + y,
                                                    gradient: () => new[] { 1.0, 1.0, 0.0 },

                                                    shouldBe: ConstraintType.EqualTo, value: 1
                                                    )
            {
                Tolerance = 1e-5
            });

            var solver = new AugmentedLagrangian(f, constraints);

            solver.Solution[0] = 1;
            solver.Solution[1] = 1;
            solver.Solution[2] = 1;

            Assert.IsTrue(solver.Minimize());
            double minValue = solver.Value;

            Assert.AreEqual(1, solver.Solution[0] + solver.Solution[1], 1e-4);

            Assert.IsFalse(Double.IsNaN(minValue));
            Assert.IsFalse(Double.IsNaN(solver.Solution[0]));
            Assert.IsFalse(Double.IsNaN(solver.Solution[1]));
            Assert.IsFalse(Double.IsNaN(solver.Solution[2]));
        }
Пример #13
0
        public void constructorTest5()
        {
            // AugmentedLagrangian with NonlinearConstraints
            // have a Gradient NullReferenceException issue
            // https://github.com/accord-net/framework/issues/177

            // Easy three dimensional minimization in ellipsoid.
            var function = new NonlinearObjectiveFunction(3,
                                                          function: x => x[0] * x[1] * x[2],
                                                          gradient: x => new[] { x[1] * x[2], x[0] * x[2], x[0] * x[1] });

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(function,
                                        constraint: x => (1.0 - x[0] * x[0] - 2.0 * x[1] * x[1] - 3.0 * x[2] * x[2]) >= 0,
                                        gradient: x => new[] { -2.0 * x[0],                                        -4.0 * x[1], -6.0 * x[2] }),
                new NonlinearConstraint(function,
                                        constraint: x => x[0] >= 0,
                                        gradient: x => new[] { 1.0,                                                          0,           0 }),
                new NonlinearConstraint(function,
                                        constraint: x => x[1] >= 0,
                                        gradient: x => new[] { 0,                                                          1.0,           0 }),
                new NonlinearConstraint(function,
                                        constraint: x => - x[2] >= 0,
                                        gradient: x => new[] { 0,                                                            0,        -1.0 }),
            };

            for (int i = 0; i < constraints.Length; i++)
            {
                Assert.AreEqual(ConstraintType.GreaterThanOrEqualTo, constraints[i].ShouldBe);
                Assert.AreEqual(0, constraints[i].Value);
            }

            var inner = new BroydenFletcherGoldfarbShanno(3);

            inner.LineSearch  = LineSearch.BacktrackingArmijo;
            inner.Corrections = 10;

            var solver = new AugmentedLagrangian(inner, function, constraints);

            Assert.AreEqual(inner, solver.Optimizer);

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

            double[] solution = solver.Solution;

            double[] expected =
            {
                1.0 / Math.Sqrt(3.0), 1.0 / Math.Sqrt(6.0), -1.0 / 3.0
            };


            for (int i = 0; i < expected.Length; i++)
            {
                Assert.AreEqual(expected[i], solver.Solution[i], 1e-3);
            }
            Assert.AreEqual(-0.078567420132031968, minimum, 1e-4);

            double expectedMinimum = function.Function(solver.Solution);

            Assert.AreEqual(expectedMinimum, minimum);
        }
 /// <summary>
 ///     Creates a new <see cref="ResilientBackpropagation" /> function optimizer.
 /// </summary>
 /// <param name="function">The function to be optimized.</param>
 public ResilientBackpropagation(NonlinearObjectiveFunction function)
     : this(function.NumberOfVariables, function.Function, function.Gradient)
 {
 }
Пример #15
0
        public void AugmentedLagrangianSolverConstructorTest5()
        {
            #region doc_lambda
            // Suppose we would like to minimize the following function:
            //
            //    f(x,y) = min 100(y-x²)²+(1-x)²
            //
            // Subject to the constraints
            //
            //    x >= 0  (x must be positive)
            //    y >= 0  (y must be positive)
            //

            // First, let's declare some symbolic variables
            double x = 0, y = 0; // (values do not matter)

            // Now, we create an objective function
            var f = new NonlinearObjectiveFunction(

                // This is the objective function:  f(x,y) = min 100(y-x²)²+(1-x)²
                function: () => 100 * Math.Pow(y - x * x, 2) + Math.Pow(1 - x, 2),

                // And this is the vector gradient for the same function:
                gradient: () => new[]
            {
                2 * (200 * Math.Pow(x, 3) - 200 * x * y + x - 1),     // df/dx = 2(200x³-200xy+x-1)
                200 * (y - x * x)                                     // df/dy = 200(y-x²)
            }
                );

            // Now we can start stating the constraints
            var constraints = new List <NonlinearConstraint>()
            {
                // Add the non-negativity constraint for x
                new NonlinearConstraint(f,
                                        // 1st constraint: x should be greater than or equal to 0
                                        function: () => x,
                                        shouldBe: ConstraintType.GreaterThanOrEqualTo,
                                        value: 0,
                                        gradient: () => new[] { 1.0, 0.0 }
                                        ),

                // Add the non-negativity constraint for y
                new NonlinearConstraint(f,
                                        // 2nd constraint: y should be greater than or equal to 0
                                        function: () => y,
                                        shouldBe: ConstraintType.GreaterThanOrEqualTo,
                                        value: 0,
                                        gradient: () => new[] { 0.0, 1.0 }
                                        )
            };

            // Finally, we create the non-linear programming solver
            var solver = new AugmentedLagrangian(f, constraints);

            // And attempt to find a minimum
            bool success = solver.Minimize();

            // The solution found was { 1, 1 }
            double[] solution = solver.Solution;

            // with the minimum value zero.
            double minValue = solver.Value;
            #endregion

            Assert.IsTrue(success);
            Assert.AreEqual(0, minValue, 1e-10);
            Assert.AreEqual(1, solver.Solution[0], 1e-6);
            Assert.AreEqual(1, solver.Solution[1], 1e-6);

            Assert.IsFalse(Double.IsNaN(minValue));
            Assert.IsFalse(Double.IsNaN(solver.Solution[0]));
            Assert.IsFalse(Double.IsNaN(solver.Solution[1]));
        }
Пример #16
0
 /// <summary>
 ///     Creates a new <see cref="NelderMead" /> non-linear optimization algorithm.
 /// </summary>
 /// <param name="function">The objective function whose optimum values should be found.</param>
 public NelderMead(NonlinearObjectiveFunction function)
     : base(function)
 {
     init(function.NumberOfVariables);
 }
Пример #17
0
 /// <summary>
 ///   Creates a new instance of the Augmented Lagrangian algorithm.
 /// </summary>
 ///
 /// <param name="function">The objective function to be optimized.</param>
 /// <param name="constraints">
 ///   The <see cref="IConstraint"/>s to which the solution must be subjected.</param>
 ///
 public AugmentedLagrangian(NonlinearObjectiveFunction function, IEnumerable <IConstraint> constraints)
     : base(function.NumberOfVariables)
 {
     init(function, constraints, null);
 }
Пример #18
0
 /// <summary>
 ///     Creates a new <see cref="Subplex" /> optimization algorithm.
 /// </summary>
 /// <param name="function">The objective function whose optimum values should be found.</param>
 public Subplex(NonlinearObjectiveFunction function)
     : base(function)
 {
     init(function.NumberOfVariables);
 }
Пример #19
0
        public static double[] OptimiseWeights(double[,] allHistoryBars, double [] retNorm)
        {
            var covMatrix = allHistoryBars.Transpose().Covariance();

            var maxRet = 0.9 * retNorm.Max();


            Func <double[], double> retNormFunc = (x) => x.Dot(retNorm) - maxRet;

            // The scoring function
            var f = new NonlinearObjectiveFunction(covMatrix.GetLength(0), x => x.DotAndDot(covMatrix, x));
            // Under the following constraints
            var constraints = new[]
            {
                //the sum of all weights is equal to 1 (ish)
                //using Enumerable sum because of Accord.Math extension redefinition
                //https://stackoverflow.com/questions/32380592/why-am-i-required-to-reference-system-numerics-with-this-simple-linq-expression
                new NonlinearConstraint(covMatrix.GetLength(0), x => - Math.Pow(Enumerable.Sum(x) - 1, 2) >= -1e-6),
                new NonlinearConstraint(covMatrix.GetLength(0), x => retNormFunc(x) >= 0),
                //the values are bounded between 0 and 1
                new NonlinearConstraint(covMatrix.GetLength(0), x => x.Min() >= -1),
                new NonlinearConstraint(covMatrix.GetLength(0), x => - x.Max() >= -1),
            };


            //var nbVar =3;

            //NelderMead algo = new NelderMead(f);



            //         var function  = new NonlinearObjectiveFunction(covMatrix.GetLength(0),
            //             function: (x) => x.DotAndDot(covMatrix, x)//,
            //             //gradient: (x) => x.DotProduct(covMatrix, x)
            //         );

            // var inner = new BroydenFletcherGoldfarbShanno(4);
            //         inner.LineSearch = LineSearch.BacktrackingArmijo;
            //         inner.Corrections = 10;

            //         var algo = new AugmentedLagrangian(inner, function, constraints);


            //         bool s = algo.Minimize();

            //var g =  new FiniteDifferences(nbVar, f);
            //
            //var algo = new NonlinearConjugateGradient (f, constraints);
            //var algo = new BroydenFletcherGoldfarbShanno(numberOfVariables: nbVar, function: f, gradient: g);
            //var algo = new AugmentedLagrangian(f, constraints);
            // Optimize it
            //TODO handle !success



            var  algo    = new Cobyla(f, constraints);
            bool success = algo.Minimize();

            if (!success)
            {
                return(null);
            }
            double minimum = algo.Value;

            double[] weights = algo.Solution;


            return(weights);
        }
Пример #20
0
        public void AugmentedLagrangianSolverConstructorTest7()
        {
            // maximize 2x + 3y, s.t. 2x² + 2y² <= 50

            // Max x' * c
            //  x

            // s.t. x' * A * x <= k
            //      x' * i     = 1
            // lower_bound < x < upper_bound

            double[] c = { 2, 3 };
            double[,] A = { { 2, 0 }, { 0, 2 } };
            double k = 50;

            // Create the objective function
            var objective = new NonlinearObjectiveFunction(2,
                                                           function: (x) => x.InnerProduct(c),
                                                           gradient: (x) => c
                                                           );

            // Test objective
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i * 2 + j * 3;
                    double actual   = objective.Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }


            // Create the optimization constraints
            var constraints = new List <NonlinearConstraint>();

            constraints.Add(new QuadraticConstraint(objective,
                                                    quadraticTerms: A,
                                                    shouldBe: ConstraintType.LesserThanOrEqualTo, value: k
                                                    ));


            // Test first constraint
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    double expected = i * (2 * i + 0 * j) + j * (0 * i + 2 * j);
                    double actual   = constraints[0].Function(new double[] { i, j });
                    Assert.AreEqual(expected, actual);
                }
            }


            // Create the solver algorithm
            AugmentedLagrangianSolver solver =
                new AugmentedLagrangianSolver(2, constraints);

            double maxValue = solver.Maximize(objective);

            Assert.AreEqual(18.02, maxValue, 0.01);
            Assert.AreEqual(2.77, solver.Solution[0], 1e-2);
            Assert.AreEqual(4.16, solver.Solution[1], 1e-2);
        }
Пример #21
0
        private void init(NonlinearObjectiveFunction function,
                          IEnumerable <IConstraint> constraints, IGradientOptimizationMethod innerSolver)
        {
            if (function is not null)
            {
                if (function.NumberOfVariables != NumberOfVariables)
                {
                    throw new ArgumentOutOfRangeException("function",
                                                          "Incorrect number of variables in the objective function. " +
                                                          "The number of variables must match the number of variables set in the solver.");
                }

                Function = function.Function;
                Gradient = function.Gradient;
            }

            if (innerSolver is null)
            {
                innerSolver = new BroydenFletcherGoldfarbShanno(NumberOfVariables)
                {
                    LineSearch    = LineSearch.BacktrackingArmijo,
                    Corrections   = 10,
                    Epsilon       = 1e-10,
                    MaxIterations = 100000
                };
            }

            var equality    = new List <IConstraint>();
            var lesserThan  = new List <IConstraint>();
            var greaterThan = new List <IConstraint>();

            foreach (var c in constraints)
            {
                switch (c.ShouldBe)
                {
                case ConstraintType.EqualTo:
                    equality.Add(c); break;

                case ConstraintType.GreaterThanOrEqualTo:
                    greaterThan.Add(c); break;

                case ConstraintType.LesserThanOrEqualTo:
                    lesserThan.Add(c); break;

                default:
                    throw new ArgumentException("Unknown constraint type.", "constraints");
                }
            }

            lesserThanConstraints  = lesserThan.ToArray();
            greaterThanConstraints = greaterThan.ToArray();
            equalityConstraints    = equality.ToArray();

            lambda = new double[equalityConstraints.Length];
            mu     = new double[lesserThanConstraints.Length];
            nu     = new double[greaterThanConstraints.Length];

            g = new double[NumberOfVariables];

            dualSolver          = innerSolver;
            dualSolver.Function = objectiveFunction;
            dualSolver.Gradient = objectiveGradient;
        }