Skip to content
This repository has been archived by the owner on Nov 19, 2020. It is now read-only.

Commit

Permalink
Working on GH-335: Nelder-mead solver not converged
Browse files Browse the repository at this point in the history
  • Loading branch information
cesarsouza committed Jul 14, 2017
1 parent 14b6efd commit 141c4d1
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 136 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public class NelderMead : BaseOptimizationMethod, IOptimizationMethod<NelderMead

NelderMeadStatus status;

private double minf_max;
private double minf_max = Double.NegativeInfinity;

private double psi;
private double fdiff;
Expand Down
282 changes: 147 additions & 135 deletions Unit Tests/Accord.Tests.Math/Optimization/NelderMeadTest.cs
Original file line number Diff line number Diff line change
@@ -1,135 +1,147 @@
// Accord Unit Tests
// The Accord.NET Framework
// http://accord-framework.net
//
// Copyright © César Souza, 2009-2017
// cesarsouza at gmail.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//

namespace Accord.Tests.Math
{
using System;
using Accord.Math.Optimization;
using NUnit.Framework;

[TestFixture]
public class NelderMeadTest
{


private TestContext testContextInstance;

public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}


[Test]
public void ConstructorTest1()
{
Func<double[], double> function = // min f(x) = 10 * (x+1)^2 + y^2
x => 10.0 * Math.Pow(x[0] + 1.0, 2.0) + Math.Pow(x[1], 2.0);

NelderMead solver = new NelderMead(2, function);

Assert.IsTrue(solver.Minimize());
double minimum = solver.Value;

double[] solution = solver.Solution;

Assert.AreEqual(0, minimum, 1e-10);
Assert.AreEqual(-1, solution[0], 1e-5);
Assert.AreEqual(0, solution[1], 1e-5);

double expectedMinimum = function(solver.Solution);
Assert.AreEqual(expectedMinimum, minimum);
}

[Test]
public void ConstructorTest4()
{
var function = new NonlinearObjectiveFunction(2, x =>
Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

NelderMead solver = new NelderMead(function);

Assert.IsTrue(solver.Minimize());
double minimum = solver.Value;
double[] solution = solver.Solution;

Assert.AreEqual(0, minimum, 1e-10);
Assert.AreEqual(-1, solution[0], 1e-5);
Assert.AreEqual(1, solution[1], 1e-4);

double expectedMinimum = function.Function(solver.Solution);
Assert.AreEqual(expectedMinimum, minimum);
}

[Test]
public void ConstructorTest5()
{
var function = new NonlinearObjectiveFunction(2, x =>
10.0 * Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

NelderMead solver = new NelderMead(function);

Assert.IsTrue(solver.Minimize());
double minimum = solver.Value;
double[] solution = solver.Solution;

Assert.AreEqual(2, solution.Length);
Assert.AreEqual(-0, minimum, 1e-6);
Assert.AreEqual(-1, solution[0], 1e-3);
Assert.AreEqual(+1, solution[1], 1e-3);

double expectedMinimum = function.Function(solver.Solution);
Assert.AreEqual(expectedMinimum, minimum);
}

[Test]
public void SubspaceTest1()
{
var function = new NonlinearObjectiveFunction(5, x =>
10.0 * Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

NelderMead solver = new NelderMead(function);

solver.NumberOfVariables = 2;

Assert.IsTrue(solver.Minimize());
double minimum = solver.Value;
double[] solution = solver.Solution;

Assert.AreEqual(5, solution.Length);
Assert.AreEqual(-0, minimum, 1e-6);
Assert.AreEqual(-1, solution[0], 1e-3);
Assert.AreEqual(+1, solution[1], 1e-3);

double expectedMinimum = function.Function(solver.Solution);
Assert.AreEqual(expectedMinimum, minimum);
}

}
}
// Accord Unit Tests
// The Accord.NET Framework
// http://accord-framework.net
//
// Copyright © César Souza, 2009-2017
// cesarsouza at gmail.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//

namespace Accord.Tests.Math
{
using System;
using Accord.Math.Optimization;
using NUnit.Framework;
using System.Diagnostics;

[TestFixture]
public class NelderMeadTest
{

[Test]
public void ConstructorTest1()
{
Func<double[], double> function = // min f(x) = 10 * (x+1)^2 + y^2
x => 10.0 * Math.Pow(x[0] + 1.0, 2.0) + Math.Pow(x[1], 2.0);

NelderMead solver = new NelderMead(2, function);

Assert.IsTrue(solver.Minimize());
double minimum = solver.Value;

double[] solution = solver.Solution;

Assert.AreEqual(0, minimum, 1e-10);
Assert.AreEqual(-1, solution[0], 1e-5);
Assert.AreEqual(0, solution[1], 1e-5);

double expectedMinimum = function(solver.Solution);
Assert.AreEqual(expectedMinimum, minimum);
}

[Test]
public void ConstructorTest4()
{
var function = new NonlinearObjectiveFunction(2, x =>
Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

NelderMead solver = new NelderMead(function);

Assert.IsTrue(solver.Minimize());
double minimum = solver.Value;
double[] solution = solver.Solution;

Assert.AreEqual(0, minimum, 1e-10);
Assert.AreEqual(-1, solution[0], 1e-5);
Assert.AreEqual(1, solution[1], 1e-4);

double expectedMinimum = function.Function(solver.Solution);
Assert.AreEqual(expectedMinimum, minimum);
}

[Test]
public void ConstructorTest5()
{
var function = new NonlinearObjectiveFunction(2, x =>
10.0 * Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

NelderMead solver = new NelderMead(function);

Assert.IsTrue(solver.Minimize());
double minimum = solver.Value;
double[] solution = solver.Solution;

Assert.AreEqual(2, solution.Length);
Assert.AreEqual(-0, minimum, 1e-6);
Assert.AreEqual(-1, solution[0], 1e-3);
Assert.AreEqual(+1, solution[1], 1e-3);

double expectedMinimum = function.Function(solver.Solution);
Assert.AreEqual(expectedMinimum, minimum);
}

[Test]
public void SubspaceTest1()
{
var function = new NonlinearObjectiveFunction(5, x =>
10.0 * Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

NelderMead solver = new NelderMead(function);

solver.NumberOfVariables = 2;

Assert.IsTrue(solver.Minimize());
double minimum = solver.Value;
double[] solution = solver.Solution;

Assert.AreEqual(5, solution.Length);
Assert.AreEqual(-0, minimum, 1e-6);
Assert.AreEqual(-1, solution[0], 1e-3);
Assert.AreEqual(+1, solution[1], 1e-3);

double expectedMinimum = function.Function(solver.Solution);
Assert.AreEqual(expectedMinimum, minimum);
}

[Test]
public void gh335()
{
// https://github.com/accord-net/framework/issues/335
Func<Double[], Double> eval = (val) =>
{
// WxMaxima command: plot3d(y^2+4*y+x^2-2*x,[x,-3,5], [y,-5,3],[grid,8,8]);
Double x = val[0];
Double y = val[1];
Double ret = y * y + 4 * y + x * x - 2 * x;
Debug.WriteLine("{2}; x={0}; y={1}", x, y, ret);
return ret;
};

// This values are relevant for my RealWorld(TM) scenario
Double[] init = new double[] { 0.5, 0 };

NelderMead nm = new NelderMead(2, eval);

nm.Minimize(init);

// Solution
Assert.AreEqual(1, nm.Solution[0], 1e-7);
Assert.AreEqual(-2, nm.Solution[1], 1e-6);
}
}
}

0 comments on commit 141c4d1

Please sign in to comment.