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