【问题标题】:C/C++ - Iteration counter for Newton's MethodC/C++ - 牛顿法的迭代计数器
【发布时间】:2012-11-17 17:03:53
【问题描述】:

我创建了一个运行牛顿法的函数,用于逼近函数(定义为 f)的解。我的函数可以很好地返回根的更好近似值,但是它不会正确显示函数中执行的迭代次数。

这是我的代码:

#include <stdio.h> 
#include <math.h> 
#include <cstdlib>
#include <iostream>

double newton(double x_0, double newtonaccuracy);

double f(double x);

double f_prime(double x);

int main() 
{
   double x_0;  

   double newtonaccuracy;  

   int converged;  

   int iter;

   printf("Enter the initial estimate for x : ");

   scanf("%lf", &x_0);

   _flushall();

   printf("\n\nEnter the accuracy required : ");

   scanf("%lf", &newtonaccuracy);

   _flushall();


   if (converged == 1) 
      {
        printf("\n\nNewton's Method required %d iterations for accuracy to %lf.\n", iter, newtonaccuracy);

        printf("\n\nThe root using Newton's Method is x = %.16lf\n", newton(x_0, newtonaccuracy));
      } 

   else 
      {
        printf("Newton algorithm didn't converge after %d steps.\n", iter);
      }



      system("PAUSE");
} 


double newton(double x_0, double newtonaccuracy) 
{
   double x = x_0;

   double x_prev;

   int iter = 0;


   do 
   {
      iter++;


      x_prev = x;

      x = x_prev - f(x_prev)/f_prime(x_prev);

   } 
   while (fabs(x - x_prev) > newtonaccuracy && iter < 100);

   if (fabs(x - x_prev) <= newtonaccuracy)
   {
      int converged = 1;
   }  
   else
   {
      int converged = 0; 
   }   




    return x;
}  


double f(double x) {
       return ( cos(2*x) - x );
}  

double f_prime(double x) 
{
   return ( -2*sin(2*x)-1 ); 
}  

为了尽可能具体,它是行:

printf("\n\nNewton's Method required %d iterations for accuracy to %lf.\n", iter, newtonaccuracy);

这给我带来了麻烦。每次我运行这个程序时,它都会说“牛顿法需要 2686764 次迭代......”但是这不可能是真的,前提是我编码正确(我的代码允许的最大迭代次数是 100)。

【问题讨论】:

    标签: c++ c function printf


    【解决方案1】:

    main 中使用的变量 iter 未初始化或未在 newton 函数中使用,您在其中使用局部变量 iter。您需要通过引用将iter 传递给newton,或者找到从函数中返回它的方法。

    下面是一个通过引用获取一些参数并对其进行修改的函数示例:

    double foo(double& initial_value, int& iterations)
    {
      initial_value *= 3.14159;
      iterations = 42;
      return initial_value/2.;
    }
    

    从调用方:

    double x + 12345.;
    int iter = 0;
    double y = foo(initial_value, iter);
    

    【讨论】:

    • @juanchopanza 感谢您的回复。最直接的方法是什么?我知道我不能使用 return,因为它已经用于给出 x。我只是习惯了编程! (另外,我发现我在“converged”上犯了同样的错误)。如果您有类似的方法来处理此问题,将不胜感激。
    • @juanchopanza 感谢您的详细说明,但我无法将您的示例与我正在尝试做的事情联系起来。您介意就我的代码解释一下需要做什么才能至少正确显示迭代次数吗?
    • @Mel 将您的newton 函数更改为引用iterconverged,并且不要在函数体内重新定义它们。您可能还想将converged 设为bool 而不是int
    猜你喜欢
    • 2018-07-30
    • 1970-01-01
    • 2022-01-16
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多