Quadratic objective function.

In mathematics, a quadratic function, a quadratic polynomial, a polynomial of degree 2, or simply a quadratic, is a polynomial function in one or more variables in which the highest-degree term is of the second degree. For example, a quadratic function in three variables x, y, and z contains exclusively terms x², y², z², xy, xz, yz, x, y, z, and a constant:

f(x,y,z) = ax² + by² +cz² + dxy + exz + fyz + gx + hy + iz + j

Please note that the function's constructor expects the function expression to be given on this form. Scalar values must be located on the left of the variables, and no term should be duplicated in the quadratic expression. Please take a look on the examples section of this page for some examples of expected functions.

References: Wikipedia, The Free Encyclopedia. Quadratic Function. Available on: https://en.wikipedia.org/wiki/Quadratic_function

Inheritance: NonlinearObjectiveFunction, IObjectiveFunction
コード例 #1
0
        public void QuadraticConstructorTest()
        {
            double[,] quadraticTerms = 
            {
                {  1, 2, 3 },
                {  2, 5, 6 },
                {  3, 6, 9 },
            };

            double[] linearTerms = { 1, 2, 3 };

            var target = new QuadraticObjectiveFunction(quadraticTerms, linearTerms);

            var function = target.Function;
            var gradient = target.Gradient;

            FiniteDifferences fd = new FiniteDifferences(3, function);

            double[][] x =
            {
                new double[] { 1, 2, 3 },
                new double[] { 3, 1, 4 },
                new double[] { -6 , 5, 9 },
                new double[] { 31, 25, 246 },
                new double[] { -0.102, 0, 10 },
            };


            { // Function test
                for (int i = 0; i < x.Length; i++)
                {
                    double expected = 0.5 * 
                        (x[i].Multiply(quadraticTerms)).InnerProduct(x[i])
                        + linearTerms.InnerProduct(x[i]);

                    double actual = function(x[i]);

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

            { // Gradient test
                for (int i = 0; i < x.Length; i++)
                {
                    double[] expected = fd.Compute(x[i]);
                    double[] actual = gradient(x[i]);

                    for (int j = 0; j < actual.Length; j++)
                        Assert.AreEqual(expected[j], actual[j], 1e-8);
                }
            }
        }
コード例 #2
0
        public void ConstructorTest1()
        {
            var f = new QuadraticObjectiveFunction("a + b = 0");

            var constraints1 = new[]
            {
                new LinearConstraint(f, "0.0732 * a + 0.0799 * b = 0.098"),
                new LinearConstraint(f, "a + b = 1"),
                new LinearConstraint(f, "a >= 0"),
                new LinearConstraint(f, "b >= 0"),
                new LinearConstraint(f, "a >= 0.5")
            };

            var constraints2 = new[]
            {
                new LinearConstraint(f, "0.0732 * a + 0.0799 * b - 0.098 = 0"),
                new LinearConstraint(f, "a + b -2 = -1"),
                new LinearConstraint(f, "-a <= 0"),
                new LinearConstraint(f, "-b <= 0"),
                new LinearConstraint(f, "-a + 0.5 <= 0")
            };

            for (int i = 0; i < constraints1.Length; i++)
            {
                var c1 = constraints1[i];
                var c2 = constraints2[i];

                for (double a = -10; a < 10; a += 0.1)
                {
                    for (double b = -10; b < 10; b += 0.1)
                    {
                        double[] x = { a, b };
                        double actual = c1.GetViolation(x);
                        double expected = c2.GetViolation(x);
                        Assert.AreEqual(expected, actual);
                    }
                }
            }
        }
コード例 #3
0
        /// <summary>
        ///   Constructs a new instance of the <see cref="GoldfarbIdnani"/> class.
        /// </summary>
        ///
        /// <param name="function">The objective function to be optimized.</param>
        /// <param name="constraintMatrix">The constraints matrix <c>A</c>.</param>
        /// <param name="constraintValues">The constraints values <c>b</c>.</param>
        /// <param name="numberOfEqualities">The number of equalities in the constraints.</param>
        ///
        public GoldfarbIdnani(QuadraticObjectiveFunction function, double[,] constraintMatrix,
                              double[] constraintValues, int numberOfEqualities = 0)
            : base(function.NumberOfVariables, function.Function, function.Gradient)
        {
            if (function.NumberOfVariables != constraintMatrix.GetLength(1))
            {
                throw new ArgumentException("The number of columns in the constraint matrix A "
                                            + "should equal the number of variables in the problem.", "constraintMatrix");
            }

            if (constraintValues.Length != constraintMatrix.GetLength(0))
            {
                throw new DimensionMismatchException("constraintValues");
            }

            if (numberOfEqualities < 0 || numberOfEqualities > constraintValues.Length)
            {
                throw new ArgumentOutOfRangeException("numberOfEqualities");
            }

            initialize(function.NumberOfVariables, function.QuadraticTerms,
                       function.LinearTerms, constraintMatrix, constraintValues, numberOfEqualities);
        }
コード例 #4
0
 /// <summary>
 ///   Attempts to create a <see cref="QuadraticObjectiveFunction"/>
 ///   from a <see cref="System.String"/> representation.
 /// </summary>
 /// 
 /// <param name="str">The string containing the function in textual form.</param>
 /// <param name="function">The resulting function, if it could be parsed.</param>
 /// 
 /// <returns><c>true</c> if the function could be parsed
 ///   from the string, <c>false</c> otherwise.</returns>
 /// 
 public static bool TryParse(string str, out QuadraticObjectiveFunction function)
 {
     return TryParse(str, CultureInfo.InvariantCulture, out function);
 }
コード例 #5
0
        public void GoldfarbIdnaniMinimizeTest1()
        {
            // This test reproduces Issue #33 at Google Code Tracker
            // https://code.google.com/p/accord/issues/detail?id=33

            // Create objective function using the
            // Hessian Q and linear terms vector d.

            double[,] Q =
            {
                { 0.12264004,  0.011579293, 0.103326825, 0.064073439 },
                { 0.011579293, 0.033856,    0.014311947, 0.014732381 },
                { 0.103326825, 0.014311947, 0.17715681,  0.067615114 },
                { 0.064073439, 0.014732381, 0.067615114, 0.11539609 }
            };

            Assert.IsTrue(Q.IsPositiveDefinite());

            double[] d = { 0, 0, 0, 0 };

            var f = new QuadraticObjectiveFunction(Q, d, "a", "b", "c", "d");

            // Now, create the constraints
            var constraints = new LinearConstraintCollection();

            constraints.Add(new LinearConstraint(f, "0.0732 * a + 0.0799 * b + 0.1926 * c + 0.0047 * d = 0.098"));
            constraints.Add(new LinearConstraint(f, "a + b + c + d = 1"));
            constraints.Add(new LinearConstraint(f, "a >= 0"));
            constraints.Add(new LinearConstraint(f, "b >= 0"));
            constraints.Add(new LinearConstraint(f, "c >= 0"));
            constraints.Add(new LinearConstraint(f, "d >= 0"));
            constraints.Add(new LinearConstraint(f, "a >= 0.5"));

            double[] b;
            int eq;
            double[,] A = constraints.CreateMatrix(4, out b, out eq);

            // Now we create the quadratic programming solver for 2 variables, using the constraints.
            GoldfarbIdnaniQuadraticSolver solver = new GoldfarbIdnaniQuadraticSolver(4, constraints);

            // And attempt to solve it.
            double minValue = solver.Minimize(f);

            double[] expected = { 0.5, 0.336259542, 0.163740458, 0 };
            double[] actual = solver.Solution;

            for (int i = 0; i < expected.Length; i++)
            {
                double e = expected[i];
                double a = actual[i];
                Assert.AreEqual(e, a);
            }
        }
コード例 #6
0
        public void GoldfarbIdnaniConstructorTest9()
        {
            // Solve the following optimization problem:
            //
            //  min f(x) = 2x² + xy + y² - 5y
            // 
            //  s.t.  -x - 3y >= -2
            //        -x -  y >= 0
            //              x >=  0
            //              y >=  0
            //



            double x = 0, y = 0;

            var f = new QuadraticObjectiveFunction(() => 2 * (x * x) + (x * y) + (y * y) - 5 * y);

            List<LinearConstraint> constraints = new List<LinearConstraint>();
            constraints.Add(new LinearConstraint(f, () => -x - 3 * y >= -2));
            constraints.Add(new LinearConstraint(f, () => -x - y >= 0));
            constraints.Add(new LinearConstraint(f, () => x >= 0));
            constraints.Add(new LinearConstraint(f, () => y >= 0));


            GoldfarbIdnaniQuadraticSolver target = new GoldfarbIdnaniQuadraticSolver(2, constraints);

            double[,] expectedA = 
            {
                { -1, -3 },
                { -1, -1 },
                {  1,  0 },
                {  0,  1 },
            };

            double[] expectedb = 
            {
                -2, 0, 0, 0
            };

            double[,] expectedQ = 
            {
                { 4, 1 },
                { 1, 2 },
            };

            double[] expectedd = 
            {
                0, -5
            };

            // Tested against R's QuadProg package
            /*
               Qmat = matrix(c(4,1,1,2),2,2)
               dvec = -c(0, -5)
               Amat =  matrix(c(-1, -3, -1, -1, 1, 0, 0, 1), 2,4)
               bvec = c(-2, 0, 0, 0)
               
               solve.QP(Qmat, dvec, Amat, bvec)
            */

            var actualA = target.ConstraintMatrix;
            var actualb = target.ConstraintValues;
            var actualQ = f.GetQuadraticTermsMatrix();
            var actuald = f.GetLinearTermsVector();

            Assert.IsTrue(expectedA.IsEqual(actualA));
            Assert.IsTrue(expectedb.IsEqual(actualb));
            Assert.IsTrue(expectedQ.IsEqual(actualQ));
            Assert.IsTrue(expectedd.IsEqual(actuald));

            double min = target.Minimize(f);

            double[] solution = target.Solution;

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

            Assert.AreEqual(0.0, min, 1e-10);

            Assert.AreEqual(0, target.Lagrangian[0], 1e-10);
            Assert.AreEqual(5, target.Lagrangian[1], 1e-10);
            Assert.AreEqual(5, target.Lagrangian[2], 1e-10);
            Assert.AreEqual(0, target.Lagrangian[3], 1e-10);


            Assert.IsFalse(Double.IsNaN(min));

            foreach (double v in target.Solution)
                Assert.IsFalse(double.IsNaN(v));

            foreach (double v in target.Lagrangian)
                Assert.IsFalse(double.IsNaN(v));
        }
コード例 #7
0
        public void GoldfarbIdnaniConstructorTest7()
        {
            // Solve the following optimization problem:
            //
            //  min f(x) = 3x² + 2xy + 3y² - y
            // 
            //  s.t.   x >=  1
            //         y >=  1
            //

            double x = 0, y = 0;

            // http://www.wolframalpha.com/input/?i=min+x%C2%B2+%2B+2xy+%2B+y%C2%B2+-+y%2C+x+%3E%3D+1%2C+y+%3E%3D+1
            var f = new QuadraticObjectiveFunction(() => 3 * (x * x) + 2 * (x * y) + 3 * (y * y) - y);

            List<LinearConstraint> constraints = new List<LinearConstraint>();
            constraints.Add(new LinearConstraint(f, () => x >= 1));
            constraints.Add(new LinearConstraint(f, () => y >= 1));


            GoldfarbIdnaniQuadraticSolver target = new GoldfarbIdnaniQuadraticSolver(2, constraints);

            double[,] A = 
            {
                { 1, 0 }, 
                { 0, 1 }, 
            };

            double[] b = 
            {
                 1, 
                 1, 
            };

            Assert.IsTrue(A.IsEqual(target.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(target.ConstraintValues));

            double[,] Q = 
            {   
                { 6, 2 }, 
                { 2, 6 },
            };

            double[] d = { 0, -1 };


            var actualQ = f.GetQuadraticTermsMatrix();
            var actuald = f.GetLinearTermsVector();

            Assert.IsTrue(Q.IsEqual(actualQ));
            Assert.IsTrue(d.IsEqual(actuald));

            double minValue = target.Minimize(f);
            double[] solution = target.Solution;

            Assert.AreEqual(7, minValue);
            Assert.AreEqual(1, solution[0]);
            Assert.AreEqual(1, solution[1]);

            Assert.AreEqual(8, target.Lagrangian[0], 1e-5);
            Assert.AreEqual(7, target.Lagrangian[1], 1e-5);

            foreach (double v in target.Solution)
                Assert.IsFalse(double.IsNaN(v));

            foreach (double v in target.Lagrangian)
                Assert.IsFalse(double.IsNaN(v));
        }
コード例 #8
0
        public void GoldfarbIdnaniConstructorTest4()
        {
            // Solve the following optimization problem:
            //
            //  min f(x) = 2x² - xy + 4y² - 5x - 6y
            // 
            //  s.t.   x - y  ==   5  (x minus y should be equal to 5)
            //             x  >=  10  (x should be greater than or equal to 10)
            //

            var f = new QuadraticObjectiveFunction("2x² - xy + 4y² - 5x - 6y");

            List<LinearConstraint> constraints = new List<LinearConstraint>();
            constraints.Add(new LinearConstraint(f, "x-y = 5"));
            constraints.Add(new LinearConstraint(f, "x >= 10"));


            GoldfarbIdnaniQuadraticSolver target = new GoldfarbIdnaniQuadraticSolver(2, constraints);

            double[,] A = 
            {
                { 1, -1 }, 
                { 1,  0 }, 
            };

            double[] b = 
            {
                 5, 
                10, 
            };

            Assert.IsTrue(A.IsEqual(target.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(target.ConstraintValues));

            double[,] Q = 
            {   
                { +2*2,  -1   }, 
                {   -1,  +4*2 },
            };

            double[] d = { -5, -6 };


            var actualQ = f.GetQuadraticTermsMatrix();
            var actuald = f.GetLinearTermsVector();

            Assert.IsTrue(Q.IsEqual(actualQ));
            Assert.IsTrue(d.IsEqual(actuald));
        }
コード例 #9
0
        public void HomogeneousTest2()
        {
            double[,] quadraticTerms = 
            {
                {  1, 0, 1 },
                {  0, 2, 0 },
                {  1, 0, 1 },
            };

            double[] linearTerms = { 0, 0, 0 };

            var target = new QuadraticObjectiveFunction(quadraticTerms, linearTerms);

            var function = target.Function;
            var gradient = target.Gradient;

            FiniteDifferences fd = new FiniteDifferences(3, function);

            double[][] x =
            {
                new double[] { 1, 2, 3 },
                new double[] { 3, 1, 4 },
                new double[] { -6 , 5, 9 },
                new double[] { 31, 25, 246 },
                new double[] { -0.102, 0, 10 },
            };

            { // Gradient test
                for (int i = 0; i < x.Length; i++)
                {
                    double[] expected = fd.Compute(x[i]);
                    double[] actual = gradient(x[i]);

                    for (int j = 0; j < actual.Length; j++)
                        Assert.AreEqual(expected[j], actual[j], 1e-8);
                }
            }
        }
コード例 #10
0
        public void GoldfarbIdnaniParseGlobalizationTest2()
        {
            String strObjective = 0.5.ToString(CultureInfo.InvariantCulture)
                + "x² +" + 0.2.ToString(CultureInfo.InvariantCulture) + "y² +"
                + 0.3.ToString(CultureInfo.InvariantCulture) + "xy";

            String[] strConstraints = 
            { 
                0.01.ToString(CultureInfo.InvariantCulture) + "x" + " + " + 
                0.02.ToString(CultureInfo.InvariantCulture) + "y - " + 
                0.03.ToString(CultureInfo.InvariantCulture) + " = 0", 
                "x + y = 100" 
            };

            QuadraticObjectiveFunction function = new QuadraticObjectiveFunction(strObjective);
            LinearConstraintCollection cst = new LinearConstraintCollection();
            foreach (var tmpCst in strConstraints)
                cst.Add(new LinearConstraint(function, tmpCst));

            var classSolver = new Accord.Math.Optimization.GoldfarbIdnani(function, cst);
            bool status = classSolver.Minimize();
            double result = classSolver.Value;

            Assert.IsTrue(status);
            Assert.AreEqual(15553.60, result, 1e-10);
        }
コード例 #11
0
ファイル: MainForm.cs プロジェクト: xyicheng/Accord
        private void button1_Click(object sender, EventArgs e)
        {
            String objectiveString = tbObjective.Text;
            String[] constraintStrings = tbConstraints.Lines;
            bool minimize = (string)comboBox1.SelectedItem == "min";

            QuadraticObjectiveFunction function;
            LinearConstraint[] constraints = new LinearConstraint[constraintStrings.Length];

            try
            {
                // Create objective function
                function = new QuadraticObjectiveFunction(objectiveString);
            }
            catch (FormatException)
            {
                tbSolution.Text = "Invalid objective function.";
                return;
            }

            // Create list of constraints
            for (int i = 0; i < constraints.Length; i++)
            {
                try
                {
                    constraints[i] = new LinearConstraint(function, constraintStrings[i]);
                }
                catch (FormatException)
                {
                    tbSolution.Text = "Invalid constraint at line " + i + ".";
                    return;
                }
            }

            // Create solver
            var solver = new GoldfarbIdnaniQuadraticSolver(function.NumberOfVariables, constraints);

            try
            {
                // Solve the minimization or maximization problem
                double value = (minimize) ? solver.Minimize(function) : solver.Maximize(function);

                // Grab the solution found
                double[] solution = solver.Solution;

                // Format and display solution
                StringBuilder sb = new StringBuilder();

                sb.AppendLine("Solution:");
                sb.AppendLine();
                sb.AppendLine(" " + objectiveString + " = " + value);
                sb.AppendLine();
                for (int i = 0; i < solution.Length; i++)
                {
                    string variableName = function.Indices[i];
                    sb.AppendLine(" " + variableName + " = " + solution[i]);
                }

                tbSolution.Text = sb.ToString();
            }
            catch (NonPositiveDefiniteMatrixException)
            {
                tbSolution.Text = "Function is not positive definite.";
            }
            catch (ConvergenceException)
            {
                tbSolution.Text = "No possible solution could be attained.";
            }

        }
コード例 #12
0
        /// <summary>
        ///   Attempts to create a <see cref="QuadraticObjectiveFunction"/>
        ///   from a <see cref="System.String"/> representation.
        /// </summary>
        ///
        /// <param name="str">The string containing the function in textual form.</param>
        /// <param name="function">The resulting function, if it could be parsed.</param>
        /// <param name="culture">The culture information specifying how
        ///   numbers written in the <paramref name="function"/> should
        ///   be parsed. Default is CultureInfo.InvariantCulture.</param>
        ///
        /// <returns><c>true</c> if the function could be parsed
        ///   from the string, <c>false</c> otherwise.</returns>
        ///
        public static bool TryParse(string str, System.Globalization.CultureInfo culture, out QuadraticObjectiveFunction function)
        {
            // TODO: implement this method without the try-catch block.

            try
            {
                function = new QuadraticObjectiveFunction(str, culture);
            }
            catch (FormatException)
            {
                function = null;
                return(false);
            }

            return(true);
        }
コード例 #13
0
        /// <summary>
        ///   Maximizes the function.
        /// </summary>
        /// 
        /// <param name="function">The function to be maximized.</param>
        /// <returns>The maximum value at the solution found.</returns>
        /// 
        public double Maximize(QuadraticObjectiveFunction function)
        {
            if (function == null)
                throw new ArgumentNullException("function");

            return Maximize(function.GetQuadraticTermsMatrix(), function.GetLinearTermsVector());
        }
コード例 #14
0
        public void ConstructorTest2()
        {
            double a = 0, b = 0;

            var f = new QuadraticObjectiveFunction(() => a + b);

            Assert.AreEqual(2, f.NumberOfVariables);
            Assert.AreEqual(0, f.Variables["a"]);
            Assert.AreEqual(1, f.Variables["b"]);
            Assert.AreEqual(1, f.LinearTerms[0]);
            Assert.AreEqual(1, f.LinearTerms[1]);

            var constraints1 = new[]
            {
                new LinearConstraint(f, () => 0.0732 * a + 0.0799 * b == 0.098),
                new LinearConstraint(f, () => a + b == 1),
                new LinearConstraint(f, () => a >= 0),
                new LinearConstraint(f, () => b >= 0),
                new LinearConstraint(f, () => a >= 0.5),
                new LinearConstraint(f, () => 1 + a >= -5),
                new LinearConstraint(f, () => -1 + a <= -5)
            };

            var constraints2 = new[]
            {
                new LinearConstraint(f, () => 0.0732 * a + 0.0799 * b - 0.098 == 0),
                new LinearConstraint(f, () => a + b -2 == -1),
                new LinearConstraint(f, () => -a + 1 <= +1),
                new LinearConstraint(f, () => -b <= 0),
                new LinearConstraint(f, () => -a + 0.5 <= 0),
                new LinearConstraint(f, () => a + 1 >= -5),
                new LinearConstraint(f, () => a - 1 <= -5)
            };

            Assert.AreEqual(0.098, constraints1[0].Value);
            Assert.AreEqual(0.098, constraints2[0].Value);

            Assert.AreEqual(0, constraints1[2].Value);
            Assert.AreEqual(0, constraints2[2].Value);

            Assert.AreEqual(1, constraints1[1].Value);
            Assert.AreEqual(1, constraints2[1].Value);

            for (int i = 0; i < constraints1.Length; i++)
            {
                var c1 = constraints1[i];
                var c2 = constraints2[i];

                for (a = -10; a < 10; a += 0.1)
                {
                    for (b = -10; b < 10; b += 0.1)
                    {
                        double[] x = { a, b };
                        double actual = c1.GetViolation(x);
                        double expected = c2.GetViolation(x);
                        Assert.AreEqual(expected, actual);
                    }
                }
            }
        }
コード例 #15
0
        public void FunctionTest5()
        {
            var f1 = new QuadraticObjectiveFunction("x² + 1");
            var f2 = new QuadraticObjectiveFunction("-x*y + y*z");
            var f3 = new QuadraticObjectiveFunction("-2x² + xy - y² - 10xz + z²");
            var f4 = new QuadraticObjectiveFunction("-2x² + xy - y² + 5y");
            var f5 = new QuadraticObjectiveFunction("2x² -5");

            double x = 0, y = 0, z = 0;
            var g1 = new QuadraticObjectiveFunction(() => x * x + 1);
            var g2 = new QuadraticObjectiveFunction(() => -x * y + y * z);
            var g3 = new QuadraticObjectiveFunction(() => -2 * x * x + x * y - y * y - 10 * x * z + z * z);
            var g4 = new QuadraticObjectiveFunction(() => -2 * x * x + x * y - y * y + 5 * y);
            var g5 = new QuadraticObjectiveFunction(() => 2 * x * x - 5);
            

            QuadraticObjectiveFunction[] f = { f1, f2, f3, f4, f5 };
            QuadraticObjectiveFunction[] g = { g1, g2, g3, g4, g5 };

            for (int l = 0; l < f.Length; l++)
            {
                var fl = f[l];
                var gl = g[l];

                Assert.AreEqual(fl.NumberOfVariables, gl.NumberOfVariables);

                for (int i = 0; i < 10; i++)
                {
                    for (int j = 0; j < 10; j++)
                    {
                        for (int k = 0; k < 10; k++)
                        {
                            x = (i - 5) / 10.0;
                            y = (j - 5) / 10.0;
                            z = (k - 5) / 10.0;

                            double a = fl.Function(new[] { x, y, z }.First(fl.NumberOfVariables));
                            double e = gl.Function(new[] { x, y, z }.First(fl.NumberOfVariables));

                            Assert.AreEqual(e, a, 1e-10);
                            Assert.IsFalse(Double.IsNaN(a));
                            Assert.IsFalse(Double.IsNaN(e));
                        }
                    }
                }
            }
        }
コード例 #16
0
 /// <summary>
 ///   Constructs a new <see cref="GoldfarbIdnani"/> class.
 /// </summary>
 ///
 /// <param name="function">The objective function to be optimized.</param>
 /// <param name="constraints">The problem's constraints.</param>
 ///
 public GoldfarbIdnani(QuadraticObjectiveFunction function, IEnumerable <LinearConstraint> constraints)
     : this(function, new LinearConstraintCollection(constraints))
 {
 }
コード例 #17
0
        public void LambdaFunctionTest4()
        {
            double x = 0;
            double y = 0;
            double z = 0;

            Func<double> expected = () => -x * y + y * z;
            var actual = new QuadraticObjectiveFunction(() => -x * y + y * z);

            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    for (int k = 0; k < 10; k++)
                    {
                        x = (i - 5) / 10.0;
                        y = (j - 5) / 10.0;
                        z = (k - 5) / 10.0;

                        double a = actual.Function(new[] { x, y, z });
                        double e = expected();

                        Assert.AreEqual(e, a, 1e-10);
                        Assert.IsFalse(Double.IsNaN(a));
                        Assert.IsFalse(Double.IsNaN(e));
                    }
                }
            }
        }
コード例 #18
0
        public void GoldfarbIdnaniParseTest()
        {
            var s = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

            String strObjective = "0" + s + "5x² + 0" + s + "2y² + 0" + s + "3xy";

            String[] strConstraints = 
            { 
                "0" + s + "01x + 0" + s + "02y - 0" + s + "03 = 0", 
                "x + y = 100" 
            };

            // Now we can start creating our function:
            QuadraticObjectiveFunction function = new QuadraticObjectiveFunction(strObjective, CultureInfo.CurrentCulture);
            LinearConstraintCollection cst = new LinearConstraintCollection();
            foreach (var tmpCst in strConstraints)
                cst.Add(new LinearConstraint(function, tmpCst, CultureInfo.CurrentCulture));

            var classSolver = new Accord.Math.Optimization.GoldfarbIdnani(function, cst);
            bool status = classSolver.Minimize();
            double result = classSolver.Value;

            Assert.IsTrue(status);
            Assert.AreEqual(15553.60, result, 1e-10);
        }
コード例 #19
0
        public void FunctionTest()
        {
            double x = 0;
            double y = 0;

            Func<double> expected = () => -2 * x * x + x * y - y * y + 5 * y;
            var actual = new QuadraticObjectiveFunction("-2x² + xy - y² + 5y");

            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    x = (i - 5) / 10.0;
                    y = (j - 5) / 10.0;

                    double a = actual.Function(new[] { x, y });
                    double e = expected();

                    Assert.AreEqual(e, a, 1e-10);
                    Assert.IsFalse(Double.IsNaN(a));
                    Assert.IsFalse(Double.IsNaN(e));
                }
            }
        }
