Beispiel #1
0
        public static void Test()
        {
            var    p = new RealPolynomial(new double[] { -1, 0, 1 });
            double x = FindRoot(p, 2, 1e-8, 20);

            Console.WriteLine("one of the root of p^2-1=0 exists near {0}", x);
        }
Beispiel #2
0
        AlgebraicLongDivision(RealPolynomial dividend, RealPolynomial divisor)
        {
            if (dividend.Degree < divisor.Degree)
            {
                throw new ArgumentException("dividendCoef degree is smaller than divisorCoef");
            }
            AllRealDivisionResult r = new AllRealDivisionResult();

            var quotient  = new double [dividend.Degree - divisor.Degree + 1];
            var divRemain = new double[dividend.Degree + 1];

            for (int i = 0; i < divRemain.Length; ++i)
            {
                divRemain[i] = dividend.C(i);
            }
            for (int i = 0; i < quotient.Length; ++i)
            {
                double q = divRemain[dividend.Degree - i]
                           / divisor.C(divisor.Degree);
                quotient[quotient.Length - 1 - i] = q;
                for (int j = 0; j <= divisor.Degree; ++j)
                {
                    divRemain[dividend.Degree - i - j] -=
                        q * divisor.C(divisor.Degree - j);
                }
            }

            r.quotient  = new RealPolynomial(quotient);
            r.remainder = new RealRationalPolynomial(
                new RealPolynomial(divRemain).RemoveLeadingZeros(),
                divisor.RemoveLeadingZeros());
            return(r);
        }
Beispiel #3
0
        public string ToString(string variableSymbol)
        {
            string n = new RealPolynomial(numer).ToString(variableSymbol);
            string d = new RealPolynomial(denom).ToString(variableSymbol);

            return(string.Format("{{ {0} }} / {{ {1} }}", n, d));
        }
Beispiel #4
0
        public RealRationalPolynomial(RealPolynomial aNumer, RealPolynomial aDenom)
        {
            numer = new double[aNumer.Degree + 1];
            denom = new double[aDenom.Degree + 1];

            for (int i = 0; i < numer.Length; ++i)
            {
                numer[i] = aNumer.C(i);
            }

            for (int i = 0; i < denom.Length; ++i)
            {
                denom[i] = aDenom.C(i);
            }
        }
Beispiel #5
0
        public static RealPolynomial Add(RealPolynomial l, RealPolynomial r)
        {
            int degree = (l.Degree < r.Degree) ? r.Degree : l.Degree;
            var c      = new double[degree + 1];

            for (int i = 0; i <= degree; ++i)
            {
                c[i] = 0;
                if (i <= l.Degree)
                {
                    c[i] += l.C(i);
                }
                if (i <= r.Degree)
                {
                    c[i] += r.C(i);
                }
            }
            return(new RealPolynomial(c));
        }
        /// <summary>
        /// 実係数n次多項式p(x)の定積分 ∫_a^b{p(x)dx}を求める。
        /// </summary>
        /// <param name="p">実係数n次多項式p(x)。</param>
        /// <param name="a">区間a。</param>
        /// <param name="b">区間b。</param>
        /// <returns>∫_a^b{p(x)dx}</returns>
        public double Calc(RealPolynomial p, double a, double b)
        {
            // xの積分区間 [a b]
            // ξの積分区間 [-1 +1]

            double flipInterval = 1;

            if (b < a)
            {
                // swap a and b
                double t = a;
                a            = b;
                b            = t;
                flipInterval = -1;
            }

            int np     = NumberOfEvalPoints(p);
            var ξwList = GetξwList(np);

            // 定積分結果値r。
            double r = 0;

            for (int k = 0; k < np; ++k)
            {
                var ξ = ξwList[k].ξ;
                var w = ξwList[k].w;

                double x = ((a + b) + ξ * (b - a)) / 2.0;

                // 地点xでpを評価:p(x)を求める。
                double px = p.Evaluate(x);

                r += w * px;
            }

            // 積分変数をx→ξに置き換えたことによるスケーリング。
            r *= (b - a) / 2.0;

            r *= flipInterval;

            return(r);
        }
Beispiel #7
0
        Mul(RealPolynomial lhs, RealPolynomial rhs)
        {
            // 1次 p 2次 = 3次
            // 2次 p 2次 = 4次
            // 2次 p 3次 = 5次

            // (p^2+2x+3) * (4x+5)

            var c = new double[lhs.Degree + rhs.Degree + 1];

            // C#では、cの要素は0で初期化される。

            for (int iL = 0; iL <= lhs.Degree; ++iL)
            {
                for (int iR = 0; iR <= rhs.Degree; ++iR)
                {
                    c[iL + iR] += lhs.C(iL) * rhs.C(iR);
                }
            }

            return(new RealPolynomial(c));
        }
