C 数值微分

C 数值微分,c,numerical-methods,numerical,C,Numerical Methods,Numerical,如何计算一个函数的数值二阶导数,该函数包含无穷远的指数和奇点。不幸的是,“C中的数值配方”中提供的Ridder方法的数值导数只能计算一阶导数(它需要事先对函数进行解析表达式)。此外,我尝试过切比雪夫近似,并在之后对函数进行微分,但给出的值与实际值相差甚远。我也尝试过数学论文中提供的一些有限差分算法,但它们也容易出错。函数是e^(x/2)/x^2。在这件事上,如果有任何帮助,我将不胜感激 提前谢谢 最新编辑:问题解决了C++中的FADBAD库做得非常好。可通过以下途径获得: 编辑: // The

如何计算一个函数的数值二阶导数,该函数包含无穷远的指数和奇点。不幸的是,“C中的数值配方”中提供的Ridder方法的数值导数只能计算一阶导数(它需要事先对函数进行解析表达式)。此外,我尝试过切比雪夫近似,并在之后对函数进行微分,但给出的值与实际值相差甚远。我也尝试过数学论文中提供的一些有限差分算法,但它们也容易出错。函数是e^(x/2)/x^2。在这件事上,如果有任何帮助,我将不胜感激

提前谢谢

<>最新编辑:问题解决了C++中的FADBAD库做得非常好。可通过以下途径获得:

编辑:

// The compilation command used is given below
// gcc Q3.c nrutil.c DFRIDR.c -lm -o Q3

#include <stdio.h>
#include <math.h>
#include "nr.h"

#define LIM1 20.0
#define a -5.0
#define b 5.0
#define pre 100.0 // This defines the pre
/* This file calculates the func at given points, makes a 
 * plot. It also calculates the maximum and minimum of the func
 * at given points and its first and second numerical derivative.
*/
float func(float x)
{
    return exp(x / 2) / pow(x, 2);
}

int main(void)
{
    FILE *fp = fopen("Q3data.dat", "w+"), *fp2 = fopen("Q3results.dat", "w+");
    int i; // Declaring our loop variable
    float x, y, min, max, err, nd1, nd2;
    // Define the initial value of the func to be the minimum
    min = func(0); 
    for(i = 0; x < LIM1 ; i++)
    {   
        x = i / pre; // There is a singularity at x = 0 
        y = func(x);
        if(y < min)
            min = y;
        fprintf(fp, "%f \t %f \n", x, y);
    }
    fprintf(fp, "\n\n");
    max = 0;
    for(i = 0, x = a; x < b; i++)
    {   
        x = a + i / pre;
        y = func(x);
        nd1 = dfridr(func, x, 0.1, &err); 
        //nd2 = dfridr((*func), x, 0.1, &err);
        fprintf(fp, "%f \t %f \t %f \t %f \n", x, y, nd1);
        if(y > max)
            max = y;
    }

    fprintf(fp2, "The minimum value of f(x) is %f when x is between 0 and 20. \n", min);
    fprintf(fp2, "The maximum value of f(x) is %f when x is between -5 and 5. \n", max);
    fclose(fp);
    fclose(fp2);
    return 0;
}
//下面给出了使用的编译命令
//gcc Q3.c nrutil.c DFRIDR.c-lm-o Q3
#包括
#包括
#包括“nr.h”
#定义LIM1 20.0
#定义一个-5.0
#定义B5.0
#定义pre 100.0//这定义了pre
/*此文件计算给定点处的func,并生成
*阴谋。它还计算func的最大值和最小值
*在给定点及其一阶和二阶数值导数。
*/
浮点函数(浮点x)
{
返回exp(x/2)/pow(x,2);
}
内部主(空)
{
文件*fp=fopen(“Q3data.dat”,“w+”),*fp2=fopen(“Q3results.dat”,“w+”);
int i;//声明循环变量
浮动x、y、最小值、最大值、误差、nd1、nd2;
//将func的初始值定义为最小值
min=func(0);
对于(i=0;x最大值)
max=y;
}
fprintf(fp2,“当x介于0和20之间时,f(x)的最小值为%f。\n”,min);
fprintf(fp2,“当x介于-5和5之间时,f(x)的最大值为%f。\n”,max);
fclose(fp);
fclose(fp2);
返回0;
}
编辑:切比雪夫

// The compilation command used is given below
//gcc Q3.c nrutil.c CHEBEV.c CHEBFT.c CHDER.c -lm -o Q3


#include <stdio.h>
#include <math.h>
#include "nr.h"
#define NVAL 150 // Degree of Chebyshev polynomial
#define LIM1 20.0
#define a -5.0
#define b 5.0
#define pre 100.0 // This defines the pre
/* This file calculates the func at given points, makes a 
 * plot. It also calculates the maximum and minimum of the func
 * at given points and its first and second numerical derivative.
*/
float func(float x)
{
    return exp(x / 2) / pow(x, 2);
}

