pomp
Inference for partially observed Markov processes
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pfilter.c File Reference
#include "internal.h"
#include <Rdefines.h>
Include dependency graph for pfilter.c:

Go to the source code of this file.

Functions

static void pred_mean_var (int, int, int, const double *, double *, double *)
 
static void filt_mean (int, int, int, long double, const double *, const double *, double *)
 
SEXP pfilter (SEXP x, SEXP params, SEXP Np, SEXP predmean, SEXP predvar, SEXP filtmean, SEXP trackancestry, SEXP doparRS, SEXP weights, SEXP wave)
 

Function Documentation

◆ filt_mean()

static void filt_mean ( int  nvars,
int  nreps,
int  all_fail,
long double  wsum,
const double *  w,
const double *  x,
double *  fm 
)
static

Definition at line 294 of file pfilter.c.

296{
297 long double sum;
298 const double *xx;
299 int j, k;
300 for (j = 0; j < nvars; j++, fm++) {
301 xx = x+j;
302 if (all_fail) { // unweighted average
303 for (k = 0, sum = 0; k < nreps; k++, xx += nvars) sum += *xx;
304 *fm = sum/((long double) nreps);
305 } else { // weighted average
306 for (k = 0, sum = 0; k < nreps; k++, xx += nvars) sum += w[k]*(*xx);
307 *fm = sum/wsum;
308 }
309 }
310}
int nreps
Definition trajectory.c:134
int nvars
Definition trajectory.c:131
Here is the caller graph for this function:

◆ pfilter()

SEXP pfilter ( SEXP  x,
SEXP  params,
SEXP  Np,
SEXP  predmean,
SEXP  predvar,
SEXP  filtmean,
SEXP  trackancestry,
SEXP  doparRS,
SEXP  weights,
SEXP  wave 
)

Definition at line 16 of file pfilter.c.

