예제 #1
0
 def setUp(self):
     self._default_qubit_lo_freq = [4.9, 5.0]
     self._u_channel_lo = []
     self._u_channel_lo.append([UchannelLO(0, 1.0 + 0.0j)])
     self._u_channel_lo.append(
         [UchannelLO(0, -1.0 + 0.0j),
          UchannelLO(1, 1.0 + 0.0j)])
    def _system_model_3Q(self, j, subsystem_list=[0, 2]):
        """Constructs a model for a 3 qubit system, with the goal that the restriction to
        [0, 2] and to qubits [1, 2] is the same as in _system_model_2Q

        Args:
            j (float): coupling strength
            subsystem_list (list): list of subsystems to include

        Returns:
            PulseSystemModel: model for qubit system
        """

        hamiltonian = {}
        hamiltonian['h_str'] = [
            '2*np.pi*j*0.25*(Z0*X2)||U0', '2*np.pi*j*0.25*(Z1*X2)||U1'
        ]
        hamiltonian['vars'] = {'j': j}
        hamiltonian['qub'] = {'0': 2, '1': 2, '2': 2}
        ham_model = HamiltonianModel.from_dict(hamiltonian,
                                               subsystem_list=subsystem_list)

        # set the U0 to have frequency of drive channel 0
        u_channel_lo = [[UchannelLO(0, 1.0 + 0.0j)],
                        [UchannelLO(0, 1.0 + 0.0j)]]
        dt = 1.

        return PulseSystemModel(hamiltonian=ham_model,
                                u_channel_lo=u_channel_lo,
                                subsystem_list=subsystem_list,
                                dt=dt)
예제 #3
0
    def _system_model_3Q(self,
                         omega_0,
                         omega_a,
                         omega_i,
                         qubit_dim=2,
                         subsystem_list=None):
        """Constructs a 3 qubit model. Purpose of this is for testing subsystem restrictions -
        It is set up so that the system restricted to [0, 2] and [1, 2] is the same (up to
        channel labelling).

        Args:
            omega_0 (float): frequency of qubit
            omega_a (float): strength of drive term
            omega_i (float): strength of interaction
            qubit_dim (int): dimension of qubit
        Returns:
            PulseSystemModel: model for qubit system
        """

        # make Hamiltonian
        hamiltonian = {}
        # qubit 0 terms
        hamiltonian['h_str'] = [
            '-0.5*omega0*Z0', '0.5*omegaa*X0||D0', '-0.5*omega0*Z1',
            '0.5*omegaa*X1||D1'
        ]
        # interaction terms
        hamiltonian['h_str'].append('omegai*(Sp0*Sm2+Sm0*Sp2)||U1')
        hamiltonian['h_str'].append('omegai*(Sp1*Sm2+Sm1*Sp2)||U2')
        hamiltonian['vars'] = {
            'omega0': omega_0,
            'omegaa': omega_a,
            'omegai': omega_i
        }
        hamiltonian['qub'] = {'0': qubit_dim, '1': qubit_dim, '2': qubit_dim}
        ham_model = HamiltonianModel.from_dict(hamiltonian, subsystem_list)

        u_channel_lo = [[UchannelLO(0, 1.0 + 0.0j)]]
        u_channel_lo.append(
            [UchannelLO(0, -1.0 + 0.0j),
             UchannelLO(2, 1.0 + 0.0j)])
        u_channel_lo.append(
            [UchannelLO(1, -1.0 + 0.0j),
             UchannelLO(2, 1.0 + 0.0j)])
        dt = 1.

        return PulseSystemModel(hamiltonian=ham_model,
                                u_channel_lo=u_channel_lo,
                                subsystem_list=subsystem_list,
                                dt=dt)
