Example #1
0
 def test_delay_drive_channel(self):
     """Test Delay on DriveChannel"""
     drive_ch = self.config.drive(0)
     pulse = SamplePulse(np.full(10, 0.1))
     # should pass as is an append
     sched = Delay(self.delay_time, drive_ch) + Play(pulse, drive_ch)
     self.assertIsInstance(sched, Schedule)
     pulse_instr = sched.instructions[-1]
     # assert last instruction is pulse
     self.assertIsInstance(pulse_instr[1], Play)
     # assert pulse is scheduled at time 10
     self.assertEqual(pulse_instr[0], 10)
     # should fail due to overlap
     with self.assertRaises(PulseError):
         sched = Delay(self.delay_time, drive_ch) | Play(pulse, drive_ch)
Example #2
0
    def test_add(self):
        """Test add, and that errors are raised when expected."""
        sched = Schedule()
        sched.append(SamplePulse(np.ones(5))(DriveChannel(0)))
        inst_map = InstructionScheduleMap()

        inst_map.add('u1', 1, sched)
        inst_map.add('u1', 0, sched)

        self.assertIn('u1', inst_map.instructions)
        self.assertEqual(inst_map.qubits_with_instruction('u1'), [0, 1])
        self.assertTrue('u1' in inst_map.qubit_instructions(0))

        with self.assertRaises(PulseError):
            inst_map.add('u1', (), sched)
        with self.assertRaises(PulseError):
            inst_map.add('u1', 1, "not a schedule")
    def _1Q_constant_sched(self, total_samples, amp=1.):
        """Creates a runnable schedule for 1Q with a constant drive pulse of a given length.

        Args:
            total_samples (int): length of pulse
            amp (float): amplitude of constant pulse (can be complex)

        Returns:
            schedule (pulse schedule): schedule with a drive pulse followed by an acquire
        """

        # set up constant pulse for doing a pi pulse
        drive_pulse = SamplePulse(amp * np.ones(total_samples))
        schedule = Schedule()
        schedule |= Play(drive_pulse, DriveChannel(0))
        schedule |= Acquire(total_samples, AcquireChannel(0), MemorySlot(0)) << schedule.duration

        return schedule
    def _2Q_constant_sched(self, total_samples, amp=1., u_idx=0):
        """Creates a runnable schedule with a single pulse on a U channel for two qubits.

        Args:
            total_samples (int): length of pulse
            amp (float): amplitude of constant pulse (can be complex)
            u_idx (int): index of U channel

        Returns:
            schedule (pulse schedule): schedule with a drive pulse followed by an acquire
        """

        # set up constant pulse for doing a pi pulse
        drive_pulse = SamplePulse(amp * np.ones(total_samples))
        schedule = Schedule()
        schedule |= Play(drive_pulse, ControlChannel(u_idx))
        schedule |= Acquire(total_samples, AcquireChannel(0), MemorySlot(0)) << total_samples
        schedule |= Acquire(total_samples, AcquireChannel(1), MemorySlot(1)) << total_samples

        return schedule
Example #5
0
def model_and_pi_schedule():
    """Return a simple model and schedule for pulse simulation"""

    # construct model
    model = duffing_system_model(dim_oscillators=2,
                                 oscillator_freqs=[5.0],
                                 anharm_freqs=[0],
                                 drive_strengths=[0.01],
                                 coupling_dict={},
                                 dt=1.0)

    # note: parameters set so that area under curve is 1/4
    sample_pulse = SamplePulse(np.ones(50))

    # construct schedule
    schedule = Schedule(name='test_sched')
    schedule |= Play(sample_pulse, DriveChannel(0))
    schedule += Acquire(10, AcquireChannel(0),
                        MemorySlot(0)) << schedule.duration

    return model, schedule
    def _3Q_constant_sched(self, total_samples, amp=1., u_idx=0, subsystem_list=[0, 2]):
        """Creates a runnable schedule for the 3Q system after the system is restricted to
        2 qubits.

        Args:
            total_samples (int): length of pulse
            amp (float): amplitude of constant pulse (can be complex)
            u_idx (int): index of U channel
            subsystem_list (list): list of qubits to restrict to

        Returns:
            schedule (pulse schedule): schedule with a drive pulse followed by an acquire
        """

        # set up constant pulse for doing a pi pulse
        drive_pulse = SamplePulse(amp * np.ones(total_samples))
        schedule = Schedule()
        schedule |= Play(drive_pulse, ControlChannel(u_idx))
        for idx in subsystem_list:
            schedule |= Acquire(total_samples,
                                AcquireChannel(idx),
                                MemorySlot(idx)) << total_samples

        return schedule
Example #7
0
 def my_test_par_sched_two(x, y, z):
     with self.assertWarns(DeprecationWarning):
         result = PulseInstruction(
             SamplePulse(np.array([x, y, z]), name='sample'),
             self.config.drive(0))
     return 5, result
