我正在使用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
答案 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!