def test_rk4_gradient_computation(self): theta = -1.2 eqn = SimpleEquation(theta) ti = 0 tf = 5*math.pi/3 (u0, du0_dp) = eqn.solution(ti) rk = RKSolver(ti, tf) rk.equation = eqn rk.set_initial_condition(u0, du0_dp) rk.set_output_gradient_flag(True) n = 4 err_soln = np.zeros((n,)) err_grad = np.zeros((n,)) dt = np.zeros((n,)) n_steps = 100 for i in range(n): n_steps *= (i+1) dt[i] = 1./n_steps rk.n_steps = n_steps rk.solve() err_soln[i] = abs(rk.state()[0] - eqn.solution(tf)[0]) err_grad[i] = abs(rk.state()[1] - eqn.solution(tf)[1]) conv_rate = np.polyfit(np.log(dt), np.log(err_soln), 1)[0] self.assertAlmostEqual(conv_rate, 4.0, 1) conv_rate = np.polyfit(np.log(dt), np.log(err_grad), 1)[0] self.assertAlmostEqual(conv_rate, 4.0, 1)
def test_rk4_solver(self): theta = -1.2 eqn = SimpleEquation(theta) u_exact = lambda t: eqn.solution(t)[0] ti = 0 tf = 5*math.pi/3 u0 = u_exact(ti) rk = RKSolver(ti, tf) rk.equation = eqn rk.set_initial_condition(u0) n = 4 err = np.zeros((n,)) dt = np.zeros((n,)) n_steps = 100 for i in range(n): n_steps *= (i+1) dt[i] = 1./n_steps rk.n_steps = n_steps rk.solve() err[i] = abs(rk.state() - u_exact(tf)) conv_rate = np.polyfit(np.log(dt), np.log(err), 1)[0] self.assertAlmostEqual(conv_rate, 4.0, 1)
class TestModelGradOp(utt.InferShapeTester): rng = np.random.RandomState(43) def setUp(self): super(TestModelGradOp, self).setUp() self.setUpModel() def setUpModel(self): # set ode solver ti = 0 tf = 20 n_steps = tf self.rk = RKSolver(ti, tf, n_steps) self.rk.output_frequency = 1 self.rk.set_output_storing_flag(True) eqn = Seir() eqn.tau = 5 self.rk.equation = eqn n_pop = 7E6 u0 = np.array([n_pop - 1, 0, 1, 0]) u0 /= n_pop du0_dp = np.zeros((eqn.n_components(), eqn.n_parameters())) self.rk.set_initial_condition(u0, du0_dp) # set cached_sim object cached_sim = CachedSEIRSimulation2(self.rk) cached_sim.set_gradient_flag(True) # set theano model op object self.op_class = ModelGradOp(cached_sim) def test_perform(self): b = theano.tensor.dscalar('myvar0') s = theano.tensor.dscalar('myvar1') g = theano.tensor.dscalar('myvar2') k = theano.tensor.dscalar('myvar3') t = theano.tensor.dscalar('myvar4') dL_df = theano.tensor.matrix() f = theano.function([b, s, g, k, t, dL_df], self.op_class((b, s, g, k, t), dL_df)) s_val = 1. / 5.2 g_val = 1. / 2.28 b_val = 2.13 * g_val k_val = 1.1 t_val = 10 dL_df_val = np.random.rand(1, 21) out = f(b_val, s_val, g_val, k_val, t_val, dL_df_val) self.rk.equation.beta = b_val self.rk.equation.sigma = s_val self.rk.equation.gamma = g_val self.rk.equation.kappa = k_val self.rk.equation.tint = t_val self.rk.solve() (_, _, df_dp) = self.rk.get_outputs() out_act = df_dp[0, :, :] @ dL_df_val.T out_act = np.reshape(out_act, (self.rk.equation.n_parameters(), )) assert np.allclose(out_act, out)
class TestModelOp(utt.InferShapeTester): rng = np.random.RandomState(43) def setUp(self): super(TestModelOp, self).setUp() self.setUpModel() def setUpModel(self): # set ode solver ti = 0 tf = 20 n_steps = tf self.rk = RKSolver(ti, tf, n_steps) self.rk.output_frequency = 1 self.rk.set_output_storing_flag(True) eqn = Seir() self.rk.equation = eqn n_pop = 7E6 u0 = np.array([n_pop - 1, 0, 1, 0]) u0 /= n_pop du0_dp = np.zeros((eqn.n_components(), eqn.n_parameters())) self.rk.set_initial_condition(u0, du0_dp) # set cached_sim object cached_sim = CachedSEIRSimulation(self.rk) cached_sim.set_gradient_flag(True) # set theano model op object self.op_class = ModelOp(cached_sim) #@unittest.skip("changed output of SEIR eq") def test_perform(self): b = theano.tensor.dscalar('myvar0') s = theano.tensor.dscalar('myvar1') g = theano.tensor.dscalar('myvar2') f = theano.function([b, s, g], self.op_class((b, s, g))) s_val = 1. / 5.2 g_val = 1. / 2.28 b_val = 2.13 * g_val out = f(b_val, s_val, g_val) self.rk.equation.beta = b_val self.rk.equation.sigma = s_val self.rk.equation.gamma = g_val self.rk.solve() (_, out_act, _) = self.rk.get_outputs() assert np.allclose(out_act, out) def test_grad(self): s_val = 1. / 5.2 g_val = 1. / 2.28 b_val = 2.13 * g_val rng = np.random.RandomState(42) theano.tensor.verify_grad(self.op_class, [(b_val, s_val, g_val)], rng=rng)
def test_rk4_gradient_computation2(self): n_pop = 7E6 sigma = 1/5.2 gamma = 1/2.28 beta = 2.13*gamma eqn = Seir(beta, sigma, gamma) ti = 0 tf = 218 n_steps = 2*tf rk = RKSolver(ti, tf, n_steps) rk.equation = eqn u0 = np.array([n_pop - 1, 0, 1, 0]) u0 /= n_pop du0_dp = np.zeros((eqn.n_components(), eqn.n_parameters())) rk.set_initial_condition(u0, du0_dp) rk.set_output_gradient_flag(True) rk.solve() (u, du_dp) = rk.state() rk.set_output_gradient_flag(False) epsi = 0.001 # perturb beta0 eqn.beta = beta + epsi rk.solve() u_p1 = rk.state() eqn.beta = beta - epsi rk.solve() u_m1 = rk.state() diff = np.linalg.norm(du_dp[:,0] - (u_p1 - u_m1)/(2*epsi))/np.linalg.norm(u0) np.testing.assert_almost_equal(diff, 0, 5) # reset eqn.beta = beta # perturb sigma eqn.sigma = sigma + epsi rk.solve() u_p1 = rk.state() eqn.sigma = sigma - epsi rk.solve() u_m1 = rk.state() diff = np.linalg.norm(du_dp[:,1] - (u_p1 - u_m1)/(2*epsi))/np.linalg.norm(u0) np.testing.assert_almost_equal(diff, 0, 5) # reset eqn.sigma = sigma # perturb gamma eqn.gamma = gamma + epsi rk.solve() u_p1 = rk.state() eqn.gamma = gamma - epsi rk.solve() u_m1 = rk.state() diff = np.linalg.norm(du_dp[:,2] - (u_p1 - u_m1)/(2*epsi))/np.linalg.norm(u0) np.testing.assert_almost_equal(diff, 0, 5) # reset eqn.gamma = gamma # perturb kappa kappa = 1 eqn.kappa = kappa + epsi rk.solve() u_p1 = rk.state() eqn.kappa = kappa - epsi rk.solve() u_m1 = rk.state() diff = np.linalg.norm(du_dp[:,3] - (u_p1 - u_m1)/(2*epsi))/np.linalg.norm(u0) np.testing.assert_almost_equal(diff, 0, 5) # reset eqn.kappa = kappa