Skip to content

Commit f216042

Browse files
author
maechler
committed
internal cwilcox() checks more rarely for user interrupt
git-svn-id: https://svn.r-project.org/R/trunk@87448 00db46b3-68df-0310-9c12-caf00c1e9a41
1 parent 8d5049b commit f216042

File tree

2 files changed

+31
-30
lines changed

2 files changed

+31
-30
lines changed

doc/NEWS.Rd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,9 @@
419419
getting \code{s <- getOption("OutDec")}, signals a warning to become
420420
an error in the future, when \code{s} is not a string with exactly
421421
one character.
422+
423+
\item \code{pwilcox()} and \code{qwilcox()} now check for user
424+
interrupt less frequencly.
422425
}
423426
}
424427
}

src/nmath/wilcox.c

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
3434
*/
3535

36-
/*
37-
Note: the checks here for R_CheckInterrupt also do stack checking.
36+
/*
37+
Note: the checks here for R_CheckUserInterrupt also do stack checking.
3838
3939
calloc/free are remapped for use in R, so allocation checks are done there.
4040
freeing is completed by an on.exit action in the R wrappers.
@@ -108,17 +108,15 @@ w_free_maybe(int m, int n)
108108
}
109109

110110

111+
#ifndef MATHLIB_STANDALONE
112+
static int ic = 99999;
113+
#endif
111114
/* This counts the number of choices with statistic = k */
112115
static double
113116
cwilcox(int k, int m, int n)
114117
{
115-
int c, u, i, j, l;
116-
117-
#ifndef MATHLIB_STANDALONE
118-
R_CheckUserInterrupt();
119-
#endif
120-
121-
u = m * n;
118+
int c, i, j,
119+
u = m * n;
122120
if (k < 0 || k > u)
123121
return(0);
124122
c = (int)(u / 2);
@@ -134,20 +132,27 @@ cwilcox(int k, int m, int n)
134132
return (k == 0);
135133

136134

137-
/* We can simplify things if k is small. Consider the Mann-Whitney
138-
definition, and sort y. Then if the statistic is k, no more
139-
than k of the y's can be <= any x[i], and since they are sorted
135+
/* We can simplify things if k is small. Consider the Mann-Whitney
136+
definition, and sort y. Then if the statistic is k, no more
137+
than k of the y's can be <= any x[i], and since they are sorted
140138
these can only be in the first k. So the count is the same as
141-
if there were just k y's.
139+
if there were just k y's.
142140
*/
143-
if (j > 0 && k < j) return cwilcox(k, i, k);
144-
141+
if (j > 0 && k < j) return cwilcox(k, i, k);
142+
143+
#ifndef MATHLIB_STANDALONE
144+
if (!ic--) {
145+
R_CheckUserInterrupt();
146+
ic = 99999;
147+
}
148+
#endif
149+
145150
if (w[i][j] == 0) {
146151
w[i][j] = (double *) calloc((size_t) c + 1, sizeof(double));
147152
#ifdef MATHLIB_STANDALONE
148153
if (!w[i][j]) MATHLIB_ERROR(_("wilcox allocation error %d"), 3);
149154
#endif
150-
for (l = 0; l <= c; l++)
155+
for (int l = 0; l <= c; l++)
151156
w[i][j][l] = -1;
152157
}
153158
if (w[i][j][k] < 0) {
@@ -162,8 +167,6 @@ cwilcox(int k, int m, int n)
162167

163168
double dwilcox(double x, double m, double n, int give_log)
164169
{
165-
double d;
166-
167170
#ifdef IEEE_754
168171
/* NaNs propagated correctly */
169172
if (ISNAN(x) || ISNAN(m) || ISNAN(n))
@@ -182,7 +185,7 @@ double dwilcox(double x, double m, double n, int give_log)
182185

183186
int mm = (int) m, nn = (int) n, xx = (int) x;
184187
w_init_maybe(mm, nn);
185-
d = give_log ?
188+
double d = give_log ?
186189
log(cwilcox(xx, mm, nn)) - lchoose(m + n, n) :
187190
cwilcox(xx, mm, nn) / choose(m + n, n);
188191

@@ -192,9 +195,6 @@ double dwilcox(double x, double m, double n, int give_log)
192195
/* args have the same meaning as R function pwilcox */
193196
double pwilcox(double q, double m, double n, int lower_tail, int log_p)
194197
{
195-
int i;
196-
double c, p;
197-
198198
#ifdef IEEE_754
199199
if (ISNAN(q) || ISNAN(m) || ISNAN(n))
200200
return(q + m + n);
@@ -215,16 +215,16 @@ double pwilcox(double q, double m, double n, int lower_tail, int log_p)
215215

216216
int mm = (int) m, nn = (int) n;
217217
w_init_maybe(mm, nn);
218-
c = choose(m + n, n);
219-
p = 0;
218+
double c = choose(m + n, n),
219+
p = 0;
220220
/* Use summation of probs over the shorter range */
221221
if (q <= (m * n / 2)) {
222-
for (i = 0; i <= q; i++)
222+
for (int i = 0; i <= q; i++)
223223
p += cwilcox(i, mm, nn) / c;
224224
}
225225
else {
226226
q = m * n - q;
227-
for (i = 0; i < q; i++)
227+
for (int i = 0; i < q; i++)
228228
p += cwilcox(i, mm, nn) / c;
229229
lower_tail = !lower_tail; /* p = 1 - p; */
230230
}
@@ -236,8 +236,6 @@ double pwilcox(double q, double m, double n, int lower_tail, int log_p)
236236

237237
double qwilcox(double x, double m, double n, int lower_tail, int log_p)
238238
{
239-
double c, p;
240-
241239
#ifdef IEEE_754
242240
if (ISNAN(x) || ISNAN(m) || ISNAN(n))
243241
return(x + m + n);
@@ -261,8 +259,8 @@ double qwilcox(double x, double m, double n, int lower_tail, int log_p)
261259

262260
int mm = (int) m, nn = (int) n;
263261
w_init_maybe(mm, nn);
264-
c = choose(m + n, n);
265-
p = 0;
262+
double c = choose(m + n, n),
263+
p = 0.;
266264
int q = 0;
267265
if (x <= 0.5) {
268266
x = x - 10 * DBL_EPSILON;

0 commit comments

Comments
 (0)