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);
        }
        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.
            GoldfarbIdnani solver = new GoldfarbIdnani(f, constraints);

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

            Assert.AreEqual(25 / 16.0, maxValue);

            Assert.AreEqual(-5 / 8.0, solver.Solution[0]);
            Assert.AreEqual(5 / 8.0, solver.Solution[1]);
        }
        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"));


            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));
            }
        }
        /// <summary>
        /// Perform portfolio optimization for a provided matrix of historical returns and an array of expected returns
        /// </summary>
        /// <param name="historicalReturns">Matrix of annualized historical returns where each column represents a security and each row returns for the given date/time (size: K x N).</param>
        /// <param name="expectedReturns">Array of double with the portfolio annualized expected returns (size: K x 1).</param>
        /// <param name="covariance">Multi-dimensional array of double with the portfolio covariance of annualized returns (size: K x K).</param>
        /// <returns>Array of double with the portfolio weights (size: K x 1)</returns>
        public double[] Optimize(double[,] historicalReturns, double[] expectedReturns = null, double[,] covariance = null)
        {
            covariance = covariance ?? historicalReturns.Covariance();
            var size    = covariance.GetLength(0);
            var returns = expectedReturns ?? historicalReturns.Mean(0);

            var constraints = new List <LinearConstraint>
            {
                // w^T µ ≥ β
                new LinearConstraint(size)
                {
                    CombinedAs = returns,
                    ShouldBe   = ConstraintType.EqualTo,
                    Value      = _targetReturn
                }
            };

            // Σw = 1
            constraints.Add(GetBudgetConstraint(size));

            // lw ≤ w ≤ up
            constraints.AddRange(GetBoundaryConditions(size));

            // Setup solver
            var optfunc = new QuadraticObjectiveFunction(covariance, Vector.Create(size, 0.0));
            var solver  = new GoldfarbIdnani(optfunc, constraints);

            // Solve problem
            var  x0      = Vector.Create(size, 1.0 / size);
            bool success = solver.Minimize(Vector.Copy(x0));

            return(success ? solver.Solution : x0);
        }
        public void RunTest3()
        {
            // Tested against R's QuadProg package

            /* solve.QP(matrix(c(10, -3,  1, -3, 11, -2, 1, -2, 12), 3, 3), c(1,5,3),
             *       t(matrix( c(-4, 2, 1, -3, 1, -2, 0, -1, 2), 3,3)), c(-8,4,-1)) */

            double[,] D =
            {
                { 10, -3,  1 },
                { -3, 11, -2 },
                {  1, -2, 12 },
            };

            double[] d = { 1, 5, 3 };

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


            double[] b = { -8, 4, -1 };

            GoldfarbIdnani target = new GoldfarbIdnani(D, d.Multiply(-1), A.Transpose(), b);

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

            Assert.AreEqual(6.8, actual, 1e-5);
            Assert.IsFalse(double.IsNaN(actual));

            Assert.AreEqual(4, target.Iterations);
            Assert.AreEqual(0, target.Deletions);

            Assert.AreEqual(+1.4, target.Solution[0], 1e-6);
            Assert.AreEqual(+0.8, target.Solution[1], 1e-6);
            Assert.AreEqual(-0.4, target.Solution[2], 1e-6);

            Assert.AreEqual(2.5333333, target.Lagrangian[0], 1e-6);
            Assert.AreEqual(9.7333333, target.Lagrangian[1], 1e-6);
            Assert.AreEqual(0.8666667, target.Lagrangian[2], 1e-6);

            Assert.AreEqual(1, target.ActiveConstraints[0]);
            Assert.AreEqual(0, target.ActiveConstraints[1]);
            Assert.AreEqual(2, target.ActiveConstraints[2]);

            foreach (double v in target.Lagrangian)
            {
                Assert.IsFalse(double.IsNaN(v));
            }

            foreach (double v in target.Solution)
            {
                Assert.IsFalse(double.IsNaN(v));
            }
        }
Beispiel #6
0
        public void Training()
        {
            var coefficients = new Dictionary <Tuple <int, int>, double>();

            ModelToUse = 1;

            for (var i = 0; i < TrainingSamples.Count; i++)
            {
                for (var j = 0; j < TrainingSamples.Count; j++)
                {
                    coefficients.Add(new Tuple <int, int>(i, j),
                                     -(1) * TrainingSamples[i].Classification * TrainingSamples[j].Classification *
                                     TrainingSamples[i].Features.Dot(TrainingSamples[j].Features));
                }
            }

            var q = new double[TrainingSamples.Count, TrainingSamples.Count];

            q.SetInitValue(coefficients);

            var d         = Enumerable.Repeat(1.0, TrainingSamples.Count).ToArray();
            var objective = new QuadraticObjectiveFunction(q, d);

            // sum(ai * yi) = 0
            var constraints = new List <LinearConstraint>
            {
                new LinearConstraint(d)
                {
                    VariablesAtIndices = Enumerable.Range(0, TrainingSamples.Count).ToArray(),
                    ShouldBe           = ConstraintType.EqualTo,
                    Value      = 0,
                    CombinedAs = TrainingSamples.Select(t => t.Classification).ToArray().ToDouble()
                }
            };

            // 0 <= ai <= C
            for (var i = 0; i < TrainingSamples.Count; i++)
            {
                constraints.Add(new LinearConstraint(1)
                {
                    VariablesAtIndices = new[] { i },
                    ShouldBe           = ConstraintType.GreaterThanOrEqualTo,
                    Value = 0
                });
            }

            var solver = new GoldfarbIdnani(objective, constraints);

            if (solver.Maximize())
            {
                var solution = solver.Solution;
                UpdateWeightVector(solution);
                UpdateBias();
            }
            else
            {
                Console.WriteLine("Error ...");
            }
        }
Beispiel #7
0
        // 求解
        public void fit()
        {
            var solver = new GoldfarbIdnani(obj_fun(), constraintMatrix(), constraintValue(), 1);

            // And attempt solve for the max:
            this.success  = solver.Maximize();
            this.solution = solver.Solution;
            this.maxValue = solver.Value;
        }
        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);
        }
        public void RunTest2()
        {
            // Maximize f(x) = x² + 4y² -8x -16y
            //
            //      s.t. x + y <= 5
            //               x <= 3
            //             x,y >= 0
            //

            double[,] D =
            {
                { 2, 0 }, // 1x²
                { 0, 8 }, // 4y²
            };

            double[] d = { -8, -16 };


            double[,] A =
            {
                { 1, 1 }, // x + y
                { 1, 0 }, // x
            };

            double[] b = { 5, 3 };


            GoldfarbIdnani target = new GoldfarbIdnani(D, d.Multiply(-1), A.Transpose(), b);

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

            Assert.AreEqual(64.8, actual, 1e-10);
            Assert.IsFalse(double.IsNaN(actual));
            Assert.AreEqual(2, target.Iterations);
            Assert.AreEqual(0, target.Deletions);

            Assert.AreEqual(4.8, target.Solution[0], 1e-6);
            Assert.AreEqual(0.2, target.Solution[1], 1e-6);

            Assert.AreEqual(17.6, target.Lagrangian[0]);
            Assert.AreEqual(0.00, target.Lagrangian[1]);

            foreach (double v in target.Lagrangian)
            {
                Assert.IsFalse(double.IsNaN(v));
            }

            foreach (double v in target.Solution)
            {
                Assert.IsFalse(double.IsNaN(v));
            }
        }
        public void GoldfarbIdnaniLargeSampleTest3_InfiniteLoop()
        {
            var Q    = readMatrixFile(new StringReader(Resources.dmatFull));
            var AMat = readMatrixFile(new StringReader(Resources.constraintMatrix11_15_3));
            var bvec = readVectorFile(new StringReader(Resources.constraints11_14_3));

            var dvec = new double[Q.GetLength(0)];

            double[] b = new double[bvec.Length];
            bvec.CopyTo(b, 0);

            bool psd = Q.IsPositiveDefinite();

            Assert.IsTrue(psd);

            GoldfarbIdnani gfI = new GoldfarbIdnani(Q, dvec, AMat, b, 2);

            for (int i = 0; i < gfI.ConstraintTolerances.Length; i++)
            {
                gfI.ConstraintTolerances[i] = 1e-10;
            }

            bool success = gfI.Minimize();

            Assert.IsTrue(success);

            double[] soln  = gfI.Solution;
            double   value = Math.Sqrt(Matrix.Multiply(Matrix.Multiply(soln, Q), soln.Transpose())[0]);

            double expectedSol = 0.052870914138455;
            double actualSol   = value;

            double[] expected =
            {
                0.4,                // 2
                0.0016271524831373, // 4
                0,                  // 5
                0,                  // 13
                0,                  // 14
                0.59837284751680053 // 19
            };

            double[] actual =
            {
                soln[1], soln[3], soln[4], soln[12], soln[13], soln[18]
            };

            Assert.AreEqual(expectedSol, actualSol, 1e-8);
            for (int i = 0; i < expected.Length; i++)
            {
                Assert.AreEqual(expected[i], actual[i], 1e-5);
            }
        }
