def logistic_ode(): # Below is for consistency with pytest & unittest. # Without a seed, unittest passes but pytest fails. # I tried multiple seeds, they all work equally well. np.random.seed(12345) delta_t = 0.2 tmax = 2 logistic = pnd.logistic((0, tmax), initrv=Constant(np.array([0.1])), params=(6, 1)) dynamod = pnss.IBM(ordint=3, spatialdim=1) measmod = pnfs.DiscreteEKFComponent.from_ode(logistic, dynamod, np.zeros((1, 1)), ek0_or_ek1=1) initmean = np.array([0.1, 0, 0.0, 0.0]) initcov = np.diag([0.0, 1.0, 1.0, 1.0]) initrv = Normal(initmean, initcov) return dynamod, measmod, initrv, { "dt": delta_t, "tmax": tmax, "ode": logistic }
def test_inputs(self): """Inputs rejected or accepted according to expected types.""" numpy_array = np.ones(3) * Constant(0.1) constant_list = [Constant(0.1), Constant(0.4)] number_list = [0.5, 0.41] inputs = [numpy_array, constant_list, number_list] inputs_acceptable = [False, True, False] for inputs, is_acceptable in zip(inputs, inputs_acceptable): with self.subTest(input=inputs, is_acceptable=is_acceptable): if is_acceptable: _RandomVariableList(inputs) else: with self.assertRaises(TypeError): _RandomVariableList(inputs)
def test_fitzhughnagumo(self): """Test the FHN IVP convenience function.""" rv = Constant(np.ones(2)) lg1 = ivp_examples.fitzhughnagumo(self.tspan, rv) lg2 = ivp_examples.fitzhughnagumo(self.tspan, rv, params=(1.0, 1.0, 1.0, 1.0)) self.assertIsInstance(lg1, ivp.IVP) self.assertIsInstance(lg2, ivp.IVP)
def test_lotkavolterra(self): """Test the LV ODE convenience function.""" rv = Constant(np.ones(2)) lg1 = ivp_examples.lotkavolterra(self.tspan, rv) lg2 = ivp_examples.lotkavolterra(self.tspan, rv, params=(1.0, 1.0, 1.0, 1.0)) self.assertIsInstance(lg1, ivp.IVP) self.assertIsInstance(lg2, ivp.IVP)
def test_seir(self): """Test the SEIR ODE convenience function.""" rv = Constant(np.array([1.0, 0.0, 0.0, 0.0])) lg1 = ivp_examples.seir(self.tspan, rv) lg2 = ivp_examples.seir(self.tspan, rv, params=(1.0, 1.0, 1.0, 1.0)) self.assertIsInstance(lg1, ivp.IVP) self.assertIsInstance(lg2, ivp.IVP)
def step(self, start, stop, current): h = stop - start x = current.mean xnew = x + h * self.ivp(start, x) return ( Constant(xnew), np.nan, ) # return nan as error estimate to ensure that it is not used
def initialize(self, ivp): return diffeq.ODESolverState( ivp=ivp, rv=Constant(ivp.y0), t=ivp.t0, error_estimate=np.nan, reference_state=None, )
def test_logistic(self): """Test the logistic ODE convenience function.""" rv = Constant(0.1) lg1 = ivp_examples.logistic(self.tspan, rv) lg2 = ivp_examples.logistic(self.tspan, rv, params=(1.0, 1.0)) self.assertIsInstance(lg1, ivp.IVP) self.assertIsInstance(lg2, ivp.IVP)
def setUp(self): initrv = Constant(20 * np.ones(2)) self.ivp = lotkavolterra([0.0, 0.5], initrv) step = 0.1 f = self.ivp.rhs t0, tmax = self.ivp.timespan y0 = self.ivp.initrv.mean self.solution = probsolve_ivp(f, t0, tmax, y0, step=step, adaptive=False)
def attempt_step(self, state, dt): t, x = state.t, state.rv.mean xnew = x + dt * state.ivp.f(t, x) # return nan as error estimate to ensure that it is not used new_state = diffeq.ODESolverState( ivp=state.ivp, rv=Constant(xnew), t=t + dt, error_estimate=np.nan, reference_state=xnew, ) return new_state
def setUp(self): initrv = Constant(0.1 * np.ones(1)) self.ivp = logistic([0.0, 1.5], initrv) step = 0.1 f = self.ivp.rhs t0, tmax = self.ivp.timespan y0 = self.ivp.initrv.mean self.solution = probsolve_ivp(f, t0, tmax, y0, algo_order=3, step=step, adaptive=False)
def test_lorenz(self): """Test the Lorenz model ODE convenience function.""" rv = Constant(np.array([1.0, 1.0, 1.0])) lg1 = ivp_examples.lorenz(self.tspan, rv) lg2 = ivp_examples.lorenz( self.tspan, rv, params=( 10.0, 28.0, 8.0 / 3.0, ), ) self.assertIsInstance(lg1, ivp.IVP) self.assertIsInstance(lg2, ivp.IVP)
def setUp(self): def rhs_(t, x): return -x def jac_(t, x): return -np.eye(len(x)) def sol_(t): return np.exp(-t) * np.ones(TEST_NDIM) some_center = np.random.rand(TEST_NDIM) rv = Constant(some_center) self.mockivp = ivp.IVP((0.0, np.random.rand()), rv, rhs=rhs_, jac=jac_, sol=sol_)
def test_fitzhughnagumo_jacobian(self): rv = Constant(np.ones(2)) lg1 = ivp_examples.fitzhughnagumo(self.tspan, rv) random_direction = 1 + 0.1 * np.random.rand(lg1.dimension) random_point = 1 + np.random.rand(lg1.dimension) fd_approx = ( 0.5 * 1.0 / self.dt * ( lg1(0.1, random_point + self.dt * random_direction) - lg1(0.1, random_point - self.dt * random_direction) ) ) self.assertAllClose( lg1.jacobian(0.1, random_point) @ random_direction, fd_approx, rtol=self.rtol, )
def test_lorenz_jacobian(self): rv = Constant(np.array([1.0, 1.0, 1.0])) lg1 = ivp_examples.lorenz(self.tspan, rv) random_direction = 1 + 0.1 * np.random.rand(lg1.dimension) random_point = 1 + np.random.rand(lg1.dimension) fd_approx = ( 0.5 * 1.0 / self.dt * ( lg1(0.1, random_point + self.dt * random_direction) - lg1(0.1, random_point - self.dt * random_direction) ) ) self.assertAllClose( lg1.jacobian(0.1, random_point) @ random_direction, fd_approx, rtol=self.rtol, )
def setUp(self): self.rv_list = _RandomVariableList([Constant(0.1), Constant(0.2)])
def setUp(self): y0 = Constant(0.3) ivp = logistic([0, 4], initrv=y0) euler_order = 1 self.solver = MockODESolver(ivp, order=euler_order) self.step = 0.2
def test_lorenz_rhs(self): rv = Constant(np.ones(3)) lg1 = ivp_examples.lorenz(self.tspan, rv) self.assertEqual(lg1.rhs(0.1, rv).shape, rv.shape)
def test_seir_rhs(self): rv = Constant(np.ones(4)) lg1 = ivp_examples.seir(self.tspan, rv) self.assertEqual(lg1.rhs(0.1, rv).shape, rv.shape)
def test_lotkavolterra_rhs(self): rv = Constant(np.ones(2)) lg1 = ivp_examples.lotkavolterra(self.tspan, rv) self.assertEqual(lg1.rhs(0.1, rv).shape, rv.shape)
def test_fitzhughnagumo_rhs(self): rv = Constant(np.ones(2)) lg1 = ivp_examples.fitzhughnagumo(self.tspan, rv) self.assertEqual(lg1.rhs(0.1, rv).shape, rv.shape)
def test_logistic_rhs(self): rv = Constant(0.1) lg1 = ivp_examples.logistic(self.tspan, rv) self.assertEqual(lg1.rhs(0.1, rv).shape, rv.shape)
def load_lotkavolterra(): """Load LV system as a basic IVP.""" initrv = Constant(np.array([20, 20])) return lotkavolterra(timespan=[0, 0.55], initrv=initrv, params=(0.5, 0.05, 0.5, 0.05))
def ivp(): initrv = Constant(20.0 * np.ones(2)) return ode.lotkavolterra([0.0, 0.25], initrv)
def ivp(): initrv = Constant(0.1 * np.ones(1)) return ode.logistic([0.0, 1.5], initrv)