112 {
113
118
119 if (deltat <= 0)
err(
"'delta.t' should be a positive number.");
120
121 int *dim;
122 dim = INTEGER(GET_DIM(xstart));
nvars = dim[0];
nreps = dim[1];
124 ntimes = LENGTH(times);
125
126 PROTECT(tstart = AS_NUMERIC(tstart));
127 PROTECT(times = AS_NUMERIC(times));
128 t0 = *(REAL(tstart));
129 if (t0 > *(REAL(times)))
err(
"'t0' must be no later than 'times[1]'.");
130
131 SEXP
Snames, Pnames, Cnames;
132 PROTECT(
Snames = GET_ROWNAMES(GET_DIMNAMES(xstart)));
133 PROTECT(Pnames = GET_ROWNAMES(GET_DIMNAMES(
params)));
135
136
138 PROTECT(cvec = NEW_NUMERIC(
ncovars));
140
141
142 nzeros = LENGTH(accumvars);
143 int *zidx = INTEGER(PROTECT(
matchnames(
Snames,accumvars,
"state variables")));
144
145
147
148
150
151
152 memcpy(REAL(
X),REAL(xstart),
nvars*
nreps*
sizeof(
double));
153
154
155
156 int nprotect = 9;
157 int *pidx = 0, *sidx = 0, *cidx = 0;
159
161
163
165 break;
166
168
169 sidx = INTEGER(GET_SLOT(func,install("stateindex")));
170 pidx = INTEGER(GET_SLOT(func,install("paramindex")));
171 cidx = INTEGER(GET_SLOT(func,install("covarindex")));
172
173 *((
void **) (&ff)) = R_ExternalPtrAddr(
fn);
174
175 GetRNGstate();
176 break;
177
178 default:
179 err(
"unrecognized 'mode' %d",
mode);
180 break;
181 }
182
183
184 int step;
185 double *xt, *time, t;
186 int first = 1;
187
188 for (
189 step = 0, xt = REAL(
X), time = REAL(times), t = t0;
190 step < ntimes;
192 ) {
193
194 double dt;
195 int nstep = 0;
196 int i, j, k;
197
198 R_CheckUserInterrupt();
199
200 if (t > time[step])
err(
"'times' must be an increasing sequence.");
201
202
203 for (j = 0; j <
nreps; j++)
204 for (i = 0; i < nzeros; i++)
205 xt[zidx[i]+
nvars*j] = 0.0;
206
207
208 switch (method) {
210 dt = time[step]-t;
211 nstep = 1;
212 break;
214 dt = deltat;
216 break;
218 dt = deltat;
220 break;
221 }
222
223
224 for (k = 0; k < nstep; k++) {
225
226
228
229
230 double *ap, *pm, *xm, *ps = REAL(
params);
231
232 for (j = 0, pm = ps, xm = xt; j <
nreps; j++, pm +=
npars, xm +=
nvars) {
233
235
237 {
238 SEXP ans, nm;
239
240 if (first) {
241
243
244 PROTECT(nm = GET_NAMES(ans));
246 err(
"'rprocess' must return a named numeric vector.");
248
249 nprotect += 3;
250
251 ap = REAL(AS_NUMERIC(ans));
252 for (i = 0; i <
nvars; i++) xm[pidx[i]] = ap[i];
253
254 first = 0;
255
256 } else {
257
259
260 ap = REAL(AS_NUMERIC(ans));
261 for (i = 0; i <
nvars; i++) xm[pidx[i]] = ap[i];
262
263 UNPROTECT(1);
264
265 }
266 }
267 break;
268
270 (*ff)(xm,pm,sidx,pidx,cidx,
cov,t,dt);
271 break;
272
273 default:
274 err(
"unrecognized 'mode' %d",
mode);
275 break;
276
277 }
278
279 }
280
281 t += dt;
282
283 if ((method ==
euler) && (k == nstep-2)) {
284 dt = time[step]-t;
285 t = time[step]-dt;
286 }
287
288 }
289
290 if (step < ntimes-1)
292
293 }
294
295
297
299
300 PutRNGstate();
301
302 }
303
304 break;
305
307
308 break;
309
310 }
311
312 UNPROTECT(nprotect);
314
315}
lookup_table_t make_covariate_table(SEXP, int *)
SEXP pomp_fun_handler(SEXP, SEXP, pompfunmode *, SEXP, SEXP, SEXP, SEXP)
void table_lookup(lookup_table_t *, double, double *)
SEXP get_covariate_names(SEXP)
int num_map_steps(double t1, double t2, double deltat)
int num_euler_steps(double t1, double t2, double *deltat)
static R_INLINE SEXP eval_call(SEXP fn, SEXP args, double *t, double *dt, double *x, int nvar, double *p, int npar, double *c, int ncov)
static R_INLINE SEXP add_args(SEXP args, SEXP Snames, SEXP Pnames, SEXP Cnames)
static R_INLINE SEXP ret_array(int n, int nreps, int ntimes, SEXP names)
void pomp_onestep_sim(double *x, const double *p, const int *stateindex, const int *parindex, const int *covindex, const double *covars, double t, double dt)
static R_INLINE SEXP matchnames(SEXP provided, SEXP needed, const char *where)
static R_INLINE int invalid_names(SEXP names)