我想整合一个概率密度函数,(-\infty, a]
因为 cdf 不能以封闭形式提供。但我不确定如何在 C++ 中做到这一点。
这个任务在 Mathematica 中非常简单;我需要做的就是定义函数,
f[x_, lambda_, alpha_, beta_, mu_] :=
Module[{gamma},
gamma = Sqrt[alpha^2 - beta^2];
(gamma^(2*lambda)/((2*alpha)^(lambda - 1/2)*Sqrt[Pi]*Gamma[lambda]))*
Abs[x - mu]^(lambda - 1/2)*
BesselK[lambda - 1/2, alpha Abs[x - mu]] E^(beta (x - mu))
];
然后调用NIntegrate
例程对其进行数值积分。
F[x_, lambda_, alpha_, beta_, mu_] :=
NIntegrate[f[t, lambda, alpha, beta, mu], {t, -\[Infinity], x}]
现在我想在 C++ 中实现同样的目标。我使用 gsl 数字库中的例程gsl_integration_qagil
。它旨在集成半无限间隔上的功能,(-\infty, a]
这正是我想要的。但不幸的是,我无法让它工作。
这是 C++ 中的密度函数,
density(double x)
{
using namespace boost::math;
if(x == _mu)
return std::numeric_limits<double>::infinity();
return pow(_gamma, 2*_lambda)/(pow(2*_alpha, _lambda-0.5)*sqrt(_pi)*tgamma(_lambda))* pow(abs(x-_mu), _lambda - 0.5) * cyl_bessel_k(_lambda-0.5, _alpha*abs(x - _mu)) * exp(_beta*(x - _mu));
}
然后我尝试通过调用 gsl 例程来集成以获取 cdf。
cdf(double x)
{
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000);
double result, error;
gsl_function F;
F.function = &density;
double epsabs = 0;
double epsrel = 1e-12;
gsl_integration_qagil (&F, x, epsabs, epsrel, 1000, w, &result, &error);
printf("result = % .18f\n", result);
printf ("estimated error = % .18f\n", error);
printf ("intervals = %d\n", w->size);
gsl_integration_workspace_free (w);
return result;
}
但是gsl_integration_qagil
返回一个错误,number of iterations was insufficient
.
double mu = 0.0f;
double lambda = 3.0f;
double alpha = 265.0f;
double beta = -5.0f;
cout << cdf(0.01) << endl;
如果我增加工作空间的大小,那么贝塞尔函数将不会计算。
我想知道是否有任何人可以让我了解我的问题。x = 0.01
通过返回调用上述相应的 Mathematica 函数0.904384
F。
可能是密度集中在一个非常小的区间附近(即[-0.05, 0.05]
密度之外几乎0
是 ,下面给出了一个图)。如果是这样,可以做些什么。谢谢阅读。