Exemplo n.º 1
0
/*
 * Asymptotic expansion for  ln(|B(a, b)|) for a > ASYMP_FACTOR*max(|b|, 1).
 */
static double lbeta_asymp(double a, double b, int *sgn)
{
    double r = lgam_sgn(b, sgn);
    r -= b * log(a);

    r += b*(1-b)/(2*a);
    r += b*(1-b)*(1-2*b)/(12*a*a);
    r += - b*b*(1-b)*(1-b)/(12*a*a*a);

    return r;
}
Exemplo n.º 2
0
static double jvs(double n, double x)
{
    double t, u, y, z, k;
    int ex, sgngam;

    z = -x * x / 4.0;
    u = 1.0;
    y = u;
    k = 1.0;
    t = 1.0;

    while (t > MACHEP) {
	u *= z / (k * (n + k));
	y += u;
	k += 1.0;
	if (y != 0)
	    t = fabs(u / y);
    }
#if CEPHES_DEBUG
    printf("power series=%.5e ", y);
#endif
    t = frexp(0.5 * x, &ex);
    ex = ex * n;
    if ((ex > -1023)
	&& (ex < 1023)
	&& (n > 0.0)
	&& (n < (MAXGAM - 1.0))) {
	t = pow(0.5 * x, n) / gamma(n + 1.0);
#if CEPHES_DEBUG
	printf("pow(.5*x, %.4e)/gamma(n+1)=%.5e\n", n, t);
#endif
	y *= t;
    }
    else {
#if CEPHES_DEBUG
	z = n * log(0.5 * x);
	k = lgam(n + 1.0);
	t = z - k;
	printf("log pow=%.5e, lgam(%.4e)=%.5e\n", z, n + 1.0, k);
#else
	t = n * log(0.5 * x) - lgam_sgn(n + 1.0, &sgngam);
#endif
	if (y < 0) {
	    sgngam = -sgngam;
	    y = -y;
	}
	t += log(y);
#if CEPHES_DEBUG
	printf("log y=%.5e\n", log(y));
#endif
	if (t < -MAXLOG) {
	    return (0.0);
	}
	if (t > MAXLOG) {
	    mtherr("Jv", OVERFLOW);
	    return (NPY_INFINITY);
	}
	y = sgngam * exp(t);
    }
    return (y);
}
Exemplo n.º 3
0
double beta(double a, double b)
{
    double y;
    int sign = 1;

    if (a <= 0.0) {
	if (a == floor(a)) {
            if (a == (int)a) {
                return beta_negint((int)a, b);
            }
            else {
                goto overflow;
            }
        }
    }

    if (b <= 0.0) {
	if (b == floor(b)) {
            if (b == (int)b) {
                return beta_negint((int)b, a);
            }
            else {
                goto overflow;
            }
        }
    }

    if (fabs(a) < fabs(b)) {
        y = a; a = b; b = y;
    }

    if (fabs(a) > ASYMP_FACTOR * fabs(b) && a > ASYMP_FACTOR) {
        /* Avoid loss of precision in lgam(a + b) - lgam(a) */
        y = lbeta_asymp(a, b, &sign);
        return sign * exp(y);
    }

    y = a + b;
    if (fabs(y) > MAXGAM || fabs(a) > MAXGAM || fabs(b) > MAXGAM) {
	int sgngam;
	y = lgam_sgn(y, &sgngam);
	sign *= sgngam;		/* keep track of the sign */
	y = lgam_sgn(b, &sgngam) - y;
	sign *= sgngam;
	y = lgam_sgn(a, &sgngam) + y;
	sign *= sgngam;
	if (y > MAXLOG) {
	    goto overflow;
	}
	return (sign * exp(y));
    }

    y = Gamma(y);
    a = Gamma(a);
    b = Gamma(b);
    if (y == 0.0)
	goto overflow;

    if (fabs(fabs(a) - fabs(y)) > fabs(fabs(b) - fabs(y))) {
        y = b / y;
        y *= a;
    }
    else {
        y = a / y;
        y *= b;
    }

    return (y);

overflow:
    mtherr("beta", OVERFLOW);
    return (sign * CEPHES_INFINITY);
}