【问题标题】:Counting iterations in Newton-Raphson's method在 Newton-Raphson 方法中计算迭代次数
【发布时间】:2017-02-27 00:20:03
【问题描述】:

我正在编写一个简单的程序,该程序使用 Newton-Raphson 方法计算任何给定函数的根。在这个程序中,我必须打印找到的根和进行的迭代次数。程序本身很好,我可以找到任何给定函数的根,但我无法正确计算迭代次数。它总是超过最大值 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 且错误 = 0.0001,它应该在第四次迭代中停止。如何解决?

【问题讨论】:

  • 计算机以二进制而非十进制工作。 0.0001 不能用二进制精确表示,因此您可能/不会得到确切的答案。 -- 对于上面程序中的函数 (e^x - 4x²),如果我输入 x0 = 0.5 并且错误 = 0.0001,它应该在第四次迭代中停止。 -- 在你的数学书中,是的,在二进制计算机上,也许,也许不是。
  • 这不是问题,但是像double f(float x) { double function1; function1 = exp(x)- 4*pow(x,2); return function1; } 这样的代码太冗长了。 double f(floats x) { return exp(x) - 4 * pow(x, 2); } 做同样的事情并且更容易阅读。
  • 你说得对,代码部分太冗长了,但这不是重点。我用二分法编写了另一个程序,一切都运行得很好。输入数字“0.0001”不会导致意外错误。我只是不明白是什么导致了牛顿方法中的这个错误。
  • @Diego 所有这一切都归结为一个简单的事实,即浮点数并不精确。我不知道说起来有多简单。无论您是尝试实现 Newton-Raphson,还是简单地将几个数字相加,都会导致舍入错误。

标签: c++ count newtons-method


【解决方案1】:

回答您的问题,这就是为什么以下代码不起作用:

;i < N || f(xNext) > error;

这仅仅是因为,在 for 循环条件中,评估的是 继续 条件,而不是 停止 条件。 在上面的代码中,您告诉编译器的是:继续只要i &lt; N 为真或f(xNext) &gt; error 为真,循环。因此,当您输入x0 = 0.5error = 0.0001N = 100 时,循环所做的是它不会停止,直到两个条件都为假,即当 i 达到 N 和 f 中的容差时(x) 小于 error

现在,解决方案是将|| 运算符换成&amp;&amp; 运算符。像这样:

i < N && f(xNext) > error;

但是,您的xNext 未初始化。因为您的 xNextxPrevious 在每个循环结束时是相等的,所以我会简单地使用 xPrevious 代替。此外,正如@Rathat 所写,评估您在 f(x) 中的容差应该采用其绝对值,因此:

i < N && abs(f(xPrevious)) > error;

最后,您应该将迭代次数输出为k + 1,因为您从i = 0开始。

这应该可以解决您的问题。

【讨论】:

  • 很好的答案!
【解决方案2】:

感谢所有答案。除了@yuxiangDev 解释得很好的for 条件背后的逻辑之外,我还发现了问题所在。尽管@RatHat 代码完全正确,但错误出现在我正在使用的math.h 库中。我试过&lt;cmath&gt;,效果很好!哈哈。

【讨论】:

    猜你喜欢
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 1970-01-01
    • 2014-01-30
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多