Skip to content

Commit e0fc83a

Browse files
committed
improve discussion of Euler-multinomials
1 parent 048b549 commit e0fc83a

File tree

4 files changed

+189
-105
lines changed

4 files changed

+189
-105
lines changed

vignettes/C_API.Rmd

+79-18
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,52 @@ The return value is the probability or log probability (as requested).
6565

6666
### Euler-multinomial distribution
6767

68-
#### Simulate Euler-multinomial transitions
68+
The Euler multinomial approximation of a continuous-time, stochastic compartmental model is as follows.
69+
Suppose a compartment has occupancy $N_t$ at time $t$ and that there are $K$ ways of exiting the compartment, with per capita rates (hazards) $\mu_1,\dots,\mu_K$, respectively.
70+
71+
-----
72+
73+
```{r compartment-diagram,echo=FALSE,purl=FALSE,out.width="200px",out.height="200px",dpi=100,fig.height=3,fig.width=3,fig.align="center",fig.cap="**Diagram:** *A single compartment within a compartmental model. Here, there are $K=2$ paths out of the compartment.*"}
74+
library(grid)
75+
vp <- viewport(width=unit(0.95,"npc"),height=unit(0.95,"npc"))
76+
pushViewport(vp)
77+
grid.rect(x=c(1/4),y=3/4,width=1/2,height=1/2,just=c(0.5,0.5),gp=gpar(fill="white",lwd=3))
78+
grid.text(x=c(1/4),y=3/4,label=c(expression(N[t])),gp=gpar(fontsize=36))
79+
grid.text(x=unit(c(3/4,1/4),"npc")+unit(c(0,18),"point"),y=unit(c(3/4,1/4),"npc")+unit(c(18,0),"point"),
80+
label=c(expression(mu[1]),expression(mu[2])),gp=gpar(fontsize=24))
81+
grid.lines(x=c(1/2,1),y=3/4,arrow=arrow(length=unit(0.04,"npc")),gp=gpar(lwd=3))
82+
grid.lines(x=c(1/4),y=c(1/2,0),arrow=arrow(length=unit(0.04,"npc")),gp=gpar(lwd=3))
83+
popViewport()
84+
```
85+
86+
-----
87+
88+
<a id="eulermultinomial-definition"></a>
89+
To make the Euler multinomial approximation, we approximate the total exit rate as constant over a small interval $[t,t+\Delta{t})$.
90+
Let the random variable $\Delta{n_k}$, $k=1,\dots,K$, be the number that exit by path $k$ in this time interval and $\Delta{n_0}$ be the number that remain.
91+
Under this assumption, the vector of numbers of exits, $(\Delta{n_{0}},\Delta{n_{1}},\dots,\Delta{n_{K}})$ is multinomially distributed with size $N_t$ and probabilities $(p_k)_{k=0}^K$, where
92+
$$p_0 = \exp\left(-\sum\!\mu_i\,\Delta{t}\right),$$
93+
and
94+
$$p_k = \frac{\mu_k}{\sum\!\mu_i}\,\left(1-p_0\right),\qquad k=1,\dots,K.$$
95+
By way of shorthand, we say that $\Delta{n}=(\Delta{n_k})_{k=1}^K$ is *Euler-multinomially distributed* with size $N_t$, rates $\mu=(\mu_k)_{k=1}^K$, and time-step $\Delta{t}$ and we write
96+
$$\Delta{n} \sim \mathrm{Eulermultinom}\left(N_t,\mu,\Delta{t}\right).$$
97+
98+
The **pomp** C API provides three functions that relate to the Euler-multinomial distribution.
99+
Their descriptions follow.
100+
101+
#### Simulate an Euler-multinomial random variable
102+
103+
The `reulermultinom` function draws a random sample from this distribution.
104+
Using the notation above, one has to pack the $K$ rates $\mu_1,\dots,\mu_K$ into contiguous memory locations and retrieve the results in (a different set of) contiguous memory locations.
105+
For example, if `rate` is a [pointer](https://www.tutorialspoint.com/cprogramming/c_pointers) to $K$ contiguous memory locations holding the rates and `dn` is a pointer to $K$ contiguous memory locations ready to hold the results, then
106+
```{c eval=FALSE}
107+
reulermultinom(K,N,rate,dt,dn);
108+
```
109+
will result in a random sample from the Euler multinomial distribution (with timestep dt) being stored in `dn[0]`, ..., `dn[K-1]`.
110+
In the foregoing, we've assumed that the quantities $N_t$ and $K$ are stored in the integer variables `N` and `K`, respectively, and that the double precision variable `dt` holds the timestep.
69111

112+
<a id="reulermultinom-prototype"></a>
113+
The prototype is:
70114

71115
```{c eval=FALSE}
72116
void reulermultinom(int m, double size, const double *rate,
@@ -81,26 +125,21 @@ Input:
81125
- `dt`, a positive real number, is the duration of time interval.
82126
- `trans` is a pointer to the vector that will hold the random deviate.
83127

128+
Output:
129+
84130
On return, `trans[0]`, ..., `trans[m-1]` will be the numbers of individuals making each of the respective transitions.
85131

86-
See [`?reulermultinom`](https://kingaa.github.io/manuals/pomp/html/eulermultinom.html) and [FAQ 3.6](./FAQ.html#eulermultinomial-approximation) for more on the Euler-multinomial distributions.
132+
See [`?reulermultinom`](https://kingaa.github.io/manuals/pomp/html/eulermultinom.html) for more on the Euler-multinomial distributions.
87133

88134
**NB:** `reulermultinom` does not call `GetRNGstate()` or `PutRNGstate()` internally.
89135
This must be done by the calling program.
90136
But note that when `reulermultinom` is called inside a **pomp** rprocess, there is no need to call either `GetRNGState()` or `PutRNGState()`;
91137
this is handled by **pomp**.
92138

93-
#### Expectation of an Euler-multinomial random variable
94-
95-
```{c eval=FALSE}
96-
void eeulermultinom(int m, double size, const double *rate,
97-
double dt, double *trans);
98-
```
99-
100-
The parameters `m`, `size`, `rate`, and `dt` have the same meaning as above.
101-
After a call to `eeulermultinom`, `trans` points to an array of `double`s holding the *expected values* of the Euler-multinomial random variables.
139+
#### Probability distribution of an Euler-multinomial random variable
102140

103-
#### Compute probabilities of Euler-multinomial transitions
141+
If $\Delta{n} \sim \mathrm{Eulermultinom}\left(N_t,\mu,\Delta{t}\right)$, then the probability it takes a specific value can be computed using the C function `deulermultinom`.
142+
Its prototype is:
104143

105144
```{c eval=FALSE}
106145
double deulermultinom(int m, double size, const double *rate,
@@ -115,13 +154,35 @@ Input:
115154
- `dt`, a positive real number, is the duration of time interval.
116155
- `trans` is pointer to vector containing the data, which are numbers of individuals making the respective transitions.
117156
- `give_log` is an integer:
118-
- `give_log=1` if log probability is desired;
119-
- `give_log=0` if probability is desired.
157+
- `give_log=0` requests that the probability be returned.
158+
- `give_log=1` requests that the log probability to be returned.
159+
160+
Output:
120161

121162
The value returned is the probability or log probability (as requested).
122163

123-
See [`?deulermultinom`](https://kingaa.github.io/manuals/pomp/html/eulermultinom.html) and [FAQ 3.6](./FAQ.html#eulermultinomial-approximation) for more on the Euler-multinomial distributions.
164+
See also [`?deulermultinom`](https://kingaa.github.io/manuals/pomp/html/eulermultinom.html).
124165

166+
#### Expectation of an Euler-multinomial random variable
167+
168+
If $\Delta{n} \sim \mathrm{Eulermultinom}\left(N_t,\mu,\Delta{t}\right)$, then the expectation of its $i$-th component is
169+
$$\mathbb{E}\left[\Delta{n}_i\right]=p_k N_t,$$
170+
where $p_k$ is as [defined above](#eulermultinomial-definition).
171+
The C function `eeulermultinom` computes this.
172+
Its prototype is:
173+
174+
```{c eval=FALSE}
175+
void eeulermultinom(int m, double size, const double *rate,
176+
double dt, double *trans);
177+
```
178+
179+
Input:
180+
181+
The parameters `m`, `size`, `rate`, and `dt` have the same meaning [as above](#reulermultinom-prototype).
182+
183+
Output:
184+
185+
After a call to `eeulermultinom`, `trans` points to an array of `double`s holding the *expected values* of the Euler-multinomial random variables.
125186

126187
### Gamma white noise
127188

@@ -224,12 +285,12 @@ double exp2geom_rate_correction(double R, double dt);
224285
```
225286

226287
This function computes $r$ such that if
227-
$$N \sim \mathrm{Geometric}\left(p=1-e^{-r\,{\Delta}t}\right)$$
288+
$$N \sim \mathrm{Geometric}\left(p=1-e^{-r\,\Delta{t}}\right)$$
228289
and
229290
$$T \sim \mathrm{Exponential}\left(\mathrm{rate}=R\right),$$
230-
then $\mathbb{E}\left[N\,{\Delta}t\right] = \mathbb{E}\left[T\right]$.
291+
then $\mathbb{E}\left[N\,\Delta{t}\right] = \mathbb{E}\left[T\right]$.
231292
That is, $r$ is the rate for an Euler process that gives the same expected waiting time as the exponential process it approximates.
232-
In particular $r \to R$ as ${\Delta}t \to 0$.
293+
In particular $r \to R$ as $\Delta{t} \to 0$.
233294

234295

235296
## Access to the userdata

0 commit comments

Comments
 (0)