Exemple #1
0
        /// <summary>
        /// output string represents "c1x + c0"
        /// </summary>
        public static string PolynomialToString(WWComplex c1, WWComplex c0, string variableSymbol)
        {
            if (c1.Magnitude() == 0)
            {
                return(string.Format("{0}", c0));
            }

            return(string.Format("{0}{1}", FirstCoeffToString(c1, variableSymbol), ZeroOrderCoeffToString(c0)));
        }
        /// <summary>
        /// rational poly
        ///   n1x + n0
        ///  ----------
        ///   d1x + d0
        /// </summary>
        /// <param name="n1">numerator first orderPlus1 coefficient</param>
        /// <param name="n0">numerator zero orderPlus1 coefficient</param>
        /// <param name="d1">denominator first orderPlus1 coefficient</param>
        /// <param name="d0">denominator zero orderPlus1 coefficient</param>
        public FirstOrderComplexRationalPolynomial(WWComplex n1, WWComplex n0, WWComplex d1, WWComplex d0)
        {
            if (d1.Magnitude() == 0 && d0.Magnitude() == 0)
            {
                throw new DivideByZeroException();
            }

            numer[1] = n1;
            numer[0] = n0;
            denom[1] = d1;
            denom[0] = d0;
        }
Exemple #3
0
        /// <summary>
        /// 1乗以上の項が存在するときに、そのあとにつなげて書くときの定数項の値表示。
        /// </summary>
        public static string ZeroOrderCoeffToString(WWComplex c)
        {
            if (c.Magnitude() == 0)
            {
                return("");
            }

            if (c.imaginary == 0)
            {
                if (c.real < 0)
                {
                    return(string.Format(" {0}", c.real));
                }
                else
                {
                    return(string.Format(" +{0}", c.real));
                }
            }

            if (c.real == 0)
            {
                if (c.imaginary == 1)
                {
                    return(string.Format(" {0}", WWComplex.imaginaryUnit));
                }

                if (c.imaginary == -1)
                {
                    return(string.Format(" -{0}", WWComplex.imaginaryUnit));
                }

                if (c.imaginary < 0)
                {
                    return(string.Format(" {0}{1}", c.imaginary, WWComplex.imaginaryUnit));
                }
                else
                {
                    return(string.Format(" +{0}{1}", c.imaginary, WWComplex.imaginaryUnit));
                }
            }

            if (c.real < 0)
            {
                return(c.ToString());
            }
            else
            {
                return(string.Format(" +{0}", c));
            }
        }
