C GSL积分,坏计数
为什么这个程序是错误的;计算(0,pi/2)范围内的积分tan(x)(计算范围约为39),Wolfram Alpha表示为7 我的代码:C GSL积分,坏计数,c,gsl,integral,C,Gsl,Integral,为什么这个程序是错误的;计算(0,pi/2)范围内的积分tan(x)(计算范围约为39),Wolfram Alpha表示为7 我的代码: #include <stdio.h> #include <math.h> #include <gsl/gsl_integration.h> double f (double x, void * params) { double alpha = *(double *) params; double f = tan(x
#include <stdio.h>
#include <math.h>
#include <gsl/gsl_integration.h>
double f (double x, void * params) {
double alpha = *(double *) params;
double f = tan(x);
return f;
}
int
main (void)
{
gsl_integration_workspace * w
= gsl_integration_workspace_alloc (1000);
double result, error;
double expected = -4.0;
double alpha = 1.0;
gsl_function F;
F.function = &f;
F.params = α
gsl_set_error_handler_off();
gsl_integration_qag (&F, 0, M_PI/2, 0, 1e-6, 1000, 1,
w, &result, &error);
printf ("result = % .18f\n", result);
printf ("exact result = % .18f\n", expected);
printf ("estimated error = % .18f\n", error);
printf ("actual error = % .18f\n", result - expected);
printf ("intervals = %d\n", w->size);
gsl_integration_workspace_free (w);
return 0;
}
#包括
#包括
#包括
双f(双x,空*参数){
双alpha=*(双*)参数;
双f=tan(x);
返回f;
}
int
主(空)
{
gsl_集成_工作区*w
=gsl_集成_工作空间_分配(1000);
双重结果,错误;
双预期=-4.0;
双α=1.0;
gsl_函数F;
函数=&F;
F.params=&alpha;
gsl_设置_错误_处理器_关闭();
gsl_集成_qag(&F,0,M_PI/2,0,1e-61000,1,
w、 结果和错误);
printf(“结果=%.18f\n”,结果);
printf(“精确结果=%.18f\n”,预期值);
printf(“估计误差=%.18f\n”,误差);
printf(“实际错误=%.18f\n”,结果-预期);
printf(“间隔=%d\n”,w->size);
gsl_集成_工作空间_自由(w);
返回0;
}
如果我删除了gsl_set_error_handler_off(),我就出现了错误“坏的被积函数行为”。该积分没有有限值
tan(x) = sin(x)/cos(x)
所以
因此,你的数值积分应该发散,因为你的函数在它的范围的边缘
你可以从分析中看到这一点:
∫tan(x)dx
= ∫sin(x)/cos(x)dx
Define u=cos(x). Then du=-sin(x)dx, so
∫sin(x)/cos(x)dx
=-∫(-sin(x))/cos(x)dx
=-∫1/u*du
=-ln|u| + C
=-ln|cos(x)| + C
从0到pi/2的积分
= -ln|cos(pi/2)| - (-ln|cos(0)|)
= -ln|0| + 0
但是,-ln(0)是,并且接近正无穷大,如x->+0。数值积分算法将尝试通过对已知切片下的面积求和来近似此无穷大积分,并在禁用错误检测的情况下生成错误的大型有限结果。启用错误检测后,良好的数值积分算法将正确报告此类错误当您启用错误检测时,gsl
正是由于无法收敛或错误评估而导致的
Wolfram Alpha,所以我不确定从何处获得~7的值。非常感谢。我使用了这样的小部件或结果为7.1355的站点
= -ln|cos(pi/2)| - (-ln|cos(0)|)
= -ln|0| + 0