Пример #1
0
        public ComplexD GetSqrt()
        {
            if (this.Imaginary == 0.0)
            {
                return(ComplexD.Sqrt(this.Real));
            }
            double modulus = this.GetModulus();

            return(new ComplexD((double)System.Math.Sign(this.Imaginary) * System.Math.Sqrt(0.5 * (modulus + this.Real)), System.Math.Sqrt(0.5 * (modulus - this.Real))));
        }
Пример #2
0
 public static void GetPolynomialRoots(
     IList <double> coefficients,
     IList <double> roots,
     double epsilon)
 {
     if (roots == null)
     {
         throw new ArgumentNullException(nameof(roots));
     }
     if (coefficients.Count < 2)
     {
         throw new ArgumentException("Number of coefficients must be 2 or greater.");
     }
     if (coefficients[coefficients.Count - 1] == 0.0)
     {
         throw new ArgumentException("The highest coefficient is expected to be non-zero.");
     }
     if (epsilon == 0.0)
     {
         epsilon = -1E-08;
     }
     if (coefficients.Count == 2)
     {
         roots.Add(-coefficients[0] / coefficients[1]);
     }
     else if (coefficients.Count == 3)
     {
         MathUtil.GetQuadraticPolynomialRoots(coefficients, roots);
     }
     else if (coefficients.Count == 4)
     {
         IList <double> cubicPolynomialRoots = MathUtil.GetCubicPolynomialRoots(coefficients);
         for (int index = 0; index < cubicPolynomialRoots.Count; ++index)
         {
             roots.Add(cubicPolynomialRoots[index]);
         }
     }
     else
     {
         double          rootBoundsRadius = MathUtil.GetPolynomialSingleRootBoundsRadius(coefficients);
         Pair <ComplexD> pair1            = new Pair <ComplexD>((ComplexD)(-rootBoundsRadius), (ComplexD)MathUtil.EvaluatePolynomial(coefficients, -rootBoundsRadius));
         Pair <ComplexD> pair2            = new Pair <ComplexD>((ComplexD)0.0, (ComplexD)MathUtil.EvaluatePolynomial(coefficients, 0.0));
         Pair <ComplexD> pair3            = new Pair <ComplexD>((ComplexD)rootBoundsRadius, (ComplexD)double.NaN);
         double          num1             = epsilon > 0.0 ? epsilon : -epsilon * rootBoundsRadius;
         double          num2             = num1 * num1;
         int             num3;
         ComplexD        first1;
         for (num3 = 50; (pair3.First - pair2.First).GetModulusSquared() > num2 && num3 > 0; pair3 = new Pair <ComplexD>(first1, new ComplexD(double.NaN)))
         {
             --num3;
             Pair <ComplexD> pair4             = new Pair <ComplexD>(pair3.First, MathUtil.EvaluatePolynomial(coefficients, pair3.First));
             ComplexD        dividedDifference = MathUtil.GetDividedDifference((IList <Pair <ComplexD> >) new Pair <ComplexD>[3] {
                 pair1, pair2, pair4
             }, 0, 3);
             ComplexD complexD1 = MathUtil.GetDividedDifference((IList <Pair <ComplexD> >) new Pair <ComplexD>[2] {
                 pair2, pair4
             }, 0, 2) + dividedDifference * (pair4.First - pair2.First);
             ComplexD second    = pair4.Second;
             ComplexD complexD2 = complexD1 * complexD1 - 4.0 * dividedDifference * second;
             first1 = new ComplexD(double.NaN);
             if (complexD2.Imaginary == 0.0)
             {
                 if (complexD2.Real >= 0.0)
                 {
                     first1 = second.Imaginary != 0.0 || complexD1.Imaginary != 0.0 ? pair4.First - 2.0 * second / (complexD1 + (ComplexD)((double)System.Math.Sign(complexD1.Real) * System.Math.Sqrt(complexD2.Real))) : pair4.First - (ComplexD)(2.0 * second.Real / (complexD1.Real + (double)System.Math.Sign(complexD1.Real) * System.Math.Sqrt(complexD2.Real)));
                 }
                 else
                 {
                     ComplexD complexD3 = ComplexD.Sqrt(complexD2.Real);
                     ComplexD complexD4 = complexD1 + complexD3;
                     ComplexD complexD5 = complexD1 - complexD3;
                     ComplexD complexD6 = complexD4.GetModulusSquared() >= complexD5.GetModulusSquared() ? complexD4 : complexD5;
                     first1 = pair4.First - 2.0 * second / complexD6;
                 }
             }
             else
             {
                 ComplexD sqrt      = complexD2.GetSqrt();
                 ComplexD complexD3 = complexD1 + sqrt;
                 ComplexD complexD4 = complexD1 - sqrt;
                 ComplexD complexD5 = complexD3.GetModulusSquared() >= complexD4.GetModulusSquared() ? complexD3 : complexD4;
                 first1 = pair4.First - 2.0 * second / complexD5;
             }
             pair1 = pair2;
             pair2 = pair4;
         }
         if (num3 <= 0)
         {
             return;
         }
         if (MathUtil.AreApproxEqual(pair3.First.Imaginary, 0.0, num1))
         {
             double real = pair3.First.Real;
             roots.Add(real);
             IList <double> coefficients1 = MathUtil.DeflatePolynomial(coefficients, real);
             if (epsilon > 0.0)
             {
                 while (coefficients1.Count > 1 && MathUtil.AreApproxEqual(MathUtil.EvaluatePolynomial(coefficients1, real), 0.0, epsilon))
                 {
                     coefficients1 = MathUtil.DeflatePolynomial(coefficients1, real);
                 }
             }
             else
             {
                 double largestTerm;
                 while (coefficients1.Count > 1 && MathUtil.AreApproxEqual(MathUtil.EvaluatePolynomial(coefficients1, real, out largestTerm), 0.0, -epsilon * largestTerm))
                 {
                     coefficients1 = MathUtil.DeflatePolynomial(coefficients1, real);
                 }
             }
             MathUtil.GetPolynomialRoots(coefficients1, roots, num1);
         }
         else
         {
             ComplexD first2    = pair3.First;
             double   real      = first2.Real;
             double   imaginary = first2.Imaginary;
             double   a1        = -2.0 * real;
             double   a0        = real * real + imaginary * imaginary;
             MathUtil.GetPolynomialRoots(MathUtil.DeflatePolynomial(coefficients, a0, a1), roots, num1);
         }
     }
 }