예제 #4
0
    def test_set_system_model_from_backend(self):
        """Test setting system model when constructing from backend."""

        armonk_backend = FakeArmonk()
        system_model = self._system_model_1Q()

        # these are 1q systems so this doesn't make sense but can still be used to test
        system_model.u_channel_lo = [[UchannelLO(0, 1.0 + 0.0j)]]

        armonk_sim = None

        # construct backend and catch warning
        with warnings.catch_warnings(record=True) as w:
            # Cause all warnings to always be triggered.
            warnings.simplefilter("always")

            armonk_sim = PulseSimulator.from_backend(backend=armonk_backend,
                                                     system_model=system_model)

            self.assertEqual(len(w), 1)
            self.assertTrue('inconsistencies' in str(w[-1].message))

        # check that system model properties have been imported
        self.assertEqual(armonk_sim.configuration().dt, system_model.dt)
        self.assertEqual(armonk_sim.configuration().u_channel_lo,
                         system_model.u_channel_lo)
    def _system_model_2Q(self, j):
        """Constructs a model for a 2 qubit system with a U channel controlling coupling and
        no other Hamiltonian terms.

        Args:
            j (float): coupling strength

        Returns:
            PulseSystemModel: model for qubit system
        """

        hamiltonian = {}
        hamiltonian['h_str'] = [
            'a*X0||D0', 'a*X0||D1', '2*np.pi*j*0.25*(Z0*X1)||U0'
        ]
        hamiltonian['vars'] = {'a': 0, 'j': j}
        hamiltonian['qub'] = {'0': 2, '1': 2}
        ham_model = HamiltonianModel.from_dict(hamiltonian)

        # set the U0 to have frequency of drive channel 0
        u_channel_lo = [[UchannelLO(0, 1.0 + 0.0j)]]
        subsystem_list = [0, 1]
        dt = 1.

        return PulseSystemModel(hamiltonian=ham_model,
                                u_channel_lo=u_channel_lo,
                                subsystem_list=subsystem_list,
                                dt=dt)
예제 #6
0
    def _system_model_2Q(self, omega_0, omega_a, omega_i, qubit_dim=2):
        """Constructs a simple 2 qubit system model.

        Args:
            omega_0 (float): frequency of qubit
            omega_a (float): strength of drive term
            omega_i (float): strength of interaction
            qubit_dim (int): dimension of qubit
        Returns:
            PulseSystemModel: model for qubit system
        """

        # make Hamiltonian
        hamiltonian = {}
        # qubit 0 terms
        hamiltonian['h_str'] = ['-0.5*omega0*Z0', '0.5*omegaa*X0||D0']
        # interaction term
        hamiltonian['h_str'].append('omegai*(Sp0*Sm1+Sm0*Sp1)||U1')
        hamiltonian['vars'] = {
            'omega0': omega_0,
            'omegaa': omega_a,
            'omegai': omega_i
        }
        hamiltonian['qub'] = {'0': qubit_dim, '1': qubit_dim}
        ham_model = HamiltonianModel.from_dict(hamiltonian)

        u_channel_lo = [[UchannelLO(0, 1.0 + 0.0j)],
                        [
                            UchannelLO(0, -1.0 + 0.0j),
                            UchannelLO(1, 1.0 + 0.0j)
                        ]]
        subsystem_list = [0, 1]
        dt = 1.

        return PulseSystemModel(hamiltonian=ham_model,
                                u_channel_lo=u_channel_lo,
                                subsystem_list=subsystem_list,
                                dt=dt)
예제 #7
0
    def test_cr_lo_list(self):
        """Test _cr_lo_list"""

        cr_dict = {(0, 1): 0, (1, 0): 1, (3, 4): 2}
        expected = [[UchannelLO(1, 1.0 + 0.0j)], [UchannelLO(0, 1.0 + 0.0j)],
                    [UchannelLO(4, 1.0 + 0.0j)]]
        self.assertEqual(model_gen._cr_lo_list(cr_dict), expected)

        cr_dict = {(0, 1): 0, (3, 4): 2, (1, 0): 1}
        expected = [[UchannelLO(1, 1.0 + 0.0j)], [UchannelLO(0, 1.0 + 0.0j)],
                    [UchannelLO(4, 1.0 + 0.0j)]]
        self.assertEqual(model_gen._cr_lo_list(cr_dict), expected)
예제 #8
0
    def test_set_system_model_options(self):
        """Test setting of options that need to be changed in multiple places."""

        athens_backend = FakeAthens()
        athens_sim = PulseSimulator.from_backend(athens_backend)

        # u channel lo
        set_attr = [[UchannelLO(0, 1.0 + 0.0j)]]
        athens_sim.set_options(u_channel_lo=set_attr)
        sim_attr = athens_sim.configuration().u_channel_lo
        model_attr = athens_sim._system_model.u_channel_lo
        self.assertTrue(sim_attr == set_attr and model_attr == set_attr)

        # dt
        set_attr = 5.
        athens_sim.set_options(dt=set_attr)
        sim_attr = athens_sim.configuration().dt
        model_attr = athens_sim._system_model.dt
        self.assertTrue(sim_attr == set_attr and model_attr == set_attr)
