diff --git a/src/FSharp/FSharp.fsproj b/src/FSharp/FSharp.fsproj index 24b296ff..8b141462 100644 --- a/src/FSharp/FSharp.fsproj +++ b/src/FSharp/FSharp.fsproj @@ -71,7 +71,7 @@ - + diff --git a/src/FSharp/LeastSquares.fs b/src/FSharp/Fit.fs similarity index 84% rename from src/FSharp/LeastSquares.fs rename to src/FSharp/Fit.fs index 28cea93d..0e9e3f8b 100644 --- a/src/FSharp/LeastSquares.fs +++ b/src/FSharp/Fit.fs @@ -1,4 +1,4 @@ -// +// // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics @@ -39,11 +39,11 @@ module Fit = let private tofs (f:Func<_,_>) = fun a -> f.Invoke(a) - let line x y = let p = LeastSquares.FitToLine(x,y) in (p.[0],p.[1]) - let linef x y = LeastSquares.FitToLineFunc(x,y) |> tofs + let line x y = let p = Fit.Line(x,y) in (p.[0],p.[1]) + let lineF x y = Fit.LineFunc(x,y) |> tofs - let polynomial order x y = LeastSquares.FitToPolynomial(x,y,order) - let polynomialf order x y = LeastSquares.FitToPolynomialFunc(x,y,order) |> tofs + let polynomial order x y = Fit.Polynomial(x,y,order) + let polynomialF order x y = Fit.PolynomialFunc(x,y,order) |> tofs let linear functions (x:float[]) (y:float[]) = functions @@ -51,6 +51,6 @@ module Fit = |> DenseMatrix.ofColumnsList (Array.length x) (List.length functions) |> fun m -> m.QR(QRMethod.Thin).Solve(DenseVector(y)).ToArray() |> List.ofArray - let linearf functions x y = + let linearF functions x y = let parts = linear functions x y |> List.zip functions in fun z -> parts |> List.fold (fun s (f,p) -> s+p*(f z)) 0.0 diff --git a/src/FSharpPortable/FSharpPortable.fsproj b/src/FSharpPortable/FSharpPortable.fsproj index af6ac149..763334b2 100644 --- a/src/FSharpPortable/FSharpPortable.fsproj +++ b/src/FSharpPortable/FSharpPortable.fsproj @@ -77,8 +77,8 @@ BigRational.fs - - LeastSquares.fs + + Fit.fs RandomVariable.fs diff --git a/src/FSharpUnitTests/CurveFittingTests.fs b/src/FSharpUnitTests/CurveFittingTests.fs index 2fee6582..b9eae831 100644 --- a/src/FSharpUnitTests/CurveFittingTests.fs +++ b/src/FSharpUnitTests/CurveFittingTests.fs @@ -7,8 +7,6 @@ open FsUnit module CurveFittingTests = - let tofs (f:Func<_,_>) = fun a -> f.Invoke(a) - [] let ``When fitting to an exact line should return exact parameters``() = let f z = 4.0 - 1.5*z @@ -20,7 +18,7 @@ module CurveFittingTests = a |> should (equalWithin 1.0e-12) 4.0 b |> should (equalWithin 1.0e-12) -1.5 - let fres = LeastSquares.FitToLineFunc(x,y) |> tofs + let fres = Fit.lineF x y in x |> Array.iter (fun x -> fres x |> should (equalWithin 1.0e-12) (f x)) [] @@ -36,5 +34,5 @@ module CurveFittingTests = (x,y) ||> Fit.linear [(fun _ -> 1.0); (Math.Sin); (Math.Cos) ] |> should (equalWithin 1.0e-4) [ -0.287476; 4.02159; -1.46962 ] - let fres = LeastSquares.FitToLinearCombinationFunc(x, y, (fun z -> 1.0), (fun z -> Math.Sin(z)), (fun z -> Math.Cos(z))) |> tofs + let fres = Fit.linearF [(fun z -> 1.0); (fun z -> Math.Sin(z)); (fun z -> Math.Cos(z))] x y in x |> Array.iter (fun x -> fres x |> should (equalWithin 1.0e-4) (4.02159*Math.Sin(x) - 1.46962*Math.Cos(x) - 0.287476)) diff --git a/src/Numerics/LeastSquares.cs b/src/Numerics/Fit.cs similarity index 82% rename from src/Numerics/LeastSquares.cs rename to src/Numerics/Fit.cs index 5e7bdf56..86b3cf69 100644 --- a/src/Numerics/LeastSquares.cs +++ b/src/Numerics/Fit.cs @@ -1,4 +1,4 @@ -// +// // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics @@ -35,13 +35,16 @@ using MathNet.Numerics.LinearAlgebra.Generic.Factorization; namespace MathNet.Numerics { - public static class LeastSquares + /// + /// Least-Squares Curve Fitting Routines + /// + public static class Fit { /// /// Least-Squares fitting the points (x,y) to a line y : x -> a+b*x, /// returning its best fitting parameters as [a, b] array. /// - public static double[] FitToLine(double[] x, double[] y) + public static double[] Line(double[] x, double[] y) { // TODO: we should use a direct algorithm instead (PERF) return DenseMatrix @@ -54,9 +57,9 @@ namespace MathNet.Numerics /// Least-Squares fitting the points (x,y) to a line y : x -> a+b*x, /// returning a function y' for the best fitting line. /// - public static Func FitToLineFunc(double[] x, double[] y) + public static Func LineFunc(double[] x, double[] y) { - var parameters = FitToLine(x, y); + var parameters = Line(x, y); double a = parameters[0], b = parameters[1]; return z => a + b*z; } @@ -65,7 +68,7 @@ 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 its best fitting parameters as [p0, p1, p2, ..., pk] array, compatible with Evaluate.Polynomial. /// - public static double[] FitToPolynomial(double[] x, double[] y, int order) + public static double[] Polynomial(double[] x, double[] y, int order) { // TODO: consider to use a specific algorithm instead return DenseMatrix @@ -78,9 +81,9 @@ 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. /// - public static Func FitToPolynomialFunc(double[] x, double[] y, int order) + public static Func PolynomialFunc(double[] x, double[] y, int order) { - var parameters = FitToPolynomial(x, y, order); + var parameters = Polynomial(x, y, order); return z => Evaluate.Polynomial(z, parameters); } @@ -88,7 +91,7 @@ namespace MathNet.Numerics /// 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[] FitToLinearCombination(double[] x, double[] y, params Func[] functions) + public static double[] LinearCombination(double[] x, double[] y, params Func[] functions) { // TODO: consider to use a specific algorithm instead return DenseMatrix @@ -101,9 +104,9 @@ namespace MathNet.Numerics /// LLeast-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 FitToLinearCombinationFunc(double[] x, double[] y, params Func[] functions) + public static Func LinearCombinationFunc(double[] x, double[] y, params Func[] functions) { - var parameters = FitToLinearCombination(x, y, functions); + var parameters = LinearCombination(x, y, functions); return z => functions.Zip(parameters, (f, p) => p*f(z)).Sum(); } } diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index d4ecee38..5c66530f 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -105,7 +105,7 @@ - + diff --git a/src/Portable/Portable.csproj b/src/Portable/Portable.csproj index 4cf36a4f..1249d03f 100644 --- a/src/Portable/Portable.csproj +++ b/src/Portable/Portable.csproj @@ -198,6 +198,9 @@ Financial\AbsoluteRiskMeasures.cs + + Fit.cs + GlobalizationHelper.cs @@ -282,9 +285,6 @@ IPrecisionSupport.cs - - LeastSquares.cs - LinearAlgebra\Complex32\DenseMatrix.cs diff --git a/src/UnitTests/LeastSquaresTests.cs b/src/UnitTests/FitTests.cs similarity index 86% rename from src/UnitTests/LeastSquaresTests.cs rename to src/UnitTests/FitTests.cs index 176cfd83..38e301d0 100644 --- a/src/UnitTests/LeastSquaresTests.cs +++ b/src/UnitTests/FitTests.cs @@ -1,4 +1,4 @@ -// +// // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics @@ -36,7 +36,7 @@ using NUnit.Framework; namespace MathNet.Numerics.UnitTests { [TestFixture] - public class LeastSquaresTests + public class FitTests { [Test] public void FitsToExactLineWhenPointsAreOnLine() @@ -44,12 +44,12 @@ namespace MathNet.Numerics.UnitTests var x = new[] {30.0, 40.0, 50.0, 12.0, -3.4, 100.5}; var y = x.Select(z => 4.0 - 1.5*z).ToArray(); - var resp = LeastSquares.FitToLine(x, y); + var resp = Fit.Line(x, y); Assert.AreEqual(2, resp.Length); Assert.AreEqual(4.0, resp[0], 1e-12); Assert.AreEqual(-1.5, resp[1], 1e-12); - var resf = LeastSquares.FitToLineFunc(x, y); + var resf = Fit.LineFunc(x, y); foreach (var z in Enumerable.Range(-3, 10)) { Assert.AreEqual(4.0 - 1.5*z, resf(z), 1e-12); @@ -65,12 +65,12 @@ namespace MathNet.Numerics.UnitTests var x = Enumerable.Range(1, 6).Select(Convert.ToDouble).ToArray(); var y = new[] {4.986, 2.347, 2.061, -2.995, -2.352, -5.782}; - var resp = LeastSquares.FitToLine(x, y); + var resp = Fit.Line(x, y); Assert.AreEqual(2, resp.Length); Assert.AreEqual(7.01013, resp[0], 1e-4); Assert.AreEqual(-2.08551, resp[1], 1e-4); - var resf = LeastSquares.FitToLineFunc(x, y); + var resf = Fit.LineFunc(x, y); foreach (var z in Enumerable.Range(-3, 10)) { Assert.AreEqual(7.01013 - 2.08551 * z, resf(z), 1e-4); @@ -86,7 +86,7 @@ namespace MathNet.Numerics.UnitTests var x = Enumerable.Range(1, 6).Select(Convert.ToDouble).ToArray(); var y = new[] { 4.986, 2.347, 2.061, -2.995, -2.352, -5.782 }; - var resp = LeastSquares.FitToPolynomial(x, y, 0); + var resp = Fit.Polynomial(x, y, 0); Assert.AreEqual(1, resp.Length); Assert.AreEqual(-0.289167, resp[0], 1e-4); Assert.AreEqual(y.Mean(), resp[0], 1e-4); @@ -101,12 +101,12 @@ namespace MathNet.Numerics.UnitTests var x = Enumerable.Range(1, 6).Select(Convert.ToDouble).ToArray(); var y = new[] { 4.986, 2.347, 2.061, -2.995, -2.352, -5.782 }; - var resp = LeastSquares.FitToPolynomial(x, y, 1); + var resp = Fit.Polynomial(x, y, 1); Assert.AreEqual(2, resp.Length); Assert.AreEqual(7.01013, resp[0], 1e-4); Assert.AreEqual(-2.08551, resp[1], 1e-4); - var resf = LeastSquares.FitToPolynomialFunc(x, y, 1); + var resf = Fit.PolynomialFunc(x, y, 1); foreach (var z in Enumerable.Range(-3, 10)) { Assert.AreEqual(7.01013 - 2.08551 * z, resf(z), 1e-4); @@ -122,13 +122,13 @@ namespace MathNet.Numerics.UnitTests var x = Enumerable.Range(1, 6).Select(Convert.ToDouble).ToArray(); var y = new[] { 4.986, 2.347, 2.061, -2.995, -2.352, -5.782 }; - var resp = LeastSquares.FitToPolynomial(x, y, 2); + var resp = Fit.Polynomial(x, y, 2); Assert.AreEqual(3, resp.Length); Assert.AreEqual(6.9703, resp[0], 1e-4); Assert.AreEqual(-2.05564, resp[1], 1e-4); Assert.AreEqual(-0.00426786, resp[2], 1e-6); - var resf = LeastSquares.FitToPolynomialFunc(x, y, 2); + var resf = Fit.PolynomialFunc(x, y, 2); foreach (var z in Enumerable.Range(-3, 10)) { Assert.AreEqual(Evaluate.Polynomial(z, resp), resf(z), 1e-4); @@ -144,13 +144,13 @@ namespace MathNet.Numerics.UnitTests var x = Enumerable.Range(1, 6).Select(Convert.ToDouble).ToArray(); var y = new[] { 4.986, 2.347, 2.061, -2.995, -2.352, -5.782 }; - var resp = LeastSquares.FitToLinearCombination(x, y, z => 1.0, Math.Sin, Math.Cos); + var resp = Fit.LinearCombination(x, y, z => 1.0, Math.Sin, Math.Cos); Assert.AreEqual(3, resp.Length); Assert.AreEqual(-0.287476, resp[0], 1e-4); Assert.AreEqual(4.02159, resp[1], 1e-4); Assert.AreEqual(-1.46962, resp[2], 1e-4); - var resf = LeastSquares.FitToLinearCombinationFunc(x, y, z => 1.0, Math.Sin, Math.Cos); + var resf = Fit.LinearCombinationFunc(x, y, z => 1.0, Math.Sin, Math.Cos); foreach (var z in Enumerable.Range(-3, 10)) { Assert.AreEqual(4.02159*Math.Sin(z) - 1.46962*Math.Cos(z) - 0.287476, resf(z), 1e-4); diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj index d13c9564..bbe923c8 100644 --- a/src/UnitTests/UnitTests.csproj +++ b/src/UnitTests/UnitTests.csproj @@ -144,7 +144,7 @@ - +