From 3999c5ebc2c1faa70c996f5eb1742cf047e70e63 Mon Sep 17 00:00:00 2001 From: tibel Date: Thu, 10 Oct 2013 20:24:11 +0200 Subject: [PATCH 1/2] Fit: use generic classes and optimize Polynomial() matrix creation --- src/Numerics/Fit.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Numerics/Fit.cs b/src/Numerics/Fit.cs index f68006b4..92633274 100644 --- a/src/Numerics/Fit.cs +++ b/src/Numerics/Fit.cs @@ -30,7 +30,7 @@ using System; using System.Linq; -using MathNet.Numerics.LinearAlgebra.Double; +using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearRegression; namespace MathNet.Numerics @@ -67,8 +67,8 @@ namespace MathNet.Numerics /// public static double[] Polynomial(double[] x, double[] y, int order) { - var design = DenseMatrix.OfColumns(x.Length, order + 1, Enumerable.Range(0, order + 1).Select(j => DenseVector.Create(x.Length, i => Math.Pow(x[i], j)))); - return MultipleRegression.QR(design, new DenseVector(y)).ToArray(); + var design = Matrix.Build.DenseOfColumns(x.Length, order + 1, Enumerable.Range(0, order + 1).Select(j => x.Select(xi => Math.Pow(xi, j)))); + return MultipleRegression.QR(design, Vector.Build.Dense(y)).ToArray(); } /// @@ -87,8 +87,8 @@ namespace MathNet.Numerics /// public static double[] LinearCombination(double[] x, double[] y, params Func[] functions) { - var design = DenseMatrix.OfColumns(x.Length, functions.Length, functions.Select(f => DenseVector.Create(x.Length, i => f(x[i])))); - return MultipleRegression.QR(design, new DenseVector(y)).ToArray(); + var design = Matrix.Build.DenseOfColumns(x.Length, functions.Length, functions.Select(f => x.Select(xi => f(xi)))); + return MultipleRegression.QR(design, Vector.Build.Dense(y)).ToArray(); } /// @@ -107,7 +107,8 @@ namespace MathNet.Numerics /// public static double[] LinearMultiDim(double[][] x, double[] y, params Func[] functions) { - return MultipleRegression.QR(x.Select(xi => functions.Select(f => f(xi)).ToArray()).ToArray(), y); + var design = Matrix.Build.DenseOfRows(x.Select(xi => functions.Select(f => f(xi)))); + return MultipleRegression.QR(design, Vector.Build.Dense(y)).ToArray(); } /// @@ -126,7 +127,8 @@ namespace MathNet.Numerics /// public static double[] LinearGeneric(T[] x, double[] y, params Func[] functions) { - return MultipleRegression.QR(x.Select(xi => functions.Select(f => f(xi)).ToArray()).ToArray(), y); + var design = Matrix.Build.DenseOfRows(x.Select(xi => functions.Select(f => f(xi)))); + return MultipleRegression.QR(design, Vector.Build.Dense(y)).ToArray(); } /// From ee9d75417234849306bacc26a7e5aea1aac2ec35 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Sun, 20 Oct 2013 16:59:21 +0200 Subject: [PATCH 2/2] Fit: more direct and slightly faster implementation; add MultiDim --- src/Numerics/Fit.cs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Numerics/Fit.cs b/src/Numerics/Fit.cs index 92633274..48a08efc 100644 --- a/src/Numerics/Fit.cs +++ b/src/Numerics/Fit.cs @@ -61,13 +61,32 @@ namespace MathNet.Numerics return z => intercept + slope*z; } + /// + /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to a linear surface y : X -> p0*x0 + p1*x1 + ... + pk*xk, + /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. + /// + public static double[] MultiDim(double[][] x, double[] y) + { + return MultipleRegression.NormalEquations(x, y); + } + + /// + /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to a linear surface y : X -> p0*x0 + p1*x1 + ... + pk*xk, + /// returning a function y' for the best fitting combination. + /// + public static Func MultiDimFunc(double[][] x, double[] y) + { + var parameters = MultipleRegression.NormalEquations(x, y); + return z => Control.LinearAlgebraProvider.DotProduct(parameters, z); + } + /// /// Least-Squares fitting the points (x,y) to a k-order polynomial y : x -> p0 + p1*x + p2*x^2 + ... + pk*x^k, /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array, compatible with Evaluate.Polynomial. /// public static double[] Polynomial(double[] x, double[] y, int order) { - var design = Matrix.Build.DenseOfColumns(x.Length, order + 1, Enumerable.Range(0, order + 1).Select(j => x.Select(xi => Math.Pow(xi, j)))); + var design = Matrix.Build.Dense(x.Length, order + 1, (i, j) => Math.Pow(x[i], j)); return MultipleRegression.QR(design, Vector.Build.Dense(y)).ToArray(); } @@ -87,7 +106,7 @@ namespace MathNet.Numerics /// public static double[] LinearCombination(double[] x, double[] y, params Func[] functions) { - var design = Matrix.Build.DenseOfColumns(x.Length, functions.Length, functions.Select(f => x.Select(xi => f(xi)))); + var design = Matrix.Build.Dense(x.Length, functions.Length, (i, j) => functions[j](x[i])); return MultipleRegression.QR(design, Vector.Build.Dense(y)).ToArray(); } @@ -107,7 +126,7 @@ namespace MathNet.Numerics /// public static double[] LinearMultiDim(double[][] x, double[] y, params Func[] functions) { - var design = Matrix.Build.DenseOfRows(x.Select(xi => functions.Select(f => f(xi)))); + var design = Matrix.Build.Dense(x.Length, functions.Length, (i, j) => functions[j](x[i])); return MultipleRegression.QR(design, Vector.Build.Dense(y)).ToArray(); } @@ -127,7 +146,7 @@ namespace MathNet.Numerics /// public static double[] LinearGeneric(T[] x, double[] y, params Func[] functions) { - var design = Matrix.Build.DenseOfRows(x.Select(xi => functions.Select(f => f(xi)))); + var design = Matrix.Build.Dense(x.Length, functions.Length, (i, j) => functions[j](x[i])); return MultipleRegression.QR(design, Vector.Build.Dense(y)).ToArray(); }