예제 #9
0
    def test_set_system_model_after_construction(self):
        """Test setting the system model after construction."""

        system_model = self._system_model_1Q()

        # these are 1q systems so this doesn't make sense but can still be used to test
        system_model.u_channel_lo = [[UchannelLO(0, 1.0 + 0.0j)]]

        # first test setting after construction with no hamiltonian
        test_sim = PulseSimulator()

        with warnings.catch_warnings(record=True) as w:
            # Cause all warnings to always be triggered.
            warnings.simplefilter("always")

            test_sim.set_options(system_model=system_model)
            self.assertEqual(len(w), 0)

        # check that system model properties have been imported
        self.assertEqual(test_sim._system_model, system_model)
        self.assertEqual(test_sim.configuration().dt, system_model.dt)
        self.assertEqual(test_sim.configuration().u_channel_lo,
                         system_model.u_channel_lo)

        # next, construct a pulse simulator with a config containing a Hamiltonian and observe
        # warnings
        armonk_backend = FakeArmonk()
        test_sim = PulseSimulator(configuration=armonk_backend.configuration())

        # add system model and verify warning is raised
        with warnings.catch_warnings(record=True) as w:
            # Cause all warnings to always be triggered.
            warnings.simplefilter("always")

            armonk_sim = test_sim.set_options(system_model=system_model)

            self.assertEqual(len(w), 1)
            self.assertTrue('inconsistencies' in str(w[-1].message))

        self.assertEqual(test_sim.configuration().dt, system_model.dt)
        self.assertEqual(test_sim.configuration().u_channel_lo,
                         system_model.u_channel_lo)
