def test_RK4(self): """Run tests on RK4 fixed-step solver.""" ode_method = method_from_string('RK4') options = DE_Options(max_dt=10**-3) # run on matrix problem solver = ode_method(t0=self.t0, y0=self.y0, rhs=self.rhs, options=options) solver.integrate(1.) expected = expm(-1j * np.pi * self.X) # set the comparison tolerance to be somewhat lenient self.assertAlmostEqual(solver.y, expected, tol=10**-8) # test with an arbitrary problem def rhs(t, y): return np.array([t**2]) solver = ode_method(t0=0., y0=np.array(0.), rhs={'rhs': rhs}, options=options) solver.integrate(1.) expected = 1. / 3 self.assertAlmostEqual(solver.y, expected, tol=10**-8)
def _test_variable_step_method(self, method_str): """Some tests for a variable step method.""" # get method and set general options ode_method = method_from_string(method_str) options = DE_Options(method=method_str, atol=10**-10, rtol=10**-10) # run on matrix problem solver = ode_method(t0=self.t0, y0=self.y0, rhs=self.rhs, options=options) solver.integrate(1.) expected = expm(-1j * np.pi * self.X) # set the comparison tolerance to be somewhat lenient self.assertAlmostEqual(solver.y, expected, tol=10**-8) # test with an arbitrary problem def rhs(t, y): return np.array([t**2]) solver = ode_method(t0=0., y0=np.array(0.), rhs={'rhs': rhs}, options=options) solver.integrate(1.) expected = 1. / 3 self.assertAlmostEqual(solver.y, expected, tol=10**-9)
def test_ScipyODE_options_and_defaults(self): """Test option handling for ScipyODE solver.""" options = DE_Options(method='scipy-RK45') solver = ScipyODE(options=options) # test restructuring/default handling for this solver self.assertTrue(solver.options.method == 'RK45') self.assertTrue(solver.options.max_step == np.inf)
def test_QiskitZVODE_instantiation_error(self): """Test option handling for QiskitZVODE solver.""" expected_message = 'QiskitZVODE solver requires t0, y0, and rhs at instantiation.' options = DE_Options(method='zvode-adams') try: solver = QiskitZVODE(options=options) except Exception as exception: self.assertEqual(str(exception), expected_message)
def test_QiskitZVODE_options_and_defaults(self): """Test option handling for QiskitZVODE solver.""" options = DE_Options(method='zvode-adams') solver = QiskitZVODE(t0 = 0., y0=np.array([1.]), rhs=self.rhs, options=options) # test restructuring/default handling for this solver self.assertTrue(solver.options.method == 'adams') self.assertTrue(solver.options.first_step == 0) self.assertTrue(solver.options.max_step == 0) self.assertTrue(solver.options.min_step == 0)
def simulate_system(y0, drift, control_ops, channel_freqs, channel_samples, dt, diag_frame): """Simulate the DE y' = G(t) @ y, where G(t) = drift + a0(t) * A0 + ... + ak(t) Ak, where control_ops = [A0, ..., Ak], and the aj(t) are the values of the signals specified by channel_freqs, channel_samples, and dt Args: y0 (array): initial state drift (array): 2d drift generator control_ops (array): 3d array representing a list of control operators channel_freqs (array): 1d array of channel frequencies channel_samples (array): 2d array of channel samples, the first index being time step and the second index indexing channel dt (float): size of each sample diag_frame (array): 1d array representing an already diagonalized frame operator assumed to be purely imaginary Returns: array: final state of the DE """ # if all channel freqs are 0 simulate using matrix exponentiation if all(channel_freqs == 0): yf = y0 for t_idx in range(len(channel_samples)): yf = expm( generator(drift, control_ops, channel_samples[t_idx]) * dt) @ yf return yf # else, simulate using standard ODE solver else: # set up rhs function in frame def rhs(t, y): chan_vals = channel_values(channel_freqs, channel_samples, dt, t) gen = generator_in_frame(drift, control_ops, chan_vals, diag_frame, t) return gen @ y de_options = DE_Options(method='RK45') ode_method = ScipyODE(t0=0., y0=y0, rhs=rhs, options=de_options) T = len(channel_samples) * dt ode_method.integrate(T) yf = np.exp(diag_frame * T) * ode_method.y return yf