Browse Source

Polynomial: rename Degree to CoefficientCount and add new Degree that matches the mathematical definition

ridge-regression
Christoph Ruegg 8 years ago
parent
commit
8bfb3535ef
  1. 46
      src/Numerics.Tests/PolynomialTests.cs
  2. 76
      src/Numerics/Polynomial.cs

46
src/Numerics.Tests/PolynomialTests.cs

@ -29,12 +29,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using MathNet.Numerics;
using MathNet.Numerics.LinearRegression;
using MathNet.Numerics.Statistics;
using NUnit.Framework; using NUnit.Framework;
namespace MathNet.Numerics.UnitTests namespace MathNet.Numerics.UnitTests
@ -46,7 +42,6 @@ namespace MathNet.Numerics.UnitTests
[TestFixture, Category("Calculus")] [TestFixture, Category("Calculus")]
public class PolynomialTests public class PolynomialTests
{ {
[TestCase(new double[] { 5, 4, 3, 0, 2 }, "5 + 4x^1 + 3x^2 + 0x^3 + 2x^4")] [TestCase(new double[] { 5, 4, 3, 0, 2 }, "5 + 4x^1 + 3x^2 + 0x^3 + 2x^4")]
[TestCase(new double[0], "")] [TestCase(new double[0], "")]
[TestCase(new double[] { 0, 4, 3, 0, 0 }, "0 + 4x^1 + 3x^2 + 0x^3 + 0x^4")] [TestCase(new double[] { 0, 4, 3, 0, 0 }, "0 + 4x^1 + 3x^2 + 0x^3 + 0x^4")]
@ -71,13 +66,12 @@ namespace MathNet.Numerics.UnitTests
} }
else else
{ {
Assert.AreEqual(expected.Length, p_res.Degree, "length mismatch"); Assert.AreEqual(expected.Length, p_res.CoefficientCount, "length mismatch");
for (int k = 0; k < p_res.Degree; k++) for (int k = 0; k < p_res.CoefficientCount; k++)
{ {
Assert.AreEqual(expected[k], p_res.Coeffs[k], "idx: " + k + " mismatch"); Assert.AreEqual(expected[k], p_res.Coeffs[k], "idx: " + k + " mismatch");
} }
} }
} }
[TestCase(new double[] { 5, 4, 3, 0, 2 }, new double[] { 0, 5.0/1.0, 4.0/2.0, 3.0/3.0, 0.0/4.0, 2.0/5.0 })] [TestCase(new double[] { 5, 4, 3, 0, 2 }, new double[] { 0, 5.0/1.0, 4.0/2.0, 3.0/3.0, 0.0/4.0, 2.0/5.0 })]
@ -95,8 +89,8 @@ namespace MathNet.Numerics.UnitTests
} }
else else
{ {
Assert.AreEqual(expected.Length, p_res.Degree, "length mismatch"); Assert.AreEqual(expected.Length, p_res.CoefficientCount, "length mismatch");
for (int k = 0; k < p_res.Degree; k++) for (int k = 0; k < p_res.CoefficientCount; k++)
{ {
Assert.AreEqual(expected[k], p_res.Coeffs[k], "idx: " + k + " mismatch"); Assert.AreEqual(expected[k], p_res.Coeffs[k], "idx: " + k + " mismatch");
} }
@ -131,8 +125,8 @@ namespace MathNet.Numerics.UnitTests
p_res.Trim(); p_res.Trim();
p_tar.Trim(); p_tar.Trim();
Assert.AreEqual(p_tar.Degree, p_res.Degree, "length mismatch"); Assert.AreEqual(p_tar.CoefficientCount, p_res.CoefficientCount, "length mismatch");
for (int k = 0; k < p_res.Degree; k++) for (int k = 0; k < p_res.CoefficientCount; k++)
{ {
Assert.AreEqual(p_tar.Coeffs[k], p_res.Coeffs[k], msg); Assert.AreEqual(p_tar.Coeffs[k], p_res.Coeffs[k], msg);
} }
@ -168,8 +162,8 @@ namespace MathNet.Numerics.UnitTests
p_res.Trim(); p_res.Trim();
p_tar.Trim(); p_tar.Trim();
Assert.AreEqual(p_tar.Degree, p_res.Degree, "length mismatch"); Assert.AreEqual(p_tar.CoefficientCount, p_res.CoefficientCount, "length mismatch");
for (int k = 0; k < p_res.Degree; k++) for (int k = 0; k < p_res.CoefficientCount; k++)
{ {
Assert.AreEqual(p_tar.Coeffs[k], p_res.Coeffs[k], msg); Assert.AreEqual(p_tar.Coeffs[k], p_res.Coeffs[k], msg);
} }
@ -204,8 +198,8 @@ namespace MathNet.Numerics.UnitTests
p_res.Trim(); p_res.Trim();
p_tar.Trim(); p_tar.Trim();
Assert.AreEqual(p_tar.Degree, p_res.Degree, "length mismatch"); Assert.AreEqual(p_tar.CoefficientCount, p_res.CoefficientCount, "length mismatch");
for (int k = 0; k < p_res.Degree; k++) for (int k = 0; k < p_res.CoefficientCount; k++)
{ {
Assert.AreEqual(p_tar.Coeffs[k], p_res.Coeffs[k], msg); Assert.AreEqual(p_tar.Coeffs[k], p_res.Coeffs[k], msg);
} }
@ -227,15 +221,6 @@ namespace MathNet.Numerics.UnitTests
} }
public void DivideLongTestScalar(Tuple<double[], double> inVals, Tuple<double[], double> expectedVals)
{
var p1 = new Polynomial(1.0d);
var p2 = new Polynomial(new double[0]);
var tpl = Polynomial.DivideLong(p1, p2);
}
[Test] [Test]
public void DivideLongTestWrongInputs() public void DivideLongTestWrongInputs()
{ {
@ -268,7 +253,6 @@ namespace MathNet.Numerics.UnitTests
[Test] [Test]
public void DivideLongTest() public void DivideLongTest()
{ {
var p11 = new Polynomial(2.0d); var p11 = new Polynomial(2.0d);
var p21 = new Polynomial(2.0d); var p21 = new Polynomial(2.0d);
var tpl1 = Polynomial.DivideLong(p11, p21); var tpl1 = Polynomial.DivideLong(p11, p21);
@ -353,7 +337,7 @@ namespace MathNet.Numerics.UnitTests
var e = eIn.OrderBy(v => v.Real).ToArray(); var e = eIn.OrderBy(v => v.Real).ToArray();
var r = r0.OrderBy(v => v.Real).ToArray(); var r = r0.OrderBy(v => v.Real).ToArray();
Assert.IsNotNull(r); Assert.IsNotNull(r);
Assert.AreEqual(e.Length, r.Length, "length mismatch"); Assert.AreEqual(e.Length, r.Length, "length mismatch");
for (int k = 0; k < r.Length; k++) for (int k = 0; k < r.Length; k++)
@ -375,8 +359,8 @@ namespace MathNet.Numerics.UnitTests
private void testEqual(double[] p_tar, Polynomial p_res, string msg = null) private void testEqual(double[] p_tar, Polynomial p_res, string msg = null)
{ {
Assert.AreEqual(p_tar.Length, p_res.Degree, "length mismatch"); Assert.AreEqual(p_tar.Length, p_res.CoefficientCount, "length mismatch");
for (int k = 0; k < p_res.Degree; k++) for (int k = 0; k < p_res.CoefficientCount; k++)
{ {
Assert.AreEqual(p_tar[k], p_res.Coeffs[k], msg); Assert.AreEqual(p_tar[k], p_res.Coeffs[k], msg);
} }
@ -384,8 +368,8 @@ namespace MathNet.Numerics.UnitTests
} }
private void testEqual(Polynomial p_tar, Polynomial p_res, string msg = null) private void testEqual(Polynomial p_tar, Polynomial p_res, string msg = null)
{ {
Assert.AreEqual(p_tar.Degree, p_res.Degree, "length mismatch"); Assert.AreEqual(p_tar.CoefficientCount, p_res.CoefficientCount, "length mismatch");
for (int k = 0; k < p_res.Degree; k++) for (int k = 0; k < p_res.CoefficientCount; k++)
{ {
Assert.AreEqual(p_tar.Coeffs[k], p_res.Coeffs[k], msg); Assert.AreEqual(p_tar.Coeffs[k], p_res.Coeffs[k], msg);
} }

76
src/Numerics/Polynomial.cs

@ -1,21 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Numerics; using System.Numerics;
using MathNet.Numerics;
using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double; using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.Statistics;
using MathNet.Numerics.IntegralTransforms;
using MathNet.Numerics.LinearRegression; using MathNet.Numerics.LinearRegression;
using MathNet.Numerics.LinearAlgebra.Factorization; using MathNet.Numerics.LinearAlgebra.Factorization;
namespace MathNet.Numerics namespace MathNet.Numerics
{ {
/// <summary> /// <summary>
/// a class handling REAL VALUED Polynomials, complex coefficients can not be handled (yet) /// A single-variable polynomial with real-valued coefficients.
/// </summary> /// </summary>
public class Polynomial public class Polynomial
{ {
@ -32,7 +27,7 @@ namespace MathNet.Numerics
/// <summary> /// <summary>
/// Length of Polynomial (max element + 1) e.G x^5 highest element, will give Length = 6 /// Length of Polynomial (max element + 1) e.G x^5 highest element, will give Length = 6
/// </summary> /// </summary>
public int Degree public int CoefficientCount
{ {
get get
{ {
@ -40,6 +35,31 @@ namespace MathNet.Numerics
} }
} }
/// <summary>
/// Degree of the polynomial, i.e. the largest monomial exponent. For example, the degree of x^2+x^5 is 5.
/// The null-polynomial returns degree -1 because the correct degree, negative infinity, cannot be represented by integers.
/// </summary>
public int Degree
{
get
{
if (Coeffs == null)
{
return -1;
}
for (int i = Coeffs.Length - 1; i >= 0; i--)
{
if (Coeffs[i] != 0.0)
{
return i;
}
}
return -1;
}
}
/// <summary> /// <summary>
/// constructor setting a Polynomial of size n containing only zeros /// constructor setting a Polynomial of size n containing only zeros
/// </summary> /// </summary>
@ -96,13 +116,13 @@ namespace MathNet.Numerics
/// </summary> /// </summary>
public void Trim() public void Trim()
{ {
if (Degree == 1) if (CoefficientCount == 1)
return; return;
int i = Degree - 1; int i = CoefficientCount - 1;
while (i >= 0 && Coeffs[i] == 0.0) while (i >= 0 && Coeffs[i] == 0.0)
i--; i--;
if (i < 0) if (i < 0)
Coeffs = new double[1] { 0.0 }; Coeffs = new double[1] { 0.0 };
else if (i == 0) else if (i == 0)
@ -114,7 +134,7 @@ namespace MathNet.Numerics
Coeffs = hold; Coeffs = hold;
} }
} }
#region Data Interaction #region Data Interaction
@ -155,7 +175,7 @@ namespace MathNet.Numerics
#region diff/int #region diff/int
public Polynomial Differentiate() public Polynomial Differentiate()
{ {
if (Coeffs.Length == 0) if (Coeffs.Length == 0)
{ {
return null; return null;
@ -224,7 +244,7 @@ namespace MathNet.Numerics
public static Polynomial operator *( Polynomial a, double k) public static Polynomial operator *( Polynomial a, double k)
{ {
var aa = a.Clone() as Polynomial; var aa = a.Clone() as Polynomial;
for (int ii = 0; ii < aa.Coeffs.Length; ii++) for (int ii = 0; ii < aa.Coeffs.Length; ii++)
aa.Coeffs[ii] *= k; aa.Coeffs[ii] *= k;
@ -269,7 +289,7 @@ namespace MathNet.Numerics
public static Polynomial operator /( Polynomial a, double k) public static Polynomial operator /( Polynomial a, double k)
{ {
var aa = a.Clone() as Polynomial; var aa = a.Clone() as Polynomial;
for (int ii = 0; ii < aa.Coeffs.Length; ii++) for (int ii = 0; ii < aa.Coeffs.Length; ii++)
aa.Coeffs[ii] /= k; aa.Coeffs[ii] /= k;
@ -297,7 +317,7 @@ namespace MathNet.Numerics
{ {
return Substract(a, b); return Substract(a, b);
} }
/// <summary> /// <summary>
/// Calculates the complex roots of the Polynomial by eigenvalue decomposition /// Calculates the complex roots of the Polynomial by eigenvalue decomposition
/// </summary> /// </summary>
@ -418,10 +438,10 @@ namespace MathNet.Numerics
var aa = a.Clone() as Polynomial; var aa = a.Clone() as Polynomial;
var bb = b.Clone() as Polynomial; var bb = b.Clone() as Polynomial;
if (aa.Degree != bb.Degree) if (aa.CoefficientCount != bb.CoefficientCount)
mkSameLength(ref aa, ref bb); mkSameLength(ref aa, ref bb);
int n = aa.Degree; int n = aa.CoefficientCount;
double[] res = new double[n]; double[] res = new double[n];
@ -444,10 +464,10 @@ namespace MathNet.Numerics
var aa = a.Clone() as Polynomial; var aa = a.Clone() as Polynomial;
var bb = b.Clone() as Polynomial; var bb = b.Clone() as Polynomial;
if (aa.Degree != bb.Degree) if (aa.CoefficientCount != bb.CoefficientCount)
mkSameLength(ref aa, ref bb); mkSameLength(ref aa, ref bb);
int n = aa.Degree; int n = aa.CoefficientCount;
double[] res = new double[n]; double[] res = new double[n];
@ -472,14 +492,14 @@ namespace MathNet.Numerics
if (b == null) if (b == null)
throw new ArgumentNullException("b"); throw new ArgumentNullException("b");
if (a.Degree <= 0) if (a.CoefficientCount <= 0)
throw new ArgumentOutOfRangeException("a Degree must be greater than zero"); throw new ArgumentOutOfRangeException("a Degree must be greater than zero");
if (b.Degree <= 0) if (b.CoefficientCount <= 0)
throw new ArgumentOutOfRangeException("b Degree must be greater than zero"); throw new ArgumentOutOfRangeException("b Degree must be greater than zero");
if (b.Coeffs[b.Degree-1] == 0) if (b.Coeffs[b.CoefficientCount-1] == 0)
throw new DivideByZeroException("b polynomial ends with zero"); throw new DivideByZeroException("b polynomial ends with zero");
var c1 = a.Coeffs.ToArray(); var c1 = a.Coeffs.ToArray();
var c2 = b.Coeffs.ToArray(); var c2 = b.Coeffs.ToArray();
@ -497,7 +517,7 @@ namespace MathNet.Numerics
quo[i] = c1[i] / fact; quo[i] = c1[i] / fact;
rem = new double[] { 0 }; rem = new double[] { 0 };
} }
else if(n1 < n2) // denominator degree higher than nominator degree else if(n1 < n2) // denominator degree higher than nominator degree
{ {
// quotient always be 0 and return c1 as remainder // quotient always be 0 and return c1 as remainder
quo = new double[] { 0 }; quo = new double[] { 0 };
@ -534,7 +554,7 @@ namespace MathNet.Numerics
for (int k = 0; k < j1; k++) for (int k = 0; k < j1; k++)
rem[k] = c1[k]; rem[k] = c1[k];
} }
if (rem == null) if (rem == null)
@ -547,7 +567,7 @@ namespace MathNet.Numerics
// output mapping // output mapping
var pQuo = new Polynomial(quo); var pQuo = new Polynomial(quo);
var pRem = new Polynomial(rem); var pRem = new Polynomial(rem);
pRem.Trim(); pRem.Trim();
pQuo.Trim(); pQuo.Trim();
return new Tuple<Polynomial, Polynomial>(pQuo, pRem); return new Tuple<Polynomial, Polynomial>(pQuo, pRem);
@ -628,7 +648,7 @@ namespace MathNet.Numerics
#region Interfacing #region Interfacing
/// <summary> /// <summary>
/// This method returns the coefficcients of the Polynomial as an array the "IsFlipped" property, /// This method returns the coefficcients of the Polynomial as an array the "IsFlipped" property,
/// which is set during construction is taken into account automatically. /// which is set during construction is taken into account automatically.
/// </summary> /// </summary>
/// <returns>the coefficcients of the Polynomial as an array</returns> /// <returns>the coefficcients of the Polynomial as an array</returns>
@ -666,7 +686,7 @@ namespace MathNet.Numerics
} }
/// <summary> /// <summary>
/// (full) convolution of two arrays /// (full) convolution of two arrays
/// </summary> /// </summary>
/// <param name="a">left vector</param> /// <param name="a">left vector</param>
/// <param name="b">right vector</param> /// <param name="b">right vector</param>

Loading…
Cancel
Save