top >
C# > 3次方程式を解く
3次方程式を解く
「解の公式は4次まである」などという言葉を聞いていたので
簡単に計算出来そうだと思っていたが、結構面倒だった。

元の式を

として

上のように変換し、展開し、a で割る。



結果、



の形式になる。
これを使ってu, v を作る。
![u=\sqrt[3]{-q+\sqrt\Delta}](http://prog-city.no-ip.info/cgi-bin/imgtex.fcgi?%5Bres=150%5D%5C%5Bu=%5Csqrt%5B3%5D%7B-q+%5Csqrt%5CDelta%7D%5C%5D)
![v=\sqrt[3]{-q-\sqrt\Delta}](http://prog-city.no-ip.info/cgi-bin/imgtex.fcgi?%5Bres=150%5D%5C%5Bv=%5Csqrt%5B3%5D%7B-q-%5Csqrt%5CDelta%7D%5C%5D)

u, v は値が3つずつある。
その中から、u * v = -p となる u + v を選ぶ。それがX。
とりあえず絶対値の差が0に近いものを選んだ。
static public Complex[] cubiceq(double p, double q) { Complex cp, cq; cp = new Complex(p, 0); cq = new Complex(q, 0); Complex[] u, v; Complex delta; double dtmp = p * p * p + q * q; delta = (dtmp< 0) ? new Complex(0, Math.Sqrt(-dtmp)) : new Complex(Math.Sqrt(dtmp), 0); u = Complex.proot(-cq + delta, 3); v = Complex.proot((-cq) - delta, 3); Complex[] result = new Complex[3]; int cnt3 = 0; for (int cnt = 0; cnt < u.Length; cnt++) { for (int cnt2 = 0; cnt2 < v.Length; cnt2++) { if (Math.Abs(Math.Abs((u[cnt] * v[cnt2]).real) - Math.Abs(p))< 0.0001) { result[cnt3++] = u[cnt] + v[cnt2]; } } } return result; } static public Complex[] cubiceq(double a, double b, double c, double d) { Complex[] res = cubiceq(-(b * b) / (9 * a * a) + c / (3 * a), (b * b * b) / (27 * a * a * a) - (b * c) / (6 * a * a) + d / (2 * a)); for (int cnt = 0; cnt < 3; cnt++) { res[cnt].real -= (b / 3.0 ); } return res; }
参考文献
高校数学+α p66 あたり (全頁pdf で読めるみたいです。)