牛顿-拉夫森方法中的迭代计数
Counting iterations in Newton-Raphson's method
我在一个简单的程序中工作,使用牛顿-拉夫森的方法计算任何给定函数的根。在这个程序中,我必须打印找到的根和迭代的次数。程序本身很好,我可以找到任何给定函数的根,但我不能正确地计算迭代的次数。它总是5除以最大值。迭代次数或比它少1。下面是c++的代码:
#include <iostream>
#include <math.h>
#include <stdlib.h>
using namespace std;
double f(float x)
{
double function1;
function1 = exp(x)- 4*pow(x,2); // given function
return function1;
}
double derivative(float x)
{
double derivative1;
derivative1 = exp(x) - 8*x; // derivative of given function
return derivative1;
}
void newtonMethod(double x0, double error, int N)
{
double xNext, xPrevious, root;
int k;
xPrevious = x0;
for(int i = 0; i < N || f(xNext) > error; i++)
{
xNext = xPrevious - (f(xPrevious)/derivative(xPrevious)); // calculates the next value of x
xPrevious = xNext;
root = xNext;
k = i;
}
cout << endl;
cout << "Iterations made: " << k << endl;
cout << endl;
cout << endl;
cout << endl;
cout << "Root is: " << root << endl;
}
int main()
{
double x0, error;
int N; // max. number of iterations you can do
cout << "Enter x0: ";
cin >> x0;
cout << "Enter the error: ";
cin >> error;
cout << "Enter the max. number of iterations: ";
cin >> N;
newtonMethod(x0, error, N);
}
我很确定错误就在这段代码中:
;i < N || f(xNext) > error;
如果我运行这个程序并把N = 100,它显示正确的根,但它打印"Iterations made = 99",但这是错误的。如何打印正确的迭代次数?例如,对于上面程序中的函数(e^x - 4x²),如果输入x0 = 0.5和error = 0.0001,它应该在第四次迭代时停止。如何解决这个问题?
回答你的问题,这就是为什么下面的一段代码不能工作:
;i < N || f(xNext) > error;
这仅仅是因为,在for循环条件中,求值的是继续条件,而不是停止条件。在上面的代码中,你告诉编译器的是:继续循环,只要i < N
为真或f(xNext) > error
为真。因此,当您输入x0 = 0.5
, error = 0.0001
和N = 100
时,循环所做的是它不会停止,直到两个标准都为假,即当i达到N并且f(x)中的容差小于误差。
现在,解决方案是简单地将||
运算符交换为&&
运算符。像这样:
i < N && f(xNext) > error;
但是,你的xNext
没有初始化。因为你的xNext
和xPrevious
在每个循环结束时是相等的,所以我将简单地用xPrevious
代替。此外,正如@Rathat所写的,在f(x)中评估您的容差应该取其绝对值,因此:
i < N && abs(f(xPrevious)) > error;
最后,您应该将迭代次数输出为k + 1
,因为您从i = 0
开始。
谢谢大家的回答。除了@yuxiangDev解释得很好的for
条件背后的逻辑外,我还发现了问题所在。尽管@RatHat代码完全正确,但错误是在我使用的math.h
库中。我尝试了<cmath>
,它工作得很好!lol。
- 在C++中迭代 2D 容器的最干净方法
- C++11 迭代向量的新方法?
- 在C++上实现高斯赛德尔迭代方法
- 使用迭代器替换映射中的常量项的方法
- C++:std::ofstream 方法 open() 在第二次迭代时擦除打开的 ifstream 文件
- 在unordered_multimap中精确迭代一次每个键的有效方法
- 向后迭代 std::array 或 std::vector 的正确方法是什么?
- 创建可以遍历 std::map 值的通用模板迭代器的最简单方法是什么?
- 从基于迭代器的for循环转换后,如何在map::find()中调用方法
- 在 C++17 中实现迭代器和const_iterator的正确方法是什么?
- 如何在不迭代的情况下对数组中的每个元素调用方法
- 编译错误 std::vector<std::shared_ptr<T>>迭代器和擦除方法
- 在 c++ 中迭代对列表的正确方法?
- 如何使用 SFINAE 从 end() 方法返回 (const_) 迭代器
- 为什么STD::( multi)集提供非常量迭代方法
- Jacobi迭代方法.(帮我输出)
- 在c++中迭代方法的返回值
- 迭代方法似乎比递归实现(硬币更换)慢
- 使用我自己的迭代方法的未定义引用
- OpenGL C++QUADS中的平面细分,迭代方法