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()); }
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)); }
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()); }
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()); }
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())); }