Coverage Report

Created: 2026-09-14 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/r-source/src/nmath/qnbeta.c
Line
Count
Source
1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
3
 *  Copyright (C) 2006 The R Core Team
4
 *
5
 *  This program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, a copy is available at
17
 *  https://www.R-project.org/Licenses/
18
 */
19
20
#include "nmath.h"
21
#include "dpq.h"
22
23
double qnbeta(double p, double a, double b, double ncp,
24
        int lower_tail, int log_p)
25
0
{
26
0
    const static double accu = 1e-15;
27
0
    const static double Eps = 1e-14; /* must be > accu */
28
29
0
    double ux, lx, nx, pp;
30
31
0
#ifdef IEEE_754
32
0
    if (ISNAN(p) || ISNAN(a) || ISNAN(b) || ISNAN(ncp))
33
0
  return p + a + b + ncp;
34
0
#endif
35
0
    if (!R_FINITE(a)) ML_WARN_return_NAN;
36
37
0
    if (ncp < 0. || a <= 0. || b <= 0.) ML_WARN_return_NAN;
38
39
0
    R_Q_P01_boundaries(p, 0, 1);
40
41
0
    p = R_DT_qIv(p);
42
43
    /* Invert pnbeta(.) :
44
     * 1. finding an upper and lower bound */
45
0
    if(p > 1 - DBL_EPSILON) return 1.0;
46
0
    pp = fmin2(1 - DBL_EPSILON, p * (1 + Eps));
47
0
    for(ux = 0.5;
48
0
  ux < 1 - DBL_EPSILON && pnbeta(ux, a, b, ncp, TRUE, FALSE) < pp;
49
0
  ux = 0.5*(1+ux));
50
0
    pp = p * (1 - Eps);
51
0
    for(lx = 0.5;
52
0
  lx > DBL_MIN && pnbeta(lx, a, b, ncp, TRUE, FALSE) > pp;
53
0
  lx *= 0.5);
54
55
    /* 2. interval (lx,ux)  halving : */
56
0
    do {
57
0
  nx = 0.5 * (lx + ux);
58
0
  if (pnbeta(nx, a, b, ncp, TRUE, FALSE) > p) ux = nx; else lx = nx;
59
0
    }
60
0
    while ((ux - lx) / nx > accu);
61
62
0
    return 0.5 * (ux + lx);
63
0
}