public void GoldfarbIdnaniParseTest()
        {
            var s = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

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

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

            // Now we can start creating our function:
            QuadraticObjectiveFunction function = new QuadraticObjectiveFunction(strObjective, CultureInfo.CurrentCulture);
            LinearConstraintCollection cst      = new LinearConstraintCollection();

            foreach (var tmpCst in strConstraints)
            {
                cst.Add(new LinearConstraint(function, tmpCst, CultureInfo.CurrentCulture));
            }

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

            Assert.IsTrue(status);
            Assert.AreEqual(15553.60, result, 1e-10);
        }
        public void GoldfarbIdnaniParseGlobalizationTest2()
        {
            String strObjective = 0.5.ToString(CultureInfo.InvariantCulture)
                                  + "x² +" + 0.2.ToString(CultureInfo.InvariantCulture) + "y² +"
                                  + 0.3.ToString(CultureInfo.InvariantCulture) + "xy";

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

            QuadraticObjectiveFunction function = new QuadraticObjectiveFunction(strObjective);
            LinearConstraintCollection cst      = new LinearConstraintCollection();

            foreach (var tmpCst in strConstraints)
            {
                cst.Add(new LinearConstraint(function, tmpCst));
            }

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

            Assert.IsTrue(status);
            Assert.AreEqual(15553.60, result, 1e-10);
        }
        public void GoldfarbIdnaniParseGlobalizationTestBase()
        {
            // minimize 0.5x² + 0.2y² + 0.3xy s.t. 0.01x + 0.02y - 0.03 = 0 AND x + y = 100
            // http://www.wolframalpha.com/input/?i=minimize+0.5x%C2%B2+%2B+0.2y%C2%B2+%2B+0.3xy+s.t.+0.01x+%2B+0.02y+-+0.03+%3D+0+AND+x+%2B+y+%3D+100

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

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

            QuadraticObjectiveFunction function = new QuadraticObjectiveFunction(strObjective);
            LinearConstraintCollection cst      = new LinearConstraintCollection();

            foreach (var tmpCst in strConstraints)
            {
                cst.Add(new LinearConstraint(function, tmpCst));
            }

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

            Assert.IsTrue(status);
            Assert.AreEqual(15553.60, result, 1e-10);
        }
