C 牛顿-拉斐逊法中的无限循环

C 牛顿-拉斐逊法中的无限循环,c,infinite-loop,newtons-method,C,Infinite Loop,Newtons Method,我正在写一个程序来计算lambda的值,除非它被困在do循环中。它似乎没有更新n值,因为我希望通过设置nMax=100,它至少能够在另一种情况(eps>=e_allow)从未发生的情况下快速完成。有人能指出无限循环的来源吗 非常感谢你的帮助。我的计划是: #include <stdio.h> #include <stdlib.h> #include <math.h> //Solution to Linear Dispersion Relationship f

我正在写一个程序来计算lambda的值,除非它被困在do循环中。它似乎没有更新n值,因为我希望通过设置nMax=100,它至少能够在另一种情况(eps>=e_allow)从未发生的情况下快速完成。有人能指出无限循环的来源吗

非常感谢你的帮助。我的计划是:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

//Solution to Linear Dispersion Relationship for a Horizontal Bottom

double f ( double, double, double, double);
double df (double, double, double); 

int main(void) {


    float pi = 3.1415927;
    double g = 9.81;                //Acceleration due to gravity
    double omega;                  //Angular frequency of wave
    double kn, dk;             //Wave numbers
    double e_allow, eps;    //Tolerance used to find difference between kNew and kOld   
    int nMax, n;          // Setting up counter for iterations
    double lambda;                 //Value we need to solve for 
    double h, T;                   //Depth and Period. User needs to input these values.
    double fn, dfn;               //Declaring functions describing linear dispersion


    printf("Enter the value of the depth (m).\n");
    scanf("%lf", &h); 
    printf("\nEnter the value for the period (s).\n");
    scanf("%lf", &T);


    /* 
    Assuming shallow water conditions. Therefore, tanh(k*d) --> kd. kOld is calculated using 
    the relationship omega^2 = kold^2/(g*d) 
    */

    omega = (2.0 * pi)/T;
    printf("Angular velocity = %.5f\n", omega); 
    kn = sqrt((omega * omega)/(g * h));             
    printf("Wave number kn = %.5f\n", kn);

    e_allow = 1.0e-5;
    n = 0; 
    nMax = 100;

    //Following the Newton Raphson Method
    do {
        fn = f(kn, omega, g, h);
        dfn = df(kn, g, h);
        dk = -(fn/dfn);
        kn = kn + dk;
        eps = fabs(dk/kn);
        n = n + 1;
    } while (eps >= e_allow || n == nMax);


    //Calculating value of lambda using final kn value. 
    lambda = (2.0 * pi)/kn;


    //printf("\nfn = %.6f, dfn = %.6f, dx = %.6f, eps = %.6f\n", fn, dfn, dk, eps);


    printf("\nkn = %.5lf, Wavelength = %.5lf\n", kn, lambda); */

    //printf("fn = %.6lf, dfn = %.6lf, eps = %.6lf, dk = %.6lf, kn = %.6lf\n", fn, dfn, eps, dk, kn);



    return 0;

}


double f (double kn, double omega, double g, double h) {
    return ((omega*omega) - (g * kn * tanh(kn * h)));
}

double df (double kn, double g, double h) {
    return ((( g * kn * h )/( 1 + ( h * h * kn * kn ))) - g * tanh( kn * h));
}
#包括
#包括
#包括
//水平底面线性色散关系的求解
双f(双,双,双,双);
双df(双,双,双);
内部主(空){
浮点数pi=3.1415927;
双g=9.81;//重力引起的加速度
双ω;//波的角频率
双kn,dk;//波数
double e_allow,eps;//用于查找Knowed和kOld之间差异的公差
int nMax,n;//设置迭代计数器
double lambda;//我们需要求解的值
双h,T;//深度和周期。用户需要输入这些值。
双fn,dfn;//声明描述线性色散的函数
printf(“输入深度值(m)。\n”);
扫描频率(“%lf”、&h);
printf(“\n输入该期间的值。\n”);
扫描频率(“%lf”、&T);
/* 
假设浅水条件。因此,tanh(k*d)-->kd.kOld使用
ω^2=kold^2/(g*d)的关系
*/
ω=(2.0*pi)/T;
printf(“角速度=%.5f\n”,ω);
kn=sqrt((ω*ω)/(g*h));
printf(“波数kn=%.5f\n”,kn);
e_allow=1.0e-5;
n=0;
nMax=100;
//遵循牛顿-拉斐逊方法
做{
fn=f(kn,ω,g,h);
dfn=df(kn,g,h);
dk=-(fn/dfn);
kn=kn+dk;
eps=fabs(丹麦克朗/千牛);
n=n+1;
}而(eps>=e|u allow | n==nMax);
//使用最终kn值计算λ值。
λ=(2.0*pi)/kn;
//printf(“\nfn=%.6f,dfn=%.6f,dx=%.6f,eps=%.6f\n”,fn,dfn,dk,eps);
printf(“\nkn=%.5lf,波长=%.5lf\n”,千牛,λ)*/
//printf(“fn=%.6lf,dfn=%.6lf,eps=%.6lf,dk=%.6lf,kn=%.6lf\n”,fn,dfn,eps,dk,kn);
返回0;
}
双f(双kn,双Ω,双g,双h){
返回((ω*ω)-(g*kn*tanh(kn*h));
}
双df(双kn、双g、双h){
返回(((g*kn*h)/(1+(h*h*kn*kn))-g*tanh(kn*h));
}

您的导数部分错误。不知怎么插上了arctan函数的导数公式

tanh(x)的导数是1/平方(cosh(x))=1-平方(tanh(x))


并跟踪正负号,负号在第一学期不会丢失。只有正确的符号才能使代码正常工作,而不会更正其余的导数。

非常感谢您发现了这一点!我还没有修复它,但希望它能修复..是的,它修复了,我尝试了两种变体。当然,这可能取决于输入,因此如果有进一步的问题,测试用例将很有帮助。