the model fails to initialize sampling, complaining about SamplingError: Initial evaluation of model at starting point failed!. Inspecting the initial values of the variables, it seems that the initial value of pt (an array with shape (T,) ) includes negative values as well as values above 1, which makes the variance part of the SDE negative, which of course breaks everything.
However, I am giving it a testval value that should be valid. However, the sampler does not take it into account.
import arviz as az
import pymc3 as pm
import numpy as np
import theano.tensor as tt
from pymc3.distributions.timeseries import EulerMaruyama
# generate some data
s = .1
N = 100
dt = 1e-1
T = 50
# time series
p = 0.1
p_t = []
# simulate
for i in range(T):
p += dt * s * p * (1-p) + np.sqrt(dt*p*(1-p)/N) * np.random.normal()
p_t.append(p)
p_t = np.array(p_t)
# z_t noisy observation
z_t = p_t + np.random.normal(size=p_t.size) * 5e-3
Now, we implement the model:
def wright_fisher_sde(p,s):
return s*p*(1-p),np.sqrt((p*(1-p)/N))
with pm.Model() as model:
s = pm.Normal("s",0,1)
pt = EulerMaruyama("pt", dt, wright_fisher_sde, (s,), shape=(T,), testval=0.1*tt.ones(T))
zh = pm.Normal("zh", mu=pt, sigma=5e-3, observed=z_t)
trace = pm.sample(1000,return_inferencedata=True,cores=1,chains=2)
This fails with error: SamplingError: Initial evaluation of model at starting point failed!.
I was able to reproduce your problem and would have expected it to work fine the way you wrote it. I’m not sure why testval was getting ignored. Either way, you can use the start keyword argument for pm.sample to properly initialize the sampler. Try this:
Sampling will use the testval (soon to be deprecated in favor of initval, FYI), but during default initialization (i.e., init="jitter+adapt_diag") the initial value is jittered. This can cause problems when the initial value is near invalid or otherwise problematic values. To avoid the jitter, use another initialization. I often use "adapt_diag" in these cases.