20{
21
22 SEXP pm = R_NilValue, pv = R_NilValue, fm = R_NilValue;
23 SEXP anc = R_NilValue, wmean = R_NilValue;
24 SEXP ess, loglik;
25 SEXP newstates = R_NilValue, newparams = R_NilValue;
26 SEXP retval, retvalnames;
27 const char *dimnm[2] = {"name",".id"};
28 double *xw = 0;
29 long double w = 0, ws, maxw, sum;
30 int *xanc = 0;
31 SEXP dimX, dimP, newdim, Xnames, Pnames;
32 int *dim, np;
33 int nvars, npars = 0, nreps;
34 int do_pm, do_pv, do_fm, do_ta, do_pr, do_wave, all_fail = 0;
35 int j, k;
36
37 PROTECT(dimX = GET_DIM(x));
38 dim = INTEGER(dimX);
39 nvars = dim[0]; nreps = dim[1];
40 PROTECT(Xnames = GET_ROWNAMES(GET_DIMNAMES(x)));
41
42 PROTECT(params = as_matrix(params));
43 PROTECT(dimP = GET_DIM(params));
44 dim = INTEGER(dimP);
45 npars = dim[0];
46 if (nreps % dim[1] != 0)
47 err("ncol('states') should be a multiple of ncol('params')"); // # nocov
48 PROTECT(Pnames = GET_ROWNAMES(GET_DIMNAMES(params)));
49
50 PROTECT(weights = duplicate(weights));
51
52 np = *(INTEGER(AS_INTEGER(Np))); // number of particles to resample
53
54 do_pm = *(LOGICAL(AS_LOGICAL(predmean))); // calculate prediction means?
55 do_pv = *(LOGICAL(AS_LOGICAL(predvar))); // calculate prediction variances?
56 do_fm = *(LOGICAL(AS_LOGICAL(filtmean))); // calculate filtering means?
57 do_ta = *(LOGICAL(AS_LOGICAL(trackancestry))); // track ancestry?
58 // Do we need to do parameter resampling?
59 do_pr = *(LOGICAL(AS_LOGICAL(doparRS)));
60 // Do we need to take a weighted average over the parameters?
61 do_wave = *(LOGICAL(AS_LOGICAL(wave)));
62
63 if (do_pr) {
64 if (dim[1] != nreps)
65 err("ncol('states') should be equal to ncol('params')"); // # nocov
66 }
67
68 PROTECT(ess = NEW_NUMERIC(1)); // effective sample size
69 PROTECT(loglik = NEW_NUMERIC(1)); // log likelihood
70
71 int nprotect = 8;
72
73 xw = REAL(weights);
74
75 // check and normalize the weights
76 for (k = 0, maxw = R_NegInf; k < nreps; k++) {
77
78 if (ISNAN(xw[k]) || xw[k] == R_PosInf) { // check the weights
79 PROTECT(retval = NEW_INTEGER(1)); nprotect++;
80 *INTEGER(retval) = k+1; // return the index of the peccant particle
81 UNPROTECT(nprotect);
82 return retval;
83 }
84
85 if (maxw < xw[k]) maxw = xw[k];
86
87 }
88
89 if (maxw == R_NegInf) all_fail = 1;
90
91 if (all_fail) {
92
93 *(REAL(loglik)) = R_NegInf;
94 *(REAL(ess)) = 0; // zero effective sample size
95
96 } else {
97
98 // compute sum and sum of squares
99 for (k = 0, w = 0, ws = 0; k < nreps; k++) {
100 xw[k] = exp(xw[k]-maxw);
101 if (xw[k] != 0) {
102 w += xw[k];
103 ws += xw[k]*xw[k];
104 }
105 }
106
107 *(REAL(loglik)) = maxw + log(w/((long double) nreps)); // mean of weights is likelihood
108 *(REAL(ess)) = w*w/ws; // effective sample size
109 }
110
111 if (do_pm || do_pv) {
112 PROTECT(pm = NEW_NUMERIC(nvars)); nprotect++;
113 }
114
115 if (do_pv) {
116 PROTECT(pv = NEW_NUMERIC(nvars)); nprotect++;
117 }
118
119 if (do_fm) {
120 PROTECT(fm = NEW_NUMERIC(nvars)); nprotect++;
121 }
122
123 if (do_ta) {
124 PROTECT(anc = NEW_INTEGER(np)); nprotect++;
125 xanc = INTEGER(anc);
126 }
127
128 if (do_wave) {
129 PROTECT(wmean = NEW_NUMERIC(npars)); nprotect++;
130 SET_NAMES(wmean,Pnames);
131 }
132
133 if (do_pm || do_pv) {
134 double *tmp = (do_pv) ? REAL(pv) : 0;
135 pred_mean_var(nvars,nreps,do_pv,REAL(x),REAL(pm),tmp);
136 }
137
138 // compute filter mean
139 if (do_fm) {
140 filt_mean(nvars,nreps,all_fail,w,xw,REAL(x),REAL(fm));
141 }
142
143 // compute weighted average of parameters
144 if (do_wave) {
145 if (all_fail)
146 warn("%s %s","filtering failure at last filter iteration:",
147 "using unweighted mean for point estimate.");
148 double *xwm = REAL(wmean);
149 for (j = 0; j < npars; j++, xwm++) {
150 double *xp = REAL(params)+j;
151 if (all_fail) { // unweighted average
152 for (k = 0, sum = 0; k < nreps; k++, xp += npars) sum += *xp;
153 *xwm = sum/((long double) nreps);
154 } else {
155 for (k = 0, sum = 0; k < nreps; k++, xp += npars) {
156 if (xw[k]!=0) sum += xw[k]*(*xp);
157 }
158 *xwm = sum/w;
159 }
160 }
161 }
162
163 GetRNGstate();
164
165 if (!all_fail) { // resample the particles unless we have filtering failure
166 int xdim[2];
167 int sample[np];
168 double *ss = 0, *st = 0, *ps = 0, *pt = 0;
169
170 // create storage for new states
171 xdim[0] = nvars; xdim[1] = np;
172 PROTECT(newstates = makearray(2,xdim)); nprotect++;
173 setrownames(newstates,Xnames,2);
174 fixdimnames(newstates,dimnm,2);
175 ss = REAL(x);
176 st = REAL(newstates);
177
178 // create storage for new parameters
179 if (do_pr) {
180 xdim[0] = npars; xdim[1] = np;
181 PROTECT(newparams = makearray(2,xdim)); nprotect++;
182 setrownames(newparams,Pnames,2);
183 fixdimnames(newparams,dimnm,2);
184 ps = REAL(params);
185 pt = REAL(newparams);
186 }
187
188 // resample
189 nosort_resamp(nreps,REAL(weights),np,sample,0);
190 for (k = 0; k < np; k++) { // copy the particles
191 int sp = sample[k];
192 double *xx, *xp;
193 for (j = 0, xx = ss+nvars*sp; j < nvars; j++, st++, xx++)
194 *st = *xx;
195 if (do_pr) {
196 for (j = 0, xp = ps+npars*sp; j < npars; j++, pt++, xp++)
197 *pt = *xp;
198 }
199 if (do_ta) xanc[k] = sp+1;
200 }
201
202 } else { // don't resample: just drop 3rd dimension in x prior to return
203
204 PROTECT(newdim = NEW_INTEGER(2)); nprotect++;
205 dim = INTEGER(newdim);
206 dim[0] = nvars; dim[1] = nreps;
207 SET_DIM(x,newdim);
208 setrownames(x,Xnames,2);
209 fixdimnames(x,dimnm,2);
210
211 if (do_ta)
212 for (k = 0; k < np; k++) xanc[k] = k+1;
213 }
214
215 PutRNGstate();
216
217 PROTECT(retval = NEW_LIST(9));
218 PROTECT(retvalnames = NEW_CHARACTER(9));
219 nprotect += 2;
220 SET_STRING_ELT(retvalnames,0,mkChar("loglik"));
221 SET_STRING_ELT(retvalnames,1,mkChar("ess"));
222 SET_STRING_ELT(retvalnames,2,mkChar("states"));
223 SET_STRING_ELT(retvalnames,3,mkChar("params"));
224 SET_STRING_ELT(retvalnames,4,mkChar("pm"));
225 SET_STRING_ELT(retvalnames,5,mkChar("pv"));
226 SET_STRING_ELT(retvalnames,6,mkChar("fm"));
227 SET_STRING_ELT(retvalnames,7,mkChar("ancestry"));
228 SET_STRING_ELT(retvalnames,8,mkChar("wmean"));
229 SET_NAMES(retval,retvalnames);
230
231 SET_ELEMENT(retval,0,loglik);
232 SET_ELEMENT(retval,1,ess);
233
234 if (all_fail) {
235 SET_ELEMENT(retval,2,x);
236 } else {
237 SET_ELEMENT(retval,2,newstates);
238 }
239
240 if (all_fail || !do_pr) {
241 SET_ELEMENT(retval,3,params);
242 } else {
243 SET_ELEMENT(retval,3,newparams);
244 }
245
246 if (do_pm) {
247 SET_ELEMENT(retval,4,pm);
248 }
249 if (do_pv) {
250 SET_ELEMENT(retval,5,pv);
251 }
252 if (do_fm) {
253 SET_ELEMENT(retval,6,fm);
254 }
255 if (do_ta) {
256 SET_ELEMENT(retval,7,anc);
257 }
258 if (do_wave) {
259 SET_ELEMENT(retval,8,wmean);
260 }
261
262 UNPROTECT(nprotect);
263 return(retval);
264}
void nosort_resamp(int, double *, int, int *, int)
Definition resample.c:25
static void filt_mean(int, int, int, long double, const double *, const double *, double *)
Definition pfilter.c:294
static void pred_mean_var(int, int, int, const double *, double *, double *)
Definition pfilter.c:266
#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 makearray(int rank, const int *dim)
static R_INLINE SEXP as_matrix(SEXP x)
int npars
Definition trajectory.c:132
SEXP params
Definition trajectory.c:128
Here is the call graph for this function:

◆ pred_mean_var()

static void pred_mean_var ( int  nvars,
int  nreps,
int  do_pv,
const double *  x,
double *  pm,
double *  pv 
)
static

Definition at line 266 of file pfilter.c.

269{
270 long double sum, sumsq, vsq;
271 const double *xx;
272 int j, k;
273
274 for (j = 0; j < nvars; j++, pm++, pv++) {
275
276 xx = x+j;
277
278 // compute prediction mean
279 for (k = 0, sum = 0; k < nreps; k++, xx += nvars) sum += *xx;
280 *pm = sum/((long double) nreps);
281
282 // compute prediction variance
283 if (do_pv) {
284 xx = x+j;
285 for (k = 0, sumsq = 0; k < nreps; k++, xx += nvars) {
286 vsq = *xx - sum;
287 sumsq += vsq*vsq;
288 }
289 *pv = sumsq/((long double) (nreps - 1));
290 }
291 }
292}
Here is the caller graph for this function: