Skip to content

Commit f3f1b40

Browse files
author
maechler
committed
comments / cosmetic
git-svn-id: https://svn.r-project.org/R/trunk@88401 00db46b3-68df-0310-9c12-caf00c1e9a41
1 parent 09530bc commit f3f1b40

File tree

14 files changed

+44
-38
lines changed

14 files changed

+44
-38
lines changed

src/nmath/bessel_i.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,12 @@ static void I_bessel(double *x, double *alpha, int *nb,
231231
/* Local variables */
232232
int nend, intx, nbmx, k, l, n, nstart;
233233
double pold, test, p, em, en, empal, emp2al, halfx,
234-
aa, bb, cc, psave, plast, tover, psavel, sum, nu, twonu;
234+
aa, bb, cc, psave, plast, tover, psavel, sum,
235235

236-
/*Parameter adjustments */
237-
--bi;
238-
nu = *alpha;
239-
twonu = nu + nu;
236+
nu = *alpha,
237+
twonu = ldexp(nu, 1); // = 2*nu
238+
239+
--bi; // use 1-indexing below
240240

241241
/*-------------------------------------------------------------------
242242
Check for X, NB, OR IZE out of range.
@@ -486,7 +486,7 @@ static void I_bessel(double *x, double *alpha, int *nb,
486486
empal = 1. + nu;
487487
#ifdef IEEE_754
488488
/* No need to check for underflow */
489-
halfx = .5 * *x;
489+
halfx = ldexp(*x, -1); // = *x / 2 = .5 * *x
490490
#else
491491
if (*x > enmten_BESS) */
492492
halfx = .5 * *x;

src/nmath/dbinom.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
* This checks for argument validity, and calls dbinom_raw().
3131
*
3232
* dbinom_raw() does the actual computation; note this is called by
33-
* other functions in addition to dbinom().
33+
* many other functions in addition to dbinom():
34+
* dnbinom(), dbeta(), df(), dgeom(), dhyper()
3435
* (1) dbinom_raw() has both p and q arguments, when one may be represented
3536
* more accurately than the other (in particular, in df()).
3637
* (2) dbinom_raw() does NOT check that inputs x and n are integers. This

src/nmath/dgamma.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141

4242
double dgamma(double x, double shape, double scale, int give_log)
4343
{
44-
double pr;
4544
#ifdef IEEE_754
4645
if (ISNAN(x) || ISNAN(shape) || ISNAN(scale))
4746
return x + shape + scale;
@@ -58,6 +57,7 @@ double dgamma(double x, double shape, double scale, int give_log)
5857
return give_log ? -log(scale) : 1 / scale;
5958
}
6059

60+
double pr;
6161
if (shape < 1) {
6262
pr = dpois_raw(shape, x/scale, give_log);
6363
return (

src/nmath/dgeom.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@
3030
#include "dpq.h"
3131

3232
double dgeom(double x, double p, int give_log)
33-
{
34-
double prob;
35-
33+
{
3634
#ifdef IEEE_754
3735
if (ISNAN(x) || ISNAN(p)) return x + p;
3836
#endif
@@ -44,7 +42,7 @@ double dgeom(double x, double p, int give_log)
4442
x = R_forceint(x);
4543

4644
/* prob = (1-p)^x, stable for small p */
47-
prob = dbinom_raw(0.,x, p,1-p, give_log);
45+
double prob = dbinom_raw(0.,x, p,1-p, give_log);
4846

4947
return((give_log) ? log(p) + prob : p*prob);
5048
}

src/nmath/dnbeta.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Mathlib : A C Library of Special Functions
3+
* Copyright (C) 2000-2021 The R Core Team
34
* Copyright (C) 1998 Ross Ihaka
4-
* Copyright (C) 2000-12 The R Core Team
55
*
66
* This program is free software; you can redistribute it and/or modify
77
* it under the terms of the GNU General Public License as published by
@@ -56,10 +56,6 @@ double dnbeta(double x, double a, double b, double ncp, int give_log)
5656
{
5757
const static double eps = 1.e-15;
5858

59-
int kMax;
60-
double k, ncp2, dx2, d, D;
61-
LDOUBLE sum, term, p_k, q;
62-
6359
#ifdef IEEE_754
6460
if (ISNAN(x) || ISNAN(a) || ISNAN(b) || ISNAN(ncp))
6561
return x + a + b + ncp;
@@ -74,18 +70,21 @@ double dnbeta(double x, double a, double b, double ncp, int give_log)
7470
if(ncp == 0)
7571
return dbeta(x, a, b, give_log);
7672

77-
/* New algorithm, starting with *largest* term : */
78-
ncp2 = 0.5 * ncp;
79-
dx2 = ncp2*x;
80-
d = (dx2 - a - 1)/2;
81-
D = d*d + dx2 * (a + b) - a;
73+
/* Non-central Beta: New algorithm, starting with *largest* term : */
74+
double
75+
ncp2 = ldexp(ncp, -1), // = 0.5 * ncp
76+
dx2 = ncp2*x,
77+
d = ldexp(dx2 - a - 1, -1), // = (...)/2
78+
D = d*d + dx2 * (a + b) - a;
79+
int kMax;
8280
if(D <= 0) {
8381
kMax = 0;
8482
} else {
8583
D = ceil(d + sqrt(D));
8684
kMax = (D > 0) ? (int)D : 0;
8785
}
8886

87+
LDOUBLE sum, term, p_k, q;
8988
/* The starting "middle term" --- first look at it's log scale: */
9089
term = dbeta(x, a + kMax, b, /* log = */ TRUE);
9190
p_k = dpois_raw(kMax, ncp2, TRUE);
@@ -101,7 +100,7 @@ double dnbeta(double x, double a, double b, double ncp, int give_log)
101100
/* Now sum from the inside out */
102101
sum = term = 1. /* = mid term */;
103102
/* middle to the left */
104-
k = kMax;
103+
double k = kMax;
105104
while(k > 0 && term > sum * eps) {
106105
k--;
107106
q = /* 1 / r_k = */ (k+1)*(k+a) / (k+a+b) / dx2;

src/nmath/dnchisq.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ double dnchisq(double x, double df, double ncp, int give_log)
6262

6363
if(mid == 0) {
6464
/* underflow to 0 -- maybe numerically correct; maybe can be more accurate,
65+
* TODO: above log(.): logmid = dpois_raw(imax, ncp2, TRUE) + dchisq(x, dfmid, TRUE);
66+
* ---- and switch to complete log-scale summation of logterm += log(q) {etc} below
6567
* particularly when give_log = TRUE */
6668
/* Use central-chisq approximation formula when appropriate;
6769
* ((FIXME: the optimal cutoff also depends on (x,df); use always here? )) */

src/nmath/dnt.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,15 @@ double dnt(double x, double df, double ncp, int give_log)
8181

8282
/* If infinite df then the density is identical to a
8383
normal distribution with mean = ncp. However, the formula
84-
loses a lot of accuracy around df=1e9
84+
loses a lot of accuracy around df=1e9 // FIXME?
8585
*/
86-
if(!R_FINITE(df) || df > 1e8)
86+
if(!R_FINITE(df) || df > 1e8)
8787
return dnorm(x, ncp, 1., give_log);
8888

8989
/* Do calculations on log scale to stabilize */
9090

9191
/* Consider two cases: x ~= 0 or not */
92-
if (fabs(x) > sqrt(df * DBL_EPSILON)) {
92+
if (fabs(x) > sqrt(df * DBL_EPSILON)) { // |x| > eps * sqrt(df)
9393
u = log(df) - log(fabs(x)) +
9494
log(fabs(pnt(x*sqrt((df+2)/df), df+2, ncp, 1, 0) -
9595
pnt(x, df, ncp, 1, 0)));

src/nmath/lbeta.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@ double lbeta(double a, double b)
7171
return lgammafn(p) + corr + p - p * log(p + q)
7272
+ (q - 0.5) * log1p(-p / (p + q));
7373
}
74-
else {
75-
/* p and q are small: p <= q < 10. */
74+
else { /* p and q are small: p <= q < 10. */
7675
/* R change for very small args */
7776
if (p < 1e-306) return lgamma(p) + (lgamma(q) - lgamma(p+q));
7877
else return log(gammafn(p) * (gammafn(q) / gammafn(p + q)));

src/nmath/lgamma.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ double lgammafn_sign(double x, int *sgn)
100100
#endif
101101
return M_LN_SQRT_2PI + (x - 0.5) * log(x) - x + lgammacor(x);
102102
}
103-
/* else: x < -10; y = -x */
103+
/* else: x < -10; y = -x > 10 */
104104
sinpiy = fabs(sinpi(y));
105105

106106
if (sinpiy == 0) { /* Negative integer argument ===

src/nmath/lgammacor.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ attribute_hidden double lgammacor(double x)
6868
* xbig = 2 ^ 26.5
6969
* xmax = DBL_MAX / 48 = 2^1020 / 3 */
7070
#define nalgm 5
71+
/* NB: -- we'd need nalgm = 6 terms for full precision, but the result is
72+
== always used in +/- terms of considerably larger size ~ x*log(x)
73+
(we could even *decrease* nalgm for larger y)
74+
*/
75+
7176
#define xbig 94906265.62425156
7277

7378
if (x < 10) // possibly consider stirlerr()

0 commit comments

Comments
 (0)