From 412d8d296c2f18ab0353d2b8d6c1cd3b6011ccaf Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Sun, 20 Jun 2021 14:12:13 +0200 Subject: [PATCH] FindMinimum.OfFunction and Fit.Curve shortcuts extended to accept two more parameters #760 --- src/Numerics/FindMinimum.cs | 22 +++++++++++++++++++++ src/Numerics/Fit.cs | 38 +++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/Numerics/FindMinimum.cs b/src/Numerics/FindMinimum.cs index 76b02944..b0f41c8a 100644 --- a/src/Numerics/FindMinimum.cs +++ b/src/Numerics/FindMinimum.cs @@ -79,6 +79,28 @@ namespace MathNet.Numerics return Tuple.Create(result.MinimizingPoint[0], result.MinimizingPoint[1], result.MinimizingPoint[2]); } + /// + /// Find vector x that minimizes the function f(x) using the Nelder-Mead Simplex algorithm. + /// For more options and diagnostics consider to use directly. + /// + public static Tuple 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 Tuple.Create(result.MinimizingPoint[0], result.MinimizingPoint[1], result.MinimizingPoint[2], result.MinimizingPoint[3]); + } + + /// + /// Find vector x that minimizes the function f(x) using the Nelder-Mead Simplex algorithm. + /// For more options and diagnostics consider to use directly. + /// + public static Tuple OfFunction(Func function, double initialGuess0, double initialGuess1, double initialGuess2, double initialGuess3, double initialGuess4, double tolerance = 1e-8, int maxIterations = 1000) + { + var objective = ObjectiveFunction.Value(v => function(v[0], v[1], v[2], v[3], v[4])); + var result = NelderMeadSimplex.Minimum(objective, CreateVector.Dense(new[] { initialGuess0, initialGuess1, initialGuess2, initialGuess3, initialGuess4 }), tolerance, maxIterations); + return Tuple.Create(result.MinimizingPoint[0], result.MinimizingPoint[1], result.MinimizingPoint[2], result.MinimizingPoint[3], result.MinimizingPoint[4]); + } + /// /// Find vector x that minimizes the function f(x) using the Nelder-Mead Simplex algorithm. /// For more options and diagnostics consider to use directly. diff --git a/src/Numerics/Fit.cs b/src/Numerics/Fit.cs index 266a33ed..06eb8f25 100644 --- a/src/Numerics/Fit.cs +++ b/src/Numerics/Fit.cs @@ -362,6 +362,24 @@ namespace MathNet.Numerics return FindMinimum.OfFunction((p0, p1, p2) => Distance.Euclidean(Generate.Map(x, t => f(p0, p1, p2, t)), y), initialGuess0, initialGuess1, initialGuess2, tolerance, maxIterations); } + /// + /// Non-linear least-squares fitting the points (x,y) to an arbitrary function y : x -> f(p0, p1, p2, p3, x), + /// returning its best fitting parameter p0, p1 and p2. + /// + public static Tuple 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, initialGuess2, initialGuess3, tolerance, maxIterations); + } + + /// + /// Non-linear least-squares fitting the points (x,y) to an arbitrary function y : x -> f(p0, p1, p2, p3, x), + /// returning its best fitting parameter p0, p1 and p2. + /// + public static Tuple Curve(double[] x, double[] y, Func f, double initialGuess0, double initialGuess1, double initialGuess2, double initialGuess3, double initialGuess4, double tolerance = 1e-8, int maxIterations = 1000) + { + return FindMinimum.OfFunction((p0, p1, p2, p3, p4) => Distance.Euclidean(Generate.Map(x, t => f(p0, p1, p2, p3, p4, t)), y), initialGuess0, initialGuess1, initialGuess2, initialGuess3, initialGuess4, tolerance, maxIterations); + } + /// /// Non-linear least-squares fitting the points (x,y) to an arbitrary function y : x -> f(p, x), /// returning a function y' for the best fitting curve. @@ -391,5 +409,25 @@ namespace MathNet.Numerics var parameters = Curve(x, y, f, initialGuess0, initialGuess1, initialGuess2, tolerance, maxIterations); return z => f(parameters.Item1, parameters.Item2, parameters.Item3, z); } + + /// + /// Non-linear least-squares fitting the points (x,y) to an arbitrary function y : x -> f(p0, p1, p2, x), + /// returning a function y' for the best fitting curve. + /// + public static Func CurveFunc(double[] x, double[] y, Func f, double initialGuess0, double initialGuess1, double initialGuess2, double initialGuess3, double tolerance = 1e-8, int maxIterations = 1000) + { + var parameters = Curve(x, y, f, initialGuess0, initialGuess1, initialGuess2, initialGuess3, tolerance, maxIterations); + return z => f(parameters.Item1, parameters.Item2, parameters.Item3, parameters.Item4, z); + } + + /// + /// Non-linear least-squares fitting the points (x,y) to an arbitrary function y : x -> f(p0, p1, p2, x), + /// returning a function y' for the best fitting curve. + /// + public static Func CurveFunc(double[] x, double[] y, Func f, double initialGuess0, double initialGuess1, double initialGuess2, double initialGuess3, double initialGuess4, double tolerance = 1e-8, int maxIterations = 1000) + { + var parameters = Curve(x, y, f, initialGuess0, initialGuess1, initialGuess2, initialGuess3, initialGuess4, tolerance, maxIterations); + return z => f(parameters.Item1, parameters.Item2, parameters.Item3, parameters.Item4, parameters.Item5, z); + } } }