def check_residual(residual, initial_m): mag_params = utils.MagParameters() tmax = 3.0 f_residual = ft.partial(residual, mag_params) # Timestep to a solution + convert to spherical result_times, m_list = ode.odeint(f_residual, sp.array(initial_m), tmax, dt=0.01) m_sph = [utils.array2sph(m) for m in m_list] result_pols = [m.pol for m in m_sph] result_azis = [m.azi for m in m_sph] # Calculate exact solutions exact_times, exact_azis = \ mlsn.calculate_equivalent_dynamics(mag_params, result_pols) # Check utils.assert_list_almost_equal(exact_azis, result_azis, 1e-3) utils.assert_list_almost_equal(exact_times, result_times, 1e-3)
def test_tr_ab2_scheme_generation(): """Make sure tr-ab can be derived using same methodology as I'm using (also checks lte expressions). """ dddy = sympy.symbols("y'''") y_np1_tr = sympy.symbols("y_{n+1}_tr") ab_pred, ynp1_ab2_expr = generate_predictor_scheme([PTInfo(0, None, None), PTInfo( 1, "corr_val", "exp test"), PTInfo( 2, "corr_val", "exp test")], "ab2", symbolic=sympy.exp(St)) # ??ds hacky, have to change the symbol to represent where y''' is being # evaluated by hand! ynp1_ab2_expr = ynp1_ab2_expr.subs(Sdddynph, dddy) # Check that it gives the same result as we know from the lte utils.assert_sym_eq(y_np1_exact - ab2_lte(Sdts[0], Sdts[1], dddy), ynp1_ab2_expr) # Now do the solve etc. y_np1_tr_expr = y_np1_exact - tr_lte(Sdts[0], dddy) A = system2matrix([ynp1_ab2_expr, y_np1_tr_expr], [dddy, y_np1_exact]) x = A.inv() exact_ynp1_symb = sum([y_est * xi.factor() for xi, y_est in zip(x.row(1), [y_np1_p1, y_np1_tr])]) exact_ynp1_f = sympy.lambdify( (y_np1_p1, y_np1_tr, Sdts[0], Sdts[1]), exact_ynp1_symb) utils.assert_sym_eq(exact_ynp1_symb - y_np1_tr, (y_np1_p1 - y_np1_tr)/(3*(1 + Sdts[1]/Sdts[0]))) # Construct an lte estimator from this estimate def lte_est(ts, ys): ynp1_p = ab_pred(ts, ys) dtn = ts[-1] - ts[-2] dtnm1 = ts[-2] - ts[-3] ynp1_exact = exact_ynp1_f(ynp1_p, ys[-1], dtn, dtnm1) return ynp1_exact - ys[-1] # Solve exp using tr t0 = 0.0 dt = 1e-2 ts, ys = ode.odeint(er.exp_residual, er.exp_exact(t0), tmax=2.0, dt=dt, method='tr') # Get error estimates using standard tr ab and the one we just # constructed here, then compare. this_ltes = ode.get_ltes_from_data(ts, ys, lte_est) tr_ab_lte = par(ode.tr_ab_lte_estimate, dydt_func=lambda t, y: y) standard_ltes = ode.get_ltes_from_data(ts, ys, tr_ab_lte) # Should be the same (actually the sign is different, but this doesn't # matter in lte). utils.assert_list_almost_equal( this_ltes, map(lambda a: a*-1, standard_ltes), 1e-8)
def test_tr_ab2_scheme_generation(): """Make sure tr-ab can be derived using same methodology as I'm using (also checks lte expressions). """ dddy = sympy.symbols("y'''") y_np1_tr = sympy.symbols("y_{n+1}_tr") ab_pred, ynp1_ab2_expr = generate_predictor_scheme([ PTInfo(0, None, None), PTInfo(1, "corr_val", "exp test"), PTInfo(2, "corr_val", "exp test") ], "ab2", symbolic=sympy.exp(St)) # ??ds hacky, have to change the symbol to represent where y''' is being # evaluated by hand! ynp1_ab2_expr = ynp1_ab2_expr.subs(Sdddynph, dddy) # Check that it gives the same result as we know from the lte utils.assert_sym_eq(y_np1_exact - ab2_lte(Sdts[0], Sdts[1], dddy), ynp1_ab2_expr) # Now do the solve etc. y_np1_tr_expr = y_np1_exact - tr_lte(Sdts[0], dddy) A = system2matrix([ynp1_ab2_expr, y_np1_tr_expr], [dddy, y_np1_exact]) x = A.inv() exact_ynp1_symb = sum([ y_est * xi.factor() for xi, y_est in zip(x.row(1), [y_np1_p1, y_np1_tr]) ]) exact_ynp1_f = sympy.lambdify((y_np1_p1, y_np1_tr, Sdts[0], Sdts[1]), exact_ynp1_symb) utils.assert_sym_eq(exact_ynp1_symb - y_np1_tr, (y_np1_p1 - y_np1_tr) / (3 * (1 + Sdts[1] / Sdts[0]))) # Construct an lte estimator from this estimate def lte_est(ts, ys): ynp1_p = ab_pred(ts, ys) dtn = ts[-1] - ts[-2] dtnm1 = ts[-2] - ts[-3] ynp1_exact = exact_ynp1_f(ynp1_p, ys[-1], dtn, dtnm1) return ynp1_exact - ys[-1] # Solve exp using tr t0 = 0.0 dt = 1e-2 ts, ys = ode.odeint(er.exp_residual, er.exp_exact(t0), tmax=2.0, dt=dt, method='tr') # Get error estimates using standard tr ab and the one we just # constructed here, then compare. this_ltes = ode.get_ltes_from_data(ts, ys, lte_est) tr_ab_lte = par(ode.tr_ab_lte_estimate, dydt_func=lambda t, y: y) standard_ltes = ode.get_ltes_from_data(ts, ys, tr_ab_lte) # Should be the same (actually the sign is different, but this doesn't # matter in lte). utils.assert_list_almost_equal(this_ltes, map(lambda a: a * -1, standard_ltes), 1e-8)