Example #8
0
 def my_test_par_sched_two(x, y, z):
     result = PulseInstruction(
         SamplePulse(np.array([x, y, z]), name='sample'),
         self.config.drive(0))
     return 5, result
Example #9
0
 def test_repr(self):
     """Test repr."""
     sched = Schedule()
     sched.append(SamplePulse(np.ones(5))(self.config.drive(0)))
     cmd_def = CmdDef({('tmp', 0): sched})
     repr(cmd_def)
Example #10
0
 def test_init(self):
     """Test `init`, `has`."""
     sched = Schedule()
     sched.append(SamplePulse(np.ones(5))(self.config.drive(0)))
     cmd_def = CmdDef({('tmp', 0): sched})
     self.assertTrue(cmd_def.has('tmp', 0))
Example #11
0
 def my_test_par_sched_two(x, y, z):
     result = PulseInstruction(
         SamplePulse(np.array([x, y, z]), name='sample'),
         device.drives[0])
     return 5, result
    def test_shift_phase(self):
        """Test ShiftPhase command."""

        omega_0 = 1.123
        r = 1.

        system_model = self._system_model_1Q(omega_0, r)

        # run a schedule in which a shifted phase causes a pulse to cancel itself.
        # Also do it in multiple phase shifts to test accumulation
        sched = Schedule()
        amp1 = 0.12
        sched += Play(SamplePulse([amp1]), DriveChannel(0))
        phi1 = 0.12374 * np.pi
        sched += ShiftPhase(phi1, DriveChannel(0))
        amp2 = 0.492
        sched += Play(SamplePulse([amp2]), DriveChannel(0))
        phi2 = 0.5839 * np.pi
        sched += ShiftPhase(phi2, DriveChannel(0))
        amp3 = 0.12 + 0.21 * 1j
        sched += Play(SamplePulse([amp3]), DriveChannel(0))

        sched |= Acquire(1, AcquireChannel(0), MemorySlot(0)) << sched.duration

        qobj = assemble([sched],
                        backend=self.backend_sim,
                        meas_level=2,
                        meas_return='single',
                        meas_map=[[0]],
                        qubit_lo_freq=[omega_0],
                        memory_slots=2,
                        shots=1)

        y0 = np.array([1., 0])
        backend_options = {'initial_state': y0}

        results = self.backend_sim.run(qobj, system_model, backend_options).result()
        pulse_sim_yf = results.get_statevector()

        #run independent simulation
        samples = np.array([[amp1],
                            [amp2 * np.exp(1j * phi1)],
                            [amp3 * np.exp(1j * (phi1 + phi2))]])
        indep_yf = simulate_1q_model(y0, omega_0, r, np.array([omega_0]), samples, 1.)

        self.assertGreaterEqual(state_fidelity(pulse_sim_yf, indep_yf), 1 - (10**-5))

        # run another schedule with only a single shift phase to verify
        sched = Schedule()
        amp1 = 0.12
        sched += Play(SamplePulse([amp1]), DriveChannel(0))
        phi1 = 0.12374 * np.pi
        sched += ShiftPhase(phi1, DriveChannel(0))
        amp2 = 0.492
        sched += Play(SamplePulse([amp2]), DriveChannel(0))
        sched |= Acquire(1, AcquireChannel(0), MemorySlot(0)) << sched.duration

        qobj = assemble([sched],
                        backend=self.backend_sim,
                        meas_level=2,
                        meas_return='single',
                        meas_map=[[0]],
                        qubit_lo_freq=[omega_0],
                        memory_slots=2,
                        shots=1)

        y0 = np.array([1., 0])
        backend_options = {'initial_state': y0}

        results = self.backend_sim.run(qobj, system_model, backend_options).result()
        pulse_sim_yf = results.get_statevector()

        #run independent simulation
        samples = np.array([[amp1], [amp2 * np.exp(1j * phi1)]])
        indep_yf = simulate_1q_model(y0, omega_0, r, np.array([omega_0]), samples, 1.)

        self.assertGreaterEqual(state_fidelity(pulse_sim_yf, indep_yf), 1 - (10**-5))
    def test_delay_instruction(self):
        """Test for delay instruction."""

        # construct system model specifically for this
        hamiltonian = {}
        hamiltonian['h_str'] = ['0.5*r*X0||D0', '0.5*r*Y0||D1']
        hamiltonian['vars'] = {'r': np.pi}
        hamiltonian['qub'] = {'0': 2}
        ham_model = HamiltonianModel.from_dict(hamiltonian)

        u_channel_lo = []
        subsystem_list = [0]
        dt = 1.

        system_model = PulseSystemModel(hamiltonian=ham_model,
                                        u_channel_lo=u_channel_lo,
                                        subsystem_list=subsystem_list,
                                        dt=dt)

        # construct a schedule that should result in a unitary -Z if delays are correctly handled
        # i.e. do a pi rotation about x, sandwiched by pi/2 rotations about y in opposite directions
        # so that the x rotation is transformed into a z rotation.
        # if delays are not handled correctly this process should fail
        sched = Schedule()
        sched += Play(SamplePulse([0.5]), DriveChannel(1))
        sched += Delay(1, DriveChannel(1))
        sched += Play(SamplePulse([-0.5]), DriveChannel(1))

        sched += Delay(1, DriveChannel(0))
        sched += Play(SamplePulse([1.]), DriveChannel(0))

        sched |= Acquire(1, AcquireChannel(0), MemorySlot(0)) << sched.duration

        qobj = assemble([sched],
                        backend=self.backend_sim,
                        meas_level=2,
                        meas_return='single',
                        meas_map=[[0]],
                        qubit_lo_freq=[0., 0.],
                        memory_slots=2,
                        shots=1)


        # Result of schedule should be the unitary -1j*Z, so check rotation of an X eigenstate
        backend_options = {'initial_state': np.array([1., 1.]) / np.sqrt(2)}

        results = self.backend_sim.run(qobj, system_model, backend_options).result()

        statevector = results.get_statevector()
        expected_vector = np.array([-1j, 1j]) / np.sqrt(2)

        self.assertGreaterEqual(state_fidelity(statevector, expected_vector), 1 - (10**-5))

        # verify validity of simulation when no delays included
        sched = Schedule()
        sched += Play(SamplePulse([0.5]), DriveChannel(1))
        sched += Play(SamplePulse([-0.5]), DriveChannel(1))

        sched += Play(SamplePulse([1.]), DriveChannel(0))

        sched |= Acquire(1, AcquireChannel(0), MemorySlot(0)) << sched.duration

        qobj = assemble([sched],
                        backend=self.backend_sim,
                        meas_level=2,
                        meas_return='single',
                        meas_map=[[0]],
                        qubit_lo_freq=[0., 0.],
                        memory_slots=2,
                        shots=1)

        backend_options = {'initial_state': np.array([1., 1.]) / np.sqrt(2)}

        results = self.backend_sim.run(qobj, system_model, backend_options).result()

        statevector = results.get_statevector()
        U = expm(1j * np.pi * self.Y /4) @ expm(-1j * np.pi * (self.Y / 4 + self.X / 2))
        expected_vector = U @ np.array([1., 1.]) / np.sqrt(2)

        self.assertGreaterEqual(state_fidelity(statevector, expected_vector), 1 - (10**-5))
    def test_2Q_exchange(self):
        r"""Test a more complicated 2q simulation"""

        q_freqs = [5., 5.1]
        r = 0.02
        j = 0.02
        total_samples = 25

        hamiltonian = {}
        hamiltonian['h_str'] = ['2*np.pi*v0*0.5*Z0',
                                '2*np.pi*v1*0.5*Z1',
                                '2*np.pi*r*0.5*X0||D0',
                                '2*np.pi*r*0.5*X1||D1',
                                '2*np.pi*j*0.5*I0*I1',
                                '2*np.pi*j*0.5*X0*X1',
                                '2*np.pi*j*0.5*Y0*Y1',
                                '2*np.pi*j*0.5*Z0*Z1']
        hamiltonian['vars'] = {'v0': q_freqs[0],
                               'v1': q_freqs[1],
                               'r': r,
                               '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 = []
        subsystem_list = [0, 1]
        dt = 1.

        system_model = PulseSystemModel(hamiltonian=ham_model,
                                        u_channel_lo=u_channel_lo,
                                        subsystem_list=subsystem_list,
                                        dt=dt)

        # try some random schedule
        schedule = Schedule()
        drive_pulse = SamplePulse(np.ones(total_samples))
        schedule += Play(drive_pulse, DriveChannel(0))
        schedule |= Play(drive_pulse, DriveChannel(1)) << 2 * total_samples

        schedule |= Acquire(total_samples,
                            AcquireChannel(0),
                            MemorySlot(0)) << 3 * total_samples
        schedule |= Acquire(total_samples,
                            AcquireChannel(1),
                            MemorySlot(1)) << 3 * total_samples

        qobj = assemble([schedule],
                        backend=self.backend_sim,
                        meas_level=2,
                        meas_return='single',
                        meas_map=[[0]],
                        qubit_lo_freq=q_freqs,
                        memory_slots=2,
                        shots=1000)
        y0 = np.array([1., 0., 0., 0.])
        backend_options = {'seed' : 9000, 'initial_state' : y0}

        result = self.backend_sim.run(qobj, system_model, backend_options).result()
        pulse_sim_yf = result.get_statevector()

        # set up and run independent simulation
        d0_samps = np.concatenate((np.ones(total_samples), np.zeros(2 * total_samples)))
        d1_samps = np.concatenate((np.zeros(2 * total_samples), np.ones(total_samples)))
        samples = np.array([d0_samps, d1_samps]).transpose()
        q_freqs = np.array(q_freqs)
        yf = simulate_2q_exchange_model(y0, q_freqs, r, j, q_freqs, samples, 1.)

        # Check fidelity of statevectors
        self.assertGreaterEqual(state_fidelity(pulse_sim_yf, yf), 1-(10**-5))