ONLY DO WHAT ONLY YOU CAN DO

こけたら立ちなはれ 立ったら歩きなはれ

C++で非線形方程式を解く (2分法)

非線形方程式の解法(2分法)を利用して2の平方根を求める

f:id:fornext1119:20140531160605p:plain
1. まず, 条件 a < b, f(a) < 0, f(b) > 0 を満たす点 a, b を考えると,
関数 f(x) の解は, 区間 (a,b) の中に存在する.
2. 次に, 区間 (a,b) の中点 c = (a + b) / 2 を考えると,
f(c) < 0 であれば, 解は区間 (c,b) の中に存在し,
同様に, f(c) > 0 であれば, 区間 (a,c) の中に存在する.
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
参考文献