예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
    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