I want to integrate the probability density function from (-\infty, a]
because cdf is not available in closed form. But I'm not sure how to do this in C ++.
This task is quite simple in Mathematica; All I have to do is define a function,
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)) ];
and then call NIntegrate
Routine for its numerical integration.
F[x_, lambda_, alpha_, beta_, mu_] := NIntegrate[f[t, lambda, alpha, beta, mu], {t, -\[Infinity], x}]
Now I want to achieve the same thing in C ++. I am using the gsl_integration_qagil
routine from the gsl library. It is designed to integrate functions at half-infinite intervals (-\infty, a]
that I want. But, unfortunately, I cannot get it to work.
This is a density function in 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)); }
Then I try to integrate to get cdf by calling the gsl procedure.
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; }
However, gsl_integration_qagil
returns an error, 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;
If I increase the size of the workspace, the bessel function will not be evaluated.
I was wondering if there is anyone who could let me understand my problem. Calling the corresponding Mathematica F function above with x = 0.01
returns 0.904384
.
Maybe the density is concentrated around a very small interval (that is, outside [-0.05, 0.05]
density is almost 0
, the graph is shown below). If so, what can be done about this. Thanks for reading.
