Бесконечный цикл в методе Ньютона-Рафсона

Я пишу программу для вычисления значения лямбды, за исключением того, что она застревает в цикле 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));
}

1 ответ

Ваша производная частично неверна. Каким-то образом вы подключили производную формулу для функции арктана.

Производная tanh(x) равна 1/ квадрат (cosh(x))=1 квадрат (tanh(x)).

И следите за знаком, знак минус не теряется в первом семестре. Один только правильный знак заставляет код работать, не исправляя остальную часть производной.

Другие вопросы по тегам