Add(ComplexPolynomial lhs, ComplexPolynomial rhs)
        {
            int order = lhs.Degree;

            if (order < rhs.Degree)
            {
                order = rhs.Degree;
            }

            var rv = new WWComplex[order + 1];

            for (int i = 0; i <= order; ++i)
            {
                WWComplex ck = WWComplex.Zero();
                if (i <= lhs.Degree)
                {
                    ck = WWComplex.Add(ck, lhs.C(i));
                }
                if (i <= rhs.Degree)
                {
                    ck = WWComplex.Add(ck, rhs.C(i));
                }
                rv[i] = ck;
            }

            // 最高次の項が0のとき削除して次数を減らす。
            return(new ComplexPolynomial(rv).ReduceDegree());
        }
Beispiel #2
0
        MulComplexConjugatePair(ComplexPolynomial p0)
        {
            if (p0.Degree != 1)
            {
                throw new ArgumentException("p0");
            }

            var n0 = p0.Coeffs();

            // n1: 共役の多項式の係数
            var n1 = new WWComplex[2];

            for (int i = 0; i < 2; ++i)
            {
                n1[i] = n0[i].ComplexConjugate();
            }

            var n = new double[3];

            n[0] = WWComplex.Mul(n0[0], n1[0]).real;
            n[1] = WWComplex.Add(WWComplex.Mul(n0[0], n1[1]), WWComplex.Mul(n0[1], n1[0])).real;
            n[2] = WWComplex.Mul(n0[1], n1[1]).real;

            return(new RealPolynomial(n));
        }
        MultiplyC(ComplexPolynomial p, WWComplex c)
        {
            var rv = new WWComplex[p.Degree + 1];

            for (int i = 0; i <= p.Degree; ++i)
            {
                rv[i] = WWComplex.Mul(p.C(i), c);
            }
            return(new ComplexPolynomial(rv));
        }
        MultiplyX(ComplexPolynomial p)
        {
            var rv = new WWComplex [p.Degree + 2];

            rv[0] = WWComplex.Zero();
            for (int i = 0; i <= p.Degree; ++i)
            {
                rv[i + 1] = p.C(i);
            }
            return(new ComplexPolynomial(rv));
        }
Beispiel #5
0
        Reduction(WWComplex [] aNumerCoeffList, WWComplex [] aDenomRootList)
        {
            var rv = new PolynomialAndRationalPolynomial();

            rv.coeffList      = new WWComplex[0];
            rv.numerCoeffList = new WWComplex[aNumerCoeffList.Length];
            Array.Copy(aNumerCoeffList, rv.numerCoeffList, aNumerCoeffList.Length);
            rv.denomRootList = new WWComplex[aDenomRootList.Length];
            Array.Copy(aDenomRootList, rv.denomRootList, aDenomRootList.Length);

            if (rv.numerCoeffList.Length - 1 < rv.denomRootList.Length)
            {
                // 既に分子の多項式の次数が分母の多項式の次数よりも低い。
                return(rv);
            }

            // 分母の根のリスト⇒分母の多項式の係数のリストに変換。
            var denomCoeffList = RootListToCoeffList(aDenomRootList, new WWComplex(1, 0));

            var quotient = new List <WWComplex>();

            while (denomCoeffList.Length <= rv.numerCoeffList.Length)
            {
                // denomの最も次数が高い項の係数がcdn、numerの最も次数が高い項の係数がcnnとすると
                // denomiCoeffListを-cnn/cdn * s^(numerの次数-denomの次数)倍してnumerCoeffListと足し合わせてnumerの次数を1下げる。
                // このときrv.coeffListにc == cnn/cdnを足す。
                var c = WWComplex.Div(rv.numerCoeffList[rv.numerCoeffList.Length - 1],
                                      denomCoeffList[denomCoeffList.Length - 1]);
                quotient.Insert(0, c);
                var denomMulX = new ComplexPolynomial(denomCoeffList);
                while (denomMulX.Degree + 1 < rv.numerCoeffList.Length)
                {
                    denomMulX = ComplexPolynomial.MultiplyX(denomMulX);
                }
                denomMulX = ComplexPolynomial.MultiplyC(denomMulX, WWComplex.Mul(c, -1));

                // ここで引き算することで分子の多項式の次数が1減る。
                int expectedOrder = rv.numerCoeffList.Length - 2;
                rv.numerCoeffList = ComplexPolynomial.TrimPolynomialOrder(
                    ComplexPolynomial.Add(denomMulX, new ComplexPolynomial(rv.numerCoeffList)),
                    expectedOrder).ToArray();

                // 引き算によって一挙に2以上次数が減った場合coeffListに0を足す。
                int actualOrder = rv.numerCoeffList.Length - 1;
                for (int i = 0; i < expectedOrder - actualOrder; ++i)
                {
                    quotient.Insert(0, WWComplex.Zero());
                }
            }

            rv.coeffList = quotient.ToArray();
            return(rv);
        }
        TrimPolynomialOrder(ComplexPolynomial p, int n)
        {
            int newOrder = n;

            if (p.Degree < newOrder)
            {
                newOrder = p.Degree;
            }
            var rv = new WWComplex[newOrder + 1];

            for (int i = 0; i <= newOrder; ++i)
            {
                rv[i] = p.C(i);
            }

            //強制的に次数を減らした結果最高位の係数が0になったとき次数を減らす処理。
            return(new ComplexPolynomial(rv).ReduceDegree());
        }
