关于在C ++中集成Bessel函数的方法的建议

时间:2017-08-30 07:51:50

标签: c++ numerical-methods bessel-functions

我需要整合这种振荡功能: enter image description here

我有贝塞尔函数振荡,而F不是很振荡。我正在寻找在C ++中执行此操作的最精确/准确的方法。希望这应该是一个已经存在的实现,我可以使用它,例如库等......

GSL库可能是一个选项,但即使在这种情况下,你能否推荐我对我来说最有用的许多例程中的哪一个?

编辑: 我知道这个存在 possibly duplicate question

但我在那里看不到明确的答案。另外,Fortran库不适合我,除非它有某种包装器。

1 个答案:

答案 0 :(得分:1)

上次我不得不做这些事情,对零交叉定义的区间进行简单整合是最先进的。这在大多数情况下是相对稳定的,如果被积函数接近零,那么合理的快速容易做到。

作为游戏的起点,我包含了一些代码。当然,您需要进行收敛检测和错误检查。这不是生产代码,但我想也许它为您提供了一个起点。它使用gsl。

在我的iMac上,此代码每次迭代大约需要2μs。通过在间隔中包含硬编码表,它不会变得更快。

我希望这对你有用。

#include <iostream>
#include <vector>
#include <gsl/gsl_sf_bessel.h>
#include <gsl/gsl_integration.h>
#include <gsl/gsl_sf.h>


double f (double x, void * params) {
    double y = 1.0 / (1.0 + x) * gsl_sf_bessel_J0 (x);
    return y;
}

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

    double sum = 0;
    double delta = 0.00001;
    int max_steps = 1000;
    gsl_integration_workspace * w = gsl_integration_workspace_alloc (max_steps);

    gsl_function F;
    F.function = &f;
    F.params = 0;

    double result, error;
    double a,b;
    for(int n=0; n < max_steps; n++)
    {
        if(n==0)
        {
            a = 0.0;
            b = gsl_sf_bessel_zero_J0(1);
        }
        else
        {
            a = n;
            b = gsl_sf_bessel_zero_J0(n+1);
        }
        gsl_integration_qag (&F,  // function
                              besselj0_intervals[n],   // from
                              besselj0_intervals[n+1],   // to
                              0,   // eps absolute
                              1e-4,// eps relative
                              max_steps,
                              GSL_INTEG_GAUSS15,
                              w,
                              &result,
                              &error);
        sum += result;

        std::cout << n << " " << result << " " << sum << "\n";

        if(abs(result) < delta)
            break;
    }
    return 0;
}