如何计算在无穷远处涉及指数和奇点的函数的数值二阶导数。不幸的是,Ridder方法中提供的数值导数“C中的数值配方”只能计算出一阶导数(它需要预先对函数进行解析表达式。)此外,我尝试了Chebyshev近似并对函数进行了区分,但给出的值是方式关闭实际值。我也尝试过在数学论文中提供的一些有限差分算法,但它们也容易出错。函数是e ^(x / 2)/ x ^ 2。对此事我感激不尽。
提前致谢
最新编辑:问题解决了C ++中可用的FADBAD库做得非常好。它们可以通过http://www.fadbad.com/fadbad.html
获得编辑:
// 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;
}
编辑:切比雪夫
// 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;
}
答案 0 :(得分:3)
该功能是可区分的,因此使用数值方法可能不是最好的。二阶导数是:
6 * exp(x / 2)/(x ^ 4)-2 * exp(x / 2)/ x ^ 3 + exp(x / 2)/(4 * x ^ 2)
以上可以简化,以加快计算速度。编辑:第一次有原始公式错误。
答案 1 :(得分:1)
如果您想要100%数字方法,请查看numerical recipes以进行公共样条插值(Charter 3.3)。它会在任何位置为您提供第二个衍生物。
使用spline()
和x
值调用y
以返回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]