C++で非線形方程式を解く (2分法)
非線形方程式の解法(2分法)を利用して2の平方根を求める
1. まず, 条件 を満たす点 を考えると,
関数 の解は, 区間 の中に存在する.
2. 次に, 区間 の中点 を考えると,
であれば, 解は区間 の中に存在し,
同様に, であれば, 区間 の中に存在する.
3. この作業を繰り返して, 区間を絞り込んで行くことで解を求める.
#include <stdio.h> #include <math.h> double f(double x) { return x * x - 2; } int main() { double low = 1; double high = 2; double fa = f(low); double fb = f(high); double x; while (true) { x = (low + high) / 2; printf("%12.10f %12.10f %12.10f\n", high, low, x); double fx = f(x); if (fabs(fx) < 0.0000000001) break; if ((fx > 0) == (fa > 0)) { low = x; fa = fx; } else { high = x; fb = fx; } } printf("%12.10f %12.10f\n", x, sqrt(2)); return 0; }
2.0000000000 1.0000000000 1.5000000000 1.5000000000 1.0000000000 1.2500000000 1.5000000000 1.2500000000 1.3750000000 1.5000000000 1.3750000000 1.4375000000 1.4375000000 1.3750000000 1.4062500000 1.4375000000 1.4062500000 1.4218750000 1.4218750000 1.4062500000 1.4140625000 1.4218750000 1.4140625000 1.4179687500 1.4179687500 1.4140625000 1.4160156250 1.4160156250 1.4140625000 1.4150390625 1.4150390625 1.4140625000 1.4145507812 1.4145507812 1.4140625000 1.4143066406 1.4143066406 1.4140625000 1.4141845703 1.4143066406 1.4141845703 1.4142456055 1.4142456055 1.4141845703 1.4142150879 1.4142150879 1.4141845703 1.4141998291 1.4142150879 1.4141998291 1.4142074585 1.4142150879 1.4142074585 1.4142112732 1.4142150879 1.4142112732 1.4142131805 1.4142150879 1.4142131805 1.4142141342 1.4142141342 1.4142131805 1.4142136574 1.4142136574 1.4142131805 1.4142134190 1.4142136574 1.4142134190 1.4142135382 1.4142136574 1.4142135382 1.4142135978 1.4142135978 1.4142135382 1.4142135680 1.4142135680 1.4142135382 1.4142135531 1.4142135680 1.4142135531 1.4142135605 1.4142135680 1.4142135605 1.4142135642 1.4142135642 1.4142135605 1.4142135624 1.4142135624 1.4142135624
非線形方程式の解法(2分法)を利用して2の立方根を求める
#include <stdio.h> #include <math.h> double f(double x) { return x * x * x - 2; } int main() { double low = 1; double high = 2; double fa = f(low); double fb = f(high); double x; while (true) { x = (low + high) / 2; printf("%12.10f %12.10f %12.10f\n", high, low, x); double fx = f(x); if (fabs(fx) < 0.0000000001) break; if ((fx > 0) == (fa > 0)) { low = x; fa = fx; } else { high = x; fb = fx; } } printf("%12.10f %12.10f\n", x, cbrt(2)); return 0; }
2.0000000000 1.0000000000 1.5000000000 1.5000000000 1.0000000000 1.2500000000 1.5000000000 1.2500000000 1.3750000000 1.3750000000 1.2500000000 1.3125000000 1.3125000000 1.2500000000 1.2812500000 1.2812500000 1.2500000000 1.2656250000 1.2656250000 1.2500000000 1.2578125000 1.2656250000 1.2578125000 1.2617187500 1.2617187500 1.2578125000 1.2597656250 1.2617187500 1.2597656250 1.2607421875 1.2607421875 1.2597656250 1.2602539062 1.2602539062 1.2597656250 1.2600097656 1.2600097656 1.2597656250 1.2598876953 1.2600097656 1.2598876953 1.2599487305 1.2599487305 1.2598876953 1.2599182129 1.2599487305 1.2599182129 1.2599334717 1.2599334717 1.2599182129 1.2599258423 1.2599258423 1.2599182129 1.2599220276 1.2599220276 1.2599182129 1.2599201202 1.2599220276 1.2599201202 1.2599210739 1.2599210739 1.2599201202 1.2599205971 1.2599210739 1.2599205971 1.2599208355 1.2599210739 1.2599208355 1.2599209547 1.2599210739 1.2599209547 1.2599210143 1.2599210739 1.2599210143 1.2599210441 1.2599210739 1.2599210441 1.2599210590 1.2599210590 1.2599210441 1.2599210516 1.2599210516 1.2599210441 1.2599210478 1.2599210516 1.2599210478 1.2599210497 1.2599210516 1.2599210497 1.2599210506 1.2599210506 1.2599210497 1.2599210502 1.2599210502 1.2599210497 1.2599210499 1.2599210499 1.2599210497 1.2599210498 1.2599210499 1.2599210498 1.2599210499 1.2599210499 1.2599210499 1.2599210499 1.2599210499 1.2599210499
参考文献