back
Math.Net.Fix.Curve uses NelderMeadSimplex
- Background
- For my application,
Fit.Curve()
threw exceptions,
because tolerance was not satified for maxIterations - 20 .
Setting tolerance = 0.00005 produces reasonable matches to cubic fit within 300 iterations...
Straight line fits solution is used for initialGuess0, initialGuess1 , with others = 0;
public static (double P0, double P1, double P2, double P3) Curve(double[] x, double[] y, Func f,
double initialGuess0, double initialGuess1, double initialGuess2, double initialGuess3,
double tolerance = 1e-8, int maxIterations = 1000)
{
return FindMinimum.OfFunction((p0, p1, p2, p3) => Distance.Euclidean(Generate.Map(x, t => f(p0, p1, p2, p3, t)), y),
initialGuess0, initialGuess1, double initialGuess2, double initialGuess3,
tolerance, maxIterations);
}
public static (double P0, double P1, double P2, double P3) OfFunction(Func function,
double initialGuess0, double initialGuess1, double initialGuess2, double initialGuess3,
double tolerance = 1e-8, int maxIterations = 1000)
{
var objective = ObjectiveFunction.Value(v => function(v[0], v[1], v[2], v[3]));
var result = NelderMeadSimplex.Minimum(objective,
CreateVector.Dense(new[] { initialGuess0, initialGuess1, initialGuess2, initialGuess3 }),
tolerance, maxIterations);
return (result.MinimizingPoint[0], result.MinimizingPoint[1], result.MinimizingPoint[2], result.MinimizingPoint[3]);
}
public static MinimizationResult Minimum(IObjectiveFunction objectiveFunction, Vector initialGuess,
double convergenceTolerance=1e-8, int maximumIterations=1000)
{
var initalPertubation = new LinearAlgebra.Double.DenseVector(initialGuess.Count);
for (int i = 0; i < initialGuess.Count; i++)
{
initalPertubation[i] = initialGuess[i] == 0.0 ? 0.00025 : initialGuess[i] * 0.05;
}
return Minimum(objectiveFunction, initialGuess, initalPertubation, convergenceTolerance, maximumIterations);
}
|