我有贝塞尔函数振荡,而F不是很振荡。我正在寻找在C ++中执行此操作的最精确/准确的方法。希望这应该是一个已经存在的实现,我可以使用它,例如库等......
GSL库可能是一个选项,但即使在这种情况下,你能否推荐我对我来说最有用的许多例程中的哪一个?
编辑: 我知道这个存在 possibly duplicate question
但我在那里看不到明确的答案。另外,Fortran库不适合我,除非它有某种包装器。
答案 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;
}