From fabce7cb9f6145b10127786d369693770ff87695 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Fri, 26 Jul 2013 20:29:05 +0200 Subject: [PATCH] Fit: rework multidim/vector linear combination fitting --- src/Numerics/Fit.cs | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/Numerics/Fit.cs b/src/Numerics/Fit.cs index 3b3c34be..6b520886 100644 --- a/src/Numerics/Fit.cs +++ b/src/Numerics/Fit.cs @@ -143,12 +143,43 @@ namespace MathNet.Numerics /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to an arbitrary linear combination y : X -> p0*f0(x0) + p1*f1(x1) + ... + pk*fk(xk), /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. /// - public static double[] LinearCombinationVector(Vector[] x, double[] y, params Func[] functions) + public static double[] MultiDimensional(double[][] x, double[] y, params Func[] functions) { return DenseMatrix - .OfColumns(x.Length, functions.Length, functions.Select((f, k) => DenseVector.Create(x.Length, i => f(x[i].At(k))))) + .OfRows(x.Length, functions.Length, x.Select(xi => functions.Select((f, k) => f(xi[k])))) .QR(QRMethod.Thin).Solve(new DenseVector(y)) .ToArray(); } + + /// + /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to an arbitrary linear combination y : X -> p0*f0(x0) + p1*f1(x1) + ... + pk*fk(xk), + /// returning a function y' for the best fitting combination. + /// + public static Func MultiDimensionalFunc(double[][] x, double[] y, params Func[] functions) + { + var parameters = MultiDimensional(x, y, functions); + return z => functions.Select((f, i) => parameters[i]*f(z[i])).Sum(); + } + + /// + /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to an arbitrary linear combination y : X -> p0*f0(x0) + p1*f1(x1) + ... + pk*fk(xk), + /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. + /// + public static Vector Vector(Vector[] x, double[] y, Func, Vector> functions) + { + return DenseMatrix + .OfRowVectors(x.Select(functions).ToArray()) // PERF: Array.map instead of seq + .QR(QRMethod.Thin).Solve(new DenseVector(y)); + } + + /// + /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to an arbitrary linear combination y : X -> p0*f0(x0) + p1*f1(x1) + ... + pk*fk(xk), + /// returning a function y' for the best fitting combination. + /// + public static Func, double> VectorFunc(Vector[] x, double[] y, Func, Vector> functions) + { + var parameters = Vector(x, y, functions); + return z => functions(z).Select((yi, i) => parameters[i]*yi).Sum(); + } } }