int main(void)
{
    FILE *fp = fopen("Q3data.dat", "w+"), *fp2 = fopen("Q3results.dat", "w+");
    int i; // Declaring our loop variable
    float x, y, min, max;
    float nd1, nd2, c[NVAL], cder[NVAL], cder2[NVAL];
    // Define the initial value of the func to be the minimum
    min = func(0); 

    for(i = 0; x < LIM1 ; i++)
    {   
        x = i / pre; // There is a singularity at x = 0 
        y = func(x);
        if(y < min)
            min = y;
        fprintf(fp, "%f \t %f \n", x, y);
    }
    fprintf(fp, "\n\n");
    max = 0;
    // We make a Chebyshev approximation to our function our interval of interest 
    // The purpose is to calculate the derivatives easily
    chebft(a,b,c,NVAL,func);
    //Evaluate the derivatives
    chder(a,b,c,cder,NVAL); // First order derivative
    chder(a,b,cder,cder2,NVAL); // Second order derivative
    for(i = 0, x = a; x < b; i++)
    {   
        x = a + i / pre;
        y = func(x);
        nd1 = chebev(a,b,cder,NVAL,x);
        nd2 = chebev(a,b,cder2,NVAL,x);

        fprintf(fp, "%f \t %f \t %f \t %f  \n", x, y, nd1, nd2);
        if(y > max)
            max = y;
    }

    fprintf(fp2, "The minimum value of f(x) is %f when x is between 0 and 20. \n", min);
    fprintf(fp2, "The maximum value of f(x) is %f when x is between -5 and 5. \n", max);
    fclose(fp);
    fclose(fp2);
    return 0;
}
//下面给出了使用的编译命令
//gcc Q3.c nrutil.c CHEBEV.c CHEBFT.c CHDER.c-lm-o Q3
#包括
#包括
#包括“nr.h”
#定义NVAL 150//切比雪夫多项式的阶数
#定义LIM1 20.0
#定义一个-5.0
#定义B5.0
#定义pre 100.0//这定义了pre
/*此文件计算给定点处的func,并生成
*阴谋。它还计算func的最大值和最小值
*在给定点及其一阶和二阶数值导数。
*/
浮点函数(浮点x)
{
返回exp(x/2)/pow(x,2);
}
内部主(空)
{
文件*fp=fopen(“Q3data.dat”,“w+”),*fp2=fopen(“Q3results.dat”,“w+”);
int i;//声明循环变量
浮动x,y,最小值,最大值;
浮点数nd1,nd2,c[NVAL],cder[NVAL],cder2[NVAL];
//将func的初始值定义为最小值
min=func(0);
对于(i=0;x最大值)
max=y;
}
fprintf(fp2,“当x介于0和20之间时,f(x)的最小值为%f。\n”,min);
fprintf(fp2,“当x介于-5和5之间时,f(x)的最大值为%f。\n”,max);
fclose(fp);
fclose(fp2);
返回0;
}

该函数是可微的,因此使用数值方法可能不是最好的。第二个导数是:

6*exp(x/2)/(x^4)-2*exp(x/2)/x^3+exp(x/2)/(4*x^2)


当然,可以简化上述步骤以加快计算速度。编辑:最初的公式是错误的。

该函数是可微的,因此使用数值方法可能不是最好的。第二个导数是:

6*exp(x/2)/(x^4)-2*exp(x/2)/x^3+exp(x/2)/(4*x^2)


当然,可以简化上述步骤以加快计算速度。编辑:第一次将原始公式弄错。

如果您想要100%的数值方法,请查看有关立方样条插值的详细信息(第3.3章)。它将给出任意位置的2rd导数

使用
x
y
值调用
spline()
,以返回
y2
中的二阶导数。二阶导数在每个区间内线性变化。例如,如果你有

x      y      y2
0     10     -30
2      5     -15
4     -5     -10
然后,在
x=1
处的二阶导数是
y2=-22.5
,介于-30和-15之间


您还可以创建一个新的
splint()
函数,以返回二阶导数
a*y2a[i]+b*y2a[i+1]

如果您想要100%的数值方法,请查看用于立方样条插值的函数(Charter 3.3)。它将给出任意位置的2rd导数

使用
x
y
值调用
spline()
,以返回
y2
中的二阶导数。二阶导数在每个区间内线性变化。例如,如果你有

x      y      y2
0     10     -30
2      5     -15
4     -5     -10
然后,在
x=1
处的二阶导数是
y2=-22.5
,介于-30和-15之间

你也可以做一个