Интеграция GSL ведет себя странно

Я делаю интеграцию через (-infty, +infty), используя процедуру gsl_integration_qagi. Я ожидаю, что при перемещении по оси X результат интегрирования (площадь под кривой) не должен измениться. Однако это не то, что я наблюдатель. Я где-то ошибаюсь? Код прилагается ниже:

Переменная смещение в основном создает перевод. Область остается той же для значений смещения 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;
}

Заранее спасибо, Нихил

1 ответ

Вы пытаетесь интегрировать функцию с очень ограниченной поддержкой, используя 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 применяется для отображения [-infinity, infinity] в интервал (0-1]), мы можем сказать, что x = 0 отображается на t = 1. Кроме того, одна из точек оценки t = half_length (1.0 + 0.991455371120812639206854697526329) ~ 1, Тогда шансы, что интегратор пропустит вашу функцию, когда смещение равно нулю, весьма малы (поэтому нет проблем интегрировать разумный центр функций в точке x = 0 с помощью qagi). Однако, когда вы переводите x по смещению, вы помещаете всю функцию (которая имеет очень ограниченную поддержку) между двумя из 30 точек оценки. В этом случае GSL полностью пропускает вашу функцию и возвращает ноль.

Резюме простыми словами: GSL пытается проанализировать весь интервал [-infinity, infinity], используя только 30 точек в первой итерации. Вероятность того, что он пропустит функцию с очень ограниченной поддержкой с центром в произвольном x, очень высока! Используйте qagi, только если поддержка вашей функции очень велика!

Другие вопросы по тегам