コード例 #20
0
        public void GoldfarbIdnaniMinimizeLessThanWithEqualityTest()
        {
            // This test reproduces Issue #33 at Google Code Tracker
            // https://code.google.com/p/accord/issues/detail?id=33

            // Create objective function using the
            // Hessian Q and linear terms vector d.

            double[,] Q =
            {
                { 0.12264004,  0.011579293, 0.103326825, 0.064073439 },
                { 0.011579293, 0.033856,    0.014311947, 0.014732381 },
                { 0.103326825, 0.014311947, 0.17715681,  0.067615114 },
                { 0.064073439, 0.014732381, 0.067615114, 0.11539609  }
            };

            Assert.IsTrue(Q.IsPositiveDefinite());

            double[] d = { 0, 0, 0, 0 };

            var f = new QuadraticObjectiveFunction(Q, d, "a", "b", "c", "d");

            // Now, create the constraints
            var constraints = new LinearConstraintCollection();

            constraints.Add(new LinearConstraint(f, "0.0732 * a + 0.0799 * b + 0.1926 * c + 0.0047 * d = 0.098"));
            constraints.Add(new LinearConstraint(f, "a + b + c + d = 1"));
            constraints.Add(new LinearConstraint(f, "-a <= 0"));
            constraints.Add(new LinearConstraint(f, "-b <= 0"));
            constraints.Add(new LinearConstraint(f, "-c <= 0"));
            constraints.Add(new LinearConstraint(f, "-d <= 0"));
            constraints.Add(new LinearConstraint(f, "-a + 0.5 <= 0.0"));

            Assert.AreEqual(-1, constraints[6].CombinedAs[0]);
            Assert.AreEqual(-0.5, constraints[6].Value);
            Assert.AreEqual(0.1, constraints[6].GetViolation(new double[] { 0.6 }), 1e-10);
            Assert.AreEqual(-0.1, constraints[6].GetViolation(new double[] { 0.4 }), 1e-10);

            bool psd = Q.IsPositiveDefinite();

            double[] b;
            int eq;
            double[,] A = constraints.CreateMatrix(4, out b, out eq);

            // Now we create the quadratic programming solver for 2 variables, using the constraints.
            GoldfarbIdnani solver = new GoldfarbIdnani(f, constraints);

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

            double[] expected = { 0.50000000000000, 0.30967169476486, 0.19032830523514, 0 };
            double[] actual = solver.Solution;

            for (int i = 0; i < constraints.Count; i++)
            {
                double error = constraints[i].GetViolation(actual);
                Assert.IsTrue(error >= 0);
            }

            for (int i = 0; i < expected.Length; i++)
            {
                double e = expected[i];
                double a = actual[i];
                Assert.AreEqual(e, a, 1e-10);
            }
        }
