private static void test2(IGradientOptimizationMethod inner)
{
// maximize 2x + 3y, s.t. 2x² + 2y² <= 50
//
// http://www.wolframalpha.com/input/?i=max+2x+%2B+3y%2C+s.t.+2x%C2%B2+%2B+2y%C2%B2+%3C%3D+50
// 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
));
// Test first constraint
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
var input = new double[] { i, j };
double expected = i * (2 * i + 0 * j) + j * (0 * i + 2 * j);
double actual = constraints[0].Function(input);
Assert.AreEqual(expected, actual);
}
}
// Create the solver algorithm
AugmentedLagrangian solver =
new AugmentedLagrangian(inner, objective, constraints);
Assert.AreEqual(inner, solver.Optimizer);
Assert.IsTrue(solver.Maximize());
double maxValue = solver.Value;
Assert.AreEqual(18.02, maxValue, 1e-2);
Assert.AreEqual(2.77, solver.Solution[0], 1e-2);
Assert.AreEqual(4.16, solver.Solution[1], 1e-2);
}