【问题标题】:GSL integrals, bad countsGSL 积分,错误计数
【发布时间】:2014-11-17 23:05:39
【问题描述】:

为什么这个程序出错了;在 (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();我有错误“不良被积行为”。

【问题讨论】:

    标签: c gsl integral


    【解决方案1】:

    该积分没有有限值。

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

    【讨论】:

    猜你喜欢
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    • 2016-11-01
    • 1970-01-01
    • 2011-03-10
    • 1970-01-01
    • 2011-08-08
    相关资源
    最近更新 更多