Beispiel #11
0
        public ProblemOutput Solve(ProblemInput problem)
        {
            var goldfarbIdnani = new GoldfarbIdnani(problem.Quadratic, problem.Linear, problem.ConstraintMatrix, problem.ConstraintValues);

            var hasSolution = goldfarbIdnani.Maximize();

            return(new ProblemOutput
            {
                HasSolution = hasSolution,
                Value = hasSolution ? goldfarbIdnani.Value:double.NaN,
                Solution = hasSolution ? goldfarbIdnani.Solution : Enumerable.Repeat(double.NaN, problem.N).ToArray()
            });
        }
        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"));


            GoldfarbIdnani target = new GoldfarbIdnani(f, 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.QuadraticTerms;
            var actuald = f.LinearTerms;

            Assert.IsTrue(Q.IsEqual(actualQ));
            Assert.IsTrue(d.IsEqual(actuald));
        }
        public static double[] SolveQP(double[,] Q, double[] d, double[,] A, double[] b, int eq)
        {
            var solver = new GoldfarbIdnani(new QuadraticObjectiveFunction(Q, d), A, b, eq);

            solver.Minimize();
            if (solver.Status == GoldfarbIdnaniStatus.Success)
            {
                return(solver.Solution.Select(x => x < 0.0 ? 0.0 : x).ToArray());
            }
            else
            {
                return(null);
            }
        }
        public void RunTest4()
        {
            double[,] D =
            {
                {  5, -2, -1 },
                { -2,  4,  3 },
                { -1,  3,  5 },
            };

            double[] d = { -2, +35, +47 };


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

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


            GoldfarbIdnani target = new GoldfarbIdnani(D, d.Multiply(-1), A.Transpose(), b);

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

            Assert.AreEqual(-249.0, actual, 1e-6);
            Assert.IsFalse(double.IsNaN(actual));
            Assert.AreEqual(1, target.Iterations);
            Assert.AreEqual(0, target.Deletions);

            Assert.AreEqual(3, target.Solution[0], 1e-6);
            Assert.AreEqual(5, target.Solution[1], 1e-6);
            Assert.AreEqual(7, target.Solution[2], 1e-6);

            Assert.AreEqual(0, target.Lagrangian[0]);
            Assert.AreEqual(0, target.Lagrangian[1]);
            Assert.AreEqual(0, target.Lagrangian[2]);

            foreach (double v in target.Lagrangian)
            {
                Assert.IsFalse(double.IsNaN(v));
            }

            foreach (double v in target.Solution)
            {
                Assert.IsFalse(double.IsNaN(v));
            }
        }
        public void GoldfarbIdnaniLargeSampleTest2()
        {
            var Q    = readMatrixFile(new StringReader(Resources.dmatFull));
            var AMat = readMatrixFile(new StringReader(Resources.constraintMatrix11_15_2));
            var bvec = readVectorFile(new StringReader(Resources.constraints11_14_2));

            var dvec = new double[Q.GetLength(0)];

            double[] b = new double[bvec.Length];
            bvec.CopyTo(b, 0);

            bool psd = Q.IsPositiveDefinite();

            Assert.IsTrue(psd);

            GoldfarbIdnani gfI = new GoldfarbIdnani(Q, dvec, AMat, b, 2);

            for (int i = 0; i < gfI.ConstraintTolerances.Length; i++)
            {
                gfI.ConstraintTolerances[i] = 1e-10;
            }

            bool success = gfI.Minimize();

            Assert.IsTrue(success);

            double[] soln  = gfI.Solution;
            double   value = Math.Sqrt(Matrix.Multiply(Matrix.Multiply(soln, Q), soln.Transpose())[0]);

            double expectedSol = 0.048224950997808;
            double actualSol   = value;

            double[] expected =
            {
                0.41144782323407, // 2
                0.27310552838116, // 13
                0.31544664838498, // 14
            };

            double[] actual =
            {
                soln[1], soln[12], soln[13]
            };

            Assert.AreEqual(expectedSol, actualSol, 1e-8);
            for (int i = 0; i < expected.Length; i++)
            {
                Assert.AreEqual(expected[i], actual[i], 1e-5);
            }
        }
        public void RunTest5()
        {
            // example from http://www.mail-archive.com/[email protected]/msg00831.html

            var cma = Matrix.Identity(10);

            var dva = new double[10];

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

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

            int meq = 2;

            GoldfarbIdnani target = new GoldfarbIdnani(cma, dva.Multiply(-1), Ama.Transpose(), bva, meq);

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

            for (int i = 0; i < target.Solution.Length; i += 2)
            {
                int N = target.Solution.Length / 2;
                Assert.AreEqual(1.0 / N, target.Solution[i], 1e-6);
                Assert.AreEqual(0.0, target.Solution[i + 1], 1e-6);
            }

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

            foreach (double v in target.Lagrangian)
            {
                Assert.IsFalse(double.IsNaN(v));
            }
        }
        public void RunTest()
        {
            double[,] D = Matrix.Identity(3);
            double[] d = { 0, 5, 0 };

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


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

            GoldfarbIdnani target = new GoldfarbIdnani(D, d.Multiply(-1), A.Transpose(), b);

            double[] expectedSolution = { 0.4761905, 1.0476190, 2.0952381 };
            double   expected         = -2.380952;

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

            Assert.AreEqual(expected, actual, 1e-6);
            Assert.IsFalse(double.IsNaN(actual));
            Assert.AreEqual(3, target.Iterations);

            Assert.AreEqual(0.4761905, target.Solution[0], 1e-6);
            Assert.AreEqual(1.0476190, target.Solution[1], 1e-6);
            Assert.AreEqual(2.0952381, target.Solution[2], 0.02);

            Assert.AreEqual(0.0000000, target.Lagrangian[0], 1e-6);
            Assert.AreEqual(0.2380952, target.Lagrangian[1], 1e-6);
            Assert.AreEqual(2.0952381, target.Lagrangian[2], 1e-6);


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

            foreach (double v in target.Lagrangian)
            {
                Assert.IsFalse(double.IsNaN(v));
            }
        }
        public void GoldfarbIdnaniLargeSampleTest1()
        {
            var Q    = readMatrixFile(new StringReader(Resources.dmatFull));
            var AMat = readMatrixFile(new StringReader(Resources.constraintMatrix11_15));
            var bvec = readVectorFile(new StringReader(Resources.constraints11_14));

            var dvec = new double[Q.GetLength(0)];

            double[] b = new double[bvec.Length];
            bvec.CopyTo(b, 0);

            bool psd = Q.IsPositiveDefinite();

            Assert.IsTrue(psd);

            GoldfarbIdnani gfI = new GoldfarbIdnani(Q, dvec, AMat, b, 2);

            bool success = gfI.Minimize();

            Assert.IsTrue(success);

            double[] soln  = gfI.Solution;
            double   value = Math.Sqrt(Matrix.Multiply(Matrix.Multiply(soln, Q), soln.Transpose())[0]);

            double expectedSol = 0.049316494677822;
            double actualSol   = value;

            double[] expected =
            {
                0.74083116998144, // 2
                0.14799651298617, // 13
                0.11117231703249, // 14
            };

            double[] actual =
            {
                soln[1], soln[12], soln[13]
            };

            Assert.AreEqual(expectedSol, actualSol, 1e-8);
            for (int i = 0; i < expected.Length; i++)
            {
                Assert.AreEqual(expected[i], actual[i], 1e-5);
            }
        }
        public static Tuple <double[], double> solver(objFuncDel handle = null)
        {
            Tuple <QuadraticObjectiveFunction, List <LinearConstraint> > fAndc = null;

            fAndc = handle == null?objectiveFuncForLabelTest() : handle.Invoke();

            var    solver  = new GoldfarbIdnani(fAndc.Item1, fAndc.Item2);
            bool   success = solver.Minimize();
            double value   = solver.Value;

            double[] solution = new double[solver.Solution.Length];

            for (int i = 0; i < solution.Length; i++)
            {
                solution[i] = solver.Solution[i];
            }
            return(new Tuple <double[], double>(item1: solution, item2: value));
        }
        public void RunTest1()
        {
            double[,] D = Matrix.Identity(3);
            double[] d = { 1, 5, 3 };

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


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

            GoldfarbIdnani target = new GoldfarbIdnani(D, d.Multiply(-1), A.Transpose(), b);

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

            Assert.AreEqual(-12.41011, actual, 1e-5);
            Assert.IsFalse(double.IsNaN(actual));
            Assert.AreEqual(3, target.Iterations);
            Assert.AreEqual(0, target.Deletions);

            Assert.AreEqual(0.4157303, target.Solution[0], 1e-6);
            Assert.AreEqual(2.1123596, target.Solution[1], 1e-6);
            Assert.AreEqual(4.2247191, target.Solution[2], 1e-6);

            Assert.AreEqual(0.1460674, target.Lagrangian[0], 1e-6);
            Assert.AreEqual(0.0000000, target.Lagrangian[1], 1e-6);
            Assert.AreEqual(1.2247191, target.Lagrangian[2], 1e-6);

            foreach (double v in target.Lagrangian)
            {
                Assert.IsFalse(double.IsNaN(v));
            }

            foreach (double v in target.Solution)
            {
                Assert.IsFalse(double.IsNaN(v));
            }
        }
        public void RunTest()
        {
            double[,] D = Matrix.Identity(3);
            double[] d = { 0, 5, 0 };

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


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

            GoldfarbIdnani target = new GoldfarbIdnani(D, d.Multiply(-1), A.Transpose(), b);

            double[] expectedSolution = { 0.4761905, 1.0476190, 2.0952381 };
            double expected = -2.380952;
            Assert.IsTrue(target.Minimize());
            double actual = target.Value;
            Assert.AreEqual(expected, actual, 1e-6);
            Assert.IsFalse(double.IsNaN(actual));
            Assert.AreEqual(3, target.Iterations);

            Assert.AreEqual(0.4761905, target.Solution[0], 1e-6);
            Assert.AreEqual(1.0476190, target.Solution[1], 1e-6);
            Assert.AreEqual(2.0952381, target.Solution[2], 0.02);

            Assert.AreEqual(0.0000000, target.Lagrangian[0], 1e-6);
            Assert.AreEqual(0.2380952, target.Lagrangian[1], 1e-6);
            Assert.AreEqual(2.0952381, target.Lagrangian[2], 1e-6);


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

            foreach (double v in target.Lagrangian)
                Assert.IsFalse(double.IsNaN(v));
        }
        /// <summary>
        /// Perform portfolio optimization for a provided matrix of historical returns and an array of expected returns
        /// </summary>
        /// <param name="historicalReturns">Matrix of annualized historical returns where each column represents a security and each row returns for the given date/time (size: K x N).</param>
        /// <param name="expectedReturns">Array of double with the portfolio annualized expected returns (size: K x 1).</param>
        /// <param name="covariance">Multi-dimensional array of double with the portfolio covariance of annualized returns (size: K x K).</param>
        /// <returns>Array of double with the portfolio weights (size: K x 1)</returns>
        public double[] Optimize(double[,] historicalReturns, double[] expectedReturns = null, double[,] covariance = null)
        {
            covariance = covariance ?? historicalReturns.Covariance();
            var returns = (expectedReturns ?? historicalReturns.Mean(0)).Subtract(_riskFreeRate);

            var size = covariance.GetLength(0);
            var x0   = Vector.Create(size, 1.0 / size);
            var k    = returns.Dot(x0);

            var constraints = new List <LinearConstraint>
            {
                // Sharpe Maximization under Quadratic Constraints
                // https://quant.stackexchange.com/questions/18521/sharpe-maximization-under-quadratic-constraints
                // (µ − r_f)^T w = k
                new LinearConstraint(size)
                {
                    CombinedAs = returns,
                    ShouldBe   = ConstraintType.EqualTo,
                    Value      = k
                }
            };

            // Σw = 1
            constraints.Add(GetBudgetConstraint(size));

            // lw ≤ w ≤ up
            constraints.AddRange(GetBoundaryConditions(size));

            // Setup solver
            var optfunc = new QuadraticObjectiveFunction(covariance, Vector.Create(size, 0.0));
            var solver  = new GoldfarbIdnani(optfunc, constraints);

            // Solve problem
            var success     = solver.Minimize(Vector.Copy(x0));
            var sharpeRatio = returns.Dot(solver.Solution) / solver.Value;

            return(success ? solver.Solution : x0);
        }
        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));
        }
        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));


            GoldfarbIdnani target = new GoldfarbIdnani(f, 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.QuadraticTerms;
            var actuald = f.LinearTerms;

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

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

            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));
        }
        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));


            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 = 
            {   
                { 6, 2 }, 
                { 2, 6 },
            };

            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();
            double minValue = target.Value;

            Assert.IsTrue(success);

            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));
        }
        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"));


            GoldfarbIdnani target = new GoldfarbIdnani(f, 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.QuadraticTerms;
            var actuald = f.LinearTerms;

            Assert.IsTrue(Q.IsEqual(actualQ));
            Assert.IsTrue(d.IsEqual(actuald));
        }
        public void GoldfarbIdnaniMinimizeWithEqualityTest2()
        {
            // This test reproduces Issue #171 at GitHub
            // Solve the following optimization problem:
            //
            //  min f(x) = a² + b² + c² + d² + e² + f² + 10a + 10b + 30c + 20d + 30e + 20f
            // 
            //  s.t.                  a == 4
            //                b + c + d == 5
            //                    e + f == 1
            //                    a + b <= 7
            //                    c + e <= 1
            //                    d + f <= 2
            //                        a >= 0
            //                        b >= 0
            //                        c >= 0
            //                        d >= 0
            //                        e >= 0
            //                        f >= 0

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

            double[] b =
            {
                4,5,1,-7,-1,-2,0,0,0,0,0,0
            };

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

            double[] d =
            {
                10,10,30,20,30,20
            };

            GoldfarbIdnani target = new GoldfarbIdnani(Q, d, A, b, 3);
            var tolerance = 0.001;
            target.ConstraintTolerances.ApplyInPlace(a => tolerance);

            Assert.IsTrue(target.Minimize());
            double[] solution = target.Solution;

            Assert.AreEqual(4, solution[0], tolerance);
            Assert.AreEqual(3, solution[1], tolerance);
            Assert.AreEqual(0.75, solution[2], tolerance);
            Assert.AreEqual(1.25, solution[3], tolerance);
            Assert.AreEqual(0.25, solution[4], tolerance);
            Assert.AreEqual(0.75, solution[5], tolerance);
        }
        public void GoldfarbIdnaniConstructorTest2()
        {
            // 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)
            //

            // Lets first group the quadratic and linear terms. The
            // quadratic terms are +2x², +3y² and -4xy. The linear 
            // terms are -2x and +1y. So our matrix of quadratic
            // terms can be expressed as:

            double[,] Q = // 2x² -1xy +4y²
            {   
                /*           x              y      */
                /*x*/ { +2 /*xx*/ *2,  -1 /*xy*/    }, 
                /*y*/ { -1 /*xy*/   ,  +4 /*yy*/ *2 },
            };

            // Accordingly, our vector of linear terms is given by:

            double[] d = { -5 /*x*/, -6 /*y*/ }; // -5x -6y

            // We have now to express our constraints. We can do it
            // either by directly specifying a matrix A in which each
            // line refers to one of the constraints, expressing the
            // relationship between the different variables in the
            // constraint, like this:

            double[,] A = 
            {
                { 1, -1 }, // This line says that x + (-y) ... (a)
                { 1,  0 }, // This line says that x alone  ... (b)
            };

            double[] b = 
            {
                 5, // (a) ... should be equal to 5.
                10, // (b) ... should be greater than or equal to 10.
            };

            // Equalities must always come first, and in this case
            // we have to specify how many of the constraints are
            // actually equalities:

            int numberOfEqualities = 1;


            // Alternatively, we may use a more explicitly form:
            List<LinearConstraint> list = new List<LinearConstraint>();

            // Define the first constraint, which involves only x
            list.Add(new LinearConstraint(numberOfVariables: 1)
                {
                    // x is the first variable, thus located at
                    // index 0. We are specifying that x >= 10:

                    VariablesAtIndices = new[] { 0 }, // index 0 (x)
                    ShouldBe = ConstraintType.GreaterThanOrEqualTo,
                    Value = 10
                });

            // Define the second constraint, which involves x and y
            list.Add(new LinearConstraint(numberOfVariables: 2)
                {
                    // x is the first variable, located at index 0, and y is
                    // the second, thus located at 1. We are specifying that
                    // x - y = 5 by saying that the variable at position 0 
                    // times 1 plus the variable at position 1 times -1 
                    // should be equal to 5.

                    VariablesAtIndices = new int[] { 0, 1 }, // index 0 (x) and index 1 (y)
                    CombinedAs = new double[] { 1, -1 }, // when combined as x - y
                    ShouldBe = ConstraintType.EqualTo,
                    Value = 5
                });


            // Now we can finally create our optimization problem
            var target = new GoldfarbIdnani(new QuadraticObjectiveFunction(Q, d), constraints: list);


            Assert.IsTrue(A.IsEqual(target.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(target.ConstraintValues));
            Assert.AreEqual(numberOfEqualities, target.NumberOfEqualities);


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


            Assert.AreEqual(170, minimumValue, 1e-10);
            Assert.AreEqual(10, target.Solution[0]);
            Assert.AreEqual(05, target.Solution[1]);

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

            foreach (double v in target.Lagrangian)
                Assert.IsFalse(double.IsNaN(v));
        }
        public void RunTest5()
        {
            // example from http://www.mail-archive.com/[email protected]/msg00831.html

            var cma = Matrix.Identity(10);

            var dva = new double[10];

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

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

            int meq = 2;

            GoldfarbIdnani target = new GoldfarbIdnani(cma, dva.Multiply(-1), Ama.Transpose(), bva, meq);

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

            for (int i = 0; i < target.Solution.Length; i += 2)
            {
                int N = target.Solution.Length / 2;
                Assert.AreEqual(1.0 / N, target.Solution[i], 1e-6);
                Assert.AreEqual(0.0, target.Solution[i + 1], 1e-6);
            }

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

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

        }
        public void RunTest3()
        {
            // Tested against R's QuadProg package
            /* solve.QP(matrix(c(10, -3,  1, -3, 11, -2, 1, -2, 12), 3, 3), c(1,5,3),
                     t(matrix( c(-4, 2, 1, -3, 1, -2, 0, -1, 2), 3,3)), c(-8,4,-1)) */

            double[,] D =
            {
                { 10, -3,  1 },
                { -3, 11, -2 },
                {  1, -2, 12 },
            };

            double[] d = { 1, 5, 3 };

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


            double[] b = { -8, 4, -1 };

            GoldfarbIdnani target = new GoldfarbIdnani(D, d.Multiply(-1), A.Transpose(), b);

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

            Assert.AreEqual(6.8, actual, 1e-5);
            Assert.IsFalse(double.IsNaN(actual));

            Assert.AreEqual(4, target.Iterations);
            Assert.AreEqual(0, target.Deletions);

            Assert.AreEqual(+1.4, target.Solution[0], 1e-6);
            Assert.AreEqual(+0.8, target.Solution[1], 1e-6);
            Assert.AreEqual(-0.4, target.Solution[2], 1e-6);

            Assert.AreEqual(2.5333333, target.Lagrangian[0], 1e-6);
            Assert.AreEqual(9.7333333, target.Lagrangian[1], 1e-6);
            Assert.AreEqual(0.8666667, target.Lagrangian[2], 1e-6);

            Assert.AreEqual(1, target.ActiveConstraints[0]);
            Assert.AreEqual(0, target.ActiveConstraints[1]);
            Assert.AreEqual(2, target.ActiveConstraints[2]);

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

            foreach (double v in target.Solution)
                Assert.IsFalse(double.IsNaN(v));
        }
Beispiel #31
0
        public double[] Solve(double[] x0, double[,] a, double[] b, double[] measurability, double[] tolerance, double[] lower, double[] upper)
        {
            // Проверка аргументов на null
            _ = x0 ?? throw new ArgumentNullException(nameof(x0));
            _ = a ?? throw new ArgumentNullException(nameof(a));
            _ = b ?? throw new ArgumentNullException(nameof(b));
            _ = measurability ?? throw new ArgumentNullException(nameof(measurability));
            _ = tolerance ?? throw new ArgumentNullException(nameof(tolerance));
            _ = lower ?? throw new ArgumentNullException(nameof(lower));
            _ = upper ?? throw new ArgumentNullException(nameof(upper));

            //Проверка аргументов на размерности
            if (x0.Length == 0)
            {
                throw new ArgumentException(nameof(x0));
            }
            if (a.GetLength(1) != x0.Length)
            {
                throw new ArgumentException("Array length by dimension 1 is not equal to X0 length.", nameof(a));
            }
            if (b.Length != a.GetLength(0))
            {
                throw new ArgumentException("Array length is not equal to A length by 0 dimension.", nameof(b));
            }
            if (measurability.Length != x0.Length)
            {
                throw new ArgumentException("Array length is not equal to X0 length.", nameof(measurability));
            }
            if (tolerance.Length != x0.Length)
            {
                throw new ArgumentException("Array length is not equal to X0 length.", nameof(tolerance));
            }
            if (lower.Length != x0.Length)
            {
                throw new ArgumentException("Array length is not equal to X0 length.", nameof(lower));
            }
            if (upper.Length != x0.Length)
            {
                throw new ArgumentException("Array length is not equal to X0 length.", nameof(upper));
            }

            var i = Matrix.Diagonal(measurability);
            var w = Matrix.Diagonal(1.Divide(tolerance.Pow(2)));

            var h = i.Dot(w);
            var d = h.Dot(x0).Multiply(-1);

            var func        = new QuadraticObjectiveFunction(h, d);
            var constraints = new List <LinearConstraint>();

            //Нижние и верхние границы
            for (var j = 0; j < x0.Length; j++)
            {
                constraints.Add(new LinearConstraint(1)
                {
                    VariablesAtIndices = new[] { j },
                    ShouldBe           = ConstraintType.GreaterThanOrEqualTo,
                    Value = lower[j]
                });

                constraints.Add(new LinearConstraint(1)
                {
                    VariablesAtIndices = new[] { j },
                    ShouldBe           = ConstraintType.LesserThanOrEqualTo,
                    Value = upper[j]
                });
            }

            //Ограничения для решения задачи баланса
            for (var j = 0; j < b.Length; j++)
            {
                var notNullElements        = Array.FindAll(a.GetRow(j), x => Math.Abs(x) > 0.0000001);
                var notNullElementsIndexes = new List <int>();
                for (var k = 0; k < x0.Length; k++)
                {
                    if (Math.Abs(a[j, k]) > 0.0000001)
                    {
                        notNullElementsIndexes.Add(k);
                    }
                }

                constraints.Add(new LinearConstraint(notNullElements.Length)
                {
                    VariablesAtIndices = notNullElementsIndexes.ToArray(),
                    CombinedAs         = notNullElements,
                    ShouldBe           = ConstraintType.EqualTo,
                    Value = b[j]
                });
            }

            var solver = new GoldfarbIdnani(func, constraints);

            if (!solver.Minimize())
            {
                throw new ApplicationException("Failed to solve balance task.");
            }

            DisbalanceOriginal = a.Dot(x0).Subtract(b).Euclidean();
            Disbalance         = a.Dot(solver.Solution).Subtract(b).Euclidean();

            return(solver.Solution);
        }
Beispiel #32
0
        /// <summary>
        ///   Computes the optimization algorithm when the user
        ///   presses the "Compute" button in the main interface.
        /// </summary>
        /// 
        private void btnCompute_Click(object sender, EventArgs e)
        {
            // First, get what the user entered on screen:
            String strObjective = tbObjective.Text;
            String[] strConstraints = tbConstraints.Lines;

            // Check if this is a minimization or maximization task
            bool minimize = (string)comboBox1.SelectedItem == "min";

            // Now we can start creating our function:
            QuadraticObjectiveFunction function;
            LinearConstraint[] constraints = new LinearConstraint[strConstraints.Length];


            // Attempt to parse the string and create the objective function
            if (!QuadraticObjectiveFunction.TryParse(strObjective, out function))
            {
                tbSolution.Text = "Invalid objective function.";
                return;
            }

            // Create list of constraints
            for (int i = 0; i < constraints.Length; i++)
            {
                if (!LinearConstraint.TryParse(strConstraints[i], function, out constraints[i]))
                {
                    tbSolution.Text = "Invalid constraint at line " + i + ".";
                    return;
                }
            }


            // After the text has been parsed, create the solver
            var solver = new GoldfarbIdnani(function, constraints);


            // Solve the optimization problem:
            if (minimize)
                solver.Minimize(); // the user wants to minimize it
            else solver.Maximize();  // the user wants to maximize it

            if (solver.Status == GoldfarbIdnaniStatus.NonPositiveDefinite)
            {
                tbSolution.Text = "Function is not positive definite.";
                return;
            }
            else if (solver.Status == GoldfarbIdnaniStatus.NoPossibleSolution)
            {
                tbSolution.Text = "No possible solution could be attained.";
                return;
            }


            // Retrieve the computed solution 
            double[] solution = solver.Solution;

            // And let's format and display it:
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("Solution:");
            sb.AppendLine();
            sb.AppendLine(" " + strObjective + " = " + solver.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();
        }
        public void GoldfarbIdnani4()
        {
            // https://github.com/accord-net/framework/issues/171

            int n = 21;
            var Q = Matrix.Diagonal(n, 2.0);
            var d = Vector.Create(3132.0, 6264, 15660, 18792, 21924, 6264, 18792, 21924, 9396, 3132, 12528, 6264, 9396, 18792, 21924, 9396, 3132, 3132, 6264, 15660, 18792);

            int m = 44;

            var b = Vector.Create(
                703.999, -704.001,
                1267.999, -1268.001,
                1565.999, -1566.001,
                471.999, -472.001,
                1425.999, -1426.001, 
                -107.001,
                -1164.001, 
                -57.001,
                -311.001,
                -1433.001, 
                -0.001,
                -0.001, 
                -788.001, 
                -472.001, 
                -850.001, 
                -273.001, 
                -0.001, -0.001, -0.001, -0.001,
                -0.001, -0.001, -0.001, -0.001, -0.001, 
                -0.001, -0.001, -0.001, -0.001, -0.001, 
                -0.001, -0.001, -0.001, -0.001, -0.001, 
                -0.001, -0.001, -0.001, -0.001);

            var A = Matrix.Create(m, n, 
                 1.0, 1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0, 
                -1,  -1, -1, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0, 
                 0,   0,  0,  0,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0, 
                 0,   0,  0,  0, -1, -1, -1, -1,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,
                 0,   0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  0,  0,   0,  0,  0,  0,  0,  0,
                 0,   0,  0,  0,  0,  0,  0,  0, -1, -1, -1, -1, -1,  0,  0,   0,  0,  0,  0,  0,  0,
                 0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,   0,  0,  0,  0,  0,  0,
                 0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1, -1,   0,  0,  0,  0,  0,  0,
                 0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   1,  1,  1,  1,  1,  1,
                 0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  -1, -1, -1, -1, -1, -1,
                 0,   0,  0,  0, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  
                 0,   0,  0,  0,  0,  0,  0,  0, -1,  0,  0,  0,  0,  0,  0,  -1,  0,  0,  0,  0,  0,
                 0,   0,  0,  0,  0,  0,  0,  0,  0, -1,  0,  0,  0,  0,  0,   0, -1,  0,  0,  0,  0,
                 0,   0,  0,  0,  0, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,
                 0,   0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,
                 0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  0,  0,  0,   0,  0,  0,  0,  0,  0,
                 0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  0,  0,   0,  0,  0,  0,  0,  0,
                -1,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0, -1,  0,  0,  0,
                 0,   0,  0,  0,  0,  0, -1,  0,  0,  0,  0,  0,  0,  -1, 0,   0,  0,  0,  0,  0,  0,
                 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);


            var solver = new GoldfarbIdnani(Q, d, A, b, 0);

            //for (int i = 0; i < solver.ConstraintTolerances.Length; i++)
            //    solver.ConstraintTolerances[i] = 1e-1;

            Assert.IsTrue(solver.Minimize());

            QuadraticObjectiveFunction f = new QuadraticObjectiveFunction(Q, d);
            f.Function(solver.Solution);

            var constraints = LinearConstraintCollection.FromMatrix(A, b, 0);

            double[] violation = constraints.Apply(x => x.GetViolation(solver.Solution));
        }
        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.
            GoldfarbIdnani solver = new GoldfarbIdnani(f, constraints);

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

            Assert.AreEqual(25 / 16.0, maxValue);

            Assert.AreEqual(-5 / 8.0, solver.Solution[0]);
            Assert.AreEqual(5 / 8.0, solver.Solution[1]);
        }
        public void GoldfarbIdnaniConstructorTest2()
        {
            // 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)
            //

            // Lets first group the quadratic and linear terms. The
            // quadratic terms are +2x², +3y² and -4xy. The linear
            // terms are -2x and +1y. So our matrix of quadratic
            // terms can be expressed as:

            double[,] Q = // 2x² -1xy +4y²
            {
                /*           x              y      */
                /*x*/ { +2 /*xx*/ * 2,     -1 /*xy*/ },
                /*y*/ {     -1 /*xy*/, +4 /*yy*/ * 2 },
            };

            // Accordingly, our vector of linear terms is given by:

            double[] d = { -5 /*x*/, -6 /*y*/ }; // -5x -6y

            // We have now to express our constraints. We can do it
            // either by directly specifying a matrix A in which each
            // line refers to one of the constraints, expressing the
            // relationship between the different variables in the
            // constraint, like this:

            double[,] A =
            {
                { 1, -1 }, // This line says that x + (-y) ... (a)
                { 1,  0 }, // This line says that x alone  ... (b)
            };

            double[] b =
            {
                5,  // (a) ... should be equal to 5.
                10, // (b) ... should be greater than or equal to 10.
            };

            // Equalities must always come first, and in this case
            // we have to specify how many of the constraints are
            // actually equalities:

            int numberOfEqualities = 1;


            // Alternatively, we may use a more explicitly form:
            List <LinearConstraint> list = new List <LinearConstraint>();

            // Define the first constraint, which involves only x
            list.Add(new LinearConstraint(numberOfVariables: 1)
            {
                // x is the first variable, thus located at
                // index 0. We are specifying that x >= 10:

                VariablesAtIndices = new[] { 0 },     // index 0 (x)
                ShouldBe           = ConstraintType.GreaterThanOrEqualTo,
                Value = 10
            });

            // Define the second constraint, which involves x and y
            list.Add(new LinearConstraint(numberOfVariables: 2)
            {
                // x is the first variable, located at index 0, and y is
                // the second, thus located at 1. We are specifying that
                // x - y = 5 by saying that the variable at position 0
                // times 1 plus the variable at position 1 times -1
                // should be equal to 5.

                VariablesAtIndices = new int[] { 0, 1 },     // index 0 (x) and index 1 (y)
                CombinedAs         = new double[] { 1, -1 }, // when combined as x - y
                ShouldBe           = ConstraintType.EqualTo,
                Value = 5
            });


            // Now we can finally create our optimization problem
            var target = new GoldfarbIdnani(new QuadraticObjectiveFunction(Q, d), constraints: list);


            Assert.IsTrue(A.IsEqual(target.ConstraintMatrix));
            Assert.IsTrue(b.IsEqual(target.ConstraintValues));
            Assert.AreEqual(numberOfEqualities, target.NumberOfEqualities);


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


            Assert.AreEqual(170, minimumValue, 1e-10);
            Assert.AreEqual(10, target.Solution[0]);
            Assert.AreEqual(05, target.Solution[1]);

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

            foreach (double v in target.Lagrangian)
            {
                Assert.IsFalse(double.IsNaN(v));
            }
        }
Beispiel #36
0
        public Result Solving(int count, double[] Ii, double[] w, double[] d, double[] b, double[][] A, List <LinearConstraint> constraints = null, double[][] extra = null)
        {
            #region Calculate matrix
            double[,] I = new double[count, count];
            double[,] W = new double[count, count];
            for (int i = 0; i < w.Length; i++)
            {
                for (int j = 0; j < w.Length; j++)
                {
                    if (j == i)
                    {
                        W[i, j] = w[i] != 0 ? (1 / (w[i] * w[i])) : 0;
                        I[i, j] = Ii[i];
                    }
                    else
                    {
                        W[i, j] = 0;
                        I[i, j] = 0;
                    }
                }
            }
            double[,] Q = Accord.Math.Matrix.Dot(W, I);

            double[] D = new double[count];
            int[]    VariablesAtIndices = new int[count];
            for (int i = 0; i < count; i++)
            {
                D[i] = -1 * d[i] * Q[i, i];
                VariablesAtIndices[i] = i;
            }

            List <double[]> combinedAs = new List <double[]>();
            for (int i = 0; i < A.Length; i++)
            {
                double[] a = new double[A[i].Length];
                for (int j = 0; j < A[i].Length; j++)
                {
                    a[j] = A[i][j];
                }
                combinedAs.Add(a);
            }
            #endregion

            #region Forming conditions
            if (constraints == null)
            {
                constraints = new List <LinearConstraint>();
            }

            if (extra != null)
            {
                for (int i = 0; i < extra.Length; i++)
                {
                    constraints.Add(new LinearConstraint(numberOfVariables: count)
                    {
                        VariablesAtIndices = VariablesAtIndices,
                        CombinedAs         = extra[i],
                        ShouldBe           = ConstraintType.EqualTo,
                        Value = 0
                    });
                }
            }

            for (int i = 0; i < b.Length; i++)
            {
                constraints.Add(new LinearConstraint(numberOfVariables: count)
                {
                    VariablesAtIndices = VariablesAtIndices,
                    CombinedAs         = combinedAs[i],
                    ShouldBe           = ConstraintType.EqualTo,
                    Value = b[i]
                });
            }
            #endregion

            var solver = new GoldfarbIdnani(
                function: new QuadraticObjectiveFunction(Q, D),
                constraints: constraints);

            bool     success  = solver.Minimize();
            double[] solution = solver.Solution;
            Result   result   = new Result(solution, success);
            return(result);
        }
        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);
        }
        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));


            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 =
            {
                { 6, 2 },
                { 2, 6 },
            };

            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();
            double minValue = target.Value;

            Assert.IsTrue(success);

            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));
            }
        }
        public void GoldfarbIdnani3()
        {
            double[] bvec = { 1, 0, -1, 0, -1, 0, -1, 0, -1 };
            double[] dvec = { -0.00090022881750228, -0.0011623872153178, -0.0012785347920969, -0.0014757189594252 };

            double[,] DMat = new double[4, 4];
            DMat[0, 0] = 0.00073558149743370;
            DMat[1, 1] = 0.00077910939546937;
            DMat[2, 2] = 0.00139571859557181;
            DMat[3, 3] = 0.00165142875705900;

            DMat[0, 1] = 0.00066386470011521;
            DMat[0, 2] = 0.00088725438967435;
            DMat[0, 3] = 0.00088643939798828;

            DMat[1, 2] = 0.00084474421503143;
            DMat[1, 3] = 0.00095081100765219;
            DMat[2, 3] = 0.00143043882089429;

            DMat[1, 0] = DMat[0, 1];
            DMat[2, 0] = DMat[0, 2];
            DMat[3, 0] = DMat[0, 3];
            DMat[2, 1] = DMat[1, 2];
            DMat[3, 1] = DMat[1, 3];
            DMat[3, 2] = DMat[2, 3];

            Assert.IsTrue(DMat.IsSymmetric());


            double[,] AMat = new double[9, 4];
            AMat[0, 0] = 1; AMat[1, 0] = 1; AMat[2, 0] = -1; AMat[3, 0] = 0; AMat[4, 0] =  0; AMat[5, 0] = 0; AMat[6, 0] =  0; AMat[7, 0] = 0; AMat[8, 0] =  0;
            AMat[0, 1] = 1; AMat[1, 1] = 0; AMat[2, 1] =  0; AMat[3, 1] = 1; AMat[4, 1] = -1; AMat[5, 1] = 0; AMat[6, 1] =  0; AMat[7, 1] = 0; AMat[8, 1] =  0;
            AMat[0, 2] = 1; AMat[1, 2] = 0; AMat[2, 2] =  0; AMat[3, 2] = 0; AMat[4, 2] =  0; AMat[5, 2] = 1; AMat[6, 2] = -1; AMat[7, 2] = 0; AMat[8, 2] =  0;
            AMat[0, 3] = 1; AMat[1, 3] = 0; AMat[2, 3] =  0; AMat[3, 3] = 0; AMat[4, 3] =  0; AMat[5, 3] = 0; AMat[6, 3] =  0; AMat[7, 3] = 1; AMat[8, 3] = -1;

            var oldA = (double[,])AMat.Clone();
            var oldD = (double[,])DMat.Clone();
            var oldb = (double[])bvec.Clone();
            var oldd = (double[])dvec.Clone();

            GoldfarbIdnani gfI = new GoldfarbIdnani(DMat, dvec, AMat, bvec, 1);

            Assert.AreEqual(4, gfI.NumberOfVariables);
            Assert.AreEqual(9, gfI.NumberOfConstraints);

            Assert.IsTrue(gfI.Minimize());

            Assert.IsTrue(oldA.IsEqual(AMat));
            Assert.IsTrue(oldD.IsEqual(DMat));
            Assert.IsTrue(oldb.IsEqual(bvec));
            Assert.IsTrue(oldd.IsEqual(dvec));

            double[] soln = gfI.Solution;
            double value = gfI.Value;

            Assert.AreEqual(0, soln[0], 1e-10);
            Assert.AreEqual(0.73222257311567, soln[1], 1e-5);
            Assert.AreEqual(0, soln[2], 1e-10);
            Assert.AreEqual(0.2677742688433, soln[3], 1e-8);
            Assert.AreEqual(-0.00079179497009427, value, 1e-6);

            double[] lagrangian = gfI.Lagrangian;
            double[] expected = { 0.0003730054618697, 0.00016053620578588, 0, 0, 0, 0.000060343913971918, 0, 0, 0 };
            for (int i = 0; i < lagrangian.Length; i++)
                Assert.AreEqual(expected[i], lagrangian[i], 1e-4);
        }
        [Ignore()] // TODO: Remove this attribute
        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.
            GoldfarbIdnani solver = new GoldfarbIdnani(f, constraints);

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

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

            double v0 = constraints[0].GetViolation(actual);
            double v1 = constraints[1].GetViolation(actual);
            double v2 = constraints[2].GetViolation(actual);
            double v3 = constraints[3].GetViolation(actual);
            double v4 = constraints[4].GetViolation(actual);
            double v5 = constraints[5].GetViolation(actual);
            double v6 = constraints[6].GetViolation(actual);

            for (int i = 0; i < expected.Length; i++)
            {
                double e = expected[i];
                double a = actual[i];
                Assert.AreEqual(e, a);
            }
        }
        public void RunTest4()
        {

            double[,] D = 
            {
                {  5, -2, -1 },
                { -2,  4,  3 },
                { -1,  3,  5 },
            };

            double[] d = { -2, +35, +47 };


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

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


            GoldfarbIdnani target = new GoldfarbIdnani(D, d.Multiply(-1), A.Transpose(), b);

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

            Assert.AreEqual(-249.0, actual, 1e-6);
            Assert.IsFalse(double.IsNaN(actual));
            Assert.AreEqual(1, target.Iterations);
            Assert.AreEqual(0, target.Deletions);

            Assert.AreEqual(3, target.Solution[0], 1e-6);
            Assert.AreEqual(5, target.Solution[1], 1e-6);
            Assert.AreEqual(7, target.Solution[2], 1e-6);

            Assert.AreEqual(0, target.Lagrangian[0]);
            Assert.AreEqual(0, target.Lagrangian[1]);
            Assert.AreEqual(0, target.Lagrangian[2]);

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

            foreach (double v in target.Solution)
                Assert.IsFalse(double.IsNaN(v));
        }