Beispiel #7
0
        RootListToCoeffList(WWComplex [] b, WWComplex c)
        {
            var coeff = new List <WWComplex>();

            if (b.Length == 0)
            {
                // 定数項のみ。(?)
                coeff.Add(c);
                return(coeff.ToArray());
            }

            var b2 = new List <WWComplex>();

            foreach (var i in b)
            {
                b2.Add(i);
            }

            // (p-b[0])
            coeff.Add(WWComplex.Mul(b2[0], -1));
            coeff.Add(WWComplex.Unity());

            b2.RemoveAt(0);

            WWComplex[] coeffArray = coeff.ToArray();
            while (0 < b2.Count)
            {
                // 多項式に(p-b[k])を掛ける。
                var s1 = ComplexPolynomial.MultiplyX(new ComplexPolynomial(coeffArray));
                var s0 = ComplexPolynomial.MultiplyC(new ComplexPolynomial(coeffArray),
                                                     WWComplex.Mul(b2[0], -1));
                coeffArray = ComplexPolynomial.Add(s1, s0).ToArray();
                b2.RemoveAt(0);
            }

            return(ComplexPolynomial.MultiplyC(new ComplexPolynomial(coeffArray), c).ToArray());
        }
Beispiel #8
0
        Add(HighOrderComplexRationalPolynomial lhs, FirstOrderComplexRationalPolynomial rhs)
        {
            /*  nL          nR
             * p^2+2x+2    p+4
             * ───────── + ────
             * p^2+ p+1    p+3
             *  dL          dR
             *
             *          dL       dR
             * 分母 = (p^2+p+1) (p+3)
             * 分母の次数 = degree(dL) + degree(dR) + 1
             *
             *          nL       dR      nR    dL
             * 分子 = (p^2+2x+2)(p+3) + (p+4)(p^2+p+1)
             * 分子の次数 = degree(nL) + degree(dR) + 1 か degree(nR) * degree(dL) + 1の大きいほう
             */

            ComplexPolynomial denomL;
            {
                var d = new WWComplex[lhs.DenomDegree() + 1];
                for (int i = 0; i <= lhs.DenomDegree(); ++i)
                {
                    d[i] = lhs.D(i);
                }
                denomL = new ComplexPolynomial(d);
            }
            ComplexPolynomial numerL;
            {
                var n = new WWComplex[lhs.NumerDegree() + 1];
                for (int i = 0; i <= lhs.NumerDegree(); ++i)
                {
                    n[i] = lhs.N(i);
                }
                numerL = new ComplexPolynomial(n);
            }

            // 分母の項
            ComplexPolynomial denomResult;
            {
                var denomX = new ComplexPolynomial(new WWComplex[0]);
                if (1 == rhs.DenomDegree())
                {
                    denomX = ComplexPolynomial.MultiplyC(ComplexPolynomial.MultiplyX(denomL), rhs.D(1));
                }
                var denomC = ComplexPolynomial.MultiplyC(denomL, rhs.D(0));
                denomResult = ComplexPolynomial.Add(denomX, denomC);
            }

            // 分子の項
            ComplexPolynomial numerResult;

            {
                ComplexPolynomial numer0;
                {
                    var numerX0 = new ComplexPolynomial(new WWComplex[0]);
                    if (1 == rhs.DenomDegree())
                    {
                        numerX0 = ComplexPolynomial.MultiplyC(ComplexPolynomial.MultiplyX(numerL), rhs.D(1));
                    }
                    var numerC0 = ComplexPolynomial.MultiplyC(numerL, rhs.D(0));
                    numer0 = ComplexPolynomial.Add(numerX0, numerC0);
                }

                ComplexPolynomial numer1;
                {
                    var numerX1 = new ComplexPolynomial(new WWComplex[0]);
                    if (1 == rhs.NumerDegree())
                    {
                        numerX1 = ComplexPolynomial.MultiplyC(ComplexPolynomial.MultiplyX(denomL), rhs.N(1));
                    }
                    var numerC1 = ComplexPolynomial.MultiplyC(denomL, rhs.N(0));
                    numer1 = ComplexPolynomial.Add(numerX1, numerC1);
                }

                numerResult = ComplexPolynomial.Add(numer0, numer1);
            }

            return(new HighOrderComplexRationalPolynomial(numerResult.ToArray(), denomResult.ToArray()));
        }