private static void test1(IGradientOptimizationMethod inner, double tol)
{
// 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);
}
}
AugmentedLagrangian solver =
new AugmentedLagrangian(inner, objective, constraints);
Assert.AreEqual(inner, solver.Optimizer);
Assert.IsTrue(solver.Maximize());
double maxValue = solver.Value;
Assert.AreEqual(6, maxValue, tol);
Assert.AreEqual(-3, solver.Solution[0], tol);
Assert.AreEqual(4, solver.Solution[1], tol);
}