GSL积分,坏计数

时间:2014-11-17 23:05:40

标签: 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);
  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 = &alpha;
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;
}

如果我删除了gsl_set_error_handler_off();我有错误的“不良的被积累行为”。

1 个答案:

答案 0 :(得分:2)

该积分没有有限值。

tan(x) = sin(x)/cos(x)

所以

tan(pi/2) = 1/0 = undefined.

因此,你的数值积分应该发散,因为你的函数在其范围的边缘是infinite

你可以分析地看到这个:

∫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)是undefined,并且接近正无穷大为x - > + 0。数值积分算法将尝试通过对已知切片下的面积求和来逼近该无限积分,并在错误检测禁用的情况下产生错误的大的有限结果。通过错误检测启用,良好的数值积分算法将正确报告错误,例如收敛失败或错误评估integrand - 这正是您在gsl看到的错误当您启用其错误检测时。

Wolfram Alpha also reports an infinite value for ∫tan(x)dx at pi/2,所以我不确定你在哪里获得了~7的价值。