C ++ метод Ньютона-Рафсона медленнее, чем деление пополам? - PullRequest
1 голос
/ 01 мая 2020


Моя задача - найти root функции с использованием метода Ньютона-Рафсона и метода деления пополам с погрешностью 10E-7. Дело в том, что мы узнаем, что метод Ньютона-Рафсона быстрее и эффективнее. Теперь почему-то я прихожу к противоположному результату. Хотя мне известно, что первоначальное предположение о root в обоих методах сильно влияет на количество необходимых итераций. Но я ввел похожее предположение в обоих алгоритмах, и мои сокурсники не получают результат, который я получаю.

Метод деления пополам:

#include <iostream>
#include <iomanip>

using namespace std;


//Declaring the given function
double func1(double x) {

    return 0.00000000027 * (x - 10000000) - 0.16460351745 * (-1 + ((1000000000) / (x))) * 1 / (sqrt(x));

}

int main() {
    std::fixed;


    //Initial guess: root ist at 10 to the 7.
    double x1 = 10000000;
    double x2 = 1000000000;
    double eps = 0.0000001;
    int i = 0;
    double x0[100000];
    x0[0] =0;


    //Exception handler
    if (func1(x1) * func1(x2) > 0) {
        cout << "Root is not inside the bracket.";
        goto end;
    }
    goto start;


    //Bisection Algorithm 
    while (abs(x0[i] - x0[i-1]) >= eps) {

    start:

        i = i + 1;
        x0[i] = 0.5 * (x1 + x2);


        if (func1(x1) * func1(x0[i]) < 0) {

            x2 = x0[i];
        }
        else {
            x1 = x0[i];
        }





    }

    cout << endl << "Bisection Method: " << fixed << setprecision(10) << x0[i] << endl << "Iterations: " << i << endl << endl << endl << endl << endl;

    end:
    return 0;
}
}

Ньютон Рафсон:

#include <iostream>
#include <iomanip>

using namespace std;

// Declaring the function and its derivative
 double func1(double x) {

  return 0.00000000027 * (x - 10000000) - 0.16460351745 * (-1 + ((1000000000) / (x))) * 1 / (sqrt(x));

}

double funcderiv1(double x) {

     return 0.00000000027+((0.1646035174)/(2*x*x*sqrt(x)))*(30000000-x);

}


int main()
{
    std::fixed;
    double eps = 1;
    double x_start = 10000000;
    double c;

    int i = 0;

    while (eps >= 0.0000001) {


        c = x_start - ((func1(x_start)) / (funcderiv1(x_start)));
        eps = abs(func1(x_start) / funcderiv1(x_start));
        x_start = c;

        i = i + 1;



    }

    cout << fixed << setprecision(5) << "RESULT " << c << endl << " Iterations: " << i << endl;

}


root находится по адресу 17903534.23630

Кто-нибудь знает, почему моему методу деления пополам требуется 55 итераций, в то время как Ньютону Рафсону нужно 82?

1 Ответ

1 голос
/ 01 мая 2020

Для функции

f(x) = A * (x - B) - C * (D / x - 1) / sqrt(x)

A = 0.00000000027
B = 10000000
C = 0.16460351745
D = 1000000000

правильная производная:

f'(x) = A - C (x - 3D) / (2 * x * x * sqrt(x))

Сравните это с вашим выражением:

g(x) = A - C (x - 3B) / (2 * x * x * sqrt(x))

После исправления формулы (по добавив два нуля), ваш код выполняет 6 итераций:

RESULT 17903534.23630

 Iterations: 6
...