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)
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
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
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
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
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)
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))
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))