Exemple #4
0
        /// <summary>
        /// output string represents "c2x^2 + c1x + c0"
        /// </summary>
        public static string PolynomialToString(WWComplex c2, WWComplex c1, WWComplex c0, string variableSymbol)
        {
            if (c2.Magnitude() == 0)
            {
                // 1乗以下の項のみ。
                return(PolynomialToString(c1, c0, variableSymbol));
            }

            if (c1.Magnitude() == 0 && c0.Magnitude() == 0)
            {
                // 2乗の項のみ。
                return(FirstCoeffToString(c2, string.Format("{0}^2", variableSymbol)));
            }

            if (c0.Magnitude() == 0)
            {
                // 2乗の項と1乗の項。
                return(string.Format("{0}{1}",
                                     FirstCoeffToString(c2, string.Format("{0}^2", variableSymbol)),
                                     ContinuedCoeffToString(c1, variableSymbol)));
            }

            if (c1.Magnitude() == 0)
            {
                // 2乗の項と定数項。
                return(string.Format("{0}{1}",
                                     FirstCoeffToString(c2, string.Format("{0}^2", variableSymbol)),
                                     ZeroOrderCoeffToString(c0)));
            }

            // 2乗+1乗+定数
            return(string.Format("{0}{1}{2}",
                                 FirstCoeffToString(c2, string.Format("{0}^2", variableSymbol)),
                                 ContinuedCoeffToString(c1, variableSymbol),
                                 ZeroOrderCoeffToString(c0)));
        }
        private void FindRootCubic(double[] coeffs)
        {
            // 3次多項式 cubic poly equation
            // https://en.wikipedia.org/wiki/Cubic_function#Algebraic_solution
            System.Diagnostics.Debug.Assert(4 == coeffs.Length);
            double a = coeffs[3];
            double b = coeffs[2];
            double c = coeffs[1];
            double d = coeffs[0];

            double Δ =
                18 * a * b * c * d
                - 4 * b * b * b * d
                + 1 * b * b * c * c
                - 4 * a * c * c * c
                - 27 * a * a * d * d;

            double Δ0 = b * b - 3 * a * c;

            // ↓ 雑な0かどうかの判定処理。
            if (AlmostZero(Δ))
            {
                if (AlmostZero(Δ0))
                {
                    // triple root
                    double root = -b / (3 * a);
                    mRoots.Add(new WWComplex(root, 0));
                    mRoots.Add(new WWComplex(root, 0));
                    mRoots.Add(new WWComplex(root, 0));
                    return;
                }
                // double root and a simple root
                double root2 = (9 * a * d - b * c) / (2 * Δ0);
                double root1 = (4 * a * b * c - 9 * a * a * d - b * b * b);
                mRoots.Add(new WWComplex(root2, 0));
                mRoots.Add(new WWComplex(root2, 0));
                mRoots.Add(new WWComplex(root1, 0));
                return;
            }

            {
                double Δ1 =
                    +2 * b * b * b
                    - 9 * a * b * c
                    + 27 * a * a * d;

                WWComplex C;
                {
                    WWComplex c1 = new WWComplex(Δ1 / 2, 0);

                    double    c2Sqrt = Math.Sqrt(Math.Abs(-27 * a * a * Δ) / 4);
                    WWComplex c2;
                    if (Δ < 0)
                    {
                        //C2 is real number
                        c2 = new WWComplex(c2Sqrt, 0);
                    }
                    else
                    {
                        //C2 is imaginary number
                        c2 = new WWComplex(0, c2Sqrt);
                    }

                    WWComplex c1c2;
                    WWComplex c1Pc2 = WWComplex.Add(c1, c2);
                    WWComplex c1Mc2 = WWComplex.Sub(c1, c2);
                    if (c1Mc2.Magnitude() <= c1Pc2.Magnitude())
                    {
                        c1c2 = c1Pc2;
                    }
                    else
                    {
                        c1c2 = c1Mc2;
                    }

                    // 3乗根 = 大きさが3分の1乗で角度が3分の1.
                    double magnitude = c1c2.Magnitude();
                    double phase     = c1c2.Phase();
                    double cMag      = Math.Pow(magnitude, 1.0 / 3.0);
                    double cPhase    = phase / 3;

                    C = new WWComplex(cMag * Math.Cos(cPhase), cMag * Math.Sin(cPhase));
                }

                var ζ   = new WWComplex(-1.0 / 2.0, 1.0 / 2.0 * Math.Sqrt(3.0));
                var ζ2  = new WWComplex(-1.0 / 2.0, -1.0 / 2.0 * Math.Sqrt(3.0));
                var r3a = new WWComplex(-1.0 / 3.0 / a, 0);

                WWComplex root0 = WWComplex.Mul(r3a, WWComplex.Add(
                                                    WWComplex.Add(new WWComplex(b, 0), C),
                                                    WWComplex.Div(new WWComplex(Δ0, 0), C)));

                WWComplex root1 = WWComplex.Mul(r3a, WWComplex.Add(
                                                    WWComplex.Add(new WWComplex(b, 0), WWComplex.Mul(ζ, C)),
                                                    WWComplex.Div(new WWComplex(Δ0, 0), WWComplex.Mul(ζ, C))));

                WWComplex root2 = WWComplex.Mul(r3a, WWComplex.Add(
                                                    WWComplex.Add(new WWComplex(b, 0), WWComplex.Mul(ζ2, C)),
                                                    WWComplex.Div(new WWComplex(Δ0, 0), WWComplex.Mul(ζ2, C))));

                mRoots.Add(root0);
                mRoots.Add(root1);
                mRoots.Add(root2);
                return;
            }
        }