c - GSL 积分、错误计数

标签 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();我有错误“不良被积函数行为”。

最佳答案

该积分没有有限值。

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 的值。

关于c - GSL 积分、错误计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26983656/

相关文章:

c - 尝试在 GSL 中使用累积分布函数

python - 概率密度的黎曼和

c - 不知道为什么 C 打印出 NaN

c - 如何将格式化字符串附加到数组中?

c - 如何关闭 GCC 中的所有优化

c++ - GSL ODE解决方案中的指针类型编译时错误

php - 在 PHP 中计算函数积分的最佳方法?

c++ - 从堆栈指针中找出函数参数值

c - 在 C 中解码密文时出现大小问题

c++ - 函数c++中的gsl集成