Beispiel #42
0
        /// <summary>
        ///   Computes the optimization algorithm when the user
        ///   presses the "Compute" button in the main interface.
        /// </summary>
        ///
        private void btnCompute_Click(object sender, EventArgs e)
        {
            // First, get what the user entered on screen:
            String strObjective = tbObjective.Text;

            String[] strConstraints = tbConstraints.Lines;

            // Check if this is a minimization or maximization task
            bool minimize = (string)comboBox1.SelectedItem == "min";

            // Now we can start creating our function:
            QuadraticObjectiveFunction function;

            LinearConstraint[] constraints = new LinearConstraint[strConstraints.Length];


            // Attempt to parse the string and create the objective function
            if (!QuadraticObjectiveFunction.TryParse(strObjective, out function))
            {
                tbSolution.Text = "Invalid objective function.";
                return;
            }

            // Create list of constraints
            for (int i = 0; i < constraints.Length; i++)
            {
                if (!LinearConstraint.TryParse(strConstraints[i], function, out constraints[i]))
                {
                    tbSolution.Text = "Invalid constraint at line " + i + ".";
                    return;
                }
            }


            // After the text has been parsed, create the solver
            var solver = new GoldfarbIdnani(function, constraints);


            // Solve the optimization problem:
            if (minimize)
            {
                solver.Minimize(); // the user wants to minimize it
            }
            else
            {
                solver.Maximize();   // the user wants to maximize it
            }
            if (solver.Status == GoldfarbIdnaniStatus.NonPositiveDefinite)
            {
                tbSolution.Text = "Function is not positive definite.";
                return;
            }
            else if (solver.Status == GoldfarbIdnaniStatus.NoPossibleSolution)
            {
                tbSolution.Text = "No possible solution could be attained.";
                return;
            }


            // Retrieve the computed solution
            double[] solution = solver.Solution;

            // And let's format and display it:
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("Solution:");
            sb.AppendLine();
            sb.AppendLine(" " + strObjective + " = " + solver.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();
        }
        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));
        }
        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);
            }
        }
        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);
        }
        public void GoldfarbIdnaniLargeSampleTest1()
        {
            var Q = readMatrixFile(new StringReader(Resources.dmatFull));
            var AMat = readMatrixFile(new StringReader(Resources.constraintMatrix11_15));
            var bvec = readVectorFile(new StringReader(Resources.constraints11_14));

            var dvec = new double[Q.GetLength(0)];
            double[] b = new double[bvec.Length];
            bvec.CopyTo(b, 0);

            bool psd = Q.IsPositiveDefinite();
            Assert.IsTrue(psd);

            GoldfarbIdnani gfI = new GoldfarbIdnani(Q, dvec, AMat, b, 2);

            bool success = gfI.Minimize();

            Assert.IsTrue(success);

            double[] soln = gfI.Solution;
            double value = Math.Sqrt(Matrix.Multiply(Matrix.Multiply(soln, Q), soln.Transpose())[0]);

            double expectedSol = 0.049316494677822;
            double actualSol = value;

            double[] expected = 
            {
                0.74083116998144, // 2
                0.14799651298617, // 13
                0.11117231703249, // 14
            };

            double[] actual =
            {
                soln[1], soln[12], soln[13]
            };

            Assert.AreEqual(expectedSol, actualSol, 1e-8);
            for (int i = 0; i < expected.Length; i++)
                Assert.AreEqual(expected[i], actual[i], 1e-5);
        }
        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);
        }
        public void GoldfarbIdnaniLargeSampleTest2()
        {
            var Q = readMatrixFile(new StringReader(Resources.dmatFull));
            var AMat = readMatrixFile(new StringReader(Resources.constraintMatrix11_15_2));
            var bvec = readVectorFile(new StringReader(Resources.constraints11_14_2));

            var dvec = new double[Q.GetLength(0)];
            double[] b = new double[bvec.Length];
            bvec.CopyTo(b, 0);

            bool psd = Q.IsPositiveDefinite();
            Assert.IsTrue(psd);

            GoldfarbIdnani gfI = new GoldfarbIdnani(Q, dvec, AMat, b, 2);

            for (int i = 0; i < gfI.ConstraintTolerances.Length; i++)
                Assert.AreEqual(0, gfI.ConstraintTolerances[i]);

            bool success = gfI.Minimize();

            Assert.IsTrue(success);

            double[] soln = gfI.Solution;
            double value = Math.Sqrt(Matrix.Multiply(Matrix.Multiply(soln, Q), soln.Transpose())[0]);

            double expectedSol = 0.048224950997808;
            double actualSol = value;

            double[] expected = 
            {
                0.41144782323407, // 2
                0.27310552838116, // 13
                0.31544664838498, // 14
            };

            double[] actual =
            {
                soln[1], soln[12], soln[13]
            };

            Assert.AreEqual(expectedSol, actualSol, 1e-8);
            for (int i = 0; i < expected.Length; i++)
                Assert.AreEqual(expected[i], actual[i], 1e-5);
        }
        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"));


            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));
        }
        public void GoldfarbIdnaniLargeSampleTest3_InfiniteLoop()
        {
            var Q = readMatrixFile(new StringReader(Resources.dmatFull));
            var AMat = readMatrixFile(new StringReader(Resources.constraintMatrix11_15_3));
            var bvec = readVectorFile(new StringReader(Resources.constraints11_14_3));

            var dvec = new double[Q.GetLength(0)];
            double[] b = new double[bvec.Length];
            bvec.CopyTo(b, 0);

            bool psd = Q.IsPositiveDefinite();
            Assert.IsTrue(psd);

            GoldfarbIdnani gfI = new GoldfarbIdnani(Q, dvec, AMat, b, 2);

            for (int i = 0; i < gfI.ConstraintTolerances.Length; i++)
                gfI.ConstraintTolerances[i] = 1e-10;

            bool success = gfI.Minimize();

            Assert.IsTrue(success);

            double[] soln = gfI.Solution;
            double value = Math.Sqrt(Matrix.Multiply(Matrix.Multiply(soln, Q), soln.Transpose())[0]);

            double expectedSol = 0.052870914138455;
            double actualSol = value;

            double[] expected = 
            {
                0.4, // 2
                0.0016271524831373, // 4
                0, // 5
                0, // 13
                0, // 14
                0.59837284751680053 // 19     
            };

            double[] actual =
            {
                soln[1], soln[3], soln[4], soln[12], soln[13], soln[18]
            };

            Assert.AreEqual(expectedSol, actualSol, 1e-8);
            for (int i = 0; i < expected.Length; i++)
                Assert.AreEqual(expected[i], actual[i], 1e-5);
        }
        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);
        }
        public void RunTest2()
        {
            // Maximize f(x) = x² + 4y² -8x -16y
            //
            //      s.t. x + y <= 5
            //               x <= 3
            //             x,y >= 0
            //

            double[,] D = 
            {
                { 2, 0 }, // 1x²
                { 0, 8 }, // 4y²
            };

            double[] d = { -8, -16 };


            double[,] A = 
            {
                { 1, 1 }, // x + y
                { 1, 0 }, // x
            };

            double[] b = { 5, 3 };


            GoldfarbIdnani target = new GoldfarbIdnani(D, d.Multiply(-1), A.Transpose(), b);

            Assert.IsTrue(target.Minimize());
            double actual = target.Value;
            Assert.AreEqual(64.8, actual, 1e-10);
            Assert.IsFalse(double.IsNaN(actual));
            Assert.AreEqual(2, target.Iterations);
            Assert.AreEqual(0, target.Deletions);

            Assert.AreEqual(4.8, target.Solution[0], 1e-6);
            Assert.AreEqual(0.2, target.Solution[1], 1e-6);

            Assert.AreEqual(17.6, target.Lagrangian[0]);
            Assert.AreEqual(0.00, target.Lagrangian[1]);

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

            foreach (double v in target.Solution)
                Assert.IsFalse(double.IsNaN(v));
        }
        public void RunTest1()
        {
            double[,] D = Matrix.Identity(3);
            double[] d = { 1, 5, 3 };

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


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

            GoldfarbIdnani target = new GoldfarbIdnani(D, d.Multiply(-1), A.Transpose(), b);

            Assert.IsTrue(target.Minimize());
            double actual = target.Value;
            Assert.AreEqual(-12.41011, actual, 1e-5);
            Assert.IsFalse(double.IsNaN(actual));
            Assert.AreEqual(3, target.Iterations);
            Assert.AreEqual(0, target.Deletions);

            Assert.AreEqual(0.4157303, target.Solution[0], 1e-6);
            Assert.AreEqual(2.1123596, target.Solution[1], 1e-6);
            Assert.AreEqual(4.2247191, target.Solution[2], 1e-6);

            Assert.AreEqual(0.1460674, target.Lagrangian[0], 1e-6);
            Assert.AreEqual(0.0000000, target.Lagrangian[1], 1e-6);
            Assert.AreEqual(1.2247191, target.Lagrangian[2], 1e-6);

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

            foreach (double v in target.Solution)
                Assert.IsFalse(double.IsNaN(v));
        }
        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));


            GoldfarbIdnani target = new GoldfarbIdnani(f, 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.QuadraticTerms;
            var actuald = f.LinearTerms;

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

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

            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));
            }
        }