Beispiel #4
0
        public void solve_vectors()
        {
            #region doc_vector
            // Suppose we would like to minimize the following function:
            //
            //    f(x,y) = min 100(y-x²)²+(1-x)²
            //
            // Subject to the constraints
            //
            //    x >= 0  (x must be positive)
            //    y >= 0  (y must be positive)
            //

            // Now, we can create an objective function using vectors
            var f = new NonlinearObjectiveFunction(numberOfVariables: 2,

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

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

            // As before, we state the constraints. However, to illustrate the flexibility
            // of the AugmentedLagrangian, we shall use LinearConstraints to constrain the problem.
            double[,] a = Matrix.Identity(2); // Set up the constraint matrix...
            double[] b = Vector.Zeros(2);     // ...and the values they must be greater than
            int      numberOfEqualities = 0;
            var      linearConstraints  = LinearConstraintCollection.Create(a, b, numberOfEqualities);

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

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

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

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

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

            Assert.IsFalse(double.IsNaN(minValue));
            Assert.IsFalse(double.IsNaN(solver.Solution[0]));
            Assert.IsFalse(double.IsNaN(solver.Solution[1]));
        }
Beispiel #5
0
        public void GoldfarbIdnaniMinimizeTest1()
        {
            // This test reproduces Issue #33 at Google Code Tracker
            // https://code.google.com/p/accord/issues/detail?id=33

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

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

            Assert.IsTrue(Q.IsPositiveDefinite());

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

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

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

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

            double[] b;
            int      eq;

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

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

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

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

            for (int i = 0; i < expected.Length; i++)
            {
                double e = expected[i];
                double a = actual[i];
                Assert.AreEqual(e, a);
            }
        }
Beispiel #6
0
        /// <summary>
        ///     Constructs a new <see cref="GoldfarbIdnani" /> class.
        /// </summary>
        /// <param name="function">The objective function to be optimized.</param>
        /// <param name="constraints">The problem's constraints.</param>
        public GoldfarbIdnani(QuadraticObjectiveFunction function, LinearConstraintCollection constraints)
            : base(function.NumberOfVariables, function.Function, function.Gradient)
        {
            int equalities;

            // Create the constraint matrix A from the specified constraint list
            var A = constraints.CreateMatrix(function.NumberOfVariables,
                                             out constraintValues, out constraintTolerances, out equalities);

            Debug.Assert(A.GetLength(1) == function.NumberOfVariables);

            initialize(function.NumberOfVariables,
                       function.QuadraticTerms, function.LinearTerms,
                       A, constraintValues, equalities);
        }
Beispiel #7
0
        private static void DoSv(Tuple<double[], double>[] classified)
        {
            var stripped = classified.Select(t => new Tuple<double[], double>(t.Item1.Skip(1).ToArray(), t.Item2))
            .ToArray();
              var q = GetQ(stripped);

              //all are 0 or more
              var lcc = new LinearConstraintCollection(
            Enumerable.Range(0, stripped.Length)
              .Select(i => new LinearConstraint(1)
              {
            VariablesAtIndices = new[] { i },
            ShouldBe = ConstraintType.GreaterThanOrEqualTo,
            Value = 0.0,
            CombinedAs= new []{1.0} //???
              }));
              //and they zero out with the classificaiton
              lcc.Add(
            //new LinearConstraint(stripped.Select(t => t.Item2).ToArray()) { Value = 0, ShouldBe = ConstraintType.EqualTo }
            new LinearConstraint(stripped.Length)
            {
              Value = 0,
              ShouldBe = ConstraintType.EqualTo,
              VariablesAtIndices = Enumerable.Range(0, stripped.Length).ToArray(),
              CombinedAs = stripped.Select(t => t.Item2).ToArray()
            }        );

              var solver = new GoldfarbIdnaniQuadraticSolver(stripped.Length, lcc);
              solver.Minimize(q, neg1Array(stripped.Length));
              //b  = 1/y - w_*x_

              var tmp = solver.Solution.Zip(stripped, (alpha, s) => s.Item1.Select(x => x * alpha * s.Item2))
            .Aggregate(VAdd).ToList();
              var support = solver.Solution.Zip(stripped, (alpha, s) => Math.Abs(alpha) > 0.0001 ? s : null).Where(x => x != null).ToArray();
              var offset = GetOffset(support, tmp); //I'm pretty sure this calculation for b is wrong: you get a different one for each of elements...
              tmp.Insert(0, offset);
              var wSupp = Norm( tmp.ToArray());
        }
        /// <summary>
        ///   Constructs a new <see cref="GoldfarbIdnaniQuadraticSolver"/> class.
        /// </summary>
        /// 
        /// <param name="numberOfVariables">The number of variables.</param>
        /// <param name="constraints">The problem's constraints.</param>
        /// 
        public GoldfarbIdnaniQuadraticSolver(int numberOfVariables, LinearConstraintCollection constraints)
        {
            int equalities;

            // Create the constraint matrix A from the specified constraint list
            double[,] A = constraints.CreateMatrix(numberOfVariables, out constraintValues, out equalities);

            System.Diagnostics.Debug.Assert(A.GetLength(1) == numberOfVariables);

            initialize(numberOfVariables, A, constraintValues, equalities);
        }
Beispiel #9
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 GoldfarbIdnaniMinimizeTest1()
        {
            // This test reproduces Issue #33 at Google Code Tracker
            // https://code.google.com/p/accord/issues/detail?id=33

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

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

            Assert.IsTrue(Q.IsPositiveDefinite());

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

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

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

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

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

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

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

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

            for (int i = 0; i < expected.Length; i++)
            {
                double e = expected[i];
                double a = actual[i];
                Assert.AreEqual(e, a);
            }
        }
        public void GoldfarbIdnaniParseGlobalizationTestBase()
        {
            // minimize 0.5x² + 0.2y² + 0.3xy s.t. 0.01x + 0.02y - 0.03 = 0 AND x + y = 100
            // http://www.wolframalpha.com/input/?i=minimize+0.5x%C2%B2+%2B+0.2y%C2%B2+%2B+0.3xy+s.t.+0.01x+%2B+0.02y+-+0.03+%3D+0+AND+x+%2B+y+%3D+100

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

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

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

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

            Assert.IsTrue(status);
            Assert.AreEqual(15553.60, result, 1e-10);
        }
        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 GoldfarbIdnaniParseTest()
        {
            var s = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

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

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

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

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

            Assert.IsTrue(status);
            Assert.AreEqual(15553.60, result, 1e-10);
        }
        public void GoldfarbIdnaniParseGlobalizationTest2()
        {
            String strObjective = 0.5.ToString(CultureInfo.InvariantCulture)
                + "x² +" + 0.2.ToString(CultureInfo.InvariantCulture) + "y² +"
                + 0.3.ToString(CultureInfo.InvariantCulture) + "xy";

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

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

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

            Assert.IsTrue(status);
            Assert.AreEqual(15553.60, result, 1e-10);
        }
        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);
            }
        }