From 33e6b82ef40e51d93528f0d21a7fa32cacd78745 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Fri, 20 Jun 2014 10:24:43 +0200 Subject: [PATCH] Regression: expose direct method option in Fit facade class --- src/Numerics/Fit.cs | 101 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 20 deletions(-) diff --git a/src/Numerics/Fit.cs b/src/Numerics/Fit.cs index f91695d2..2a829c5e 100644 --- a/src/Numerics/Fit.cs +++ b/src/Numerics/Fit.cs @@ -66,9 +66,20 @@ namespace MathNet.Numerics /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. /// If an intercept is added, its coefficient will be prepended to the resulting parameters. /// - public static double[] MultiDim(double[][] x, double[] y, bool intercept = false) + public static double[] MultiDim(double[][] x, double[] y, bool intercept = false, DirectRegressionMethod method = DirectRegressionMethod.NormalEquations) { - return MultipleRegression.NormalEquations(x, y, intercept); + return MultipleRegression.DirectMethod(x, y, intercept, method); + } + + /// + /// 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. + /// If an intercept is added, its coefficient will be prepended to the resulting parameters. + /// + public static Func MultiDimFunc(double[][] x, double[] y, bool intercept = false, DirectRegressionMethod method = DirectRegressionMethod.NormalEquations) + { + var parameters = MultipleRegression.DirectMethod(x, y, intercept, method); + return z => Control.LinearAlgebraProvider.DotProduct(parameters, z); } /// @@ -81,23 +92,23 @@ namespace MathNet.Numerics } /// - /// 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. + /// 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 Func MultiDimFunc(double[][] x, double[] y) + public static double[] Polynomial(double[] x, double[] y, int order, DirectRegressionMethod method = DirectRegressionMethod.QR) { - var parameters = MultipleRegression.NormalEquations(x, y); - return z => Control.LinearAlgebraProvider.DotProduct(parameters, z); + var design = Matrix.Build.Dense(x.Length, order + 1, (i, j) => Math.Pow(x[i], j)); + return MultipleRegression.DirectMethod(design, Vector.Build.Dense(y), method).ToArray(); } /// /// 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. + /// returning a function y' for the best fitting polynomial. /// - public static double[] Polynomial(double[] x, double[] y, int order) + public static Func PolynomialFunc(double[] x, double[] y, int order, DirectRegressionMethod method = DirectRegressionMethod.QR) { - 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(); + var parameters = Polynomial(x, y, order, method); + return z => Evaluate.Polynomial(z, parameters); } /// @@ -111,32 +122,42 @@ namespace MathNet.Numerics } /// - /// Least-Squares fitting the points (x,y) to a k-order polynomial y : x -> p0 + p1*x + p2*x^2 + ... + pk*x^k, - /// returning a function y' for the best fitting polynomial. + /// Least-Squares fitting the points (x,y) to an arbitrary linear combination y : x -> p0*f0(x) + p1*f1(x) + ... + pk*fk(x), + /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. /// - public static Func PolynomialFunc(double[] x, double[] y, int order) + public static double[] LinearCombination(double[] x, double[] y, params Func[] functions) { - var parameters = Polynomial(x, y, order); - return z => Evaluate.Polynomial(z, parameters); + var design = Matrix.Build.Dense(x.Length, functions.Length, (i, j) => functions[j](x[i])); + return MultipleRegression.QR(design, Vector.Build.Dense(y)).ToArray(); + } + + /// + /// Least-Squares fitting the points (x,y) to an arbitrary linear combination y : x -> p0*f0(x) + p1*f1(x) + ... + pk*fk(x), + /// returning a function y' for the best fitting combination. + /// + public static Func LinearCombinationFunc(double[] x, double[] y, params Func[] functions) + { + var parameters = LinearCombination(x, y, functions); + return z => functions.Zip(parameters, (f, p) => p*f(z)).Sum(); } /// /// Least-Squares fitting the points (x,y) to an arbitrary linear combination y : x -> p0*f0(x) + p1*f1(x) + ... + pk*fk(x), /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. /// - public static double[] LinearCombination(double[] x, double[] y, params Func[] functions) + public static double[] LinearCombination(double[] x, double[] y, DirectRegressionMethod method, params Func[] functions) { var design = Matrix.Build.Dense(x.Length, functions.Length, (i, j) => functions[j](x[i])); - return MultipleRegression.QR(design, Vector.Build.Dense(y)).ToArray(); + return MultipleRegression.DirectMethod(design, Vector.Build.Dense(y), method).ToArray(); } /// /// Least-Squares fitting the points (x,y) to an arbitrary linear combination y : x -> p0*f0(x) + p1*f1(x) + ... + pk*fk(x), /// returning a function y' for the best fitting combination. /// - public static Func LinearCombinationFunc(double[] x, double[] y, params Func[] functions) + public static Func LinearCombinationFunc(double[] x, double[] y, DirectRegressionMethod method, params Func[] functions) { - var parameters = LinearCombination(x, y, functions); + var parameters = LinearCombination(x, y, method, functions); return z => functions.Zip(parameters, (f, p) => p*f(z)).Sum(); } @@ -160,6 +181,26 @@ namespace MathNet.Numerics return z => functions.Zip(parameters, (f, p) => p * f(z)).Sum(); } + /// + /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to an arbitrary linear combination y : X -> p0*f0(x) + p1*f1(x) + ... + pk*fk(x), + /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. + /// + public static double[] LinearMultiDim(double[][] x, double[] y, DirectRegressionMethod method, params Func[] functions) + { + var design = Matrix.Build.Dense(x.Length, functions.Length, (i, j) => functions[j](x[i])); + return MultipleRegression.DirectMethod(design, Vector.Build.Dense(y), method).ToArray(); + } + + /// + /// Least-Squares fitting the points (X,y) = ((x0,x1,..,xk),y) to an arbitrary linear combination y : X -> p0*f0(x) + p1*f1(x) + ... + pk*fk(x), + /// returning a function y' for the best fitting combination. + /// + public static Func LinearMultiDimFunc(double[][] x, double[] y, DirectRegressionMethod method, params Func[] functions) + { + var parameters = LinearMultiDim(x, y, method, functions); + return z => functions.Zip(parameters, (f, p) => p * f(z)).Sum(); + } + /// /// Least-Squares fitting the points (T,y) = (T,y) to an arbitrary linear combination y : X -> p0*f0(T) + p1*f1(T) + ... + pk*fk(T), /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. @@ -179,5 +220,25 @@ namespace MathNet.Numerics var parameters = LinearGeneric(x, y, functions); return z => functions.Zip(parameters, (f, p) => p * f(z)).Sum(); } + + /// + /// Least-Squares fitting the points (T,y) = (T,y) to an arbitrary linear combination y : X -> p0*f0(T) + p1*f1(T) + ... + pk*fk(T), + /// returning its best fitting parameters as [p0, p1, p2, ..., pk] array. + /// + public static double[] LinearGeneric(T[] x, double[] y, DirectRegressionMethod method, params Func[] functions) + { + var design = Matrix.Build.Dense(x.Length, functions.Length, (i, j) => functions[j](x[i])); + return MultipleRegression.DirectMethod(design, Vector.Build.Dense(y), method).ToArray(); + } + + /// + /// Least-Squares fitting the points (T,y) = (T,y) to an arbitrary linear combination y : X -> p0*f0(T) + p1*f1(T) + ... + pk*fk(T), + /// returning a function y' for the best fitting combination. + /// + public static Func LinearGenericFunc(T[] x, double[] y, DirectRegressionMethod method, params Func[] functions) + { + var parameters = LinearGeneric(x, y, method, functions); + return z => functions.Zip(parameters, (f, p) => p * f(z)).Sum(); + } } }