/// <summary> /// Factorizes polynomial to its linear factors. /// </summary> /// <returns></returns> public FactorizedPolynomial Factorize() { // this is to be returned FactorizedPolynomial p = new FactorizedPolynomial(); // cannot factorize polynomial of degree 0 or 1 if (this.Degree <= 1) { p.Factor = new Polynomial[] { this }; p.Power = new int[] { 1 }; return p; } Complex[] roots = Roots(this); //ArrayList rootlist = new ArrayList(); //foreach (Complex z in roots) rootlist.Add(z); //roots = null; // don't need you anymore //rootlist.Sort(); //// number of different roots //int num = 1; // ... at least one //// ...or more? //for (int i = 1; i < rootlist.Count; i++) // if (rootlist[i] != rootlist[i - 1]) num++; Polynomial[] factor = new Polynomial[roots.Length]; int[] power = new int[roots.Length]; //factor[0] = new Polynomial( new Complex[]{ -(Complex)rootlist[0] * Coefficients[Degree], // Coefficients[Degree] } ); //power[0] = 1; //num = 1; //len = 0; //for (int i = 1; i < rootlist.Count; i++) //{ // len++; // if (rootlist[i] != rootlist[i - 1]) // { // factor[num] = new Polynomial(new Complex[] { -(Complex)rootlist[i], Complex.One }); // power[num] = len; // num++; // len = 0; // } //} power[0] = 1; factor[0] = new Polynomial(new Complex[] { -Coefficients[Degree] * (Complex)roots[0], Coefficients[Degree] }); for (int i = 1; i < roots.Length; i++) { power[i] = 1; factor[i] = new Polynomial(new Complex[] { -(Complex)roots[i], Complex.One }); } p.Factor = factor; p.Power = power; return p; }
/// <summary> /// Computes the definite integral within the borders a and b. /// </summary> /// <param name="a">Left integration border.</param> /// <param name="b">Right integration border.</param> /// <returns></returns> public Complex Integrate(Complex a, Complex b) { Complex[] buf = new Complex[Degree + 2]; buf[0] = Complex.Zero; // this value can be arbitrary, in fact for (int i = 1; i < buf.Length; i++) buf[i] = Coefficients[i - 1] / i; Polynomial p = new Polynomial(buf); return (p.Evaluate(b) - p.Evaluate(a)); }
/// <summary> /// Normalizes the polynomial, e.i. divides each coefficient by the /// coefficient of a_n the greatest term if a_n != 1. /// </summary> public static Polynomial Normalize(Polynomial p) { Polynomial q = Clean(p); if (q.Coefficients[q.Degree] != Complex.One) for (int k = 0; k <= q.Degree; k++) q.Coefficients[k] /= q.Coefficients[q.Degree]; return q; }
/// <summary> /// Computes the roots of polynomial p via Weierstrass iteration. /// </summary> /// <param name="p">Polynomial to compute the roots of.</param> /// <param name="tolerance">Computation precision; e.g. 1e-12 denotes 12 exact digits.</param> /// <param name="max_iterations">Maximum number of iterations; this value is used to bound /// the computation effort if desired pecision is hard to achieve.</param> /// <returns></returns> public static Complex[] Roots(Polynomial p, double tolerance, int max_iterations) { Polynomial q = Normalize(p); Complex[] z = new Complex[q.Degree]; // approx. for roots Complex[] w = new Complex[q.Degree]; // Weierstraß corrections // init z for (int k = 0; k < q.Degree; k++) //z[k] = (new Complex(.4, .9)) ^ k; z[k] = Complex.Exp(2 * Math.PI * Complex.I * k / q.Degree); for (int iter = 0; iter < max_iterations && MaxValue(q, z) > tolerance; iter++) for (int i = 0; i < 10; i++) { for (int k = 0; k < q.Degree; k++) w[k] = q.Evaluate(z[k]) / WeierNull(z, k); for (int k = 0; k < q.Degree; k++) z[k] -= w[k]; } // clean... for (int k = 0; k < q.Degree; k++) { z[k].Re = Math.Round(z[k].Re, 12); z[k].Im = Math.Round(z[k].Im, 12); } return z; }
/// <summary> /// Integrates given polynomial p. /// </summary> /// <param name="p"></param> /// <returns></returns> public static Polynomial Integral(Polynomial p) { Complex[] buf = new Complex[p.Degree + 2]; buf[0] = Complex.Zero; // this value can be arbitrary, in fact for (int i = 1; i < buf.Length; i++) buf[i] = p.Coefficients[i - 1] / i; return new Polynomial(buf); }
/// <summary> /// Computes the greatest value |p(z_k)|. /// </summary> /// <param name="p"></param> /// <param name="z"></param> /// <returns></returns> public static double MaxValue(Polynomial p, Complex[] z) { double buf = 0; for (int i = 0; i < z.Length; i++) { if(Complex.Abs(p.Evaluate(z[i])) > buf) buf = Complex.Abs(p.Evaluate(z[i])); } return buf; }
/// <summary> /// Expands factorized polynomial p_1(x)^(k_1)*...*p_r(x)^(k_r) to its normal form a_0 + a_1 x + ... + a_n x^n. /// </summary> /// <param name="p"></param> /// <returns></returns> public static Polynomial Expand(FactorizedPolynomial p) { Polynomial q = new Polynomial(new Complex[] { Complex.One }); for (int i = 0; i < p.Factor.Length; i++) { for (int j = 0; j < p.Power[i]; j++) q *= p.Factor[i]; q.Clean(); } // clean... for (int k = 0; k <= q.Degree; k++) { q.Coefficients[k].Re = Math.Round(q.Coefficients[k].Re, 12); q.Coefficients[k].Im = Math.Round(q.Coefficients[k].Im, 12); } return q; }
public static Polynomial[] GetStandardBase(int dim) { if(dim < 1) throw new ArgumentException("Dimension expected to be greater than zero."); Polynomial[] buf = new Polynomial[dim]; for (int i = 0; i < dim; i++) buf[i] = Monomial(i); return buf; }
/// <summary> /// Removes unncessary leading zeros. /// </summary> /// <param name="p"></param> /// <returns></returns> public static Polynomial Clean(Polynomial p) { int i; for (i = p.Degree; i >= 0 && p.Coefficients[i] == 0; i--) ; Complex[] coeffs = new Complex[i + 1]; for (int k = 0; k <= i; k++) coeffs[k] = p.Coefficients[k]; return new Polynomial(coeffs); }
/// <summary> /// Differentiates given polynomial p. /// </summary> /// <param name="p"></param> /// <returns></returns> public static Polynomial Derivative(Polynomial p) { Complex[] buf = new Complex[p.Degree]; for (int i = 0; i < buf.Length; i++) buf[i] = (i + 1) * p.Coefficients[i + 1]; return new Polynomial(buf); }
public static Polynomial operator *(Polynomial p, Polynomial q) { int degree = p.Degree + q.Degree; Polynomial r = new Polynomial(); for (int i = 0; i <= p.Degree; i++) for (int j = 0; j <= q.Degree; j++) r += (p.Coefficients[i] * q.Coefficients[j]) * Monomial(i + j); return r; }
internal Interval(IntervalSet parent, System.Decimal lowerBoundary, System.Decimal upperBoundary, Polynomial polynomial) { Complex[] cs = polynomial.Coefficients; List<decimal> r = new List<decimal>(); foreach(Complex c in cs) if (c.IsReal()) r.Add((decimal)c.Re); _parent = parent; _lowerBound = lowerBoundary; _upperBound = upperBoundary; _coefficients = r.ToArray(); }
/// <summary> /// Returns real roots of the specified polynomial which belongs to the specified interval /// </summary> /// <param name="input"></param> /// <param name="lowerBound">lower boundary of the interval</param> /// <param name="upperBound">upper boundary of the interval</param> /// <returns></returns> public static decimal[] RealRoots(Polynomial input, decimal lowerBound, decimal upperBound) { List<decimal> output = new List<decimal>(); Complex[] roots = input.Roots(); foreach (Complex c in roots) { if (c.IsReal() && !output.Contains((decimal)c.Re) && ((decimal)c.Re) >= lowerBound && ((decimal)c.Re) <= upperBound) output.Add((decimal)c.Re); } return output.ToArray(); }
/// <summary> /// True if the membeship function is 0 /// </summary> /// <param name="input"></param> /// <returns></returns> public static bool IsEmpty(Polynomial input) { return input.Coefficients == new Complex[] { new Complex(0) }; }
/// <summary> /// Factorizes polynomial to its linear factors. /// </summary> /// <returns></returns> public FactorizedPolynomial Factorize() { // this is to be returned FactorizedPolynomial p = new FactorizedPolynomial(); // cannot factorize polynomial of degree 0 or 1 if (this.Degree <= 1) { p.Factor = new Polynomial[] { this }; p.Power = new int[] { 1 }; return(p); } Complex[] roots = Roots(this); //ArrayList rootlist = new ArrayList(); //foreach (Complex z in roots) rootlist.Add(z); //roots = null; // don't need you anymore //rootlist.Sort(); //// number of different roots //int num = 1; // ... at least one //// ...or more? //for (int i = 1; i < rootlist.Count; i++) // if (rootlist[i] != rootlist[i - 1]) num++; Polynomial[] factor = new Polynomial[roots.Length]; int[] power = new int[roots.Length]; //factor[0] = new Polynomial( new Complex[]{ -(Complex)rootlist[0] * Coefficients[Degree], // Coefficients[Degree] } ); //power[0] = 1; //num = 1; //len = 0; //for (int i = 1; i < rootlist.Count; i++) //{ // len++; // if (rootlist[i] != rootlist[i - 1]) // { // factor[num] = new Polynomial(new Complex[] { -(Complex)rootlist[i], Complex.One }); // power[num] = len; // num++; // len = 0; // } //} power[0] = 1; factor[0] = new Polynomial(new Complex[] { -Coefficients[Degree] * (Complex)roots[0], Coefficients[Degree] }); for (int i = 1; i < roots.Length; i++) { power[i] = 1; factor[i] = new Polynomial(new Complex[] { -(Complex)roots[i], Complex.One }); } p.Factor = factor; p.Power = power; return(p); }