Browse Source

removed the isflipped Property, improved the clone method, fixed the divideLong

pull/588/head
Tobias Glaubach 8 years ago
parent
commit
8a34e61275
  1. 163
      src/Numerics/Polynomial.cs

163
src/Numerics/Polynomial.cs

@ -24,11 +24,6 @@ namespace MathNet.Numerics
/// </summary> /// </summary>
public double[] Coeffs { get; set; } public double[] Coeffs { get; set; }
/// <summary>
/// indicator if Polynomial was flipped
/// </summary>
public bool IsFlipped { get; }
/// <summary> /// <summary>
/// Only needed for the ToString method /// Only needed for the ToString method
/// </summary> /// </summary>
@ -65,7 +60,6 @@ namespace MathNet.Numerics
/// <param name="coeff">just the "x^0" part</param> /// <param name="coeff">just the "x^0" part</param>
public Polynomial(double coeff) public Polynomial(double coeff)
{ {
IsFlipped = false;
this.Coeffs = new double[1]; this.Coeffs = new double[1];
Coeffs[0] = coeff; Coeffs[0] = coeff;
} }
@ -73,59 +67,44 @@ namespace MathNet.Numerics
/// <summary> /// <summary>
/// make Polynomial: e.G new double[] {5, 0, 2} = "5 + 0 x^1 + 2 x^2" /// make Polynomial: e.G new double[] {5, 0, 2} = "5 + 0 x^1 + 2 x^2"
/// </summary> /// </summary>
/// <param name="coeffs"> Polynomial coefficiens as array</param> /// <param name="coeffs"> Polynomial coefficiens as enumerable</param>
public Polynomial(double[] coeffs) public Polynomial(IEnumerable<double> coeffs)
{ {
if (coeffs == null) if (coeffs == null)
{ {
throw new ArgumentNullException("coeffs"); throw new ArgumentNullException("coeffs");
} }
this.Coeffs = new double[coeffs.Length]; this.Coeffs = coeffs.ToArray();
Array.Copy(coeffs, this.Coeffs, coeffs.Length);
} }
/// <summary> /// <summary>
/// constructor setting Polynomial coefficiens and flipping them if necessary. /// make Polynomial: e.G new double[] {5, 0, 2} = "5 + 0 x^1 + 2 x^2"
///
/// e.G:
/// var x = new double[] {5, 4, 3, 0, 2};
/// var xP1 = new Polynomial(x, isFlip:true);
/// var xP2 = new Polynomial(x, isFlip:false);
///
/// xP1: 2 + 0x^1 + 3x^2 + 4x^3 + 5x^4
/// xP2: 5 + 4x^1 + 3x^2 + 0x^3 + 2x^4
///
/// </summary> /// </summary>
/// <param name="coeffs"> Polynomial coefficiens as array</param> /// <param name="coeffs"> Polynomial coefficiens as array</param>
/// <param name="isFlip">use true for flipping</param> public Polynomial(double[] coeffs)
public Polynomial(double[] coeffs, bool isFlip)
{ {
if (coeffs == null) if (coeffs == null)
{ {
throw new ArgumentNullException("coeffs"); throw new ArgumentNullException("coeffs");
} }
this.Coeffs = new double[coeffs.Length]; this.Coeffs = new double[coeffs.Length];
Array.Copy(coeffs, Coeffs, coeffs.Length); Array.Copy(coeffs, this.Coeffs, coeffs.Length);
if (isFlip)
{
Coeffs = Coeffs.Reverse().ToArray();
IsFlipped = true;
}
} }
/// <summary> /// <summary>
/// remove all trailing zeros, e.G before: "0.00 x^2 + 1.0 x^1 + 1.00" after: "1.0 x^1 + 1.00" /// remove all trailing zeros, e.G before: "3 + 2 x^1 + 0 x^2" after: "3 + 2 x^1"
/// </summary> /// </summary>
public void Trim() public void Trim()
{ {
if (Degree == 1)
return;
int i = Degree - 1; int i = Degree - 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[0]; Coeffs = new double[1] { 0.0 };
else else
{ {
var hold = new double[i+1]; var hold = new double[i+1];
@ -187,7 +166,7 @@ namespace MathNet.Numerics
{ {
cNew[i-1] = t.Coeffs[i] * i; cNew[i-1] = t.Coeffs[i] * i;
} }
var p = new Polynomial(cNew, isFlip: IsFlipped); var p = new Polynomial(cNew);
p.Trim(); p.Trim();
return p; return p;
} }
@ -201,7 +180,7 @@ namespace MathNet.Numerics
{ {
cNew[i] = t.Coeffs[i-1] / i; cNew[i] = t.Coeffs[i-1] / i;
} }
var p = new Polynomial(cNew, isFlip: IsFlipped); var p = new Polynomial(cNew);
p.Trim(); p.Trim();
return p; return p;
} }
@ -219,11 +198,13 @@ namespace MathNet.Numerics
/// <returns>resulting Polynomial</returns> /// <returns>resulting Polynomial</returns>
public static Polynomial operator *( Polynomial a, Polynomial b) public static Polynomial operator *( Polynomial a, Polynomial b)
{ {
var aa = a.Clone() as Polynomial;
var bb = b.Clone() as Polynomial;
// do not cut trailing zeros, since it may corrupt the outcom, if the array is of form 1 + x^-1 + x^-2 + x^-3 // do not cut trailing zeros, since it may corrupt the outcom, if the array is of form 1 + x^-1 + x^-2 + x^-3
//a.Trim(); //a.Trim();
//b.Trim(); //b.Trim();
double[] ret = conv(a.Coeffs, b.Coeffs); double[] ret = conv(aa.Coeffs, bb.Coeffs);
Polynomial ret_p = new Polynomial(ret); Polynomial ret_p = new Polynomial(ret);
//ret_p.Trim(); //ret_p.Trim();
@ -240,10 +221,13 @@ namespace MathNet.Numerics
/// <returns>resulting Polynomial</returns> /// <returns>resulting Polynomial</returns>
public static Polynomial operator *( Polynomial a, double k) public static Polynomial operator *( Polynomial a, double k)
{ {
for (int ii = 0; ii < a.Coeffs.Length; ii++) var aa = a.Clone() as Polynomial;
a.Coeffs[ii] *= k;
return a; for (int ii = 0; ii < aa.Coeffs.Length; ii++)
aa.Coeffs[ii] *= k;
return aa;
} }
/// <summary> /// <summary>
@ -254,8 +238,10 @@ namespace MathNet.Numerics
/// <returns>resulting Polynomial</returns> /// <returns>resulting Polynomial</returns>
public static Polynomial operator +( Polynomial a, double k) public static Polynomial operator +( Polynomial a, double k)
{ {
a.Coeffs[0] += k; var aa = a.Clone() as Polynomial;
return a;
aa.Coeffs[0] += k;
return aa;
} }
/// <summary> /// <summary>
@ -266,9 +252,10 @@ namespace MathNet.Numerics
/// <returns>resulting Polynomial</returns> /// <returns>resulting Polynomial</returns>
public static Polynomial operator -( Polynomial a, double k) public static Polynomial operator -( Polynomial a, double k)
{ {
var aa = a.Clone() as Polynomial;
a.Coeffs[0] -= k; a.Coeffs[0] -= k;
return a; return aa;
} }
/// <summary> /// <summary>
@ -279,10 +266,12 @@ namespace MathNet.Numerics
/// <returns>resulting Polynomial</returns> /// <returns>resulting Polynomial</returns>
public static Polynomial operator /( Polynomial a, double k) public static Polynomial operator /( Polynomial a, double k)
{ {
for (int ii = 0; ii < a.Coeffs.Length; ii++) var aa = a.Clone() as Polynomial;
a.Coeffs[ii] /= k;
return a; for (int ii = 0; ii < aa.Coeffs.Length; ii++)
aa.Coeffs[ii] /= k;
return aa;
} }
/// <summary> /// <summary>
@ -372,16 +361,19 @@ namespace MathNet.Numerics
/// <returns>resulting Polynomial</returns> /// <returns>resulting Polynomial</returns>
public static Polynomial DividePointwise( Polynomial a, Polynomial b) public static Polynomial DividePointwise( Polynomial a, Polynomial b)
{ {
if (a.Coeffs.Length != b.Coeffs.Length) var aa = a.Clone() as Polynomial;
mkSameLength(ref a, ref b); var bb = b.Clone() as Polynomial;
if (aa.Coeffs.Length != bb.Coeffs.Length)
mkSameLength(ref aa, ref bb);
int n = a.Coeffs.Length; int n = aa.Coeffs.Length;
double[] res = new double[a.Coeffs.Length]; double[] res = new double[aa.Coeffs.Length];
for (int ii = 0; ii < n; ii++) for (int ii = 0; ii < n; ii++)
{ {
res[ii] = a.Coeffs[ii] / b.Coeffs[ii]; res[ii] = aa.Coeffs[ii] / bb.Coeffs[ii];
} }
Polynomial res_poly = new Polynomial(res); Polynomial res_poly = new Polynomial(res);
return (res_poly); return (res_poly);
@ -395,16 +387,19 @@ namespace MathNet.Numerics
/// <returns>resulting Polynomial</returns> /// <returns>resulting Polynomial</returns>
public static Polynomial MultiplyPointwise( Polynomial a, Polynomial b) public static Polynomial MultiplyPointwise( Polynomial a, Polynomial b)
{ {
if (a.Coeffs.Length != b.Coeffs.Length) var aa = a.Clone() as Polynomial;
mkSameLength(ref a, ref b); var bb = b.Clone() as Polynomial;
if (aa.Coeffs.Length != bb.Coeffs.Length)
mkSameLength(ref aa, ref bb);
int n = a.Coeffs.Length; int n = aa.Coeffs.Length;
double[] res = new double[a.Coeffs.Length]; double[] res = new double[aa.Coeffs.Length];
for (int ii = 0; ii < n; ii++) for (int ii = 0; ii < n; ii++)
{ {
res[ii] = a.Coeffs[ii] * b.Coeffs[ii]; res[ii] = aa.Coeffs[ii] * bb.Coeffs[ii];
} }
Polynomial res_poly = new Polynomial(res); Polynomial res_poly = new Polynomial(res);
return (res_poly); return (res_poly);
@ -418,17 +413,19 @@ namespace MathNet.Numerics
/// <returns>resulting Polynomial</returns> /// <returns>resulting Polynomial</returns>
public static Polynomial Add( Polynomial a, Polynomial b) public static Polynomial Add( Polynomial a, Polynomial b)
{ {
var aa = a.Clone() as Polynomial;
var bb = b.Clone() as Polynomial;
if (a.Degree != b.Degree) if (aa.Degree != bb.Degree)
mkSameLength(ref a, ref b); mkSameLength(ref aa, ref bb);
int n = a.Degree; int n = aa.Degree;
double[] res = new double[n]; double[] res = new double[n];
for (int ii = 0; ii < n; ii++) for (int ii = 0; ii < n; ii++)
{ {
res[ii] = a.Coeffs[ii] + b.Coeffs[ii]; res[ii] = aa.Coeffs[ii] + bb.Coeffs[ii];
} }
Polynomial res_poly = new Polynomial(res); Polynomial res_poly = new Polynomial(res);
return (res_poly); return (res_poly);
@ -442,17 +439,19 @@ namespace MathNet.Numerics
/// <returns>resulting Polynomial</returns> /// <returns>resulting Polynomial</returns>
public static Polynomial Substract( Polynomial a, Polynomial b) public static Polynomial Substract( Polynomial a, Polynomial b)
{ {
var aa = a.Clone() as Polynomial;
var bb = b.Clone() as Polynomial;
if (a.Degree != b.Degree) if (aa.Degree != bb.Degree)
mkSameLength(ref a, ref b); mkSameLength(ref aa, ref bb);
int n = a.Degree; int n = aa.Degree;
double[] res = new double[n]; double[] res = new double[n];
for (int ii = 0; ii < n; ii++) for (int ii = 0; ii < n; ii++)
{ {
res[ii] = a.Coeffs[ii] - b.Coeffs[ii]; res[ii] = aa.Coeffs[ii] - bb.Coeffs[ii];
} }
Polynomial res_poly = new Polynomial(res); Polynomial res_poly = new Polynomial(res);
return (res_poly); return (res_poly);
@ -476,7 +475,7 @@ namespace MathNet.Numerics
if (b.Degree <= 0) if (b.Degree <= 0)
throw new ArgumentOutOfRangeException("b Degree must be greater than zero"); throw new ArgumentOutOfRangeException("b Degree must be greater than zero");
if (b.Coeffs.Last() == 0) if (b.Coeffs[b.Degree-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();
@ -514,24 +513,25 @@ namespace MathNet.Numerics
int j = n1 - 1; int j = n1 - 1;
while (i >= 0) while (i >= 0)
{ {
var v = c1[j];
var vals = new double[j - i]; var vals = new double[j - i];
for (int k = 0; k < vals.Length; k++) for (int k = i; k < j; k++)
vals[k] = c22[k] * c1[j]; c1[k] -= c22[k-i] * v;
for (int idx = i; idx < j; idx++)
c1[idx] -= vals[idx - i];
i--; i--;
j--; j--;
} }
rem = new double[j + 1]; var j1 = j + 1;
quo = new double[n1 - j + 1]; var l1 = n1 - j1;
Array.Copy(c1, rem, j + 1); rem = new double[j1];
quo = new double[l1];
for (int idx2 = j+1; idx2 < n1; idx2++) for (int k = 0; k < l1; k++)
quo[idx2 - j + 1] = c1[idx2] / scl; quo[k] = c1[k + j1] / scl;
for (int k = 0; k < j1; k++)
rem[k] = c1[k];
} }
@ -545,9 +545,9 @@ 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);
pQuo.Trim();
pQuo.Trim();
pRem.Trim();
pQuo.Trim();
return new Tuple<Polynomial, Polynomial>(pQuo, pRem); return new Tuple<Polynomial, Polynomial>(pQuo, pRem);
} }
@ -633,10 +633,7 @@ namespace MathNet.Numerics
/// <returns>the coefficcients of the Polynomial as an array</returns> /// <returns>the coefficcients of the Polynomial as an array</returns>
public double[] ToArray() public double[] ToArray()
{ {
if (IsFlipped == true) return (Coeffs.ToArray());
return (Coeffs.Reverse().ToArray());
else
return (Coeffs);
} }
#endregion #endregion
@ -689,9 +686,7 @@ namespace MathNet.Numerics
public object Clone() public object Clone()
{ {
var p = new double[this.Coeffs.Length]; return new Polynomial(p);
Array.Copy(Coeffs, p, Coeffs.Length);
return new Polynomial(p, isFlip: IsFlipped);
} }
#endregion #endregion

Loading…
Cancel
Save