예제 #10
0
    def test_set_system_model_in_constructor(self):
        """Test setting system model when constructing."""

        system_model = self._system_model_1Q()

        # these are 1q systems so this doesn't make sense but can still be used to test
        system_model.u_channel_lo = [[UchannelLO(0, 1.0 + 0.0j)]]

        # construct directly
        test_sim = None
        # construct backend and verify no warnings
        with warnings.catch_warnings(record=True) as w:
            # Cause all warnings to always be triggered.
            warnings.simplefilter("always")

            test_sim = PulseSimulator(system_model=system_model)

            self.assertEqual(len(w), 0)

        # check that system model properties have been imported
        self.assertEqual(test_sim.configuration().dt, system_model.dt)
        self.assertEqual(test_sim.configuration().u_channel_lo, system_model.u_channel_lo)
    def test_duffing_system_model1(self):
        """First test of duffing_system_model, 2 qubits, 2 dimensional"""

        dim_oscillators = 2
        oscillator_freqs = [5.0, 5.1]
        anharm_freqs = [-0.33, -0.33]
        drive_strengths = [1.1, 1.2]
        coupling_dict = {(0,1): 0.02}
        dt = 1.3

        system_model = model_gen.duffing_system_model(dim_oscillators,
                                                      oscillator_freqs,
                                                      anharm_freqs,
                                                      drive_strengths,
                                                      coupling_dict,
                                                      dt)
        cr_idx_dict = {label: idx for idx, label in enumerate(system_model.control_channel_labels)}

        # check basic parameters
        self.assertEqual(system_model.subsystem_list, [0, 1])
        self.assertEqual(system_model.dt, 1.3)

        # check that cr_idx_dict is correct
        self.assertEqual(cr_idx_dict, {(0,1): 0, (1,0): 1})
        self.assertEqual(system_model.control_channel_index((0,1)), 0)

        # check u_channel_lo is correct
        self.assertEqual(system_model.u_channel_lo,
                         [[UchannelLO(1, 1.0+0.0j)], [UchannelLO(0, 1.0+0.0j)]])

        # check consistency of system_model.u_channel_lo with cr_idx_dict
        # this should in principle be redundant with the above two checks
        for q_pair, idx in cr_idx_dict.items():
            self.assertEqual(system_model.u_channel_lo[idx],
                             [UchannelLO(q_pair[1], 1.0+0.0j)])

        # check correct hamiltonian
        ham_model = system_model.hamiltonian
        expected_vars = {'v0': 5.0, 'v1': 5.1,
                         'alpha0': -0.33, 'alpha1': -0.33,
                         'r0': 1.1, 'r1': 1.2,
                         'j01': 0.02}
        self.assertEqual(ham_model._variables, expected_vars)
        self.assertEqual(ham_model._subsystem_dims, {0: 2, 1: 2})
        self._compare_str_lists(list(ham_model._channels), ['D0', 'D1', 'U0', 'U1'])

        # check that Hamiltonian terms have been imported correctly
        # constructing the expected_terms requires some knowledge of how the strings get generated
        # and then parsed
        O0 = self._operator_array_from_str(2, ['I', 'O'])
        O1 = self._operator_array_from_str(2, ['O', 'I'])
        OO0 = O0 & O0
        OO1 = O1 & O1
        X0 = self._operator_array_from_str(2, ['I', 'X'])
        X1 = self._operator_array_from_str(2, ['X', 'I'])
        exchange = self._operator_array_from_str(2, ['Sm', 'Sp']) + self._operator_array_from_str(2, ['Sp', 'Sm'])
        expected_terms = [('np.pi*(2*v0-alpha0)', O0),
                          ('np.pi*(2*v1-alpha1)', O1),
                          ('np.pi*alpha0', OO0),
                          ('np.pi*alpha1', OO1),
                          ('2*np.pi*r0*D0', X0),
                          ('2*np.pi*r1*D1', X1),
                          ('2*np.pi*j01', exchange),
                          ('2*np.pi*r0*U0', X0),
                          ('2*np.pi*r1*U1', X1)]

        # first check the number of terms is correct, then loop through
        # each expected term and verify that it is present and consistent
        self.assertEqual(len(ham_model._system), len(expected_terms))
        for expected_string, expected_op in expected_terms:
            idx = 0
            found = False
            while idx < len(ham_model._system) and found is False:
                op, string = ham_model._system[idx]
                if expected_string == string:
                    found = True
                    self.assertTrue(array_equal(expected_op, op))
                idx += 1
            self.assertTrue(found)
    def test_duffing_system_model3(self):
        """Third test of duffing_system_model, 4 qubits, 2 dimensional"""

        # do similar tests for different model
        dim_oscillators = 2
        oscillator_freqs = [5.0, 5.1, 5.2, 5.3]
        anharm_freqs = [-0.33, -0.33, -0.32, -0.31]
        drive_strengths = [1.1, 1.2, 1.3, 1.4]
        coupling_dict = {(0,2): 0.03, (1,0): 0.02, (0,3): 0.14, (3,1): 0.18, (1,2) : 0.33}
        dt = 1.3

        system_model = model_gen.duffing_system_model(dim_oscillators,
                                                      oscillator_freqs,
                                                      anharm_freqs,
                                                      drive_strengths,
                                                      coupling_dict,
                                                      dt)
        cr_idx_dict = {label: idx for idx, label in enumerate(system_model.control_channel_labels)}

        # check basic parameters
        self.assertEqual(system_model.subsystem_list, [0, 1, 2, 3])
        self.assertEqual(system_model.dt, 1.3)

        # check that cr_idx_dict is correct
        self.assertEqual(cr_idx_dict, {(0,1): 0, (1,0): 1,
                                       (0,2): 2, (2,0): 3,
                                       (0,3): 4, (3,0): 5,
                                       (1,2): 6, (2,1): 7,
                                       (1,3): 8, (3,1): 9})
        self.assertEqual(system_model.control_channel_index((1,2)), 6)

        # check u_channel_lo is correct
        self.assertEqual(system_model.u_channel_lo,
                         [[UchannelLO(1, 1.0+0.0j)], [UchannelLO(0, 1.0+0.0j)],
                          [UchannelLO(2, 1.0+0.0j)], [UchannelLO(0, 1.0+0.0j)],
                          [UchannelLO(3, 1.0+0.0j)], [UchannelLO(0, 1.0+0.0j)],
                          [UchannelLO(2, 1.0+0.0j)], [UchannelLO(1, 1.0+0.0j)],
                          [UchannelLO(3, 1.0+0.0j)], [UchannelLO(1, 1.0+0.0j)]])

        # check consistency of system_model.u_channel_lo with cr_idx_dict
        # this should in principle be redundant with the above two checks
        for q_pair, idx in cr_idx_dict.items():
            self.assertEqual(system_model.u_channel_lo[idx],
                             [UchannelLO(q_pair[1], 1.0+0.0j)])

        # check correct hamiltonian
        ham_model = system_model.hamiltonian
        expected_vars = {'v0': 5.0, 'v1': 5.1, 'v2': 5.2, 'v3': 5.3,
                         'alpha0': -0.33, 'alpha1': -0.33, 'alpha2': -0.32, 'alpha3': -0.31,
                         'r0': 1.1, 'r1': 1.2, 'r2': 1.3, 'r3': 1.4,
                         'j01': 0.02, 'j02': 0.03, 'j03': 0.14, 'j12': 0.33, 'j13': 0.18}
        self.assertEqual(ham_model._variables, expected_vars)
        self.assertEqual(ham_model._subsystem_dims, {0: 2, 1: 2, 2: 2, 3: 2})
        self._compare_str_lists(list(ham_model._channels), ['D0', 'D1', 'D3', 'D4',
                                                            'U0', 'U1', 'U2', 'U3', 'U4',
                                                            'U5', 'U6', 'U7', 'U8', 'U9'])

        # check that Hamiltonian terms have been imported correctly
        # constructing the expected_terms requires some knowledge of how the strings get generated
        # and then parsed
        O0 = self._operator_array_from_str(2, ['I', 'I', 'I', 'O'])
        O1 = self._operator_array_from_str(2, ['I', 'I', 'O', 'I'])
        O2 = self._operator_array_from_str(2, ['I', 'O', 'I', 'I'])
        O3 = self._operator_array_from_str(2, ['O', 'I', 'I', 'I'])
        OO0 = O0 & O0
        OO1 = O1 & O1
        OO2 = O2 & O2
        OO3 = O3 & O3
        X0 = self._operator_array_from_str(2, ['I','I', 'I', 'A']) + self._operator_array_from_str(2, ['I', 'I', 'I', 'C'])
        X1 = self._operator_array_from_str(2, ['I', 'I', 'A', 'I']) + self._operator_array_from_str(2, ['I', 'I', 'C', 'I'])
        X2 = self._operator_array_from_str(2, ['I', 'A', 'I', 'I']) + self._operator_array_from_str(2, ['I', 'C', 'I', 'I'])
        X3 = self._operator_array_from_str(2, ['A', 'I', 'I', 'I']) + self._operator_array_from_str(2, ['C', 'I', 'I', 'I'])
        exchange01 = self._operator_array_from_str(2, ['I', 'I', 'Sm', 'Sp']) + self._operator_array_from_str(2, ['I', 'I', 'Sp', 'Sm'])
        exchange02 = self._operator_array_from_str(2, ['I', 'Sm', 'I', 'Sp']) + self._operator_array_from_str(2, ['I', 'Sp', 'I', 'Sm'])
        exchange03 = self._operator_array_from_str(2, ['Sm', 'I', 'I', 'Sp']) + self._operator_array_from_str(2, ['Sp', 'I', 'I', 'Sm'])
        exchange12 = self._operator_array_from_str(2, ['I', 'Sm', 'Sp', 'I']) + self._operator_array_from_str(2, ['I', 'Sp', 'Sm', 'I'])
        exchange13 = self._operator_array_from_str(2, ['Sm', 'I', 'Sp', 'I']) + self._operator_array_from_str(2, ['Sp', 'I', 'Sm', 'I'])
        expected_terms = [('np.pi*(2*v0-alpha0)', O0),
                          ('np.pi*(2*v1-alpha1)', O1),
                          ('np.pi*(2*v2-alpha2)', O2),
                          ('np.pi*(2*v3-alpha3)', O3),
                          ('np.pi*alpha0', OO0),
                          ('np.pi*alpha1', OO1),
                          ('np.pi*alpha2', OO2),
                          ('np.pi*alpha3', OO3),
                          ('2*np.pi*r0*D0', X0),
                          ('2*np.pi*r1*D1', X1),
                          ('2*np.pi*r2*D2', X2),
                          ('2*np.pi*r3*D3', X3),
                          ('2*np.pi*j01', exchange01),
                          ('2*np.pi*j02', exchange02),
                          ('2*np.pi*j03', exchange03),
                          ('2*np.pi*j12', exchange12),
                          ('2*np.pi*j13', exchange13),
                          ('2*np.pi*r0*U0', X0),
                          ('2*np.pi*r1*U1', X1),
                          ('2*np.pi*r0*U2', X0),
                          ('2*np.pi*r2*U3', X2),
                          ('2*np.pi*r0*U4', X0),
                          ('2*np.pi*r3*U5', X3),
                          ('2*np.pi*r1*U6', X1),
                          ('2*np.pi*r2*U7', X2),
                          ('2*np.pi*r1*U8', X1),
                          ('2*np.pi*r3*U9', X3)]

        # first check the number of terms is correct, then loop through
        # each expected term and verify that it is present and consistent
        self.assertEqual(len(ham_model._system), len(expected_terms))
        for expected_string, expected_op in expected_terms:
            idx = 0
            found = False
            while idx < len(ham_model._system) and found is False:
                op, string = ham_model._system[idx]
                if expected_string == string:
                    found = True
                    self.assertTrue(array_equal(expected_op, op))
                idx += 1
            self.assertTrue(found)