C++ Newton Raphson 方法比二分法慢?
C++ Newton Raphson method is slower than bisection?
我的任务是使用 Newton Raphson 和二分法在 10E-7 的误差范围内找到函数的根。
所有这一切的重点是,我们了解到牛顿拉夫森方法更快、更有效。
现在出于某种原因,我得出了相反的结果。尽管我知道这两种方法中根的初始猜测都会强烈影响必要的迭代次数。但是我在两种算法中都输入了类似的猜测,我的同学们没有得到我做的结果。
二分法:
#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;
}
根地址为 17903534.23630
有谁知道为什么我的二分法需要 55 次迭代,而 Newton Raphson 需要 82 次迭代?
对于函数
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
我的任务是使用 Newton Raphson 和二分法在 10E-7 的误差范围内找到函数的根。
所有这一切的重点是,我们了解到牛顿拉夫森方法更快、更有效。
现在出于某种原因,我得出了相反的结果。尽管我知道这两种方法中根的初始猜测都会强烈影响必要的迭代次数。但是我在两种算法中都输入了类似的猜测,我的同学们没有得到我做的结果。
二分法:
#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;
}
根地址为 17903534.23630
有谁知道为什么我的二分法需要 55 次迭代,而 Newton Raphson 需要 82 次迭代?
对于函数
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