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