public void MinimizeTest() { Func<double[], double> f = BroydenFletcherGoldfarbShannoTest.rosenbrockFunction; Func<double[], double[]> g = BroydenFletcherGoldfarbShannoTest.rosenbrockGradient; Assert.AreEqual(104, f(new[] { -1.0, 2.0 })); int n = 2; // number of variables double[] initial = { -1.2, 1 }; ConjugateGradient cg = new ConjugateGradient(n, f, g); cg.Method = ConjugateGradientMethod.FletcherReeves; Assert.IsTrue(cg.Minimize(initial)); double actual = cg.Value; double expected = 0; Assert.AreEqual(expected, actual, 1e-6); double[] result = cg.Solution; Assert.AreEqual(127, cg.Evaluations); Assert.AreEqual(34, cg.Iterations); Assert.AreEqual(1.0, result[0], 1e-3); Assert.AreEqual(1.0, result[1], 1e-3); Assert.IsFalse(double.IsNaN(result[0])); Assert.IsFalse(double.IsNaN(result[1])); double y = f(result); double[] d = g(result); Assert.AreEqual(0.0, y, 1e-6); Assert.AreEqual(0.0, d[0], 1e-3); Assert.AreEqual(0.0, d[1], 1e-3); Assert.IsFalse(double.IsNaN(y)); Assert.IsFalse(double.IsNaN(d[0])); Assert.IsFalse(double.IsNaN(d[1])); }
public void ConstructorTest2() { Accord.Math.Tools.SetupGenerator(0); var function = new NonlinearObjectiveFunction(2, function: x => x[0] * x[1], gradient: x => new[] { x[1], x[0] }); NonlinearConstraint[] constraints = { new NonlinearConstraint(function, function: x => 1.0 - x[0] * x[0] - x[1] * x[1], gradient: x => new [] { -2 * x[0], -2 * x[1]}), new NonlinearConstraint(function, function: x => x[0], gradient: x => new [] { 1.0, 0.0}), }; var target = new ConjugateGradient(2); AugmentedLagrangian solver = new AugmentedLagrangian(target, function, constraints); Assert.IsTrue(solver.Minimize()); double minimum = solver.Value; double[] solution = solver.Solution; double sqrthalf = Math.Sqrt(0.5); Assert.AreEqual(-0.5, minimum, 1e-5); Assert.AreEqual(sqrthalf, solution[0], 1e-5); Assert.AreEqual(-sqrthalf, solution[1], 1e-5); double expectedMinimum = function.Function(solver.Solution); Assert.AreEqual(expectedMinimum, minimum); }
public void AugmentedLagrangianSolverConstructorTest6() { // maximize 2x + 3y, s.t. 2x² + 2y² <= 50 and x+y = 1 // Max x' * c // x // s.t. x' * A * x <= k // x' * i = 1 // lower_bound < x < upper_bound double[] c = { 2, 3 }; double[,] A = { { 2, 0 }, { 0, 2 } }; double k = 50; // Create the objective function var objective = new NonlinearObjectiveFunction(2, function: (x) => x.InnerProduct(c), gradient: (x) => c ); // Test objective for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { double expected = i * 2 + j * 3; double actual = objective.Function(new double[] { i, j }); Assert.AreEqual(expected, actual); } } // Create the optimization constraints var constraints = new List<NonlinearConstraint>(); constraints.Add(new QuadraticConstraint(objective, quadraticTerms: A, shouldBe: ConstraintType.LesserThanOrEqualTo, value: k )); constraints.Add(new NonlinearConstraint(objective, function: (x) => x.Sum(), gradient: (x) => new[] { 1.0, 1.0 }, shouldBe: ConstraintType.EqualTo, value: 1, withinTolerance: 1e-10 )); // Test first constraint for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { double expected = i * (2 * i + 0 * j) + j * (0 * i + 2 * j); double actual = constraints[0].Function(new double[] { i, j }); Assert.AreEqual(expected, actual); } } // Test second constraint for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { double expected = i + j; double actual = constraints[1].Function(new double[] { i, j }); Assert.AreEqual(expected, actual); } } // Create the solver algorithm var inner = new ConjugateGradient(2); AugmentedLagrangianSolver solver = new AugmentedLagrangianSolver(inner, constraints); double maxValue = solver.Maximize(objective); Assert.AreEqual(6, maxValue, 1e-4); Assert.AreEqual(-3, solver.Solution[0], 1e-4); Assert.AreEqual(4, solver.Solution[1], 1e-4); }