Beispiel #55
0
        public void ConstructorTest2()
        {
            // https://github.com/accord-net/framework/issues/171

            int n = 21;
            var Q = Matrix.Diagonal(n, 2.0);
            var d = Vector.Create(3132.0, 6264, 15660, 18792, 21924, 6264, 18792, 21924, 9396, 3132, 12528, 6264, 9396, 18792, 21924, 9396, 3132, 3132, 6264, 15660, 18792);

            int m = 44;

            var b = Vector.Create(
                703.999, -704.001,
                1267.999, -1268.001,
                1565.999, -1566.001,
                471.999, -472.001,
                1425.999, -1426.001,
                -107.001,
                -1164.001,
                -57.001,
                -311.001,
                -1433.001,
                -0.001,
                -0.001,
                -788.001,
                -472.001,
                -850.001,
                -273.001,
                -0.001, -0.001, -0.001, -0.001,
                -0.001, -0.001, -0.001, -0.001, -0.001,
                -0.001, -0.001, -0.001, -0.001, -0.001,
                -0.001, -0.001, -0.001, -0.001, -0.001,
                -0.001, -0.001, -0.001, -0.001);

            var A = Matrix.Create(m, n,
                                  1.0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1,
                                  0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0,
                                  -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0,
                                  0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);


            var aa = A.Reshape();
            var qq = Q.Reshape();
            var r  = Quadprog.Compute(n, m, aa, b, 0, qq, d);

            double[] expected = r.Item2;

            var constraints = LinearConstraintCollection.FromMatrix(A, b, 0);

            double[] expectedViolation = constraints.Apply(x => x.GetViolation(r.Item2));
            for (int i = 0; i < expectedViolation.Length; i++)
            {
                Assert.IsTrue(expectedViolation[i] <= 1e-3);
            }


            var solver = new GoldfarbIdnani(Q, d.Multiply(-1), A, b, 0);

            Assert.IsTrue(solver.Minimize());

            double[] actual = solver.Solution;
            Assert.IsTrue(actual.IsEqual(expected, 1e-3));


            double[] actualViolation = constraints.Apply(x => x.GetViolation(solver.Solution));
            Assert.IsTrue(actualViolation.IsEqual(expectedViolation, 1e-3));
        }
        public void ConstructorTest2()
        {
            // https://github.com/accord-net/framework/issues/171

            int n = 21;
            var Q = Matrix.Diagonal(n, 2.0);
            var d = Vector.Create(3132.0, 6264, 15660, 18792, 21924, 6264, 18792, 21924, 9396, 3132, 12528, 6264, 9396, 18792, 21924, 9396, 3132, 3132, 6264, 15660, 18792);

            int m = 44;

            var b = Vector.Create(
                703.999, -704.001,
                1267.999, -1268.001,
                1565.999, -1566.001,
                471.999, -472.001,
                1425.999, -1426.001,
                -107.001,
                -1164.001,
                -57.001,
                -311.001,
                -1433.001,
                -0.001,
                -0.001,
                -788.001,
                -472.001,
                -850.001,
                -273.001,
                -0.001, -0.001, -0.001, -0.001,
                -0.001, -0.001, -0.001, -0.001, -0.001,
                -0.001, -0.001, -0.001, -0.001, -0.001,
                -0.001, -0.001, -0.001, -0.001, -0.001,
                -0.001, -0.001, -0.001, -0.001);

            var A = Matrix.Create(m, n,
                 1.0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1,
                 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0,
                -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);


            var aa = A.Reshape();
            var qq = Q.Reshape();
            var r = Quadprog.Compute(n, m, aa, b, 0, qq, d);

            double[] expected = r.Item2;

            var constraints = LinearConstraintCollection.FromMatrix(A, b, 0);
            double[] expectedViolation = constraints.Apply(x => x.GetViolation(r.Item2));
            for (int i = 0; i < expectedViolation.Length; i++)
                Assert.IsTrue(expectedViolation[i] <= 1e-3);


            var solver = new GoldfarbIdnani(Q, d.Multiply(-1), A, b, 0);

            Assert.IsTrue(solver.Minimize());

            double[] actual = solver.Solution;
            Assert.IsTrue(actual.IsEqual(expected, 1e-3));


            double[] actualViolation = constraints.Apply(x => x.GetViolation(solver.Solution));
            Assert.IsTrue(actualViolation.IsEqual(expectedViolation, 1e-3));
        }