diff --git a/src/Numerics/Fit.cs b/src/Numerics/Fit.cs
index 2a829c5e..9960e87a 100644
--- a/src/Numerics/Fit.cs
+++ b/src/Numerics/Fit.cs
@@ -3,9 +3,9 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
-//
-// Copyright (c) 2009-2013 Math.NET
-//
+//
+// Copyright (c) 2009-2015 Math.NET
+//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
@@ -14,10 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
-//
+//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
-//
+//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -94,6 +94,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.
+ /// A polynomial with order/degree k has (k+1) coefficients and thus requires at least (k+1) samples.
///
public static double[] Polynomial(double[] x, double[] y, int order, DirectRegressionMethod method = DirectRegressionMethod.QR)
{
@@ -104,6 +105,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 a function y' for the best fitting polynomial.
+ /// A polynomial with order/degree k has (k+1) coefficients and thus requires at least (k+1) samples.
///
public static Func PolynomialFunc(double[] x, double[] y, int order, DirectRegressionMethod method = DirectRegressionMethod.QR)
{
@@ -114,6 +116,7 @@ namespace MathNet.Numerics
///
/// Weighted Least-Squares fitting the points (x,y) and weights w 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.
+ /// A polynomial with order/degree k has (k+1) coefficients and thus requires at least (k+1) samples.
///
public static double[] PolynomialWeighted(double[] x, double[] y, double[] w, int order)
{
diff --git a/src/Numerics/LinearRegression/MultipleRegression.cs b/src/Numerics/LinearRegression/MultipleRegression.cs
index 42e1a705..d925c65e 100644
--- a/src/Numerics/LinearRegression/MultipleRegression.cs
+++ b/src/Numerics/LinearRegression/MultipleRegression.cs
@@ -3,9 +3,9 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
-//
-// Copyright (c) 2009-2014 Math.NET
-//
+//
+// Copyright (c) 2009-2015 Math.NET
+//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
@@ -14,10 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
-//
+//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
-//
+//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -31,6 +31,7 @@
using System;
using System.Collections.Generic;
using MathNet.Numerics.LinearAlgebra;
+using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearRegression
{
@@ -135,6 +136,16 @@ namespace MathNet.Numerics.LinearRegression
/// Best fitting vector for model parameters β
public static Vector NormalEquations(Matrix x, Vector y) where T : struct, IEquatable, IFormattable
{
+ if (x.RowCount != y.Count)
+ {
+ throw new ArgumentException(string.Format(Resources.SampleVectorsSameLength, x.RowCount, y.Count));
+ }
+
+ if (x.ColumnCount > y.Count)
+ {
+ throw new ArgumentException(string.Format(Resources.RegressionNotEnoughSamples, x.ColumnCount, y.Count));
+ }
+
return x.TransposeThisAndMultiply(x).Cholesky().Solve(x.TransposeThisAndMultiply(y));
}
@@ -147,6 +158,16 @@ namespace MathNet.Numerics.LinearRegression
/// Best fitting vector for model parameters β
public static Matrix NormalEquations(Matrix x, Matrix y) where T : struct, IEquatable, IFormattable
{
+ if (x.RowCount != y.RowCount)
+ {
+ throw new ArgumentException(string.Format(Resources.SampleVectorsSameLength, x.RowCount, y.RowCount));
+ }
+
+ if (x.ColumnCount > y.RowCount)
+ {
+ throw new ArgumentException(string.Format(Resources.RegressionNotEnoughSamples, x.ColumnCount, y.RowCount));
+ }
+
return x.TransposeThisAndMultiply(x).Cholesky().Solve(x.TransposeThisAndMultiply(y));
}
@@ -166,6 +187,16 @@ namespace MathNet.Numerics.LinearRegression
predictor = predictor.InsertColumn(0, Vector.Build.Dense(predictor.RowCount, Vector.One));
}
+ if (predictor.RowCount != y.Length)
+ {
+ throw new ArgumentException(string.Format(Resources.SampleVectorsSameLength, predictor.RowCount, y.Length));
+ }
+
+ if (predictor.ColumnCount > y.Length)
+ {
+ throw new ArgumentException(string.Format(Resources.RegressionNotEnoughSamples, predictor.ColumnCount, y.Length));
+ }
+
var response = Vector.Build.Dense(y);
return predictor.TransposeThisAndMultiply(predictor).Cholesky().Solve(predictor.TransposeThisAndMultiply(response)).ToArray();
}
@@ -192,6 +223,16 @@ namespace MathNet.Numerics.LinearRegression
/// Best fitting vector for model parameters β
public static Vector QR(Matrix x, Vector y) where T : struct, IEquatable, IFormattable
{
+ if (x.RowCount != y.Count)
+ {
+ throw new ArgumentException(string.Format(Resources.SampleVectorsSameLength, x.RowCount, y.Count));
+ }
+
+ if (x.ColumnCount > y.Count)
+ {
+ throw new ArgumentException(string.Format(Resources.RegressionNotEnoughSamples, x.ColumnCount, y.Count));
+ }
+
return x.QR().Solve(y);
}
@@ -204,6 +245,16 @@ namespace MathNet.Numerics.LinearRegression
/// Best fitting vector for model parameters β
public static Matrix QR(Matrix x, Matrix y) where T : struct, IEquatable, IFormattable
{
+ if (x.RowCount != y.RowCount)
+ {
+ throw new ArgumentException(string.Format(Resources.SampleVectorsSameLength, x.RowCount, y.RowCount));
+ }
+
+ if (x.ColumnCount > y.RowCount)
+ {
+ throw new ArgumentException(string.Format(Resources.RegressionNotEnoughSamples, x.ColumnCount, y.RowCount));
+ }
+
return x.QR().Solve(y);
}
@@ -223,6 +274,16 @@ namespace MathNet.Numerics.LinearRegression
predictor = predictor.InsertColumn(0, Vector.Build.Dense(predictor.RowCount, Vector.One));
}
+ if (predictor.RowCount != y.Length)
+ {
+ throw new ArgumentException(string.Format(Resources.SampleVectorsSameLength, predictor.RowCount, y.Length));
+ }
+
+ if (predictor.ColumnCount > y.Length)
+ {
+ throw new ArgumentException(string.Format(Resources.RegressionNotEnoughSamples, predictor.ColumnCount, y.Length));
+ }
+
return predictor.QR().Solve(Vector.Build.Dense(y)).ToArray();
}
@@ -248,6 +309,16 @@ namespace MathNet.Numerics.LinearRegression
/// Best fitting vector for model parameters β
public static Vector Svd(Matrix x, Vector y) where T : struct, IEquatable, IFormattable
{
+ if (x.RowCount != y.Count)
+ {
+ throw new ArgumentException(string.Format(Resources.SampleVectorsSameLength, x.RowCount, y.Count));
+ }
+
+ if (x.ColumnCount > y.Count)
+ {
+ throw new ArgumentException(string.Format(Resources.RegressionNotEnoughSamples, x.ColumnCount, y.Count));
+ }
+
return x.Svd().Solve(y);
}
@@ -260,6 +331,16 @@ namespace MathNet.Numerics.LinearRegression
/// Best fitting vector for model parameters β
public static Matrix Svd(Matrix x, Matrix y) where T : struct, IEquatable, IFormattable
{
+ if (x.RowCount != y.RowCount)
+ {
+ throw new ArgumentException(string.Format(Resources.SampleVectorsSameLength, x.RowCount, y.RowCount));
+ }
+
+ if (x.ColumnCount > y.RowCount)
+ {
+ throw new ArgumentException(string.Format(Resources.RegressionNotEnoughSamples, x.ColumnCount, y.RowCount));
+ }
+
return x.Svd().Solve(y);
}
@@ -279,6 +360,16 @@ namespace MathNet.Numerics.LinearRegression
predictor = predictor.InsertColumn(0, Vector.Build.Dense(predictor.RowCount, Vector.One));
}
+ if (predictor.RowCount != y.Length)
+ {
+ throw new ArgumentException(string.Format(Resources.SampleVectorsSameLength, predictor.RowCount, y.Length));
+ }
+
+ if (predictor.ColumnCount > y.Length)
+ {
+ throw new ArgumentException(string.Format(Resources.RegressionNotEnoughSamples, predictor.ColumnCount, y.Length));
+ }
+
return predictor.Svd().Solve(Vector.Build.Dense(y)).ToArray();
}
diff --git a/src/Numerics/LinearRegression/SimpleRegression.cs b/src/Numerics/LinearRegression/SimpleRegression.cs
index 1b2cbc1a..41332cdd 100644
--- a/src/Numerics/LinearRegression/SimpleRegression.cs
+++ b/src/Numerics/LinearRegression/SimpleRegression.cs
@@ -3,9 +3,9 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
-//
+//
// Copyright (c) 2009-2013 Math.NET
-//
+//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
@@ -14,10 +14,10 @@
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
-//
+//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
-//
+//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -47,12 +47,12 @@ namespace MathNet.Numerics.LinearRegression
{
if (x.Length != y.Length)
{
- throw new ArgumentException(Resources.ArgumentVectorsSameLength);
+ throw new ArgumentException(string.Format(Resources.SampleVectorsSameLength, x.Length, y.Length));
}
if (x.Length <= 1)
{
- throw new ArgumentException(string.Format(Resources.ArrayTooSmall, 2));
+ throw new ArgumentException(string.Format(Resources.RegressionNotEnoughSamples, 2, x.Length));
}
// First Pass: Mean (Less robust but faster than ArrayStatistics.Mean)
diff --git a/src/Numerics/Properties/Resources.Designer.cs b/src/Numerics/Properties/Resources.Designer.cs
index a8569c78..b4650370 100644
--- a/src/Numerics/Properties/Resources.Designer.cs
+++ b/src/Numerics/Properties/Resources.Designer.cs
@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.34209
+// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -12,8 +12,8 @@ using System.Reflection;
namespace MathNet.Numerics.Properties {
using System;
-
-
+
+
///
/// A strongly-typed resource class, for looking up localized strings, etc.
///
@@ -25,15 +25,15 @@ namespace MathNet.Numerics.Properties {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resources {
-
+
private static global::System.Resources.ResourceManager resourceMan;
-
+
private static global::System.Globalization.CultureInfo resourceCulture;
-
+
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
-
+
///
/// Returns the cached ResourceManager instance used by this class.
///
@@ -56,7 +56,7 @@ namespace MathNet.Numerics.Properties {
return resourceMan;
}
}
-
+
///
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
@@ -394,7 +394,7 @@ namespace MathNet.Numerics.Properties {
return ResourceManager.GetString("ArgumentOutOfRangeSmaller", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to {0} must be smaller than or equal to {1}..
///
@@ -403,7 +403,7 @@ namespace MathNet.Numerics.Properties {
return ResourceManager.GetString("ArgumentOutOfRangeSmallerEqual", resourceCulture);
}
}
-
+
///
/// Looks up a localized string similar to The chosen parameter set is invalid (probably some value is out of range)..
///
@@ -864,6 +864,15 @@ namespace MathNet.Numerics.Properties {
}
}
+ ///
+ /// Looks up a localized string similar to A regression of the requested order requires at least {0} samples. Only {1} samples have been provided. .
+ ///
+ public static string RegressionNotEnoughSamples {
+ get {
+ return ResourceManager.GetString("RegressionNotEnoughSamples", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to The algorithm has failed, exceeded the number of iterations allowed or there is no root within the provided bounds..
///
@@ -909,6 +918,15 @@ namespace MathNet.Numerics.Properties {
}
}
+ ///
+ /// Looks up a localized string similar to All sample vectors must have the same length. However, vectors with disagreeing length {0} and {1} have been provided. A sample with index i is given by the value at index i of each provided vector..
+ ///
+ public static string SampleVectorsSameLength {
+ get {
+ return ResourceManager.GetString("SampleVectorsSameLength", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to U is singular, and the inversion could not be completed..
///
diff --git a/src/Numerics/Properties/Resources.resx b/src/Numerics/Properties/Resources.resx
index d87f9a72..e3c53791 100644
--- a/src/Numerics/Properties/Resources.resx
+++ b/src/Numerics/Properties/Resources.resx
@@ -436,4 +436,10 @@
U is singular, and the inversion could not be completed. The {0}-th diagonal element of the factor U is zero.
+
+ A regression of the requested order requires at least {0} samples. Only {1} samples have been provided.
+
+
+ All sample vectors must have the same length. However, vectors with disagreeing length {0} and {1} have been provided. A sample with index i is given by the value at index i of each provided vector.
+
\ No newline at end of file