Ejemplo n.º 1
0
/*!
 * Modified Bessel function of the first kind
 * This function wraps the following order-specific functions
 */
double besselI(size_t order, double x)
{
    switch (order)
    {
        case 0:
            return besselIOrderZero(x);

        case 1:
            return besselIOrderOne(x);

        default:
            return besselIOrderN(order, x);
    }
}
Ejemplo n.º 2
0
/*!
 * Modified Bessel function of the first kind, order n > 1
 */
double besselIOrderN(size_t order, double x)
{
    const double ACC = 200;
    const int IEXP = std::numeric_limits<double>::max_exponent / 2;
    int k;
    double bm, dum;

    if (x * x <= 8.0 * std::numeric_limits<double>::min())
    {
        return 0;
    }

    double tox = 2.0 / std::abs(x);
    double bip = 0;
    double ans = 0;
    double bi = 1.0;

    //Downward recurrence from even n
    for (size_t jj = 2 * (order + int(std::sqrt(ACC * order))); jj > 0; jj--)
    {
        double bim = bip + (jj * tox * bi);
        bip = bi;
        bi = bim;
        dum = std::frexp(bi, &k);

        //Renormalize to prevent overflow
        if (k > IEXP)
        {
            ans = std::ldexp(ans, -IEXP);
            bi = std::ldexp(bi, -IEXP);
            bip = std::ldexp(bip, -IEXP);
        }
        if (jj == order)
        {
            ans = bip;
        }
    }
    //Normalize
    ans *= besselIOrderZero(x) / bi;
    return x < 0 && (order & 1) ? -ans : ans;
}