C 牛顿-拉斐逊法中的无限循环
我正在写一个程序来计算lambda的值,除非它被困在do循环中。它似乎没有更新n值,因为我希望通过设置nMax=100,它至少能够在另一种情况(eps>=e_allow)从未发生的情况下快速完成。有人能指出无限循环的来源吗 非常感谢你的帮助。我的计划是: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
#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))
并跟踪正负号,负号在第一学期不会丢失。只有正确的符号才能使代码正常工作,而不会更正其余的导数。非常感谢您发现了这一点!我还没有修复它,但希望它能修复..是的,它修复了,我尝试了两种变体。当然,这可能取决于输入,因此如果有进一步的问题,测试用例将很有帮助。