pomp
Inference for partially observed Markov processes
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
skeleton.c
Go to the documentation of this file.
1// dear emacs, please treat this as -*- C++ -*-
2
3#include <R.h>
4#include <Rmath.h>
5#include <Rdefines.h>
6
7
8#include "internal.h"
9
10SEXP add_skel_args (SEXP args, SEXP Snames, SEXP Pnames, SEXP Cnames)
11{
12
13 SEXP var;
14 int v;
15
16 PROTECT(args = VectorToPairList(args));
17
18 // Covariates
19 for (v = LENGTH(Cnames)-1; v >= 0; v--) {
20 var = NEW_NUMERIC(1);
21 args = LCONS(var,args);
22 UNPROTECT(1);
23 PROTECT(args);
24 SET_TAG(args,installChar(STRING_ELT(Cnames,v)));
25 }
26
27 // Parameters
28 for (v = LENGTH(Pnames)-1; v >= 0; v--) {
29 var = NEW_NUMERIC(1);
30 args = LCONS(var,args);
31 UNPROTECT(1);
32 PROTECT(args);
33 SET_TAG(args,installChar(STRING_ELT(Pnames,v)));
34 }
35
36 // Latent state variables
37 for (v = LENGTH(Snames)-1; v >= 0; v--) {
38 var = NEW_NUMERIC(1);
39 args = LCONS(var,args);
40 UNPROTECT(1);
41 PROTECT(args);
42 SET_TAG(args,installChar(STRING_ELT(Snames,v)));
43 }
44
45 // Time
46 var = NEW_NUMERIC(1);
47 args = LCONS(var,args);
48 UNPROTECT(1);
49 PROTECT(args);
50 SET_TAG(args,install("t"));
51
52 UNPROTECT(1);
53 return args;
54
55}
56
57static R_INLINE SEXP eval_call (
58 SEXP fn, SEXP args,
59 double *t,
60 double *x, int nvar,
61 double *p, int npar,
62 double *c, int ncov)
63{
64
65 SEXP var = args, ans, ob;
66 int v;
67
68 *(REAL(CAR(var))) = *t; var = CDR(var);
69 for (v = 0; v < nvar; v++, x++, var=CDR(var)) *(REAL(CAR(var))) = *x;
70 for (v = 0; v < npar; v++, p++, var=CDR(var)) *(REAL(CAR(var))) = *p;
71 for (v = 0; v < ncov; v++, c++, var=CDR(var)) *(REAL(CAR(var))) = *c;
72
73 PROTECT(ob = LCONS(fn,args));
74 PROTECT(ans = eval(ob,CLOENV(fn)));
75
76 UNPROTECT(2);
77 return ans;
78
79}
80
81static R_INLINE SEXP ret_array (int nvars, int nreps, int ntimes, SEXP Snames)
82{
83 SEXP X;
84 int dim[3] = {nvars, nreps, ntimes};
85 const char *dimnms[3] = {"name",".id","time"};
86 PROTECT(X = makearray(3,dim));
88 fixdimnames(X,dimnms,3);
89 UNPROTECT(1);
90 return X;
91}
92
94(
95 double *f, double *time, double *x, double *p,
96 SEXP fn, SEXP args, SEXP Snames,
97 int nvars, int npars, int ncovars, int ntimes,
98 int nrepx, int nrepp, int nreps,
100 ) {
101
102 SEXP ans, nm;
103 double *fs;
104 int *posn = 0;
105 int i, j, k;
106 int first = 1;
107 int nprotect = 0;
108
109 for (k = 0; k < ntimes; k++, time++) {
110
111 R_CheckUserInterrupt();
112
113 // interpolate the covar functions for the covariates
115
116 for (j = 0; j < nreps; j++, f += nvars) {
117
118 if (first) {
119
120 PROTECT(ans = eval_call(fn,args,time,
121 x+nvars*((j%nrepx)+nrepx*k),nvars,
122 p+npars*(j%nrepp),npars,
123 cov,ncovars));
124
125 if (LENGTH(ans)!=nvars)
126 err("'skeleton' returns a vector of %d state variables but %d are expected.",LENGTH(ans),nvars);
127
128 // get name information to fix alignment problems
129 PROTECT(nm = GET_NAMES(ans));
130 if (invalid_names(nm))
131 err("'skeleton' must return a named numeric vector.");
132 posn = INTEGER(PROTECT(matchnames(Snames,nm,"state variables")));
133
134 fs = REAL(AS_NUMERIC(ans));
135 for (i = 0; i < nvars; i++) f[posn[i]] = fs[i];
136
137 nprotect += 3;
138 first = 0;
139
140 } else {
141
142 PROTECT(ans = eval_call(fn,args,time,
143 x+nvars*((j%nrepx)+nrepx*k),nvars,
144 p+npars*(j%nrepp),npars,
145 cov,ncovars));
146
147 fs = REAL(AS_NUMERIC(ans));
148 for (i = 0; i < nvars; i++) f[posn[i]] = fs[i];
149
150 UNPROTECT(1);
151
152 }
153
154 }
155 }
156
157 UNPROTECT(nprotect);
158
159}
160
162 double *X, double t, double deltat,
163 double *time, double *x, double *p,
164 SEXP fn, SEXP args, SEXP Snames,
165 int nvars, int npars, int ncovars, int ntimes,
166 int nrepp, int nreps, int nzeros,
167 lookup_table_t *covar_table, int *zeroindex,
168 double *cov)
169{
170
171 SEXP ans, nm;
172 double *ap, *xs;
173 int nsteps;
174 int *posn = 0;
175 int h, i, j, k;
176 int first = 1;
177 int nprotect = 0;
178
179 for (k = 0; k < ntimes; k++, time++, X += nvars*nreps) {
180
181 R_CheckUserInterrupt();
182
183 // compute number of steps needed
184 nsteps = num_map_steps(t,*time,deltat);
185
186 // set accumulator variables to zero
187 for (i = 0; i < nzeros; i++)
188 for (j = 0, xs = &x[zeroindex[i]]; j < nreps; j++, xs += nvars)
189 *xs = 0.0;
190
191 for (h = 0; h < nsteps; h++) {
192
193 // interpolate the covariates
195
196 for (j = 0, xs = x; j < nreps; j++, xs += nvars) {
197
198 if (first) {
199
200 PROTECT(ans = eval_call(fn,args,&t,xs,nvars,p+npars*(j%nrepp),npars,cov,ncovars));
201
202 if (LENGTH(ans) != nvars)
203 err("'skeleton' returns a vector of %d state variables but %d are expected.",LENGTH(ans),nvars);
204
205 // get name information to fix alignment problems
206 PROTECT(nm = GET_NAMES(ans));
207 if (invalid_names(nm)) err("'skeleton' must return a named numeric vector.");
208 posn = INTEGER(PROTECT(matchnames(Snames,nm,"state variables")));
209
210 ap = REAL(AS_NUMERIC(ans));
211 for (i = 0; i < nvars; i++) xs[posn[i]] = ap[i];
212
213 nprotect += 3;
214 first = 0;
215
216 } else {
217
218 PROTECT(ans = eval_call(fn,args,&t,xs,nvars,p+npars*(j%nrepp),npars,cov,ncovars));
219
220 ap = REAL(AS_NUMERIC(ans));
221 for (i = 0; i < nvars; i++) xs[posn[i]] = ap[i];
222
223 UNPROTECT(1);
224
225 }
226
227 }
228
229 if (h != nsteps-1) {
230 t += deltat;
231 } else {
232 t = *time;
233 }
234
235 }
236
237 memcpy(X,x,nvars*nreps*sizeof(double));
238
239 }
240
241 UNPROTECT(nprotect);
242
243}
244
246 double *f, double *time, double *x, double *p,
247 int nvars, int npars, int ncovars, int ntimes,
248 int nrepx, int nrepp, int nreps,
249 int *sidx, int *pidx, int *cidx,
251 double *cov)
252{
253 double *xp, *pp;
254 int j, k;
255
256 for (k = 0; k < ntimes; k++, time++) {
257
258 R_CheckUserInterrupt();
259
261
262 for (j = 0; j < nreps; j++, f += nvars) {
263
264 xp = &x[nvars*((j%nrepx)+nrepx*k)];
265 pp = &p[npars*(j%nrepp)];
266
267 (*fun)(f,xp,pp,sidx,pidx,cidx,cov,*time);
268
269 }
270 }
271
272}
273
275 double *X, double t, double deltat,
276 double *time, double *x, double *p,
277 int nvars, int npars, int ncovars, int ntimes,
278 int nrepp, int nreps, int nzeros,
279 int *sidx, int *pidx, int *cidx,
280 lookup_table_t *covar_table, int *zeroindex,
281 pomp_skeleton *fun, SEXP args, double *cov)
282{
283 int nsteps;
284 double *xs, *Xs;
285 int h, i, j, k;
286
287 for (k = 0; k < ntimes; k++, time++, X += nvars*nreps) {
288
289 R_CheckUserInterrupt();
290
291 // compute number of steps needed
292 nsteps = num_map_steps(t,*time,deltat);
293
294 // set accumulator variables to zero
295 for (i = 0; i < nzeros; i++)
296 for (j = 0, xs = &x[zeroindex[i]]; j < nreps; j++, xs += nvars)
297 *xs = 0.0;
298
299 for (h = 0; h < nsteps; h++) {
300
301 // interpolate the covariates
303
304 for (j = 0, Xs = X, xs = x; j < nreps; j++, Xs += nvars, xs += nvars) {
305
306 (*fun)(Xs,xs,p+npars*(j%nrepp),sidx,pidx,cidx,cov,t);
307
308 }
309
310 memcpy(x,X,nvars*nreps*sizeof(double));
311
312 if (h != nsteps-1) {
313 t += deltat;
314 } else {
315 t = *time;
316 }
317
318 }
319
320 if (nsteps == 0) memcpy(X,x,nvars*nreps*sizeof(double));
321
322 }
323
324}
325
326SEXP do_skeleton (SEXP object, SEXP x, SEXP t, SEXP params, SEXP gnsi)
327{
328
329 int nvars, npars, nrepp, nrepx, nreps, ntimes, ncovars;
331 int *dim;
332 SEXP Snames, Cnames, Pnames;
333 SEXP pompfun, cov, ob;
334 SEXP fn, args, F;
335 lookup_table_t covariate_table;
336
337 PROTECT(t = AS_NUMERIC(t));
338 ntimes = LENGTH(t);
339
340 PROTECT(x = as_state_array(x));
341 dim = INTEGER(GET_DIM(x));
342 nvars = dim[0]; nrepx = dim[1];
343 if (ntimes != dim[2])
344 err("length of 'times' and 3rd dimension of 'x' do not agree.");
345
346 PROTECT(params = as_matrix(params));
347 dim = INTEGER(GET_DIM(params));
348 npars = dim[0]; nrepp = dim[1];
349
350 // 2nd dimension of 'x' and 'params' need not agree
351 nreps = (nrepp > nrepx) ? nrepp : nrepx;
352 if ((nreps % nrepp != 0) || (nreps % nrepx != 0))
353 err("2nd dimensions of 'x' and 'params' are incompatible");
354
355 PROTECT(Snames = GET_ROWNAMES(GET_DIMNAMES(x)));
356 PROTECT(Pnames = GET_ROWNAMES(GET_DIMNAMES(params)));
357 PROTECT(Cnames = get_covariate_names(GET_SLOT(object,install("covar"))));
358
359 // set up the covariate table
360 covariate_table = make_covariate_table(GET_SLOT(object,install("covar")),&ncovars);
361 PROTECT(cov = NEW_NUMERIC(ncovars));
362
363 // extract the user-defined function
364 PROTECT(ob = GET_SLOT(object,install("skeleton")));
365 PROTECT(pompfun = GET_SLOT(ob,install("skel.fn")));
366 PROTECT(fn = pomp_fun_handler(pompfun,gnsi,&mode,Snames,Pnames,NA_STRING,Cnames));
367
368 // extract 'userdata' as pairlist
369 PROTECT(args = GET_SLOT(object,install("userdata")));
370
371 PROTECT(F = ret_array(nvars,nreps,ntimes,Snames));
372
373 int nprotect = 12;
374
375 switch (mode) {
376
377 case Rfun: {
378
379 PROTECT(args = add_skel_args(args,Snames,Pnames,Cnames)); nprotect++;
380
381 eval_skeleton_R(REAL(F),REAL(t),REAL(x),REAL(params),
382 fn,args,Snames,
383 nvars,npars,ncovars,ntimes,nrepx,nrepp,nreps,
384 &covariate_table,REAL(cov));
385
386 }
387
388 break;
389
390 case native: case regNative: {
391 int *sidx, *pidx, *cidx;
392 pomp_skeleton *ff = NULL;
393
394 sidx = INTEGER(GET_SLOT(pompfun,install("stateindex")));
395 pidx = INTEGER(GET_SLOT(pompfun,install("paramindex")));
396 cidx = INTEGER(GET_SLOT(pompfun,install("covarindex")));
397
398 *((void **) (&ff)) = R_ExternalPtrAddr(fn);
399
401 REAL(F),REAL(t),REAL(x),REAL(params),
402 nvars,npars,ncovars,ntimes,nrepx,nrepp,nreps,
403 sidx,pidx,cidx,&covariate_table,ff,args,REAL(cov));
404
405 }
406
407 break;
408
409 default: {
410
411 double *ft = REAL(F);
412 int i, n = nvars*nreps*ntimes;
413 for (i = 0; i < n; i++, ft++) *ft = R_NaReal;
414 warn("'skeleton' unspecified: NAs generated.");
415
416 }
417
418 }
419
420 UNPROTECT(nprotect);
421 return F;
422}
int num_map_steps(double, double, double)
Definition euler.c:342
lookup_table_t make_covariate_table(SEXP, int *)
SEXP pomp_fun_handler(SEXP, SEXP, pompfunmode *, SEXP, SEXP, SEXP, SEXP)
Definition pomp_fun.c:30
void table_lookup(lookup_table_t *, double, double *)
SEXP get_covariate_names(SEXP)
Definition lookup_table.c:7
#define X
Definition gompertz.c:14
void pomp_skeleton(double *f, const double *x, const double *p, const int *stateindex, const int *parindex, const int *covindex, const double *covars, double t)
Definition pomp.h:73
#define warn(...)
Definition pomp.h:22
#define err(...)
Definition pomp.h:21
static R_INLINE void fixdimnames(SEXP x, const char **names, int n)
static R_INLINE void setrownames(SEXP x, SEXP names, int rank)
static R_INLINE SEXP matchnames(SEXP provided, SEXP needed, const char *where)
static R_INLINE SEXP makearray(int rank, const int *dim)
static R_INLINE SEXP as_state_array(SEXP x)
pompfunmode
@ Rfun
@ native
@ undef
@ regNative
static R_INLINE int invalid_names(SEXP names)
static R_INLINE SEXP as_matrix(SEXP x)
void eval_skeleton_native(double *f, double *time, double *x, double *p, int nvars, int npars, int ncovars, int ntimes, int nrepx, int nrepp, int nreps, int *sidx, int *pidx, int *cidx, lookup_table_t *covar_table, pomp_skeleton *fun, SEXP args, double *cov)
Definition skeleton.c:245
static R_INLINE SEXP ret_array(int nvars, int nreps, int ntimes, SEXP Snames)
Definition skeleton.c:81
SEXP add_skel_args(SEXP args, SEXP Snames, SEXP Pnames, SEXP Cnames)
Definition skeleton.c:10
SEXP do_skeleton(SEXP object, SEXP x, SEXP t, SEXP params, SEXP gnsi)
Definition skeleton.c:326
static R_INLINE SEXP eval_call(SEXP fn, SEXP args, double *t, double *x, int nvar, double *p, int npar, double *c, int ncov)
Definition skeleton.c:57
void iterate_skeleton_R(double *X, double t, double deltat, double *time, double *x, double *p, SEXP fn, SEXP args, SEXP Snames, int nvars, int npars, int ncovars, int ntimes, int nrepp, int nreps, int nzeros, lookup_table_t *covar_table, int *zeroindex, double *cov)
Definition skeleton.c:161
void eval_skeleton_R(double *f, double *time, double *x, double *p, SEXP fn, SEXP args, SEXP Snames, int nvars, int npars, int ncovars, int ntimes, int nrepx, int nrepp, int nreps, lookup_table_t *covar_table, double *cov)
Definition skeleton.c:94
void iterate_skeleton_native(double *X, double t, double deltat, double *time, double *x, double *p, int nvars, int npars, int ncovars, int ntimes, int nrepp, int nreps, int nzeros, int *sidx, int *pidx, int *cidx, lookup_table_t *covar_table, int *zeroindex, pomp_skeleton *fun, SEXP args, double *cov)
Definition skeleton.c:274
int npars
Definition trajectory.c:132
SEXP Snames
Definition trajectory.c:140
int ncovars
Definition trajectory.c:133
SEXP params
Definition trajectory.c:128
pompfunmode mode
Definition trajectory.c:126
lookup_table_t covar_table
Definition trajectory.c:130
int nreps
Definition trajectory.c:134
SEXP args
Definition trajectory.c:139
pomp_skeleton * fun
Definition trajectory.c:147
SEXP cov
Definition trajectory.c:129
SEXP fn
Definition trajectory.c:138
int nvars
Definition trajectory.c:131