/// <summary> /// Finds root of polynom /// </summary> /// <param name="accuracy">Accuracy</param> /// <returns>Root</returns> public Complex Root(double accuracy) { ComplexPolynom p = this; ComplexPolynom der = p.Derivation; ComplexPolynom sec = der.Derivation; int n = p.Deg; ComplexPolynom pol = -p * n; ComplexPolynom h = (n - 1) * ((n - 1) * der * der + pol * sec); double a = 1; Complex x = new Complex(0, 0); do { x = x + (Complex)x.Iterate(pol, der, h); Complex r = (Complex)p[x]; Complex d = (Complex)der[x]; double b = d.Magnitude; a = r.Magnitude; if (b > 0) { a /= b; } }while (a > accuracy); return(x); }
/// <summary> /// Gets roots of real polynom /// </summary> /// <param name="p">Coefficients of real polynom</param> /// <returns>Complex roots</returns> public static Complex[] GetRoots(double[] p) { ComplexPolynom pol = new ComplexPolynom(p); Complex[] c = pol.Roots(1e-15); return(c); }
/// <summary> /// Addition /// </summary> /// <param name="a">First term</param> /// <param name="b">Second term</param> /// <returns>Sum</returns> public static ComplexPolynom operator +(ComplexPolynom a, ComplexPolynom b) { Complex[] max = a.coeff; int min = b.coeff.Length; if (max.Length < min) { max = b.coeff; min = a.coeff.Length; } int i = 0; Complex[] c = new Complex[max.Length]; for (; i < min; i++) { c[i] = a.coeff[i] + b.coeff[i]; } if (a.coeff.Length == b.coeff.Length) { ComplexPolynom p = new ComplexPolynom(c); p.Reduce(); return(p); } for (; i < max.Length; i++) { c[i] = new Complex(max[i].Real, max[i].Imaginary); } return(new ComplexPolynom(c)); }
IDivision IDivision.Divide(IDivision divisor, out IDivision reminder) { ComplexPolynom pd = divisor as ComplexPolynom; ComplexPolynom[] cp = Divide(pd); cp[1].Reduce(); reminder = cp[1]; return(cp[0]); }
/// <summary> /// Divides this polynom with reminder /// </summary> /// <param name="divisor">Divisor</param> /// <returns>{Divident, Reminder}</returns> public ComplexPolynom[] Divide(ComplexPolynom divisor) { Complex[] cf = divisor.coeff; ComplexPolynom rem = Copy; if (cf.Length > coeff.Length) { return(new ComplexPolynom[] { new ComplexPolynom(new Complex[] { new Complex() }), rem }); } List <Complex> q = new List <Complex>(); Complex lead = cf[cf.Length - 1]; do { Complex[] cr = rem.coeff; Complex cm = cr[cr.Length - 1]; if (cm.Magnitude < 1e-15) { q.Add(0); Complex[] c = new Complex[cr.Length - 1]; Array.Copy(cr, c, c.Length); rem = new ComplexPolynom(c); } else { int dr = rem.Deg; Complex cn = cm / lead; q.Add(cn); ComplexPolynom cp = -(Monom(rem.Deg - divisor.Deg, cn) * divisor); rem = rem + cp; rem = rem.Cut(dr); /* for (int i = rem.Deg; i < dr; i++) * { * q.Add(0); * }*/ if (rem.Deg < divisor.Deg) { break; } cm = rem.coeff[rem.coeff.Length - 1]; } //Complex re }while (rem.Deg >= divisor.Deg); Complex[] crr = new Complex[q.Count]; for (int i = 0; i < crr.Length; i++) { crr[i] = q[q.Count - i - 1]; } return(new ComplexPolynom[] { new ComplexPolynom(crr), rem }); }
/// <summary> /// Iteration for finding roots /// </summary> /// <param name="complex">Complex</param> /// <param name="p">Polynom</param> /// <param name="der">Derivation</param> /// <param name="h">Auxiliary polynom</param> /// <returns>Iteration result</returns> internal static Complex Iterate(this Complex complex, ComplexPolynom p, ComplexPolynom der, ComplexPolynom h) { Complex he = (Complex)h[complex]; Complex sq = he.Sqrt(); Complex d = (Complex)der[complex]; Complex den1 = (Complex)(d + sq); Complex den2 = (Complex)(d - sq); Complex den = (den1.Magnitude > den2.Magnitude) ? den1 : den2; return((Complex)p[complex] / den); }
/// <summary> /// Finds all roots of polynom /// </summary> /// <param name="accuracy">Accuracy</param> /// <returns>Array of roots</returns> public Complex[] Roots(double accuracy) { if (Deg == 1) { return(new Complex[] { (-coeff[0] / coeff[1]) }); } if (Deg == 2) { return(SquareRoots); } ComplexPolynom polynom = this; ComplexPolynom p = this; ComplexPolynom deri = Derivation; IDivision div = this; ComplexPolynom comd = StaticExtensionClassicalAlgebra.GreatestCommonDivisor(this, deri) as ComplexPolynom; if (comd.Deg > 0) { List <Complex> r = new List <Complex>(); ComplexPolynom divcomdeg = Divide(comd)[0]; Complex[] r1 = comd.Roots(accuracy); Complex[] r2 = divcomdeg.Roots(accuracy); r.AddRange(r1); r.AddRange(r2); return(r.ToArray()); } Complex[] roots = new Complex[p.Deg]; for (int i = 0; i < roots.Length; i++) { if (p.Deg == 1) { roots[i] = (-p.coeff[0]) / p.coeff[1]; break; } Complex x = p.Root(accuracy); roots[i] = x; ComplexPolynom pol = new ComplexPolynom(new Complex[] { -x, 1 }); p = p.Divide(pol)[0]; } return(roots); }