牛顿方法实现

时间:2011-10-07 06:19:58

标签: c++ numerical-methods

我已经发布了几个小时前关于牛顿方法的问题,我得到了答案,并希望感谢大家,现在我已经尝试实现代码本身

#include <iostream>
#include <math.h>
using namespace std;
#define h powf(10,-7)
#define PI 180
float funct(float x){

    return cos(x)-x;


}
float derivative (float x){
    return (( funct(x+h)-funct(x-h))/(2*h));

}
int main(){
    float tol=.001;
    int N=3;
    float p0=PI/4;
    float p=0;
    int i=1;
    while(i<N){

        p=p0-(float)funct(p0)/derivative(p0);
        if ((p-p0)<tol){
            cout<<p<<endl;
            break;

        }


        i=i+1;
        p0=p;


    if (i>=N){
        cout<<"solution not found "<<endl;
        break;
    }
    }



    return 0;
}

但是我写了输出“找不到解决方案”,在n = 3的三次迭代后的书中,它找到了这个.7390851332的解决方案,所以我的问题是我应该多么小的改变h或者我该如何改变我的这样的代码,得到正确的答案?

3 个答案:

答案 0 :(得分:2)

有几件事:

  1. 即使在最好的情况下,2次迭代也很少。
  2. 您需要确保您的起点实际上是收敛的。
  3. 请注意derivative功能中的破坏性取消。你正在减去两个彼此非常接近的数字,因此差异会失去很多精确度。
  4. 要扩展最后一点,一般方法是在值收敛时减少h。但正如我在上一个问题中所提到的,这种“调整”h方法基本上(代数)减少为正割方法。

答案 1 :(得分:1)

你只允许2次迭代,这可能不足以接近答案。如果您只有1个正确的位可以启动,那么在2次迭代后,您最多可以获得大约4个好位。你正在寻找10位精度(0.001大约是1/2 ^ 10),你必须允许至少2次迭代。

此外,二次收敛属性仅在您接近解决方案时才成立。当你离开时,接近解决方案可能需要更长的时间。

使用中心差计算数值导数的最优h是单精度(浮点数)的0.005 * max(1,| x |),其中| x |是参数x的绝对值。对于双精度,它大约是5e-6 * max(1,| x |)。

答案 2 :(得分:1)

如果你的h太小,那么由于浮点舍入,你的导数将是不准确的。您的代码将受益于使用双精度而不是单精度,尤其是当您通过有限差分进行区分时。使用双精度,你的h值就可以了。如果坚持单精度,则需要使用更大的值。

仅允许2次迭代似乎相当严格。使N更大并让程序打印出所使用的迭代次数。

此外,无需使用战俘。只需写1e-7。