Example #1
0
DBL chdtri(DBL df, DBL  y)
{
    DBL x;

    if ((y < 0.0) || (y > 1.0) || (df < 1.0))
        throw POV_EXCEPTION_STRING("Illegal values in chdtri().");

    x = igami(0.5 * df, y);

    return (2.0 * x);
}
Example #2
0
double chdtri (double df, double y)
{
    double x;

    if (y < 0.0 || y > 1.0 || df < 1.0) {
	mtherr("chdtri", CEPHES_DOMAIN);
	return 0.0;
    }

    x = igami(0.5 * df, y);

    return 2.0 * x;
}
Example #3
0
double pdtri( int k, double y )
{
double v;

if( (k < 0) || (y < 0.0) || (y >= 1.0) )
	{
	mtherr( "pdtri", DOMAIN );
	return( 0.0 );
	}
v = k+1;
v = igami( v, y );
return( v );
}
Example #4
0
double
gammaincinv(double a, double y)
{
    double lo = 0.0, hi;
    double flo = -y, fhi = 0.25 - y;
    double params[2];
    double best_x, best_f, errest;
    fsolve_result_t r;

    if (a <= 0.0 || y <= 0.0 || y >= 0.25) {
        return igami(a, 1-y);
    }

    /* Note: flo and fhi must have different signs (and be != 0),
     *       otherwise fsolve terminates with an error.
     */

    params[0] = a;
    params[1] = y;
    hi = igami(a, 0.75);
    /* I found Newton to be unreliable. Also, after we generate a small
       interval by bisection above, false position will do a large step
       from an interval of width ~1e-4 to ~1e-14 in one step (a=10, x=0.05,
       but similiar for other values).
     */

    r = false_position(&lo, &flo, &hi, &fhi,
                       (objective_function)gammainc, params,
                       2*MACHEP, 2*MACHEP, 1e-2*a,
                       &best_x, &best_f, &errest);
    if (!(r == FSOLVE_CONVERGED || r == FSOLVE_EXACT) &&
            errest > ALLOWED_ATOL + ALLOWED_RTOL*fabs(best_x)) {
        best_x = GAMMAINCINV_NaN;
    }
    return best_x;
}
Example #5
0
double igamci(double a, double q)
{
    int i;
    double x, fac, f_fp, fpp_fp;

    if (npy_isnan(a) || npy_isnan(q)) {
	return NPY_NAN;
    }
    else if ((a < 0.0) || (q < 0.0) || (q > 1.0)) {
	mtherr("gammainccinv", DOMAIN);
    }
    else if (q == 0.0) {
	return NPY_INFINITY;
    }
    else if (q == 1.0) {
	return 0.0;
    }
    else if (q > 0.9) {
	return igami(a, 1 - q);
    }

    x = find_inverse_gamma(a, 1 - q, q);
    for (i = 0; i < 3; i++) {
	fac = igam_fac(a, x);
	if (fac == 0.0) {
	    return x;
	}
	f_fp = (igamc(a, x) - q) * x / (-fac);
	fpp_fp = -1.0 + (a - 1) / x;
	if (npy_isinf(fpp_fp)) {
	    x = x - f_fp;
	}
	else {
	    x = x - f_fp / (1.0 - 0.5 * f_fp * fpp_fp);
	}
    }

    return x;
}