首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GSL积分,坏计数

GSL积分,坏计数
EN

Stack Overflow用户
提问于 2014-11-17 23:05:39
回答 1查看 137关注 0票数 2

为什么这个程序是错误的;计数积分tan(x)在范围(0,pi/2)(计算在~39左右),Wolfram Alpha说它是7。

我的代码:

代码语言:javascript
复制
#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(),就会出现“坏的integrand行为”错误。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-18 06:49:31

这个积分没有一个有限值。

代码语言:javascript
复制
tan(x) = sin(x)/cos(x)

所以

代码语言:javascript
复制
tan(pi/2) = 1/0 = undefined.

因此,您的数值积分应该会发散,因为您的函数在其范围的边缘是无限

你可以分析地看到这一点:

代码语言:javascript
复制
∫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的积分

代码语言:javascript
复制
= -ln|cos(pi/2)| - (-ln|cos(0)|)
= -ln|0| + 0

但是,-ln(0)是未定义,以x -> +0的形式逼近正无穷大。数值积分算法将试图通过对已知切片下的区域求和来逼近这个无限积分,并产生错误的、大的、有错误检测能力的有限结果。在启用了错误检测之后,一个好的数值积分算法将正确地报告错误,例如无法收敛或错误评估被积体 --这正是您在启用gsl错误检测时所看到的。

沃尔夫拉姆阿尔法还报告了pi/2处∫tan(x)dx的无限值。,所以我不知道你从哪里得到~7的值。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26983656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档