Browse Source

Polynomial: more systematic arithmetics

ridge-regression
Christoph Ruegg 8 years ago
parent
commit
610921f6c2
  1. 303
      src/Numerics/Polynomial.cs

303
src/Numerics/Polynomial.cs

@ -10,7 +10,7 @@ using MathNet.Numerics.LinearAlgebra.Factorization;
namespace MathNet.Numerics
{
/// <summary>
/// A single-variable polynomial with real-valued coefficients.
/// A single-variable polynomial with real-valued coefficients and non-negative exponents.
/// </summary>
public class Polynomial
{
@ -136,8 +136,8 @@ namespace MathNet.Numerics
/// </summary>
public static Polynomial Fit(double[] x, double[] y, int order, DirectRegressionMethod method = DirectRegressionMethod.QR)
{
var pArr = Numerics.Fit.Polynomial(x, y, order, method);
return new Polynomial(pArr);
var coefficients = Numerics.Fit.Polynomial(x, y, order, method);
return new Polynomial(coefficients);
}
/// <summary>
@ -149,19 +149,31 @@ namespace MathNet.Numerics
return Numerics.Evaluate.Polynomial(z, Coefficients);
}
/// <summary>
/// Evaluate a polynomial at point x.
/// </summary>
/// <param name="z">The location where to evaluate the polynomial at.</param>
public Complex Evaluate(Complex z)
{
return Numerics.Evaluate.Polynomial(z, Coefficients);
}
/// <summary>
/// Evaluate a polynomial at points z.
/// </summary>
/// <param name="z">The locations where to evaluate the polynomial at.</param>
public IEnumerable<double> Evaluate(IEnumerable<double> z)
{
var result = new List<double>();
foreach (var item in z)
{
result.Add(Evaluate(item));
}
return z.Select(Evaluate);
}
return result;
/// <summary>
/// Evaluate a polynomial at points z.
/// </summary>
/// <param name="z">The locations where to evaluate the polynomial at.</param>
public IEnumerable<Complex> Evaluate(IEnumerable<Complex> z)
{
return z.Select(Evaluate);
}
public Polynomial Differentiate()
@ -199,11 +211,87 @@ namespace MathNet.Numerics
return p;
}
/// <summary>
/// Addition of two Polynomials (piecewise)
/// </summary>
/// <param name="a">Left polynomial</param>
/// <param name="b">Right polynomial</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial operator +(Polynomial a, Polynomial b)
{
return Add(a, b);
}
/// <summary>
/// adds a scalar to a polynomial.
/// </summary>
/// <param name="a">Polynomial</param>
/// <param name="k">Scalar value</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial operator +(Polynomial a, double k)
{
return Add(a, k);
}
/// <summary>
/// adds a scalar to a polynomial.
/// </summary>
/// <param name="k">Scalar value</param>
/// <param name="a">Polynomial</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial operator +(double k, Polynomial a)
{
return Add(a, k);
}
/// <summary>
/// Subtraction of two polynomial.
/// </summary>
/// <param name="a">Left polynomial</param>
/// <param name="b">Right polynomial</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial operator -(Polynomial a, Polynomial b)
{
return Subtract(a, b);
}
/// <summary>
/// Subtracts a scalar from a polynomial.
/// </summary>
/// <param name="a">Polynomial</param>
/// <param name="k">Scalar value</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial operator -(Polynomial a, double k)
{
return Subtract(a, k);
}
/// <summary>
/// Subtracts a polynomial from a scalar.
/// </summary>
/// <param name="k">Scalar value</param>
/// <param name="a">Polynomial</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial operator -(double k, Polynomial a)
{
return Subtract(k, a);
}
/// <summary>
/// Negates a polynomial.
/// </summary>
/// <param name="a">Polynomial</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial operator -(Polynomial a)
{
return Negate(a);
}
/// <summary>
/// multiplies a Polynomial by a Polynomial using convolution [ASINCO.libs.subfun.conv(a.Coeffs, b.Coeffs)]
/// </summary>
/// <param name="a">left Polynomial</param>
/// <param name="b">right Polynomial</param>
/// <param name="a">Left polynomial</param>
/// <param name="b">Right polynomial</param>
/// <returns>resulting Polynomial</returns>
public static Polynomial operator *(Polynomial a, Polynomial b)
{
@ -219,15 +307,14 @@ namespace MathNet.Numerics
//ret_p.Trim();
return result;
}
/// <summary>
/// multiplies a Polynomial by a scalar
/// </summary>
/// <param name="a">left Polynomial</param>
/// <param name="k">scalar value</param>
/// <returns>resulting Polynomial</returns>
/// <param name="a">Polynomial</param>
/// <param name="k">Scalar value</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial operator *(Polynomial a, double k)
{
var aa = a.Clone() as Polynomial;
@ -238,40 +325,12 @@ namespace MathNet.Numerics
return aa;
}
/// <summary>
/// adds a scalar to a Polynomial (to the x^0 element)
/// </summary>
/// <param name="a">left Polynomial</param>
/// <param name="k">scalar value</param>
/// <returns>resulting Polynomial</returns>
public static Polynomial operator +(Polynomial a, double k)
{
var aa = a.Clone() as Polynomial;
aa.Coefficients[0] += k;
return aa;
}
/// <summary>
/// substracs a scalar from a Polynomial (from the x^0 element)
/// </summary>
/// <param name="a">left Polynomial</param>
/// <param name="k">scalar value</param>
/// <returns>resulting Polynomial</returns>
public static Polynomial operator -(Polynomial a, double k)
{
var aa = a.Clone() as Polynomial;
a.Coefficients[0] -= k;
return aa;
}
/// <summary>
/// divide Polynomial by scalar value
/// </summary>
/// <param name="a">left Polynomial</param>
/// <param name="k">scalar value</param>
/// <returns>resulting Polynomial</returns>
/// <param name="a">Polynomial</param>
/// <param name="k">Scalar value</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial operator /(Polynomial a, double k)
{
var aa = a.Clone() as Polynomial;
@ -282,28 +341,6 @@ namespace MathNet.Numerics
return aa;
}
/// <summary>
/// Addition of two Polynomials (piecewise)
/// </summary>
/// <param name="a">left Polynomial</param>
/// <param name="b">right Polynomial</param>
/// <returns>resulting Polynomial</returns>
public static Polynomial operator +(Polynomial a, Polynomial b)
{
return Add(a, b);
}
/// <summary>
/// Subtraction of two Polynomials (piecewise)
/// </summary>
/// <param name="a">left Polynomial</param>
/// <param name="b">right Polynomial</param>
/// <returns>resulting Polynomial</returns>
public static Polynomial operator -(Polynomial a, Polynomial b)
{
return Subtract(a, b);
}
/// <summary>
/// Calculates the complex roots of the Polynomial by eigenvalue decomposition
/// </summary>
@ -365,61 +402,70 @@ namespace MathNet.Numerics
}
/// <summary>
/// Point-wise division of two Polynomials
/// Addition of two Polynomials (point-wise).
/// </summary>
/// <param name="a">Left Polynomial</param>
/// <param name="b">Right Polynomial</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial PointwiseDivide(Polynomial a, Polynomial b)
public static Polynomial Add(Polynomial a, Polynomial b)
{
var ac = a.Coefficients;
var bc = b.Coefficients;
var degree = a.Degree;
var degree = Math.Max(a.Degree, b.Degree);
var result = new double[degree + 1];
var commonLength = Math.Min(Math.Min(ac.Length, bc.Length), result.Length);
for (int i = 0; i < commonLength; i++)
{
result[i] = ac[i] / bc[i];
result[i] = ac[i] + bc[i];
}
for (int i = commonLength; i < result.Length; i++)
int acLength = Math.Min(ac.Length, result.Length);
for (int i = commonLength; i < acLength; i++)
{
result[i] = ac[i] / 0.0;
// no need to add since only one of both applies
result[i] = ac[i];
}
int bcLength = Math.Min(bc.Length, result.Length);
for (int i = commonLength; i < bcLength; i++)
{
// no need to add since only one of both applies
result[i] = bc[i];
}
return new Polynomial(result);
}
/// <summary>
/// Point-wise multiplication of two Polynomials
/// Addition of a polynomial and a scalar.
/// </summary>
/// <param name="a">Left Polynomial</param>
/// <param name="b">Right Polynomial</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial PointwiseMultiply(Polynomial a, Polynomial b)
public static Polynomial Add(Polynomial a, double b)
{
var ac = a.Coefficients;
var bc = b.Coefficients;
var degree = Math.Min(a.Degree, b.Degree);
var degree = Math.Max(a.Degree, 0);
var result = new double[degree + 1];
for (int i = 0; i < result.Length; i++)
var commonLength = Math.Min(ac.Length, result.Length);
for (int i = 0; i < commonLength; i++)
{
result[i] = ac[i] * bc[i];
result[i] = ac[i];
}
result[0] += b;
return new Polynomial(result);
}
/// <summary>
/// Addition of two Polynomials (point-wise).
/// Subtraction of two Polynomials (point-wise).
/// </summary>
/// <param name="a">Left Polynomial</param>
/// <param name="b">Right Polynomial</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial Add(Polynomial a, Polynomial b)
public static Polynomial Subtract(Polynomial a, Polynomial b)
{
var ac = a.Coefficients;
var bc = b.Coefficients;
@ -430,7 +476,7 @@ namespace MathNet.Numerics
var commonLength = Math.Min(Math.Min(ac.Length, bc.Length), result.Length);
for (int i = 0; i < commonLength; i++)
{
result[i] = ac[i] + bc[i];
result[i] = ac[i] - bc[i];
}
int acLength = Math.Min(ac.Length, result.Length);
@ -444,44 +490,103 @@ namespace MathNet.Numerics
for (int i = commonLength; i < bcLength; i++)
{
// no need to add since only one of both applies
result[i] = bc[i];
result[i] = -bc[i];
}
return new Polynomial(result);
}
/// <summary>
/// Subtraction of two Polynomials (point-wise).
/// Addition of a scalar from a polynomial.
/// </summary>
public static Polynomial Subtract(Polynomial a, double b)
{
return Add(a, -b);
}
/// <summary>
/// Addition of a polynomial from a scalar.
/// </summary>
public static Polynomial Subtract(double b, Polynomial a)
{
var ac = a.Coefficients;
var degree = Math.Max(a.Degree, 0);
var result = new double[degree + 1];
var commonLength = Math.Min(ac.Length, result.Length);
for (int i = 0; i < commonLength; i++)
{
result[i] = -ac[i];
}
result[0] += b;
return new Polynomial(result);
}
/// <summary>
/// Negation of a polynomial.
/// </summary>
public static Polynomial Negate(Polynomial a)
{
var ac = a.Coefficients;
var degree = a.Degree;
var result = new double[degree + 1];
for (int i = 0; i < result.Length; i++)
{
result[i] = -ac[i];
}
return new Polynomial(result);
}
/// <summary>
/// Point-wise division of two Polynomials
/// </summary>
/// <param name="a">Left Polynomial</param>
/// <param name="b">Right Polynomial</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial Subtract(Polynomial a, Polynomial b)
public static Polynomial PointwiseDivide(Polynomial a, Polynomial b)
{
var ac = a.Coefficients;
var bc = b.Coefficients;
var degree = Math.Max(a.Degree, b.Degree);
var degree = a.Degree;
var result = new double[degree + 1];
var commonLength = Math.Min(Math.Min(ac.Length, bc.Length), result.Length);
for (int i = 0; i < commonLength; i++)
{
result[i] = ac[i] - bc[i];
result[i] = ac[i] / bc[i];
}
int acLength = Math.Min(ac.Length, result.Length);
for (int i = commonLength; i < acLength; i++)
for (int i = commonLength; i < result.Length; i++)
{
// no need to add since only one of both applies
result[i] = ac[i];
result[i] = ac[i] / 0.0;
}
int bcLength = Math.Min(bc.Length, result.Length);
for (int i = commonLength; i < bcLength; i++)
return new Polynomial(result);
}
/// <summary>
/// Point-wise multiplication of two Polynomials
/// </summary>
/// <param name="a">Left Polynomial</param>
/// <param name="b">Right Polynomial</param>
/// <returns>Resulting Polynomial</returns>
public static Polynomial PointwiseMultiply(Polynomial a, Polynomial b)
{
var ac = a.Coefficients;
var bc = b.Coefficients;
var degree = Math.Min(a.Degree, b.Degree);
var result = new double[degree + 1];
for (int i = 0; i < result.Length; i++)
{
// no need to add since only one of both applies
result[i] = -bc[i];
result[i] = ac[i] * bc[i];
}
return new Polynomial(result);

Loading…
Cancel
Save