def test_logp_scalar_ode(): """Test the computation of the log probability for these models""" # Differential equation def system_1(y, t, p): return np.exp(-t) - p[0] * y[0] # Parameters and inital condition alpha = 0.4 y0 = 0.0 times = np.arange(0.5, 8, 0.5) yobs = np.array( [0.30, 0.56, 0.51, 0.55, 0.47, 0.42, 0.38, 0.30, 0.26, 0.21, 0.22, 0.13, 0.13, 0.09, 0.09] )[:, np.newaxis] ode_model = DifferentialEquation(func=system_1, t0=0, times=times, n_theta=1, n_states=1) integrated_solution, *_ = ode_model._simulate([y0], [alpha]) assert integrated_solution.shape == yobs.shape # compare automatic and manual logp values manual_logp = norm.logpdf(x=np.ravel(yobs), loc=np.ravel(integrated_solution), scale=1).sum() with pm.Model() as model_1: forward = ode_model(theta=[alpha], y0=[y0]) y = pm.Normal("y", mu=forward, sd=1, observed=yobs) pymc_logp = model_1.logp() np.testing.assert_allclose(manual_logp, pymc_logp)
def test_simulate(): """Tests the integration in DifferentialEquation""" # Create an ODe to integrate def ode_func(y, t, p): return np.exp(-t) - p[0] * y[0] # Evaluate exact solution y0 = 0 t = np.arange(0, 12, 0.25).reshape(-1, 1) a = 0.472 y = 1.0 / (a - 1) * (np.exp(-t) - np.exp(-a * t)) # Instantiate ODE model ode_model = DifferentialEquation(func=ode_func, t0=0, times=t, n_states=1, n_theta=1) simulated_y, sens = ode_model._simulate([y0], [a]) assert simulated_y.shape == (len(t), 1) assert sens.shape == (len(t), 1, 1 + 1) np.testing.assert_allclose(y, simulated_y, rtol=1e-5)