Esempio n. 1
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 cephes_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 = cephes_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)) {
        sf_error("gammaincinv", SF_ERROR_NO_RESULT,
                 "failed to converge at (a, y) = (%.20g, %.20g): got %g +- %g, code %d\n",
                 a, y, best_x, errest, r);
        best_x = NPY_NAN;
    }
    return best_x;
}
Esempio n. 2
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;
}