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