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