phylopomp
Phylodynamics for POMPs
Loading...
Searching...
No Matches
seirs_pomp.c
Go to the documentation of this file.
1#include "pomplink.h"
2#include "internal.h"
3
4#define Exposed 1
5#define Infected 2
6
7static const int nrate = 6;
8
9static inline int random_choice (double n) {
10 return floor(R_unif_index(n));
11}
12
13static void change_color (double *color, int nsample,
14 int n, int from, int to) {
15 int i = -1;
16 i = -1;
17 while (n >= 0 && i < nsample) {
18 i++;
19 if (!ISNA(color[i]) && nearbyint(color[i]) == from) n--;
20 }
21 assert(i < nsample);
22 assert(n == -1);
23 assert(nearbyint(color[i]) == from);
24 color[i] = to;
25}
26
27#define Beta (__p[__parindex[0]])
28#define sigma (__p[__parindex[1]])
29#define gamma (__p[__parindex[2]])
30#define psi (__p[__parindex[3]])
31#define chi (__p[__parindex[4]])
32#define omega (__p[__parindex[5]])
33#define S0 (__p[__parindex[6]])
34#define E0 (__p[__parindex[7]])
35#define I0 (__p[__parindex[8]])
36#define R0 (__p[__parindex[9]])
37#define POP (__p[__parindex[10]])
38#define S (__x[__stateindex[0]])
39#define E (__x[__stateindex[1]])
40#define I (__x[__stateindex[2]])
41#define R (__x[__stateindex[3]])
42#define ll (__x[__stateindex[4]])
43#define node (__x[__stateindex[5]])
44#define ellE (__x[__stateindex[6]])
45#define ellI (__x[__stateindex[7]])
46#define COLOR (__x[__stateindex[8]])
47
48#define EVENT_RATES \
49 event_rates(__x,__p,t, \
50 __stateindex,__parindex,__covindex, \
51 __covars,rate,logpi,&penalty) \
52
53static double event_rates
54(
55 double *__x,
56 const double *__p,
57 double t,
58 const int *__stateindex,
59 const int *__parindex,
60 const int *__covindex,
61 const double *__covars,
62 double *rate,
63 double *logpi,
64 double *penalty
65 ) {
66 double event_rate = 0;
67 double alpha, pi;
68 *penalty = 0;
69 // 0: transmission, s=(0,0) or s=(0,1)
70 assert(S>=0 && I>=0);
71 alpha = (POP > 0) ? Beta*S*I/POP : 0;
72 pi = (I > 0) ? 1-ellI/I : 0;
73 assert(I >= ellI);
74 event_rate += (*rate = alpha*pi); rate++;
75 *logpi = log(pi); logpi++;
76 // 1: transmission, s=(1,0)
77 pi = 1-pi;
78 event_rate += (*rate = alpha*pi); rate++;
79 *logpi = log(pi)-log(ellI); logpi++;
80 // 2: progression, s=(0,0)
81 assert(E>=0);
82 alpha = sigma*E;
83 pi = (E > 0) ? 1-ellE/E : 1;
84 assert(E >= ellE);
85 event_rate += (*rate = alpha*pi); rate++;
86 *logpi = log(pi); logpi++;
87 // 3: progression, s=(0,1)
88 pi = 1-pi;
89 event_rate += (*rate = alpha*pi); rate++;
90 *logpi = log(pi)-log(ellE); logpi++;
91 // 4: recovery
92 assert(I>=0);
93 alpha = gamma*I;
94 if (I > ellI) {
95 event_rate += (*rate = alpha); rate++;
96 *logpi = 0; logpi++;
97 } else {
98 *rate = 0; rate++;
99 *logpi = 0; logpi++;
100 *penalty += alpha;
101 }
102 // 5: waning
103 event_rate += (*rate = omega*R); rate++;
104 *logpi = 0; logpi++;
105 // sampling (Q = 0): non-destructive (psi) + destructive (chi)
106 *penalty += (psi+chi)*I;
107 assert(R_FINITE(event_rate));
108 return event_rate;
109}
110
118(
119 double *__x,
120 const double *__p,
121 double t0,
122 const int *__stateindex,
123 const int *__parindex,
124 const int *__covindex,
125 const double *__covars
126 ){
127 double adj = POP/(S0+E0+I0+R0);
128 S = nearbyint(S0*adj);
129 E = nearbyint(E0*adj);
130 I = nearbyint(I0*adj);
131 R = nearbyint(R0*adj);
132 ellE = 0;
133 ellI = 0;
134 ll = 0;
135 node = 0;
136}
137
143(
144 double *__x,
145 const double *__p,
146 const int *__stateindex,
147 const int *__parindex,
148 const int *__covindex,
149 const double *__covars,
150 double t,
151 double dt
152 ){
153 double tstep = 0.0, tmax = t + dt;
154 double *color = &COLOR;
155 const int nsample = *get_userdata_int("nsample");
156 const int *nodetype = get_userdata_int("nodetype");
157 const int *lineage = get_userdata_int("lineage");
158 const int *sat = get_userdata_int("saturation");
159 const int *index = get_userdata_int("index");
160 const int *child = get_userdata_int("child");
161
162 int parent = (int) nearbyint(node);
163
164#ifndef NDEBUG
165 int nnode = *get_userdata_int("nnode");
166 assert(parent>=0);
167 assert(parent<=nnode);
168#endif
169
170 int parlin = lineage[parent];
171 int parcol = color[parlin];
172 assert(parlin >= 0 && parlin < nsample);
173
174 ll = 0;
175
176 // singular portion of filter equation
177 switch (nodetype[parent]) {
178 default: // non-genealogical event #nocov
179 break; // #nocov
180 case 0: // root
181 // color lineages by sampling without replacement
182 assert(sat[parent]==1);
183 int c = child[index[parent]];
184 assert(lineage[parent]==lineage[c]);
185 if (E-ellE + I-ellI > 0) {
186 double x = (E-ellE)/(E-ellE + I-ellI);
187 if (unif_rand() < x) { // lineage is put into E deme
188 color[lineage[c]] = Exposed;
189 ellE += 1;
190 ll -= log(x);
191 } else { // lineage is put into I deme
192 color[lineage[c]] = Infected;
193 ellI += 1;
194 ll -= log(1-x);
195 }
196 } else { // more roots than infectives
197 ll += R_NegInf; // this is incompatible with the genealogy
198 // the following keeps the state valid
199 if (unif_rand() < 0.5) { // lineage is put into E deme
200 color[lineage[c]] = Exposed;
201 ellE += 1; E += 1;
202 // ll -= log(0.5);
203 } else { // lineage is put into I deme
204 color[lineage[c]] = Infected;
205 ellI += 1; I += 1;
206 // ll -= log(0.5);
207 }
208 }
209 break;
210 case 1: // sample
211 // If parent is not in deme I, likelihood = 0.
212 if (parcol != Infected) {
213 ll += R_NegInf;
214 color[parlin] = Infected;
215 // the following keeps the state valid
216 ellE -= 1; ellI += 1;
217 E -= 1; I += 1;
218 }
219 if (sat[parent] == 1) { // s=(0,1)
220 int c = child[index[parent]];
221 color[lineage[c]] = Infected;
222 ll += log(psi);
223 } else if (sat[parent] == 0) { // s=(0,0)
224 ellI -= 1;
225 ll += log(psi+chi);
226 if (unif_rand() < psi/(psi+chi)) { // non-destructive sample
227 ll += log(I-ellI);
228 } else { // destructive sample
229 ll += log(I);
230 I -= 1;
231 }
232 } else {
233 assert(0); // #nocov
234 ll += R_NegInf; // #nocov
235 }
236 color[parlin] = R_NaReal;
237 break;
238 case 2: // branch point s=(1,1)
239 // If parent is not in deme I, likelihood = 0.
240 if (parcol != Infected) {
241 ll += R_NegInf;
242 color[parlin] = Infected;
243 // the following keeps the state valid
244 ellE -= 1; ellI += 1;
245 E -= 1; I += 1;
246 }
247 assert(sat[parent]==2);
248 ll += (S > 0 && I > 0) ? log(Beta*S/POP/(E+1)) : R_NegInf;
249 S -= 1; E += 1;
250 ellE += 1;
251 S = (S > 0) ? S : 0;
252 int c1 = child[index[parent]];
253 int c2 = child[index[parent]+1];
254 assert(c1 != c2);
255 assert(lineage[c1] != lineage[c2]);
256 assert(lineage[c1] != parlin || lineage[c2] != parlin);
257 assert(lineage[c1] == parlin || lineage[c2] == parlin);
258 if (unif_rand() < 0.5) {
259 color[lineage[c1]] = Exposed;
260 color[lineage[c2]] = Infected;
261 } else {
262 color[lineage[c1]] = Infected;
263 color[lineage[c2]] = Exposed;
264 }
265 ll -= log(0.5);
266 break;
267 }
268
269 // continuous portion of filter equation:
270 // take Gillespie steps to the end of the interval
271 if (tmax > t && R_FINITE(ll)) {
272
273 double rate[nrate], logpi[nrate];
274 int event;
275 double event_rate = 0;
276 double penalty = 0;
277
278 event_rate = EVENT_RATES;
279 tstep = exp_rand()/event_rate;
280
281 while (t + tstep < tmax) {
282 event = rcateg(event_rate,rate,nrate);
283 assert(event>=0 && event<nrate);
284 ll -= penalty*tstep + logpi[event];
285 switch (event) {
286 case 0: // transmission, s=(0,0) or s=(0,1)
287 assert(S>=1);
288 S -= 1; E += 1;
289 ll += log(1-ellE/E);
290 assert(!ISNAN(ll));
291 break;
292 case 1: // transmission, s=(1,0)
293 assert(S>=1);
295 ellE += 1; ellI -= 1;
296 S -= 1; E += 1;
297 ll += log(1-ellI/I)-log(E);
298 assert(!ISNAN(ll));
299 break;
300 case 2: // progression, s=(0,0)
301 assert(E>=1);
302 E -= 1; I += 1;
303 ll += log(1-ellI/I);
304 assert(!ISNAN(ll));
305 break;
306 case 3: // progression, s=(0,1)
307 assert(E>=1);
309 ellE -= 1; ellI += 1;
310 E -= 1; I += 1;
311 ll -= log(I);
312 assert(!ISNAN(ll));
313 break;
314 case 4: // recovery
315 assert(I>=1);
316 I -= 1; R += 1;
317 assert(!ISNAN(ll));
318 break;
319 case 5: // waning
320 assert(R>=1);
321 R -= 1; S += 1;
322 assert(!ISNAN(ll));
323 break;
324 default: // #nocov
325 assert(0); // #nocov
326 ll += R_NegInf; // #nocov
327 break; // #nocov
328 }
329
330 ellE = nearbyint(ellE);
331 ellI = nearbyint(ellI);
332
333 t += tstep;
334 event_rate = EVENT_RATES;
335 tstep = exp_rand()/event_rate;
336
337 }
338 tstep = tmax - t;
339 ll -= penalty*tstep;
340 }
341 node += 1;
342}
343
344# define lik (__lik[0])
345
348(
349 double *__lik,
350 const double *__y,
351 const double *__x,
352 const double *__p,
353 int give_log,
354 const int *__obsindex,
355 const int *__stateindex,
356 const int *__parindex,
357 const int *__covindex,
358 const double *__covars,
359 double t
360 ) {
361 assert(!ISNAN(ll));
362 lik = (give_log) ? ll : exp(ll);
363}
SEXP nsample(TYPE &X)
Definition generics.h:12
get_userdata_int_t * get_userdata_int
Definition init.c:7
static int rcateg(double erate, double *rate, int nrate)
Definition internal.h:85
#define chi
Definition lbdp_pomp.c:7
#define lik
Definition lbdp_pomp.c:165
#define n
Definition lbdp_pomp.c:9
#define ll
Definition lbdp_pomp.c:10
#define psi
Definition lbdp_pomp.c:6
#define EVENT_RATES
Definition lbdp_pomp.c:14
#define node
Definition lbdp_pomp.c:12
#define ellE
Definition seirs_pomp.c:44
#define E
Definition seirs_pomp.c:39
#define POP
Definition seirs_pomp.c:37
static void change_color(double *color, int nsample, int n, int from, int to)
Definition seirs_pomp.c:13
#define R0
Definition seirs_pomp.c:36
#define gamma
Definition seirs_pomp.c:29
#define COLOR
Definition seirs_pomp.c:46
static double event_rates(double *__x, const double *__p, double t, const int *__stateindex, const int *__parindex, const int *__covindex, const double *__covars, double *rate, double *logpi, double *penalty)
Definition seirs_pomp.c:54
static int random_choice(double n)
Definition seirs_pomp.c:9
#define R
Definition seirs_pomp.c:41
#define S0
Definition seirs_pomp.c:33
#define I
Definition seirs_pomp.c:40
#define sigma
Definition seirs_pomp.c:28
#define Beta
Definition seirs_pomp.c:27
#define I0
Definition seirs_pomp.c:35
#define E0
Definition seirs_pomp.c:34
#define ellI
Definition seirs_pomp.c:45
void seirs_gill(double *__x, const double *__p, const int *__stateindex, const int *__parindex, const int *__covindex, const double *__covars, double t, double dt)
Definition seirs_pomp.c:143
void seirs_dmeas(double *__lik, const double *__y, const double *__x, const double *__p, int give_log, const int *__obsindex, const int *__stateindex, const int *__parindex, const int *__covindex, const double *__covars, double t)
Measurement model likelihood (dmeasure).
Definition seirs_pomp.c:348
static const int nrate
Definition seirs_pomp.c:7
#define Infected
Definition seirs_pomp.c:5
void seirs_rinit(double *__x, const double *__p, double t0, const int *__stateindex, const int *__parindex, const int *__covindex, const double *__covars)
Definition seirs_pomp.c:118
#define omega
Definition seirs_pomp.c:32
#define Exposed
Definition seirs_pomp.c:4
#define S
Definition seirs_pomp.c:38