【问题标题】:newtons methods implementation牛顿法实现
【发布时间】:2011-10-07 06:19:57
【问题描述】:

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

#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,所以我的问题是我应该改变多小或者我应该如何改变我的代码这样那,得到正确答案吗?

【问题讨论】:

    标签: c++ numerical-methods


    【解决方案1】:

    几件事:

    1. 即使在最好的情况下,2 次迭代也很少足够。
    2. 您需要确保您的起点实际上是收敛的。
    3. 注意derivative 函数中的破坏性取消。您正在减去两个彼此非常接近的数字,因此差异会损失很多精度。

    在最后一点上展开,一般的方法是随着值的收敛减小h。但正如我在上一个问题中提到的,这种“调整”h 方法本质上(代数上)简化为正割方法。

    【讨论】:

      【解决方案2】:

      如果你将 h 设置得太小,那么由于浮点舍入,你的导数将不准确。您的代码将受益于使用双精度而不是单精度,特别是当您通过有限差分进行微分时。使用双精度,您的 h 值会很好。如果您坚持单精度,则需要使用更大的值。

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

      另外,不需要使用 pow。只需写 1e-7。

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

        • 我想用格鲁吉亚语(madloba)表示感谢 :) 非常感谢
        猜你喜欢
        • 2019-09-08
        • 1970-01-01
        • 1970-01-01
        • 2013-10-17
        • 2017-05-05
        • 1970-01-01
        • 2015-06-22
        • 2019-06-27
        • 2012-06-24
        相关资源
        最近更新 更多