Skip to content

Commit 719cd3e

Browse files
marmaduke woodmanspringcoil
authored andcommitted
IPyNB and unit test for EM SDE (#1486)
* add original example * restart nb & convert oscillator * add lin sde as test
1 parent 1327069 commit 719cd3e

File tree

2 files changed

+1712
-0
lines changed

2 files changed

+1712
-0
lines changed

docs/source/notebooks/Euler-Maruyama and SDEs.ipynb

Lines changed: 1663 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from __future__ import division
2+
3+
from ..model import Model
4+
from ..distributions.continuous import Flat, Normal
5+
from ..distributions.timeseries import EulerMaruyama
6+
from ..tuning.starting import find_MAP
7+
from ..sampling import sample, sample_ppc
8+
from ..step_methods.nuts import NUTS
9+
10+
import numpy as np
11+
from scipy.optimize import fmin_l_bfgs_b
12+
13+
14+
def _gen_sde_path(sde, pars, dt, n, x0):
15+
xs = [x0]
16+
wt = np.random.normal(size=(n,) if isinstance(x0, float) else (n, x0.size))
17+
for i in range(n):
18+
f, g = sde(xs[-1], *pars)
19+
xs.append(
20+
xs[-1] + f * dt + np.sqrt(dt) * g * wt[i]
21+
)
22+
return np.array(xs)
23+
24+
25+
def test_linear():
26+
lam = -0.78
27+
sig2 = 5e-3
28+
N = 300
29+
dt = 1e-1
30+
sde = lambda x, lam: (lam * x, sig2)
31+
x = _gen_sde_path(sde, (lam,), dt, N, 5.0)
32+
z = x + np.random.randn(x.size) * 5e-3
33+
# build model
34+
with Model() as model:
35+
lamh = Flat('lamh')
36+
xh = EulerMaruyama('xh', dt, sde, (lamh,), shape=N + 1, testval=x)
37+
zh = Normal('zh', mu=xh, sd=5e-3, observed=z)
38+
# invert
39+
with model:
40+
start = find_MAP(vars=[xh], fmin=fmin_l_bfgs_b)
41+
warmup = sample(200, NUTS(scaling=start))
42+
trace = sample(1000, NUTS(scaling=warmup[-1], gamma=0.25), start=warmup[-1])
43+
ppc = sample_ppc(trace, model=model)
44+
# test
45+
p95 = [2.5, 97.5]
46+
lo, hi = np.percentile(trace[lamh], p95, axis=0)
47+
assert (lo < lam) and (lam < hi)
48+
lo, hi = np.percentile(ppc['zh'], p95, axis=0)
49+
assert ((lo < z) * (z < hi)).mean() > 0.95

0 commit comments

Comments
 (0)