pomp
Inference for partially observed Markov processes
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
wpfilter.c
Go to the documentation of this file.
1// -*- C++ -*-
2
3#include <Rdefines.h>
4#include "internal.h"
5
6// examines weights for filtering failure.
7// computes conditional log likelihood and effective sample size.
8// returns a named list.
9// AT PRESENT, NO PARAMETER RESAMPLING IS PERFORMED.
10SEXP wpfilter (SEXP X, SEXP Params, SEXP Weights, SEXP W, SEXP Trigger, SEXP Target, SEXP Np)
11{
12
13 SEXP dimX, dimP, Xnames, Pnames;
14 int nvars, nreps, np;
15 // REVISIT THIS IF PARAMETER RESAMPLING IS IMPLEMENTED
16 // int npars;
17 // int do_pr = 0; // do parameter resampling? at the moment, we do not
18 int *dim, k;
19 const char *dimnm[] = {"name",".id"};
20
21 PROTECT(dimX = GET_DIM(X));
22 dim = INTEGER(dimX);
23 nvars = dim[0]; nreps = dim[1];
24 PROTECT(Xnames = GET_ROWNAMES(GET_DIMNAMES(X)));
25
26 PROTECT(Params = as_matrix(Params));
27 PROTECT(dimP = GET_DIM(Params));
28 dim = INTEGER(dimP);
29 // npars = dim[0];
30 if (dim[1] > 1 && nreps != dim[1]) // #nocov
31 err("ncol('params') does not match ncol('states')"); // #nocov
32 PROTECT(Pnames = GET_ROWNAMES(GET_DIMNAMES(Params)));
33
34 np = *INTEGER(AS_INTEGER(Np));
35 // REVISIT THIS IF PARAMETER RESAMPLING IS IMPLEMENTED
36 // do_pr = (dim[1] > 1); // resample parameters as well as states
37
38 PROTECT(Weights = duplicate(AS_NUMERIC(Weights)));
39 PROTECT(W = duplicate(AS_NUMERIC(W)));
40
41 int nprotect = 7;
42
43 double trigger, target;
44 trigger = *REAL(AS_NUMERIC(Trigger));
45 target = *REAL(AS_NUMERIC(Target));
46
47 // add W to Weights. check weights for NAN or +Inf. find max of weights.
48 long double maxlogw = R_NegInf, oldw = 0;
49 double *xW = REAL(Weights);
50 double *xw = REAL(W);
51 for (k = 0; k < nreps; k++, xw++, xW++) {
52
53 oldw += exp(*xW);
54 *xW += *xw;
55
56 if (ISNAN(*xW) || *xW == R_PosInf) { // check the weights
57 SEXP rv;
58 PROTECT(rv = ScalarInteger(k+1)); nprotect++;
59 UNPROTECT(nprotect);
60 return rv;
61 }
62
63 if (maxlogw < *xW) maxlogw = *xW;
64
65 }
66
67 // set up return list
68 SEXP retval, retvalnames, newdim;
69
70 PROTECT(retval = NEW_LIST(5));
71 PROTECT(retvalnames = NEW_CHARACTER(5));
72 PROTECT(newdim = NEW_INTEGER(2));
73 nprotect += 3;
74
75 dim = INTEGER(newdim);
76 dim[0] = nvars; dim[1] = nreps;
77 SET_DIM(X,newdim);
78 setrownames(X,Xnames,2);
79 fixdimnames(X,dimnm,2);
80
81 SET_STRING_ELT(retvalnames,0,mkChar("states"));
82 SET_STRING_ELT(retvalnames,1,mkChar("params"));
83 SET_STRING_ELT(retvalnames,2,mkChar("weights"));
84 SET_STRING_ELT(retvalnames,3,mkChar("ess"));
85 SET_STRING_ELT(retvalnames,4,mkChar("loglik"));
86 SET_NAMES(retval,retvalnames);
87
88 SEXP ess, loglik;
89 PROTECT(ess = NEW_NUMERIC(1)); // effective sample size
90 PROTECT(loglik = NEW_NUMERIC(1)); // conditional log likelihood
91 nprotect += 2;
92
93 if (maxlogw == R_NegInf) { // all particles have zero likelihood
94 *REAL(ess) = 0;
95 *REAL(loglik) = R_NegInf;
96 } else {
97 // compute sum and sum of squares
98 long double w = 0, ws = 0;
99 xw = REAL(W);
100 xW = REAL(Weights);
101 for (k = 0; k < nreps; k++, xw++, xW++) {
102 *xW -= maxlogw;
103 *xw = exp(*xW);
104 if (*xw != 0) {
105 w += *xw;
106 ws += (*xw)*(*xw);
107 }
108 }
109 *(REAL(ess)) = w*w/ws;
110 *(REAL(loglik)) = maxlogw + log(w) - log(oldw);
111 }
112
113 SET_ELEMENT(retval,3,ess);
114 SET_ELEMENT(retval,4,loglik);
115
116 if (maxlogw == R_NegInf || (*REAL(ess) >= nreps*trigger && np == nreps)) { // do not resample
117
118 SET_ELEMENT(retval,0,X);
119 SET_ELEMENT(retval,1,Params);
120 SET_ELEMENT(retval,2,Weights);
121
122 } else { // no resampling
123
124 // create storage for new states
125 SEXP newstates = R_NilValue;
126 double *ss = 0, *st = 0;
127 {
128 int xdim[] = {nvars, np};
129 PROTECT(newstates = makearray(2,xdim)); nprotect++;
130 setrownames(newstates,Xnames,2);
131 fixdimnames(newstates,dimnm,2);
132 ss = REAL(X);
133 st = REAL(newstates);
134 }
135 SET_ELEMENT(retval,0,newstates);
136
137 // REVISIT THIS IF PARAMETER RESAMPLING IS IMPLEMENTED
138 // create storage for new parameters
139 // SEXP newparams = R_NilValue;
140 // double *ps = 0, *pt = 0;
141 // if (do_pr) {
142 // int xdim[] = {npars, np};
143 // PROTECT(newparams = makearray(2,xdim)); nprotect++;
144 // setrownames(newparams,Pnames,2);
145 // fixdimnames(newparams,dimnm,2);
146 // ps = REAL(Params);
147 // pt = REAL(newparams);
148 // SET_ELEMENT(retval,1,newparams);
149 // } else {
150 SET_ELEMENT(retval,1,Params);
151 // }
152
153 // create storage for new weights
154 SEXP newweights = R_NilValue;
155 double *ws = 0, *wt = 0;
156 {
157 PROTECT(newweights = NEW_NUMERIC(np)); nprotect++;
158 ws = REAL(Weights);
159 wt = REAL(newweights);
160 }
161 SET_ELEMENT(retval,2,newweights);
162
163 // compute target resampling weights
164 for (k = 0, xw = REAL(W), xW = REAL(Weights); k < nreps; k++, xw++, xW++) {
165 *xw = *xW;
166 *xW *= target;
167 *xw = exp(*xw - *xW);
168 }
169
170 // do resampling
171 {
172 int sample[np];
173 GetRNGstate();
174 nosort_resamp(nreps,REAL(W),np,sample,0);
175 PutRNGstate();
176
177 for (k = 0; k < np; k++) { // copy the particles
178 int sp = sample[k], j;
179 double *xx;
180 // double *xp;
181 for (j = 0, xx = ss+nvars*sp; j < nvars; j++, st++, xx++)
182 *st = *xx;
183 // REVISIT THIS IF PARAMETER RESAMPLING IS IMPLEMENTED
184 // if (do_pr) {
185 // for (j = 0, xp = ps+npars*sp; j < npars; j++, pt++, xp++)
186 // *pt = *xp;
187 // }
188 wt[k] = ws[sp];
189 }
190 }
191 }
192
193 UNPROTECT(nprotect);
194 return(retval);
195}
void nosort_resamp(int, double *, int, int *, int)
Definition resample.c:25
#define X
Definition gompertz.c:14
#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 makearray(int rank, const int *dim)
static R_INLINE SEXP as_matrix(SEXP x)
int nreps
Definition trajectory.c:134
int nvars
Definition trajectory.c:131
SEXP wpfilter(SEXP X, SEXP Params, SEXP Weights, SEXP W, SEXP Trigger, SEXP Target, SEXP Np)
Definition wpfilter.c:10