Skip to content

Commit 387daf3

Browse files
committed
better exception trapping in eulermultinom
1 parent d483b4f commit 387daf3

File tree

10 files changed

+163
-76
lines changed

10 files changed

+163
-76
lines changed

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Package: pomp
22
Type: Package
33
Title: Statistical Inference for Partially Observed Markov Processes
4-
Version: 5.2.0.0
5-
Date: 2023-06-06
4+
Version: 5.2.1.0
5+
Date: 2023-06-09
66
Authors@R: c(person(given=c("Aaron","A."),family="King",role=c("aut","cre"),email="kingaa@umich.edu",comment=c(ORCID="0000-0001-6159-3207")),
77
person(given=c("Edward","L."),family="Ionides",role="aut",comment=c(ORCID="0000-0002-4190-0174")) ,
88
person(given="Carles",family="Bretó",role="aut",comment=c(ORCID="0000-0003-4695-4902")),

inst/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
_N_e_w_s _f_o_r _p_a_c_k_a_g_e '_p_o_m_p'
22

3+
_C_h_a_n_g_e_s _i_n '_p_o_m_p' _v_e_r_s_i_o_n _5._2._1:
4+
5+
• ‘reulermultinom’ now returns ‘NA’ rather than ‘NaN’, in
6+
keeping with the behavior of ‘rbinom’. Thanks to John Drake
7+
for calling attention to this issue.
8+
39
_C_h_a_n_g_e_s _i_n '_p_o_m_p' _v_e_r_s_i_o_n _5._1._1:
410

511
• A bug in ‘stew’ resulting in namespace conflicts has been

inst/NEWS.Rd

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
\name{NEWS}
22
\title{News for package `pomp'}
3+
\section{Changes in \pkg{pomp} version 5.2.1}{
4+
\itemize{
5+
\item \code{reulermultinom} now returns \code{NA} rather than \code{NaN}, in keeping with the behavior of \code{rbinom}.
6+
Thanks to John Drake for calling attention to this issue.
7+
}
8+
}
39
\section{Changes in \pkg{pomp} version 5.1.1}{
410
\itemize{
511
\item A bug in \code{stew} resulting in namespace conflicts has been repaired.

inst/include/pomp.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,26 @@ static R_INLINE void reulermultinom (int m, double size, const double *rate,
4444
double dt, double *trans) {
4545
double p = 0.0;
4646
int j, k;
47-
if ((size < 0.0) || (dt < 0.0) || (floor(size+0.5) != size)) {
48-
for (k = 0; k < m; k++) trans[k] = R_NaN;
47+
if ( !R_FINITE(size) || size < 0.0 || floor(size+0.5) != size ||
48+
!R_FINITE(dt) || dt < 0.0) {
49+
for (k = 0; k < m; k++) trans[k] = R_NaReal;
50+
warningcall(R_NilValue,"in 'reulermultinom': NAs produced.");
4951
return;
5052
}
5153
for (k = 0; k < m; k++) {
52-
if (rate[k] < 0.0) {
53-
for (j = 0; j < m; j++) trans[j] = R_NaN;
54+
if (!R_FINITE(rate[k]) || rate[k] < 0.0) {
55+
for (j = 0; j < m; j++) trans[j] = R_NaReal;
56+
warningcall(R_NilValue,"in 'reulermultinom': NAs produced.");
5457
return;
5558
}
5659
p += rate[k]; // total event rate
5760
}
5861
if (p > 0.0) {
5962
size = rbinom(size,1-exp(-p*dt)); // total number of events
60-
if (!(R_FINITE(size)))
61-
warningcall(R_NilValue,"in 'reulermultinom': result of binomial draw is not finite.");
6263
m -= 1;
6364
for (k = 0; k < m; k++) {
6465
if (rate[k] > p) p = rate[k];
6566
trans[k] = ((size > 0) && (p > 0)) ? rbinom(size,rate[k]/p) : 0;
66-
if (!(R_FINITE(size)&&R_FINITE(p)&&R_FINITE(rate[k])&&R_FINITE(trans[k])))
67-
warningcall(R_NilValue,"in 'reulermultinom': result of binomial draw is not finite.");
6867
size -= trans[k];
6968
p -= rate[k];
7069
}

src/distributions.c

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,45 @@
44

55
#include "pomp_internal.h"
66

7-
static void reulermultinom_multi (int *n, int *ntrans, double *size, double *rate, double *deltat, double *trans) {
7+
static void reulermultinom_multi (int m, int n, double *size, double *rate, double *deltat, double *trans) {
88
int k;
9-
int m = *ntrans;
10-
for (k = 0; k < *n; k++) {
11-
reulermultinom(*ntrans,*size,rate,*deltat,trans);
9+
for (k = 0; k < n; k++) {
10+
reulermultinom(m,*size,rate,*deltat,trans);
1211
trans += m;
1312
}
1413
}
1514

16-
static void deulermultinom_multi (int *n, int *ntrans, double *size, double *rate, double *deltat, double *trans, int *give_log, double *f) {
15+
static void deulermultinom_multi (int m, int n, double *size, double *rate, double *deltat, double *trans, int *give_log, double *f) {
1716
int k;
18-
int m = *ntrans;
19-
for (k = 0; k < *n; k++) {
20-
f[k] = deulermultinom(*ntrans,*size,rate,*deltat,trans,*give_log);
17+
for (k = 0; k < n; k++) {
18+
f[k] = deulermultinom(m,*size,rate,*deltat,trans,*give_log);
2119
trans += m;
2220
}
2321
}
2422

2523
SEXP R_Euler_Multinom (SEXP n, SEXP size, SEXP rate, SEXP deltat) {
2624
int ntrans = length(rate);
2725
int dim[2];
28-
SEXP nn, x, nm;
26+
SEXP x, nm;
2927
if (length(size)>1)
3028
warn("in 'reulermultinom': only the first element of 'size' is meaningful");
3129
if (length(deltat)>1)
3230
warn("in 'reulermultinom': only the first element of 'dt' is meaningful");
33-
PROTECT(nn = AS_INTEGER(n));
31+
PROTECT(n = AS_INTEGER(n));
32+
PROTECT(size = AS_NUMERIC(size));
33+
PROTECT(rate = AS_NUMERIC(rate));
34+
PROTECT(deltat = AS_NUMERIC(deltat));
3435
dim[0] = ntrans;
35-
dim[1] = INTEGER(nn)[0];
36+
dim[1] = *INTEGER(n);
37+
if (dim[1] == NA_INTEGER || dim[1] < 0)
38+
err("in 'reulermultinom': 'n' must be a non-negative integer.");
3639
PROTECT(x = makearray(2,dim));
3740
PROTECT(nm = GET_NAMES(rate));
3841
setrownames(x,nm,2);
3942
GetRNGstate();
40-
reulermultinom_multi(INTEGER(nn),&ntrans,REAL(size),REAL(rate),REAL(deltat),REAL(x));
43+
reulermultinom_multi(dim[0],dim[1],REAL(size),REAL(rate),REAL(deltat),REAL(x));
4144
PutRNGstate();
42-
UNPROTECT(3);
45+
UNPROTECT(6);
4346
return x;
4447
}
4548

@@ -56,8 +59,12 @@ SEXP D_Euler_Multinom (SEXP x, SEXP size, SEXP rate, SEXP deltat, SEXP log) {
5659
if (length(deltat)>1)
5760
warn("in 'deulermultinom': only the first element of 'dt' is meaningful");
5861
PROTECT(f = NEW_NUMERIC(n));
59-
deulermultinom_multi(&n,&ntrans,REAL(size),REAL(rate),REAL(deltat),REAL(x),INTEGER(log),REAL(f));
60-
UNPROTECT(1);
62+
PROTECT(size = AS_NUMERIC(size));
63+
PROTECT(rate = AS_NUMERIC(rate));
64+
PROTECT(deltat = AS_NUMERIC(deltat));
65+
PROTECT(log = AS_LOGICAL(log));
66+
deulermultinom_multi(ntrans,n,REAL(size),REAL(rate),REAL(deltat),REAL(x),INTEGER(log),REAL(f));
67+
UNPROTECT(5);
6168
return f;
6269
}
6370

src/pomp.h

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,26 @@ static R_INLINE void reulermultinom (int m, double size, const double *rate,
4444
double dt, double *trans) {
4545
double p = 0.0;
4646
int j, k;
47-
if ((size < 0.0) || (dt < 0.0) || (floor(size+0.5) != size)) {
48-
for (k = 0; k < m; k++) trans[k] = R_NaN;
47+
if ( !R_FINITE(size) || size < 0.0 || floor(size+0.5) != size ||
48+
!R_FINITE(dt) || dt < 0.0) {
49+
for (k = 0; k < m; k++) trans[k] = R_NaReal;
50+
warningcall(R_NilValue,"in 'reulermultinom': NAs produced.");
4951
return;
5052
}
5153
for (k = 0; k < m; k++) {
52-
if (rate[k] < 0.0) {
53-
for (j = 0; j < m; j++) trans[j] = R_NaN;
54+
if (!R_FINITE(rate[k]) || rate[k] < 0.0) {
55+
for (j = 0; j < m; j++) trans[j] = R_NaReal;
56+
warningcall(R_NilValue,"in 'reulermultinom': NAs produced.");
5457
return;
5558
}
5659
p += rate[k]; // total event rate
5760
}
5861
if (p > 0.0) {
5962
size = rbinom(size,1-exp(-p*dt)); // total number of events
60-
if (!(R_FINITE(size)))
61-
warningcall(R_NilValue,"in 'reulermultinom': result of binomial draw is not finite.");
6263
m -= 1;
6364
for (k = 0; k < m; k++) {
6465
if (rate[k] > p) p = rate[k];
6566
trans[k] = ((size > 0) && (p > 0)) ? rbinom(size,rate[k]/p) : 0;
66-
if (!(R_FINITE(size)&&R_FINITE(p)&&R_FINITE(rate[k])&&R_FINITE(trans[k])))
67-
warningcall(R_NilValue,"in 'reulermultinom': result of binomial draw is not finite.");
6867
size -= trans[k];
6968
p -= rate[k];
7069
}

tests/R_v_C.Rout

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,16 @@ https://kingaa.github.io/pomp/blog.html.
117117
> ## ----comparison----------------------------------------------------------
118118
> system.time(simulate(gompertz,nsim=10000,format="arrays"))
119119
user system elapsed
120-
7.079 0.038 7.118
120+
7.012 0.069 7.082
121121
> system.time(simulate(Gompertz,nsim=10000,format="arrays"))
122122
user system elapsed
123-
0.148 0.011 0.160
123+
0.156 0.004 0.160
124124
> system.time(pfilter(gompertz,Np=1000))
125125
user system elapsed
126-
0.653 0.031 0.683
126+
0.649 0.000 0.649
127127
> system.time(pfilter(Gompertz,Np=1000))
128128
user system elapsed
129-
0.028 0.000 0.028
129+
0.029 0.000 0.028
130130
>
131131
> dev.off()
132132
null device

tests/eulermultinom.R

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ reulermultinom(n=1,size=c(100,200,300),rate=c(1,2,3),dt=0.2)
1515
reulermultinom(n=1,size=0,rate=c(1,2,3),dt=0.2)
1616
reulermultinom(n=1,size=10,rate=c(1,Inf,1),0.1)
1717
reulermultinom(n=1,size=Inf,rate=c(1,100,1),0.1)
18+
try(reulermultinom(n=NA,size=100,rate=c(1,2,3),dt=1))
19+
reulermultinom(n=5,size=NA,rate=c(1,2,3),dt=1)
20+
reulermultinom(n=5,size=100,rate=c(1,NA,3),dt=1)
21+
reulermultinom(n=5,size=100,rate=c(1,2,3),dt=NA)
22+
reulermultinom(n=5,size=100,rate=c(0,0,0,0),dt=1)
23+
1824
x <- reulermultinom(n=3,size=100,rate=c(3,2,1),dt=0.1)
1925
try(deulermultinom(rbind(x,c(0,1,0)),size=100,rate=c(3,2,1),dt=0.1))
2026
deulermultinom(x,size=c(100,NA),rate=c(3,2,1),dt=0.1)
@@ -24,6 +30,7 @@ deulermultinom(x=c(3,4,0),size=10,rate=c(1,1,1),dt=0-.1)
2430
deulermultinom(x=c(3,4,0),size=10,rate=c(1,1,-1),dt=0.1)
2531
deulermultinom(x=c(3,-4,0),size=10,rate=c(1,1,1),dt=0.1)
2632
deulermultinom(x=c(3,6,3),size=10,rate=c(1,1,0),dt=0.1,log=TRUE)
33+
2734
rgammawn(n=5,sigma=2,dt=0.1)
2835
rgammawn(n=5,sigma=1:5,dt=0.1)
2936
rgammawn(n=5,sigma=1,dt=rep(1,5))

tests/eulermultinom.Rout.save

Lines changed: 94 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -36,39 +36,62 @@ https://kingaa.github.io/pomp/blog.html.
3636
[3,] 20 22 21 23 20
3737
> reulermultinom(n=5,size=-3,rate=c(1,2,3),dt=0.1)
3838
[,1] [,2] [,3] [,4] [,5]
39-
[1,] NaN NaN NaN NaN NaN
40-
[2,] NaN NaN NaN NaN NaN
41-
[3,] NaN NaN NaN NaN NaN
39+
[1,] NA NA NA NA NA
40+
[2,] NA NA NA NA NA
41+
[3,] NA NA NA NA NA
42+
Warning messages:
43+
1: in 'reulermultinom': NAs produced.
44+
2: in 'reulermultinom': NAs produced.
45+
3: in 'reulermultinom': NAs produced.
46+
4: in 'reulermultinom': NAs produced.
47+
5: in 'reulermultinom': NAs produced.
4248
> reulermultinom(n=5,size=100,rate=c(1,-2,3),dt=0.1)
4349
[,1] [,2] [,3] [,4] [,5]
44-
[1,] NaN NaN NaN NaN NaN
45-
[2,] NaN NaN NaN NaN NaN
46-
[3,] NaN NaN NaN NaN NaN
50+
[1,] NA NA NA NA NA
51+
[2,] NA NA NA NA NA
52+
[3,] NA NA NA NA NA
53+
Warning messages:
54+
1: in 'reulermultinom': NAs produced.
55+
2: in 'reulermultinom': NAs produced.
56+
3: in 'reulermultinom': NAs produced.
57+
4: in 'reulermultinom': NAs produced.
58+
5: in 'reulermultinom': NAs produced.
4759
> reulermultinom(n=5,size=100,rate=c(1,NA,3),dt=0.1)
4860
[,1] [,2] [,3] [,4] [,5]
49-
[1,] 0 0 0 0 0
50-
[2,] 0 0 0 0 0
51-
[3,] 0 0 0 0 0
61+
[1,] NA NA NA NA NA
62+
[2,] NA NA NA NA NA
63+
[3,] NA NA NA NA NA
64+
Warning messages:
65+
1: in 'reulermultinom': NAs produced.
66+
2: in 'reulermultinom': NAs produced.
67+
3: in 'reulermultinom': NAs produced.
68+
4: in 'reulermultinom': NAs produced.
69+
5: in 'reulermultinom': NAs produced.
5270
> reulermultinom(n=5,size=100.3,rate=c(1,2,3),dt=0.1)
5371
[,1] [,2] [,3] [,4] [,5]
54-
[1,] NaN NaN NaN NaN NaN
55-
[2,] NaN NaN NaN NaN NaN
56-
[3,] NaN NaN NaN NaN NaN
72+
[1,] NA NA NA NA NA
73+
[2,] NA NA NA NA NA
74+
[3,] NA NA NA NA NA
75+
Warning messages:
76+
1: in 'reulermultinom': NAs produced.
77+
2: in 'reulermultinom': NAs produced.
78+
3: in 'reulermultinom': NAs produced.
79+
4: in 'reulermultinom': NAs produced.
80+
5: in 'reulermultinom': NAs produced.
5781
> reulermultinom(n=0,size=100,rate=c(1,2,3),dt=0.1)
5882

5983
[1,]
6084
[2,]
6185
[3,]
6286
> try(reulermultinom(n=-2,size=100,rate=c(1,2,3),dt=0.1))
63-
Error : in 'reulermultinom': negative length vectors are not allowed
87+
Error : in 'reulermultinom': in 'reulermultinom': 'n' must be a non-negative integer.
6488
> reulermultinom(n=1,size=100,rate=c(1,2e400,3),dt=0.1)
6589
[,1]
66-
[1,] 0
67-
[2,] NaN
68-
[3,] NaN
69-
Warning messages:
70-
1: in 'reulermultinom': result of binomial draw is not finite.
71-
2: in 'reulermultinom': result of binomial draw is not finite.
90+
[1,] NA
91+
[2,] NA
92+
[3,] NA
93+
Warning message:
94+
in 'reulermultinom': NAs produced.
7295
> reulermultinom(n=1,size=100,rate=c(1,2,3),dt=c(0.1,0.2,0.3,Inf))
7396
[,1]
7497
[1,] 11
@@ -90,21 +113,60 @@ in 'reulermultinom': only the first element of 'size' is meaningful
90113
[3,] 0
91114
> reulermultinom(n=1,size=10,rate=c(1,Inf,1),0.1)
92115
[,1]
93-
[1,] 0
94-
[2,] NaN
95-
[3,] NaN
96-
Warning messages:
97-
1: in 'reulermultinom': result of binomial draw is not finite.
98-
2: in 'reulermultinom': result of binomial draw is not finite.
116+
[1,] NA
117+
[2,] NA
118+
[3,] NA
119+
Warning message:
120+
in 'reulermultinom': NAs produced.
99121
> reulermultinom(n=1,size=Inf,rate=c(1,100,1),0.1)
100122
[,1]
101-
[1,] 0
102-
[2,] 0
103-
[3,] NaN
123+
[1,] NA
124+
[2,] NA
125+
[3,] NA
126+
Warning message:
127+
in 'reulermultinom': NAs produced.
128+
> try(reulermultinom(n=NA,size=100,rate=c(1,2,3),dt=1))
129+
Error : in 'reulermultinom': in 'reulermultinom': 'n' must be a non-negative integer.
130+
> reulermultinom(n=5,size=NA,rate=c(1,2,3),dt=1)
131+
[,1] [,2] [,3] [,4] [,5]
132+
[1,] NA NA NA NA NA
133+
[2,] NA NA NA NA NA
134+
[3,] NA NA NA NA NA
135+
Warning messages:
136+
1: in 'reulermultinom': NAs produced.
137+
2: in 'reulermultinom': NAs produced.
138+
3: in 'reulermultinom': NAs produced.
139+
4: in 'reulermultinom': NAs produced.
140+
5: in 'reulermultinom': NAs produced.
141+
> reulermultinom(n=5,size=100,rate=c(1,NA,3),dt=1)
142+
[,1] [,2] [,3] [,4] [,5]
143+
[1,] NA NA NA NA NA
144+
[2,] NA NA NA NA NA
145+
[3,] NA NA NA NA NA
146+
Warning messages:
147+
1: in 'reulermultinom': NAs produced.
148+
2: in 'reulermultinom': NAs produced.
149+
3: in 'reulermultinom': NAs produced.
150+
4: in 'reulermultinom': NAs produced.
151+
5: in 'reulermultinom': NAs produced.
152+
> reulermultinom(n=5,size=100,rate=c(1,2,3),dt=NA)
153+
[,1] [,2] [,3] [,4] [,5]
154+
[1,] NA NA NA NA NA
155+
[2,] NA NA NA NA NA
156+
[3,] NA NA NA NA NA
104157
Warning messages:
105-
1: in 'reulermultinom': result of binomial draw is not finite.
106-
2: in 'reulermultinom': result of binomial draw is not finite.
107-
3: in 'reulermultinom': result of binomial draw is not finite.
158+
1: in 'reulermultinom': NAs produced.
159+
2: in 'reulermultinom': NAs produced.
160+
3: in 'reulermultinom': NAs produced.
161+
4: in 'reulermultinom': NAs produced.
162+
5: in 'reulermultinom': NAs produced.
163+
> reulermultinom(n=5,size=100,rate=c(0,0,0,0),dt=1)
164+
[,1] [,2] [,3] [,4] [,5]
165+
[1,] 0 0 0 0 0
166+
[2,] 0 0 0 0 0
167+
[3,] 0 0 0 0 0
168+
[4,] 0 0 0 0 0
169+
>
108170
> x <- reulermultinom(n=3,size=100,rate=c(3,2,1),dt=0.1)
109171
> try(deulermultinom(rbind(x,c(0,1,0)),size=100,rate=c(3,2,1),dt=0.1))
110172
Error : in 'deulermultinom': NROW('x') should match length of 'rate'
@@ -130,6 +192,7 @@ in 'deulermultinom': NaNs produced.
130192
[1] 0
131193
> deulermultinom(x=c(3,6,3),size=10,rate=c(1,1,0),dt=0.1,log=TRUE)
132194
[1] -Inf
195+
>
133196
> rgammawn(n=5,sigma=2,dt=0.1)
134197
[1] 2.593438e-18 2.417425e-05 5.489565e-25 1.344180e-18 3.775061e-03
135198
> rgammawn(n=5,sigma=1:5,dt=0.1)

0 commit comments

Comments
 (0)