コード例 #21
0
        public void GoldfarbIdnaniConstructorTest3()
        {
            // Solve the following optimization problem:
            //
            //  min f(x) = 2x² - xy + 4y² - 5x - 6y
            // 
            //  s.t.   x - y  ==   5  (x minus y should be equal to 5)
            //             x  >=  10  (x should be greater than or equal to 10)
            //

            // In this example we will be using some symbolic processing. 
            // The following variables could be initialized to any value.
            double x = 0, y = 0;

            // Create our objective function using a lambda expression
            var f = new QuadraticObjectiveFunction(() => 2 * (x * x) - (x * y) + 4 * (y * y) - 5 * x - 6 * y);

            // Now, create the constraints
            List<LinearConstraint> constraints = new List<LinearConstraint>();
            constraints.Add(new LinearConstraint(f, () => x - y == 5));
            constraints.Add(new LinearConstraint(f, () => x >= 10));

            // Now we create the quadratic programming solver for 2 variables, using the constraints.
            GoldfarbIdnaniQuadraticSolver solver = new GoldfarbIdnaniQuadraticSolver(2, constraints);


            double[,] A = 
            {
                { 1, -1 }, 
                { 1,  0 }, 
            };

            double[] b = 
            {
                 5, 
                10, 
            };

            Assert.IsTrue(A.IsEqual(solver.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(solver.ConstraintValues));


            double[,] Q = 
            {   
                { +2*2,  -1   }, 
                {   -1,  +4*2 },
            };

            double[] d = { -5, -6 };


            var actualQ = f.GetQuadraticTermsMatrix();
            var actuald = f.GetLinearTermsVector();

            Assert.IsTrue(Q.IsEqual(actualQ));
            Assert.IsTrue(d.IsEqual(actuald));


            // And attempt to solve it.
            double minimumValue = solver.Minimize(f);

        }
コード例 #22
0
        public void GoldfarbIdnaniConstructorTest1()
        {
            double[,] D = Matrix.Identity(3);
            double[] d = { 0, 5, 0 };

            double[,] A = 
            {
                { -4, -3, 0 },
                {  2,  1, 0 },
                {  0, -2, 1 },
            };

            double[] b = { -8, 2, 0 };

            List<LinearConstraint> constraints = new List<LinearConstraint>();
            constraints.Add(new LinearConstraint(-4, -3, +0) { Value = -8 });
            constraints.Add(new LinearConstraint(+2, +1, +0) { Value = +2 });
            constraints.Add(new LinearConstraint(+0, -2, +1) { Value = +0 });

            QuadraticObjectiveFunction f = new QuadraticObjectiveFunction("2x² + y - z + 2");

            GoldfarbIdnani target = new GoldfarbIdnani(f, constraints);

            Assert.IsTrue(A.IsEqual(target.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(target.ConstraintValues));
        }
コード例 #23
0
        public void GoldfarbIdnaniConstructorTest6()
        {
            // min 1x² - 2xy + 3y² +z² - 4x - 5y -z, 6x-7y <= 8, 9x + 1y <= 11, 9x-y <= 11, -z-y = 12
            // http://www.wolframalpha.com/input/?i=min+1x%C2%B2+-+2xy+%2B+3y%C2%B2+%2Bz%C2%B2+-+4x+-+5y+-z%2C+6x-7y+%3C%3D+8%2C+9x+%2B+1y+%3C%3D+11%2C+9x-y+%3C%3D+11%2C+-z-y+%3D+12

            var f = new QuadraticObjectiveFunction("1x² - 2xy + 3y² + z² - 4x - 5y -z");

            List<LinearConstraint> constraints = new List<LinearConstraint>();
            constraints.Add(new LinearConstraint(f, "6x-7y <= 8"));
            constraints.Add(new LinearConstraint(f, "9x + 1y <= 11"));
            constraints.Add(new LinearConstraint(f, "9x-y <= 11"));
            constraints.Add(new LinearConstraint(f, "-z-y = 12"));


            GoldfarbIdnaniQuadraticSolver target = new GoldfarbIdnaniQuadraticSolver(f.NumberOfVariables, constraints);

            double value = target.Minimize(f);

            Assert.AreEqual(14376 / 109.0, value, 1e-10);

            Assert.AreEqual(-186 / 109.0, target.Solution[0], 1e-10);
            Assert.AreEqual(-284 / 109.0, target.Solution[1], 1e-10);
            Assert.AreEqual(-1024 / 109.0, target.Solution[2], 1e-10);

            foreach (double v in target.Solution)
                Assert.IsFalse(double.IsNaN(v));
        }
コード例 #24
0
        public void GoldfarbIdnaniConstructorTest3()
        {
            // http://www.wolframalpha.com/input/?i=min+2x%C2%B2+-+xy+%2B+4y%C2%B2+-+5x+-+6y+s.t.+x+-+y++%3D%3D+++5%2C+x++%3E%3D++10

            // Solve the following optimization problem:
            //
            //  min f(x) = 2x² - xy + 4y² - 5x - 6y
            // 
            //  s.t.   x - y  ==   5  (x minus y should be equal to 5)
            //             x  >=  10  (x should be greater than or equal to 10)
            //

            // In this example we will be using some symbolic processing. 
            // The following variables could be initialized to any value.
            double x = 0, y = 0;

            // Create our objective function using a lambda expression
            var f = new QuadraticObjectiveFunction(() => 2 * (x * x) - (x * y) + 4 * (y * y) - 5 * x - 6 * y);

            // Now, create the constraints
            List<LinearConstraint> constraints = new List<LinearConstraint>();
            constraints.Add(new LinearConstraint(f, () => x - y == 5));
            constraints.Add(new LinearConstraint(f, () => x >= 10));

            // Now we create the quadratic programming solver for 2 variables, using the constraints.
            GoldfarbIdnani solver = new GoldfarbIdnani(f, constraints);


            double[,] A = 
            {
                { 1, -1 }, 
                { 1,  0 }, 
            };

            double[] b = 
            {
                 5, 
                10, 
            };

            Assert.IsTrue(A.IsEqual(solver.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(solver.ConstraintValues));


            double[,] Q = 
            {   
                { +2*2,  -1   }, 
                {   -1,  +4*2 },
            };

            double[] d = { -5, -6 };


            var actualQ = f.QuadraticTerms;
            var actuald = f.LinearTerms;

            Assert.IsTrue(Q.IsEqual(actualQ));
            Assert.IsTrue(d.IsEqual(actuald));


            // And attempt to solve it.
            bool success = solver.Minimize();
            Assert.AreEqual(170, solver.Value);
            Assert.IsTrue(success);
        }
コード例 #25
0
        public void GoldfarbIdnaniConstructorTest8()
        {
            // Solve the following optimization problem:
            //
            //  min f(x) = x² + 2xy + y² - y
            // 
            //  s.t.   x >=  1
            //         y >=  1
            //

            double x = 0, y = 0;

            // http://www.wolframalpha.com/input/?i=min+x%C2%B2+%2B+2xy+%2B+y%C2%B2+-+y%2C+x+%3E%3D+1%2C+y+%3E%3D+1
            var f = new QuadraticObjectiveFunction(() => (x * x) + 2 * (x * y) + (y * y) - y);

            List<LinearConstraint> constraints = new List<LinearConstraint>();
            constraints.Add(new LinearConstraint(f, () => x >= 1));
            constraints.Add(new LinearConstraint(f, () => y >= 1));


            GoldfarbIdnaniQuadraticSolver target = new GoldfarbIdnaniQuadraticSolver(2, constraints);

            double[,] A = 
            {
                { 1, 0 }, 
                { 0, 1 }, 
            };

            double[] b = 
            {
                 1, 
                 1, 
            };

            Assert.IsTrue(A.IsEqual(target.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(target.ConstraintValues));

            double[,] Q = 
            {   
                { 2, 2 }, 
                { 2, 2 },
            };

            double[] d = { 0, -1 };


            var actualQ = f.GetQuadraticTermsMatrix();
            var actuald = f.GetLinearTermsVector();

            Assert.IsTrue(Q.IsEqual(actualQ));
            Assert.IsTrue(d.IsEqual(actuald));

            bool thrown = false;
            try
            {
                target.Minimize(f);
            }
            catch (NonPositiveDefiniteMatrixException)
            {
                thrown = true;
            }

            Assert.IsTrue(thrown);
        }
コード例 #26
0
        public void GoldfarbIdnaniConstructorTest11()
        {
            // http://www.wolframalpha.com/input/?i=minimize+f%28x%2Cy%29+%3D+2x%5E2+-+xy+%2B+4y%5E2+-+5x+-+6y+-+100%2C+s.t.+x+-+y++%3D+++5%2C+x++%3E%3D++10

            double x = 0, y = 0;

            var f = new QuadraticObjectiveFunction(() => 2 * (x * x) - (x * y) + 4 * (y * y) - 5 * x - 6 * y + 100);

            List<LinearConstraint> constraints = new List<LinearConstraint>();
            constraints.Add(new LinearConstraint(f, () => x - y == 5));
            constraints.Add(new LinearConstraint(f, () => x >= 10));

            GoldfarbIdnani solver = new GoldfarbIdnani(f, constraints);

            double[,] Q = 
            {   
                { +2*2,  -1   }, 
                {   -1,  +4*2 },
            };

            double[] d = { -5, -6 };

            var actualQ = f.QuadraticTerms;
            var actuald = f.LinearTerms;

            Assert.IsTrue(Q.IsEqual(actualQ));
            Assert.IsTrue(d.IsEqual(actuald));
            Assert.AreEqual(100, f.ConstantTerm);

            bool success = solver.Minimize();
            Assert.AreEqual(270, solver.Value);
            Assert.IsTrue(success);
        }
コード例 #27
0
        public void GoldfarbIdnaniMaximizeTest1()
        {
            // Solve the following optimization problem:
            //
            //  max f(x) = -2x² + xy - y² + 5y
            // 
            //  s.t.   x + y  <= 0
            //             y  >= 0
            //

            // Create our objective function using a text string
            var f = new QuadraticObjectiveFunction("-2x² + xy - y² + 5y");

            // Now, create the constraints
            List<LinearConstraint> constraints = new List<LinearConstraint>();
            constraints.Add(new LinearConstraint(f, "x + y <= 0"));
            constraints.Add(new LinearConstraint(f, "    y >= 0"));

            // Now we create the quadratic programming solver for 2 variables, using the constraints.
            GoldfarbIdnaniQuadraticSolver solver = new GoldfarbIdnaniQuadraticSolver(2, constraints);

            // And attempt to solve it.
            double maxValue = solver.Maximize(f);

            Assert.AreEqual(25 / 16.0, maxValue);

            Assert.AreEqual(-5 / 8.0, solver.Solution[0]);
            Assert.AreEqual(5 / 8.0, solver.Solution[1]);
        }
コード例 #28
0
        public void GoldfarbIdnaniConstructorTest5()
        {
            // min 1x² - 2xy + 3y² +z² - 4x - 5y -z, 6x-7y <= 8, 9x + 1y <= 11, 9x-y <= 11, -z-y = 12
            // http://www.wolframalpha.com/input/?i=min+1x%C2%B2+-+2xy+%2B+3y%C2%B2+%2Bz%C2%B2+-+4x+-+5y+-z%2C+6x-7y+%3C%3D+8%2C+9x+%2B+1y+%3C%3D+11%2C+9x-y+%3C%3D+11%2C+-z-y+%3D+12

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

            var f = new QuadraticObjectiveFunction(() => x * x - 2 * x * y + 3 * y * y + z * z - 4 * x - 5 * y - z);

            List<LinearConstraint> constraints = new List<LinearConstraint>();
            constraints.Add(new LinearConstraint(f, () => 6 * x - 7 * y <= 8));
            constraints.Add(new LinearConstraint(f, () => 9 * x + 1 * y <= 11));
            constraints.Add(new LinearConstraint(f, () => 9 * x - y <= 11));
            constraints.Add(new LinearConstraint(f, () => -z - y == 12));


            GoldfarbIdnani target = new GoldfarbIdnani(f, constraints);

            bool success = target.Minimize();
            double value = target.Value;

            Assert.IsTrue(success);

            Assert.AreEqual(14376 / 109.0, value, 1e-10);

            Assert.AreEqual(-186 / 109.0, target.Solution[0], 1e-10);
            Assert.AreEqual(-284 / 109.0, target.Solution[1], 1e-10);
            Assert.AreEqual(-1024 / 109.0, target.Solution[2], 1e-10);

            foreach (double v in target.Solution)
                Assert.IsFalse(double.IsNaN(v));

        }
コード例 #29
0
        /// <summary>
        ///   Minimizes the function.
        /// </summary>
        /// 
        /// <param name="function">The function to be minimized.</param>
        /// <returns>The minimum value at the solution found.</returns>
        /// 
        public double Minimize(QuadraticObjectiveFunction function)
        {
            if (function == null)
                throw new ArgumentNullException("function");

            double[,] Q = function.GetQuadraticTermsMatrix();
            double[] d = function.GetLinearTermsVector();
            return Minimize(Q, d);
        }
コード例 #30
0
        public void GoldfarbIdnaniConstructorTest8()
        {
            // Solve the following optimization problem:
            //
            //  min f(x) = x² + 2xy + y² - y
            // 
            //  s.t.   x >=  1
            //         y >=  1
            //

            double x = 0, y = 0;

            // http://www.wolframalpha.com/input/?i=min+x%C2%B2+%2B+2xy+%2B+y%C2%B2+-+y%2C+x+%3E%3D+1%2C+y+%3E%3D+1
            var f = new QuadraticObjectiveFunction(() => (x * x) + 2 * (x * y) + (y * y) - y);

            List<LinearConstraint> constraints = new List<LinearConstraint>();
            constraints.Add(new LinearConstraint(f, () => x >= 1));
            constraints.Add(new LinearConstraint(f, () => y >= 1));


            GoldfarbIdnani target = new GoldfarbIdnani(f, constraints);

            double[,] A = 
            {
                { 1, 0 }, 
                { 0, 1 }, 
            };

            double[] b = 
            {
                 1, 
                 1, 
            };

            Assert.IsTrue(A.IsEqual(target.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(target.ConstraintValues));

            double[,] Q = 
            {   
                { 2, 2 }, 
                { 2, 2 },
            };

            double[] d = { 0, -1 };


            var actualQ = f.QuadraticTerms;
            var actuald = f.LinearTerms;

            Assert.IsTrue(Q.IsEqual(actualQ));
            Assert.IsTrue(d.IsEqual(actuald));

            bool success = target.Minimize();

            Assert.IsFalse(success);
        }
コード例 #31
0
        /// <summary>
        ///   Attempts to create a <see cref="QuadraticObjectiveFunction"/>
        ///   from a <see cref="System.String"/> representation.
        /// </summary>
        /// 
        /// <param name="str">The string containing the function in textual form.</param>
        /// <param name="function">The resulting function, if it could be parsed.</param>
        /// <param name="culture">The culture information specifying how
        ///   numbers written in the <paramref name="function"/> should
        ///   be parsed. Default is CultureInfo.InvariantCulture.</param>
        ///   
        /// <returns><c>true</c> if the function could be parsed
        ///   from the string, <c>false</c> otherwise.</returns>
        /// 
        public static bool TryParse(string str, CultureInfo culture, out QuadraticObjectiveFunction function)
        {
            // TODO: implement this method without the try-catch block.

            try
            {
                function = new QuadraticObjectiveFunction(str, culture);
            }
            catch (FormatException)
            {
                function = null;
                return false;
            }

            return true;
        }
コード例 #32
0
        public void GoldfarbIdnaniParseGlobalizationTestBase()
        {
            // minimize 0.5x² + 0.2y² + 0.3xy s.t. 0.01x + 0.02y - 0.03 = 0 AND x + y = 100
            // http://www.wolframalpha.com/input/?i=minimize+0.5x%C2%B2+%2B+0.2y%C2%B2+%2B+0.3xy+s.t.+0.01x+%2B+0.02y+-+0.03+%3D+0+AND+x+%2B+y+%3D+100

            String strObjective = "0.5x² + 0.2y² + 0.3xy";

            String[] strConstraints = 
            { 
                "0.01x + 0.02y - 0.03 = 0", 
                "x + y = 100" 
            };

            QuadraticObjectiveFunction function = new QuadraticObjectiveFunction(strObjective);
            LinearConstraintCollection cst = new LinearConstraintCollection();
            foreach (var tmpCst in strConstraints)
                cst.Add(new LinearConstraint(function, tmpCst));

            var classSolver = new Accord.Math.Optimization.GoldfarbIdnani(function, cst);
            bool status = classSolver.Minimize();
            double result = classSolver.Value;

            Assert.IsTrue(status);
            Assert.AreEqual(15553.60, result, 1e-10);
        }
コード例 #33
0
 /// <summary>
 ///   Attempts to create a <see cref="QuadraticObjectiveFunction"/>
 ///   from a <see cref="System.String"/> representation.
 /// </summary>
 ///
 /// <param name="str">The string containing the function in textual form.</param>
 /// <param name="function">The resulting function, if it could be parsed.</param>
 ///
 /// <returns><c>true</c> if the function could be parsed
 ///   from the string, <c>false</c> otherwise.</returns>
 ///
 public static bool TryParse(string str, out QuadraticObjectiveFunction function)
 {
     return(TryParse(str, CultureInfo.InvariantCulture, out function));
 }
コード例 #34
0
        public void LambdaFunctionTest3()
        {
            double x = 0;

            Func<double> expected = () => x * x + 1;
            var actual = new QuadraticObjectiveFunction(() => x * x + 1);

            for (int i = 0; i < 10; i++)
            {
                x = (i - 5) / 10.0;

                double a = actual.Function(new[] { x });
                double e = expected();

                Assert.AreEqual(e, a, 1e-10);
                Assert.IsFalse(Double.IsNaN(a));
                Assert.IsFalse(Double.IsNaN(e));
            }
        }