GSL集成表现得很奇怪

时间:2013-08-12 14:45:43

标签: c++ gsl

我正在使用gsl_integration_qagi例程对(-infty,+ infty)进行集成。我的期望是,沿x轴平移时,积分结果(曲线下面积)不应改变。然而,这不是,我观察。我在某个地方犯了错误吗?代码如下:

变量offset基本上创建了翻译。对于偏移值0,10.0,20.0(如预期),该区域保持不变,但在偏移~40.0后突然降至零

double offset=200.0;

double f (double x, void * params) {
   double alpha = *(double *) params;
   x += offset;
   double f = exp(-x*x);
   return f;
}

int main(int argc, const char * argv[])
{

    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_integration_qagi (&F, 0, 0.001, 1000,
                          w, &result, &error);

    printf ("result = % .18f\n", result);

    return 0;
}

提前致谢, NIKHIL

1 个答案:

答案 0 :(得分:3)

你正在尝试使用qagi集成一个非常有限的支持功能,这很糟糕。整合将完全错过被积函数的可能性很大。为什么呢?

Qagi使用15点高斯规则。这近似意味着它将在以下固定点(第一次迭代)评估函数

  const double center = 0.5 * (a + b);
  const double half_length = 0.5 * (b - a);
  const double abscissa = half_length * xgk[jtw];
  const double fval1 = GSL_FN_EVAL (f, center - abscissa);
  const double fval2 = GSL_FN_EVAL (f, center + abscissa);  

其中

  static const double xgk[8] =    /* abscissae of the 15-point kronrod rule */
  {
     0.991455371120812639206854697526329,
     0.949107912342758524526189684047851,
     0.864864423359769072789712788640926,
     0.741531185599394439863864773280788,
     0.586087235467691130294144838258730,
     0.405845151377397166906606412076961,
     0.207784955007898467600689403773245,
     0.000000000000000000000000000000000
 };

(这是直接从GSL代码中获取的)。然后,根据GSL从这些点获得的值,它可以进一步划分特定区域并再次应用此规则。

从非线性变换x = (1-t)/t(这是变换gsl适用于map [-infinity,infinity]到(0-1)间隔),我们可以说x = 0映射在t = 1此外,其中一个评估点是t = half_length (1.0 + 0.991455371120812639206854697526329) ~ 1。然后,积分器在偏移为零时错过功能的可能性非常小(这就是为什么在x = 0时集成合理的函数中心没有问题的原因但是,当您通过偏移量转换x时,您可以在30个评估点中的两个点之间拟合整个函数(它具有非常有限的支持)。在这种情况下,GSL完全错过了您的函数并返回零。 / p>

简单的总结:GSL试图在第一次迭代中仅使用30个点来分析整个[-infinity,infinity]区间。错过一个以任意x为中心的支持非常有限的功能的可能性非常高!!如果您的功能支持非常大,请仅使用qagi!