/* * complex-newton.C -- Newton 法で方程式 f(x)=0 を解く * コンパイル: g++ -o complex-newton complex-newton.C * 実行: ./complex-newton * * 2016/3/22修正 */ #include <iostream> #include <complex> using namespace std; int main(void) { int i, maxitr = 100; complex<double> f(complex<double>), dfdz(complex<double>), x, dx; double eps; cout << " 初期値 x0, 許容精度ε="; cin >> x >> eps; cout.precision(16); for (i = 0; i < maxitr; i++) { dx = - f(x) / dfdz(x); x += dx; cout << "f(" << x << ")=" << f(x) << endl; if (abs(dx) <= eps) break; } return 0; } /* * この関数の例は杉原・室田『数値計算法の数理』岩波書店, p.67 による * f(z) = z^3-2z+2 * 1実根(≒-1.769292354238631),2虚根(≒0.8846461771193157±0.5897428050222054) * を持つが、原点の近くに初期値を取ると、0 と 1 の間を振動する。 */ complex<double> f(complex<double> z) { /* return z * z * z - 2 * z + 2; */ return z * (z * z - 2.0) + 2.0; } /* 関数 f の導関数 (df/dx のつもりで名前をつけた) */ complex<double> dfdz(complex<double> z) { return 3.0 * z * z - complex<double>(2,0); }
コンパイル&実行例 |
% g++ complex-newton.C % ./a.out 初期値 x0, 許容精度ε=0.3 1e-14 f((1.12485549132948,0))=(1.173568531458942,0) f((0.4713843772268934,0))=(1.161974377253067,0) f((1.342827923349606,0))=(1.735713781960667,0) f((0.8337553363070073,0))=(0.9120726492429374,0) f((-9.840767203756229,0))=(-931.3052418605159,0) f((-6.612920012816673,0))=(-273.9618545552224,0) f((-4.4923431047393,0))=(-79.67594843313302,0) f((-3.131371682066463,0))=(-22.44188600195348,0) f((-2.312816652470607,0))=(-5.745902514520807,0) f((-1.903778836863019,0))=(-1.092448577226583,0) f((-1.780659980946024,0))=(-0.0847076152532642,0) f((-1.769384049454865,0))=(-0.0006777810558658004,0) f((-1.769292360276141,0))=(-4.462436198338082e-08,0) f((-1.769292354238631,0))=(2.220446049250313e-16,0) f((-1.769292354238631,0))=(2.220446049250313e-16,0) mk@katsuradanoMacBook-Pro-555 progs-algebraic-equation % ./a.out 初期値 x0, 許容精度ε=0.1 1e-14 f((1.014213197969543,0))=(1.014822114238246,0) f((0.07965576631987636,0))=(1.841193886472037,0) f((1.009098740372765,0))=(1.009347854859992,0) f((0.05222652653371329,0))=(1.895689400532465,0) f((1.003965184727484,0))=(1.004012415140623,0) f((0.02332943565497392,0))=(1.953353826028611,0) f((1.000804353182403,0))=(1.000806294654933,0) f((0.004806794546775128,0))=(1.990386521968754,0) f((1.000034548045781,0))=(1.000034551626525,0) f((0.0002072524744252124,0))=(1.999585495060052,0) f((1.000000064421484,0))=(1.000000064421497,0) f((3.865287804272199e-07,0))=(1.999999226942439,0) f((1.000000000000224,0))=(1.000000000000224,0) f((1.34559030584569e-12,0))=(1.999999999997309,0) f((1,0))=(1,0) f((0,0))=(2,0) f((1,0))=(1,0) f((0,0))=(2,0)中略 f((0,0))=(2,0) f((1,0))=(1,0) f((0,0))=(2,0) % |
初期値 で始めると実根に収束するが、 初期値 で始めると、途中から と の間を振動する。 確かに本に書いてある通り。