public void ConstructorTest3()
{
// minimize f(x) = x*y*z,
// s.t.
//
// 1 - x² - 2y² - 3z² > 0
// x > 0,
// y > 0
//
// Easy three dimensional minimization in ellipsoid.
var function = new NonlinearObjectiveFunction(3,
function: x => x[0] * x[1] * x[2],
gradient: x => new[] { x[1] * x[2], x[0] * x[2], x[0] * x[1] });
NonlinearConstraint[] constraints =
{
new NonlinearConstraint(3,
function: x => 1.0 - x[0] * x[0] - 2.0 * x[1] * x[1] - 3.0 * x[2] * x[2],
gradient: x => new[] { -2.0 * x[0], -4.0 * x[1], -6.0 * x[2] }),
new NonlinearConstraint(3,
function: x => x[0],
gradient: x => new[] { 1.0, 0, 0 }),
new NonlinearConstraint(3,
function: x => x[1],
gradient: x => new[] { 0, 1.0, 0 }),
new NonlinearConstraint(3,
function: x => -x[2],
gradient: x => new[] { 0, 0, -1.0 }),
};
for (int i = 0; i < constraints.Length; i++)
{
Assert.AreEqual(ConstraintType.GreaterThanOrEqualTo, constraints[i].ShouldBe);
Assert.AreEqual(0, constraints[i].Value);
}
var inner = new BroydenFletcherGoldfarbShanno(3);
inner.LineSearch = LineSearch.BacktrackingArmijo;
inner.Corrections = 10;
var solver = new AugmentedLagrangian(inner, function, constraints);
Assert.AreEqual(inner, solver.Optimizer);
Assert.IsTrue(solver.Minimize());
double minimum = solver.Value;
double[] solution = solver.Solution;
double[] expected =
{
1.0 / Math.Sqrt(3.0), 1.0 / Math.Sqrt(6.0), -1.0 / 3.0
};
for (int i = 0; i < expected.Length; i++)
Assert.AreEqual(expected[i], solver.Solution[i], 1e-3);
Assert.AreEqual(-0.078567420132031968, minimum, 1e-4);
double expectedMinimum = function.Function(solver.Solution);
Assert.AreEqual(expectedMinimum, minimum);
}