Beispiel #8
0
        /// <summary>
        /// Find one real root of specified real poly
        /// </summary>
        /// <param name="coeffs">poly coeffs. coef[0]: constant, coef[1] 1st degree coeff</param>
        /// <param name="initialX">initial estimate of the root position</param>
        /// <returns>p</returns>
        public static double FindRoot(RealPolynomial rpoly, double initialX, double kEpsilon, int loopCount)
        {
            var deriv = rpoly.Derivative();

            double prev = initialX;
            double x    = initialX;

            for (int i = 0; i < loopCount; ++i)
            {
                double f      = rpoly.Evaluate(x);
                double fPrime = deriv.Evaluate(x);
                x = x - f / fPrime;

                if (Math.Abs(prev - x) < kEpsilon)
                {
                    break;
                }

                prev = x;
            }

            return(x);
        }
 /// <summary>
 /// 多項式を評価する点の数。
 /// </summary>
 public static int NumberOfEvalPoints(RealPolynomial p)
 {
     return(p.Degree / 2 + 1);
 }
Beispiel #10
0
        public static void Test()
        {
            {
                /*
                 * 部分分数分解のテスト。
                 *           s + 3
                 * X(s) = -------------
                 *         (s+1)s(s-2)
                 *
                 * 部分分数分解すると
                 *
                 *          2/3      -3/2      5/6
                 * X(s) = ------- + ------ + -------
                 *         s + 1       s      s - 2
                 */
                var numerCoeffs = new WWComplex [] {
                    new WWComplex(3, 0),
                    new WWComplex(1, 0)
                };

                var dRoots = new WWComplex [] {
                    new WWComplex(-1, 0),
                    WWComplex.Zero(),
                    new WWComplex(2, 0)
                };

                var p = WWPolynomial.PartialFractionDecomposition(numerCoeffs, dRoots);

                for (int i = 0; i < p.Count; ++i)
                {
                    Console.WriteLine(p[i].ToString("s"));
                    if (i != p.Count - 1)
                    {
                        Console.WriteLine(" + ");
                    }
                }

                Console.WriteLine("");
            }

            {
                // 約分のテスト
                //  p-1        (p+1) -(p+1) + (p-1)            -2
                // ─────  ⇒  ──────────────────────  ⇒  1 + ─────
                //  p+1                  p+1                   p+1

                var numerC = new List <WWComplex>();
                numerC.Add(new WWComplex(-1, 0)); // 定数項。
                numerC.Add(WWComplex.Unity());    // 1乗の項。

                var denomR = new List <WWComplex>();
                denomR.Add(new WWComplex(-1, 0));

                var r = Reduction(numerC.ToArray(), denomR.ToArray());
                r.Print("p");
            }

            {
                // 約分のテスト
                //  p^2+3x+2            (p^2+3x+2) -(p^2+7x+12)            -4x-10
                // ────────────  ⇒ 1+ ─────────────────────────  ⇒  1 + ────────────
                //  (p+3)(p+4)           p^2+7x+12                         (p+3)(p+4)

                var numerC = new WWComplex [] {
                    new WWComplex(2, 0), // 定数項。
                    new WWComplex(3, 0), // 1乗の項。
                    WWComplex.Unity()
                };                       // 2乗の項。

                var denomR = new WWComplex [] {
                    new WWComplex(-3, 0),
                    new WWComplex(-4, 0)
                };

                var r = Reduction(numerC, denomR);
                r.Print("p");
            }
            {
                // 部分分数分解。
                //  -4x-10             2      -6
                // ────────────  ⇒  ───── + ─────
                //  (p+3)(p+4)        p+3     p+4

                var numerC = new WWComplex [] {
                    new WWComplex(-10, 0),
                    new WWComplex(-4, 0)
                };

                var denomR = new WWComplex [] {
                    new WWComplex(-3, 0),
                    new WWComplex(-4, 0)
                };

                var p = WWPolynomial.PartialFractionDecomposition(numerC, denomR);

                for (int i = 0; i < p.Count; ++i)
                {
                    Console.WriteLine(p[i].ToString("s"));
                    if (i != p.Count - 1)
                    {
                        Console.WriteLine(" + ");
                    }
                }

                Console.WriteLine("");
            }

            {
                var deriv = new RealPolynomial(new double[] { 1, 1, 1, 1 }).Derivative();
                Console.WriteLine("derivative of p^3+p^2+p+1={0}",
                                  deriv.ToString("p"));
            }

            {
                var r2 = AlgebraicLongDivision(new RealPolynomial(new double[] { 6, 3, 1 }),
                                               new RealPolynomial(new double[] { 1, 1 }));
                Console.WriteLine("(p^2+3x+6)/(p+1) = {0} r {1}",
                                  r2.quotient.ToString(), r2.remainder.ToString());
            }
        }