public void AugmentedLagrangianSolverConstructorTest3() { // min x*y+ y*z // // s.t. x^2 - y^2 + z^2 - 2 >= 0 // x^2 + y^2 + z^2 - 10 <= 0 // double x = 0, y = 0, z = 0; var f = new NonlinearObjectiveFunction( function: () => x * y + y * z, gradient: () => new[] { y, // df/dx x + z, // df/dy y, // df/dz } ); var constraints = new List <NonlinearConstraint>(); constraints.Add(new NonlinearConstraint(f, function: () => x * x - y * y + z * z, gradient: () => new[] { 2 * x, -2 * y, 2 * z }, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 2 )); constraints.Add(new NonlinearConstraint(f, function: () => x * x + y * y + z * z, gradient: () => new[] { 2 * x, 2 * y, 2 * z }, shouldBe: ConstraintType.LesserThanOrEqualTo, value: 10 )); var solver = new AugmentedLagrangianSolver(3, constraints); solver.Solution[0] = 1; solver.Solution[1] = 1; solver.Solution[2] = 1; double minValue = solver.Minimize(f); Assert.AreEqual(-6.9, minValue, 1e-1); Assert.AreEqual(+1.73, solver.Solution[0], 1e-2); Assert.AreEqual(-2.00, solver.Solution[1], 1e-2); Assert.AreEqual(+1.73, solver.Solution[2], 1e-2); Assert.IsFalse(Double.IsNaN(minValue)); Assert.IsFalse(Double.IsNaN(solver.Solution[0])); Assert.IsFalse(Double.IsNaN(solver.Solution[1])); Assert.IsFalse(Double.IsNaN(solver.Solution[2])); }
public static double solve(bool isFine, IEnumerable <Constraint> cons) { var constraints = cons.ToArray(); // Get the parameters that need solving by selecting "free" ones Parameter[] x = constraints.SelectMany(p => p) .Distinct() .Where(p => p.free == true) .ToArray(); Console.WriteLine("Number of free vars is " + x.Length); // Wrap our constraint error function for Accord.NET Func <double[], double> objective = args => { int i = 0; foreach (var arg in args) { x [i].Value = arg; i++; } return(Constraint.calc(constraints)); }; var nlConstraints = new List <NonlinearConstraint> (); // Finally, we create the non-linear programming solver var solver = new AugmentedLagrangianSolver(x.Length, nlConstraints); // Copy in the initial conditions x.Select(v => v.Value).ToArray().CopyTo(solver.Solution, 0); // And attempt to solve the problem return(solver.Minimize(LogWrap(objective), LogWrap(Grad(x.Length, objective)))); }
public void AugmentedLagrangianSolverConstructorTest2() { // min 100(y-x*x)²+(1-x)² // // s.t. x >= 0 // y >= 0 // var f = new NonlinearObjectiveFunction(2, function: (x) => 100 * Math.Pow(x[1] - x[0] * x[0], 2) + Math.Pow(1 - x[0], 2), gradient: (x) => new[] { 2.0 * (200.0 * Math.Pow(x[0], 3) - 200.0 * x[0] * x[1] + x[0] - 1), // df/dx 200 * (x[1] - x[0] * x[0]) // df/dy } ); var constraints = new List <NonlinearConstraint>(); constraints.Add(new NonlinearConstraint(f, function: (x) => x[0], gradient: (x) => new[] { 1.0, 0.0 }, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0 )); constraints.Add(new NonlinearConstraint(f, function: (x) => x[1], gradient: (x) => new[] { 0.0, 1.0 }, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0 )); var solver = new AugmentedLagrangianSolver(2, constraints); double minValue = solver.Minimize(f); Assert.AreEqual(0, minValue, 1e-10); Assert.AreEqual(1, solver.Solution[0], 1e-10); Assert.AreEqual(1, solver.Solution[1], 1e-10); Assert.IsFalse(Double.IsNaN(minValue)); Assert.IsFalse(Double.IsNaN(solver.Solution[0])); Assert.IsFalse(Double.IsNaN(solver.Solution[1])); }
public void AugmentedLagrangianSolverConstructorTest1() { Accord.Math.Tools.SetupGenerator(0); // min 100(y-x*x)²+(1-x)² // // s.t. x <= 0 // y <= 0 // var f = new NonlinearObjectiveFunction(2, function: (x) => 100 * Math.Pow(x[1] - x[0] * x[0], 2) + Math.Pow(1 - x[0], 2), gradient: (x) => new[] { 2.0 * (200.0 * x[0] * x[0] * x[0] - 200.0 * x[0] * x[1] + x[0] - 1), // df/dx 200 * (x[1] - x[0] * x[0]) // df/dy } ); var constraints = new List <NonlinearConstraint>(); constraints.Add(new NonlinearConstraint(f, function: (x) => x[0], gradient: (x) => new[] { 1.0, 0.0 }, shouldBe: ConstraintType.LesserThanOrEqualTo, value: 0 )); constraints.Add(new NonlinearConstraint(f, function: (x) => x[1], gradient: (x) => new[] { 0.0, 1.0 }, shouldBe: ConstraintType.LesserThanOrEqualTo, value: 0 )); var solver = new AugmentedLagrangianSolver(2, constraints); double minValue = solver.Minimize(f); Assert.AreEqual(1, minValue, 1e-5); Assert.AreEqual(0, solver.Solution[0], 1e-5); Assert.AreEqual(0, solver.Solution[1], 1e-5); }
public void AugmentedLagrangianSolverConstructorTest5() { // Suppose we would like to minimize the following function: // // f(x,y) = min 100(y-x²)²+(1-x)² // // Subject to the constraints // // x >= 0 (x must be positive) // y >= 0 (y must be positive) // double x = 0, y = 0; // First, we create our objective function var f = new NonlinearObjectiveFunction( // This is the objective function: f(x,y) = min 100(y-x²)²+(1-x)² function: () => 100 * Math.Pow(y - x * x, 2) + Math.Pow(1 - x, 2), // The gradient vector: gradient: () => new[] { 2 * (200 * Math.Pow(x, 3) - 200 * x * y + x - 1), // df/dx = 2(200x³-200xy+x-1) 200 * (y - x * x) // df/dy = 200(y-x²) } ); // Now we can start stating the constraints var constraints = new List <NonlinearConstraint>(); // Add the non-negativity constraint for x constraints.Add(new NonlinearConstraint(f, // 1st constraint: x should be greater than or equal to 0 function: () => x, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0, gradient: () => new[] { 1.0, 0.0 } )); // Add the non-negativity constraint for y constraints.Add(new NonlinearConstraint(f, // 2nd constraint: y should be greater than or equal to 0 function: () => y, shouldBe: ConstraintType.GreaterThanOrEqualTo, value: 0, gradient: () => new[] { 0.0, 1.0 } )); // Finally, we create the non-linear programming solver var solver = new AugmentedLagrangianSolver(2, constraints); // And attempt to solve the problem double minValue = solver.Minimize(f); Assert.AreEqual(0, minValue, 1e-10); Assert.AreEqual(1, solver.Solution[0], 1e-10); Assert.AreEqual(1, solver.Solution[1], 1e-10); Assert.IsFalse(Double.IsNaN(minValue)); Assert.IsFalse(Double.IsNaN(solver.Solution[0])); Assert.IsFalse(Double.IsNaN(solver.Solution[1])); }