def setUp(self): #Setup a simple non-coupled two qubit system self.systemParams = SystemParams() self.Q1 = SCQubit(2, 5e9, name='Q1') self.systemParams.add_sub_system(self.Q1) self.Q2 = SCQubit(2, 6e9, name='Q2') self.systemParams.add_sub_system(self.Q2) X = 0.5 * (self.Q1.loweringOp + self.Q1.raisingOp) Y = 0.5 * (-1j * self.Q1.loweringOp + 1j * self.Q2.raisingOp) self.systemParams.add_control_ham( inphase=Hamiltonian(self.systemParams.expand_operator('Q1', X)), quadrature=Hamiltonian(self.systemParams.expand_operator('Q1', Y))) self.systemParams.add_control_ham( inphase=Hamiltonian(self.systemParams.expand_operator('Q2', X)), quadrature=Hamiltonian(self.systemParams.expand_operator('Q2', Y))) self.systemParams.measurement = self.systemParams.expand_operator( 'Q1', self.Q1.pauliZ) + self.systemParams.expand_operator( 'Q2', self.Q2.pauliZ) self.systemParams.create_full_Ham() #Define Rabi frequency and pulse lengths self.rabiFreq = 10e6 #Define the initial state as the ground state self.rhoIn = np.zeros((self.systemParams.dim, self.systemParams.dim)) self.rhoIn[0, 0] = 1
def testInversion(self): ''' Try a simple three level SC qubit system and see if can prepare the excited state. ''' #Setup a three level qubit and a 100MHz delta Q1 = SCQubit(3, 4.987456e9, -100e6, name='Q1') systemParams = SystemParams() systemParams.add_sub_system(Q1) systemParams.add_control_ham( inphase=Hamiltonian(0.5 * (Q1.loweringOp + Q1.raisingOp)), quadrature=Hamiltonian(0.5 * (-1j * Q1.loweringOp + 1j * Q1.raisingOp))) systemParams.create_full_Ham() systemParams.measurement = Q1.levelProjector(1) #Setup the pulse parameters for the optimization pulseParams = PulseParams() pulseParams.timeSteps = 1e-9 * np.ones(30) pulseParams.rhoStart = Q1.levelProjector(0) pulseParams.rhoGoal = Q1.levelProjector(1) pulseParams.add_control_line(freq=-Q1.omega) pulseParams.H_int = Hamiltonian(Q1.omega * np.diag(np.arange(Q1.dim))) pulseParams.optimType = 'state2state' #Call the optimization optimize_pulse(pulseParams, systemParams) #Now test the optimized pulse and make sure it puts all the population in the excited state result = simulate_sequence(pulseParams, systemParams, pulseParams.rhoStart, simType='unitary')[0] assert result > 0.99
def testInversion(self): ''' Try a simple three level SC qubit system and see if can prepare the excited state. ''' #Setup a three level qubit and a 100MHz delta Q1 = SCQubit(3, 4.987456e9, -100e6, name='Q1') systemParams = SystemParams() systemParams.add_sub_system(Q1) systemParams.add_control_ham(inphase = Hamiltonian(0.5*(Q1.loweringOp + Q1.raisingOp)), quadrature = Hamiltonian(0.5*(-1j*Q1.loweringOp + 1j*Q1.raisingOp))) systemParams.create_full_Ham() systemParams.measurement = Q1.levelProjector(1) #Setup the pulse parameters for the optimization pulseParams = PulseParams() pulseParams.timeSteps = 1e-9*np.ones(30) pulseParams.rhoStart = Q1.levelProjector(0) pulseParams.rhoGoal = Q1.levelProjector(1) pulseParams.add_control_line(freq=-Q1.omega) pulseParams.H_int = Hamiltonian(Q1.omega*np.diag(np.arange(Q1.dim))) pulseParams.optimType = 'state2state' #Call the optimization optimize_pulse(pulseParams, systemParams) #Now test the optimized pulse and make sure it puts all the population in the excited state result = simulate_sequence(pulseParams, systemParams, pulseParams.rhoStart, simType='unitary')[0] assert result > 0.99
def setUp(self): #Setup the system self.systemParams = SystemParams() self.qubit = SCQubit(2, 0e9, name='Q1', T1=1e-6) self.systemParams.add_sub_system(self.qubit) #self.systemParams.add_control_ham(inphase = Hamiltonian(0.5*(self.qubit.loweringOp + self.qubit.raisingOp)), quadrature = Hamiltonian(0.5*(-1j*self.qubit.loweringOp + 1j*self.qubit.raisingOp))) self.systemParams.add_control_ham( inphase=Hamiltonian(0.5 * self.qubit.pauliX), quadrature=Hamiltonian(0.5 * self.qubit.pauliY)) self.systemParams.measurement = self.qubit.pauliZ self.systemParams.create_full_Ham() #Define Rabi frequency and pulse lengths self.rabiFreq = 10e6 self.pulseLengths = np.linspace(0, 100e-9, 40) #Define the initial state as the ground state self.rhoIn = self.qubit.levelProjector(0)
def setUp(self): #Setup the system self.systemParams = SystemParams() self.qubit = SCQubit(3, 5e9, -100e6, name='Q1', T1=2e-6) self.systemParams.add_sub_system(self.qubit) self.systemParams.add_control_ham( inphase=Hamiltonian( 0.5 * (self.qubit.loweringOp + self.qubit.raisingOp)), quadrature=Hamiltonian( -0.5 * (-1j * self.qubit.loweringOp + 1j * self.qubit.raisingOp))) self.systemParams.measurement = self.qubit.pauliZ self.systemParams.create_full_Ham() #Add the 2us T1 dissipator self.systemParams.dissipators = [Dissipator(self.qubit.T1Dissipator)] #Define the initial state as the ground state self.rhoIn = self.qubit.levelProjector(0)
def setUp(self): #Setup the system self.systemParams = SystemParams() self.qubit = SCQubit(3, 5e9, -100e6, name='Q1', T1=2e-6) self.systemParams.add_sub_system(self.qubit) self.systemParams.add_control_ham(inphase = Hamiltonian(0.5*(self.qubit.loweringOp + self.qubit.raisingOp)), quadrature = Hamiltonian(-0.5*(-1j*self.qubit.loweringOp + 1j*self.qubit.raisingOp))) self.systemParams.measurement = self.qubit.pauliZ self.systemParams.create_full_Ham() #Add the 2us T1 dissipator self.systemParams.dissipators = [Dissipator(self.qubit.T1Dissipator)] #Define the initial state as the ground state self.rhoIn = self.qubit.levelProjector(0)
def testDRAG(self): ''' Try a unitary inversion pulse on a three level SCQuibt and see if we get something close to DRAG ''' #Setup a three level qubit and a 100MHz delta Q1 = SCQubit(3, 4.987456e9, -150e6, name='Q1') systemParams = SystemParams() systemParams.add_sub_system(Q1) systemParams.add_control_ham(inphase = Hamiltonian(0.5*(Q1.loweringOp + Q1.raisingOp)), quadrature = Hamiltonian(0.5*(-1j*Q1.loweringOp + 1j*Q1.raisingOp))) systemParams.add_control_ham(inphase = Hamiltonian(0.5*(Q1.loweringOp + Q1.raisingOp)), quadrature = Hamiltonian(0.5*(-1j*Q1.loweringOp + 1j*Q1.raisingOp))) systemParams.create_full_Ham() systemParams.measurement = Q1.levelProjector(1) #Setup the pulse parameters for the optimization numPoints = 30 pulseTime = 15e-9 pulseParams = PulseParams() pulseParams.timeSteps = (pulseTime/numPoints)*np.ones(numPoints) pulseParams.rhoStart = Q1.levelProjector(0) pulseParams.rhoGoal = Q1.levelProjector(1) pulseParams.Ugoal = Q1.pauliX pulseParams.add_control_line(freq=-Q1.omega, bandwidth=300e6, maxAmp=200e6) pulseParams.add_control_line(freq=-Q1.omega, phase=-np.pi/2, bandwidth=300e6, maxAmp=200e6) pulseParams.H_int = Hamiltonian((Q1.omega)*np.diag(np.arange(Q1.dim))) pulseParams.optimType = 'unitary' pulseParams.derivType = 'finiteDiff' #Start with a Gaussian tmpGauss = np.exp(-np.linspace(-2,2,numPoints)**2) tmpScale = 0.5/(np.sum(pulseParams.timeSteps*tmpGauss)) pulseParams.startControlAmps = np.vstack((tmpScale*tmpGauss, np.zeros(numPoints))) #Call the optimization optimize_pulse(pulseParams, systemParams) if plotResults: plt.plot(np.cumsum(pulseParams.timeSteps)*1e9,pulseParams.controlAmps.T/1e6); plt.ylabel('Pulse Amplitude (MHz)') plt.xlabel('Time (ns)') plt.legend(('X Quadrature', 'Y Quadrature')) plt.title('DRAG Pulse from Optimal Control') plt.show() #Now test the optimized pulse and make sure it does give us the desired unitary result = simulate_sequence(pulseParams, systemParams, pulseParams.rhoStart, simType='unitary') assert np.abs(np.trace(np.dot(result[1].conj().T, pulseParams.Ugoal)))**2/np.abs(np.trace(np.dot(pulseParams.Ugoal.conj().T, pulseParams.Ugoal)))**2 > 0.99
class SingleQutrit(unittest.TestCase): def setUp(self): #Setup the system self.systemParams = SystemParams() self.qubit = SCQubit(3, 5e9, -100e6, name='Q1', T1=2e-6) self.systemParams.add_sub_system(self.qubit) self.systemParams.add_control_ham( inphase=Hamiltonian( 0.5 * (self.qubit.loweringOp + self.qubit.raisingOp)), quadrature=Hamiltonian( -0.5 * (-1j * self.qubit.loweringOp + 1j * self.qubit.raisingOp))) self.systemParams.measurement = self.qubit.pauliZ self.systemParams.create_full_Ham() #Add the 2us T1 dissipator self.systemParams.dissipators = [Dissipator(self.qubit.T1Dissipator)] #Define the initial state as the ground state self.rhoIn = self.qubit.levelProjector(0) def tearDown(self): pass def testTwoPhoton(self): ''' Test spectroscopy and the two photon transition from the ground to the second excited state. ''' freqSweep = 1e9 * np.linspace(4.9, 5.1, 1000) rabiFreq = 1e6 #Setup the pulseSequences as a series of 10us low-power pulses pulseSeqs = [] for freq in freqSweep: tmpPulseSeq = PulseSequence() tmpPulseSeq.add_control_line(freq=freq, phase=0) tmpPulseSeq.controlAmps = np.array([[rabiFreq]], dtype=np.float64) tmpPulseSeq.timeSteps = np.array([10e-6]) tmpPulseSeq.maxTimeStep = np.Inf tmpPulseSeq.H_int = Hamiltonian( np.diag(freq * np.arange(3, dtype=np.complex128))) pulseSeqs.append(tmpPulseSeq) results = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='lindblad')[0] if plotResults: plt.figure() plt.plot(freqSweep / 1e9, results) plt.xlabel('Frequency') plt.ylabel(r'$\sigma_z$') plt.title('Qutrit Spectroscopy') plt.show()
def setUp(self): #Setup the system self.systemParams = SystemParams() self.qubit = SCQubit(2,0e9, name='Q1', T1=1e-6) self.systemParams.add_sub_system(self.qubit) #self.systemParams.add_control_ham(inphase = Hamiltonian(0.5*(self.qubit.loweringOp + self.qubit.raisingOp)), quadrature = Hamiltonian(0.5*(-1j*self.qubit.loweringOp + 1j*self.qubit.raisingOp))) self.systemParams.add_control_ham(inphase = Hamiltonian(0.5*self.qubit.pauliX), quadrature = Hamiltonian(0.5*self.qubit.pauliY)) self.systemParams.measurement = self.qubit.pauliZ self.systemParams.create_full_Ham() #Define Rabi frequency and pulse lengths self.rabiFreq = 10e6 self.pulseLengths = np.linspace(0,100e-9,40) #Define the initial state as the ground state self.rhoIn = self.qubit.levelProjector(0)
class SingleQutrit(unittest.TestCase): def setUp(self): #Setup the system self.systemParams = SystemParams() self.qubit = SCQubit(3, 5e9, -100e6, name='Q1', T1=2e-6) self.systemParams.add_sub_system(self.qubit) self.systemParams.add_control_ham(inphase = Hamiltonian(0.5*(self.qubit.loweringOp + self.qubit.raisingOp)), quadrature = Hamiltonian(-0.5*(-1j*self.qubit.loweringOp + 1j*self.qubit.raisingOp))) self.systemParams.measurement = self.qubit.pauliZ self.systemParams.create_full_Ham() #Add the 2us T1 dissipator self.systemParams.dissipators = [Dissipator(self.qubit.T1Dissipator)] #Define the initial state as the ground state self.rhoIn = self.qubit.levelProjector(0) def tearDown(self): pass def testTwoPhoton(self): ''' Test spectroscopy and the two photon transition from the ground to the second excited state. ''' freqSweep = 1e9*np.linspace(4.9, 5.1, 1000) rabiFreq = 1e6 #Setup the pulseSequences as a series of 10us low-power pulses pulseSeqs = [] for freq in freqSweep: tmpPulseSeq = PulseSequence() tmpPulseSeq.add_control_line(freq=freq, phase=0) tmpPulseSeq.controlAmps = np.array([[rabiFreq]], dtype=np.float64) tmpPulseSeq.timeSteps = np.array([10e-6]) tmpPulseSeq.maxTimeStep = np.Inf tmpPulseSeq.H_int = Hamiltonian(np.diag(freq*np.arange(3, dtype=np.complex128))) pulseSeqs.append(tmpPulseSeq) results = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='lindblad')[0] if plotResults: plt.figure() plt.plot(freqSweep/1e9,results) plt.xlabel('Frequency') plt.ylabel(r'$\sigma_z$') plt.title('Qutrit Spectroscopy') plt.show()
def sim_setup_cython(Hnat, controlHams, controlFields, controlFreqs): systemParams = SystemParams() systemParams.Hnat = Hamiltonian(Hnat) pulseSeq = PulseSequence() pulseSeq.controlAmps = controlFields for ct in range(len(controlHams)): systemParams.add_control_ham(inphase=Hamiltonian(controlHams[ct])) pulseSeq.add_control_line(freq = controlFreqs[ct], phase=0, controlType='sinusoidal') for ct in range(np.int(np.log2(Hnat.shape[0]))): systemParams.add_sub_system(SCQubit(2,0e9, name='Q1', T1=1e-6)) pulseSeq.timeSteps = 0.01*np.ones(controlFields.shape[1]) pulseSeq.maxTimeStep = 1e6 return systemParams, pulseSeq
def setUp(self): #Setup a simple non-coupled two qubit system self.systemParams = SystemParams() self.Q1 = SCQubit(2, 5e9, name='Q1') self.systemParams.add_sub_system(self.Q1) self.Q2 = SCQubit(2, 6e9, name='Q2') self.systemParams.add_sub_system(self.Q2) X = 0.5*(self.Q1.loweringOp + self.Q1.raisingOp) Y = 0.5*(-1j*self.Q1.loweringOp + 1j*self.Q2.raisingOp) self.systemParams.add_control_ham(inphase = Hamiltonian(self.systemParams.expand_operator('Q1', X)), quadrature = Hamiltonian(self.systemParams.expand_operator('Q1', Y))) self.systemParams.add_control_ham(inphase = Hamiltonian(self.systemParams.expand_operator('Q2', X)), quadrature = Hamiltonian(self.systemParams.expand_operator('Q2', Y))) self.systemParams.measurement = self.systemParams.expand_operator('Q1', self.Q1.pauliZ) + self.systemParams.expand_operator('Q2', self.Q2.pauliZ) self.systemParams.create_full_Ham() #Define Rabi frequency and pulse lengths self.rabiFreq = 10e6 #Define the initial state as the ground state self.rhoIn = np.zeros((self.systemParams.dim, self.systemParams.dim)) self.rhoIn[0,0] = 1
Test script to play around with 2D Rabi vs drive frequency experiments """ import numpy as np import matplotlib.pyplot as plt import matplotlib.cm as cm from PySim.SystemParams import SystemParams from PySim.PulseSequence import PulseSequence from PySim.Simulation import simulate_sequence_stack from PySim.QuantumSystems import SCQubit, Hamiltonian #Setup the system systemParams = SystemParams() qubit = SCQubit(6, 4.76e9, delta=-200e6, name='Q1', T1=1e-6) systemParams.add_sub_system(qubit) systemParams.add_control_ham(inphase = Hamiltonian(0.5*(qubit.loweringOp + qubit.raisingOp)), quadrature = Hamiltonian(0.5*(-1j*qubit.loweringOp + 1j*qubit.raisingOp))) systemParams.create_full_Ham() systemParams.measurement = np.diag([0.72, 0.70, 0.69, 0.685, 0.6825, 0.68125]) #Define the initial state as the ground state rhoIn = qubit.levelProjector(0) #Some parameters for the pulse timeStep = 1/1.2e9 pulseAmps = 250e6*np.linspace(-1,1,81) freqs = np.linspace(4.3e9, 4.9e9,450)
class SingleQubit(unittest.TestCase): def setUp(self): #Setup the system self.systemParams = SystemParams() self.qubit = SCQubit(2, 0e9, name='Q1', T1=1e-6) self.systemParams.add_sub_system(self.qubit) #self.systemParams.add_control_ham(inphase = Hamiltonian(0.5*(self.qubit.loweringOp + self.qubit.raisingOp)), quadrature = Hamiltonian(0.5*(-1j*self.qubit.loweringOp + 1j*self.qubit.raisingOp))) self.systemParams.add_control_ham( inphase=Hamiltonian(0.5 * self.qubit.pauliX), quadrature=Hamiltonian(0.5 * self.qubit.pauliY)) self.systemParams.measurement = self.qubit.pauliZ self.systemParams.create_full_Ham() #Define Rabi frequency and pulse lengths self.rabiFreq = 10e6 self.pulseLengths = np.linspace(0, 100e-9, 40) #Define the initial state as the ground state self.rhoIn = self.qubit.levelProjector(0) def tearDown(self): pass def testRabiRotatingFrame(self): ''' Test Rabi oscillations in the rotating frame, i.e. with zero drift Hamiltonian drive frequency of zero. ''' #Setup the pulseSequences pulseSeqs = [] for pulseLength in self.pulseLengths: tmpPulseSeq = PulseSequence() tmpPulseSeq.add_control_line(freq=0e9, phase=0) tmpPulseSeq.controlAmps = self.rabiFreq * np.array( [[1]], dtype=np.float64) tmpPulseSeq.timeSteps = np.array([pulseLength]) tmpPulseSeq.maxTimeStep = pulseLength tmpPulseSeq.H_int = None pulseSeqs.append(tmpPulseSeq) results = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='unitary')[0] expectedResults = np.cos(2 * pi * self.rabiFreq * self.pulseLengths) if plotResults: plt.figure() plt.plot(self.pulseLengths, results) plt.plot(self.pulseLengths, expectedResults, color='r', linestyle='--', linewidth=2) plt.title('10MHz Rabi Oscillations in Rotating Frame') plt.xlabel('Pulse Length') plt.ylabel(r'$\sigma_z$') plt.legend(('Simulated Results', '10MHz Cosine')) plt.show() np.testing.assert_allclose(results, expectedResults, atol=1e-4) def testRabiInteractionFrame(self): ''' Test Rabi oscillations after moving into an interaction frame that is different to the pulsing frame and with an irrational timestep for good measure. ''' #Setup the system self.systemParams.subSystems[0] = SCQubit(2, 5e9, 'Q1') self.systemParams.create_full_Ham() #Setup the pulseSequences pulseSeqs = [] for pulseLength in self.pulseLengths: tmpPulseSeq = PulseSequence() tmpPulseSeq.add_control_line(freq=-5.0e9, phase=0) tmpPulseSeq.controlAmps = self.rabiFreq * np.array( [[1]], dtype=np.float64) tmpPulseSeq.timeSteps = np.array([pulseLength]) tmpPulseSeq.maxTimeStep = pi / 2 * 1e-10 tmpPulseSeq.H_int = Hamiltonian( np.array([[0, 0], [0, 5.005e9]], dtype=np.complex128)) pulseSeqs.append(tmpPulseSeq) results = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='unitary')[0] expectedResults = np.cos(2 * pi * self.rabiFreq * self.pulseLengths) if plotResults: plt.figure() plt.plot(self.pulseLengths, results) plt.plot(self.pulseLengths, expectedResults, color='r', linestyle='--', linewidth=2) plt.title('10MHz Rabi Oscillations in Interaction Frame') plt.xlabel('Pulse Length') plt.ylabel(r'$\sigma_z$') plt.legend(('Simulated Results', '10MHz Cosine')) plt.show() np.testing.assert_allclose(results, expectedResults, atol=1e-4) def testRamsey(self): ''' Just look at Ramsey decay to make sure we get the off-resonance right. ''' #Setup the system self.systemParams.subSystems[0] = SCQubit(2, 5e9, 'Q1') self.systemParams.create_full_Ham() self.systemParams.dissipators = [Dissipator(self.qubit.T1Dissipator)] #Setup the pulseSequences delays = np.linspace(0, 8e-6, 200) t90 = 0.25 * (1 / self.rabiFreq) offRes = 0.56789e6 pulseSeqs = [] for delay in delays: tmpPulseSeq = PulseSequence() #Shift the pulsing frequency down by offRes tmpPulseSeq.add_control_line(freq=-(5.0e9 - offRes), phase=0) #Pulse sequence is X90, delay, X90 tmpPulseSeq.controlAmps = self.rabiFreq * np.array( [[1, 0, 1]], dtype=np.float64) tmpPulseSeq.timeSteps = np.array([t90, delay, t90]) #Interaction frame with some odd frequency tmpPulseSeq.H_int = Hamiltonian( np.array([[0, 0], [0, 5.00e9]], dtype=np.complex128)) pulseSeqs.append(tmpPulseSeq) results = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='lindblad')[0] expectedResults = -np.cos(2 * pi * offRes * (delays + t90)) * np.exp(-delays / (2 * self.qubit.T1)) if plotResults: plt.figure() plt.plot(1e6 * delays, results) plt.plot(1e6 * delays, expectedResults, color='r', linestyle='--', linewidth=2) plt.title('Ramsey Fringes 0.56789MHz Off-Resonance') plt.xlabel('Pulse Spacing (us)') plt.ylabel(r'$\sigma_z$') plt.legend( ('Simulated Results', '0.57MHz Cosine with T1 limited decay.')) plt.show() def testYPhase(self): ''' Make sure the frame-handedness matches what we expect: i.e. if the qubit frequency is greater than the driver frequency this corresponds to a positive rotation. ''' #Setup the system self.systemParams.subSystems[0] = SCQubit(2, 5e9, 'Q1') self.systemParams.create_full_Ham() #Add a Y control Hamiltonian self.systemParams.add_control_ham( inphase=Hamiltonian(0.5 * self.qubit.pauliX), quadrature=Hamiltonian(0.5 * self.qubit.pauliY)) #Setup the pulseSequences delays = np.linspace(0, 8e-6, 200) t90 = 0.25 * (1 / self.rabiFreq) offRes = 1.2345e6 pulseSeqs = [] for delay in delays: tmpPulseSeq = PulseSequence() #Shift the pulsing frequency down by offRes tmpPulseSeq.add_control_line(freq=-(5.0e9 - offRes), phase=0) tmpPulseSeq.add_control_line(freq=-(5.0e9 - offRes), phase=-pi / 2) #Pulse sequence is X90, delay, Y90 tmpPulseSeq.controlAmps = self.rabiFreq * np.array( [[1, 0, 0], [0, 0, 1]], dtype=np.float64) tmpPulseSeq.timeSteps = np.array([t90, delay, t90]) #Interaction frame with some odd frequency tmpPulseSeq.H_int = Hamiltonian( np.array([[0, 0], [0, 5.00e9]], dtype=np.complex128)) pulseSeqs.append(tmpPulseSeq) results = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='lindblad')[0] expectedResults = -np.sin(2 * pi * offRes * (delays + t90)) if plotResults: plt.figure() plt.plot(1e6 * delays, results) plt.plot(1e6 * delays, expectedResults, color='r', linestyle='--', linewidth=2) plt.title('Ramsey Fringes {0:.2f} MHz Off-Resonance'.format( offRes / 1e6)) plt.xlabel('Pulse Spacing (us)') plt.ylabel(r'$\sigma_z$') plt.legend(('Simulated Results', ' {0:.2f} MHz -Sin.'.format(offRes / 1e6))) plt.show() def testT1Recovery(self): ''' Test a simple T1 recovery without any pulses. Start in the first excited state and watch recovery down to ground state. ''' self.systemParams.dissipators = [Dissipator(self.qubit.T1Dissipator)] #Just setup a series of delays delays = np.linspace(0, 5e-6, 40) pulseSeqs = [] for tmpDelay in delays: tmpPulseSeq = PulseSequence() tmpPulseSeq.add_control_line() tmpPulseSeq.controlAmps = np.array([[0]]) tmpPulseSeq.timeSteps = np.array([tmpDelay]) tmpPulseSeq.maxTimeStep = tmpDelay tmpPulseSeq.H_int = None pulseSeqs.append(tmpPulseSeq) results = simulate_sequence_stack(pulseSeqs, self.systemParams, np.array([[0, 0], [0, 1]], dtype=np.complex128), simType='lindblad')[0] expectedResults = 1 - 2 * np.exp(-delays / self.qubit.T1) if plotResults: plt.figure() plt.plot(1e6 * delays, results) plt.plot(1e6 * delays, expectedResults, color='r', linestyle='--', linewidth=2) plt.xlabel(r'Recovery Time ($\mu$s)') plt.ylabel(r'Expectation Value of $\sigma_z$') plt.title(r'$T_1$ Recovery to the Ground State') plt.legend(('Simulated Results', 'Exponential T1 Recovery')) plt.show() np.testing.assert_allclose(results, expectedResults, atol=1e-4)
from copy import deepcopy from scipy.constants import pi from scipy.linalg import eigh from PySim.SystemParams import SystemParams from PySim.QuantumSystems import Hamiltonian, Dissipator from PySim.PulseSequence import PulseSequence from PySim.Simulation import simulate_sequence_stack, simulate_sequence from PySim.QuantumSystems import SCQubit from PySim.OptimalControl import optimize_pulse, PulseParams #Setup the system systemParams = SystemParams() #First the two qubits defined in the lab frame Q1 = SCQubit(numLevels=3, omega=4.76093e9, delta=-244e6, name='Q1', T1=10e-6) systemParams.add_sub_system(Q1) Q2 = SCQubit(numLevels=3, omega=5.34012e9, delta=-224e6, name='Q2', T1=10e-6) systemParams.add_sub_system(Q2) #Add an interaction between the qubits to get the the cross-resonance effect systemParams.add_interaction('Q1', 'Q2', 'FlipFlop', 2e6) #Create the full Hamiltonian systemParams.create_full_Ham() #Calculate the eigenframe for the natural Hamiltonian
def setup_system(): ''' Should probably take in some parameters, but for now hard-code things. ''' #Setup the system systemParams = SystemParams() #First the two qubits defined in the lab frame Q1 = SCQubit(numLevels=3, omega=4.279e9, delta=-239e6, name='Q1', T1=10e-6) systemParams.add_sub_system(Q1) Q2 = SCQubit(numLevels=3, omega=4.06e9, delta=-224e6, name='Q2', T1=10e-6) systemParams.add_sub_system(Q2) #Add an interaction between the qubits to get the the cross-resonance effect systemParams.add_interaction('Q1', 'Q2', 'FlipFlop', 2e6) #Create the full Hamiltonian systemParams.create_full_Ham() #Calculate the eigenframe for the natural Hamiltonian d, v = eigh(systemParams.Hnat.matrix) #Reorder the transformation matrix to maintain the computational basis ordering sortOrder = np.argsort(np.argmax(np.abs(v), axis=0)) v = v[:, sortOrder] systemParams.Hnat.matrix = np.complex128(np.diag(d[sortOrder])) #Some operators for the controls X = 0.5 * (Q1.loweringOp + Q1.raisingOp) Y = 0.5 * (-1j * Q1.loweringOp + 1j * Q1.raisingOp) #The cross-coupling between the drives crossCoupling12 = 5.0 / 20 crossCoupling21 = 2.0 / 30 #Add the Q1 drive Hamiltonians inPhaseHam = Hamiltonian( np.dot( v.conj().T, np.dot( systemParams.expand_operator('Q1', X) + crossCoupling12 * systemParams.expand_operator('Q2', X), v))) quadratureHam = Hamiltonian( np.dot( v.conj().T, np.dot( systemParams.expand_operator('Q1', Y) + crossCoupling12 * systemParams.expand_operator('Q2', Y), v))) systemParams.add_control_ham(inphase=inPhaseHam, quadrature=quadratureHam) systemParams.add_control_ham(inphase=inPhaseHam, quadrature=quadratureHam) #Add the cross-drive Hamiltonians (same drive line as Q1) inPhaseHam = Hamiltonian( np.dot( v.conj().T, np.dot( systemParams.expand_operator('Q1', X) + crossCoupling12 * systemParams.expand_operator('Q2', X), v))) quadratureHam = Hamiltonian( np.dot( v.conj().T, np.dot( systemParams.expand_operator('Q1', Y) + crossCoupling12 * systemParams.expand_operator('Q2', Y), v))) systemParams.add_control_ham(inphase=inPhaseHam, quadrature=quadratureHam) systemParams.add_control_ham(inphase=inPhaseHam, quadrature=quadratureHam) #Add the Q2 drive Hamiltonians inPhaseHam = Hamiltonian( np.dot( v.conj().T, np.dot( systemParams.expand_operator('Q2', X) + crossCoupling21 * systemParams.expand_operator('Q1', X), v))) quadratureHam = Hamiltonian( np.dot( v.conj().T, np.dot( systemParams.expand_operator('Q2', Y) + crossCoupling21 * systemParams.expand_operator('Q1', Y), v))) systemParams.add_control_ham(inphase=inPhaseHam, quadrature=quadratureHam) systemParams.add_control_ham(inphase=inPhaseHam, quadrature=quadratureHam) #Setup the measurement operator systemParams.measurement = np.diag( np.array([0.088, 0.082, 0.080, 0.080, 0.78, 0.75, 0.078, 0.074, 0.072])) ##Add the T1 dissipators #systemParams.dissipators.append(Dissipator(systemParams.expand_operator('Q1', Q1.T1Dissipator))) #systemParams.dissipators.append(Dissipator(systemParams.expand_operator('Q2', Q2.T1Dissipator))) # return systemParams, (Q1, Q2)
@author: cryan ''' from PySim.SystemParams import SystemParams from PySim.QuantumSystems import SCQubit, Hamiltonian, Dissipator from PySim.PulseSequence import PulseSequence from PySim.Simulation import simulate_sequence_stack, simulate_sequence from PySim.OptimalControl import optimize_pulse, PulseParams import numpy as np import matplotlib.pyplot as plt from scipy.constants import pi '''System Setup''' systemParams = SystemParams() qubit = SCQubit(3, 0e9, -100e6, name='Q1', T1=50e-9) systemParams.add_sub_system(qubit) systemParams.add_control_ham( inphase=Hamiltonian(0.5 * (qubit.loweringOp + qubit.raisingOp)), quadrature=Hamiltonian(-0.5 * (-1j * qubit.loweringOp + 1j * qubit.raisingOp))) systemParams.add_control_ham( inphase=Hamiltonian(0.5 * (qubit.loweringOp + qubit.raisingOp)), quadrature=Hamiltonian(-0.5 * (-1j * qubit.loweringOp + 1j * qubit.raisingOp))) systemParams.measurement = qubit.levelProjector(1) systemParams.create_full_Ham() #Add the T1 dissipator systemParams.dissipators = [Dissipator(qubit.T1Dissipator)]
import matplotlib.pyplot as plt from copy import deepcopy from scipy.constants import pi import scipy.optimize from PySim.SystemParams import SystemParams from PySim.QuantumSystems import Hamiltonian, Dissipator from PySim.PulseSequence import PulseSequence from PySim.Simulation import simulate_sequence_stack, simulate_sequence from PySim.QuantumSystems import SCQubit if __name__ == '__main__': #Setup the system systemParams = SystemParams() #First the two qubits Q1 = SCQubit(numLevels=3, omega=4.8636e9, delta=-321.7e6, name='Q1', T1=5.2e-6) systemParams.add_sub_system(Q1) Q2 = SCQubit(numLevels=3, omega=5.1934e9, delta=-313.656e6, name='Q2', T1=4.4e-6) systemParams.add_sub_system(Q2)
Test script to play around with 2D Rabi vs drive frequency experiments """ import numpy as np import matplotlib.pyplot as plt import matplotlib.cm as cm from PySim.SystemParams import SystemParams from PySim.PulseSequence import PulseSequence from PySim.Simulation import simulate_sequence_stack from PySim.QuantumSystems import SCQubit, Hamiltonian #Setup the system systemParams = SystemParams() qubit = SCQubit(6, 4.76e9, delta=-200e6, name='Q1', T1=1e-6) systemParams.add_sub_system(qubit) systemParams.add_control_ham( inphase=Hamiltonian(0.5 * (qubit.loweringOp + qubit.raisingOp)), quadrature=Hamiltonian(0.5 * (-1j * qubit.loweringOp + 1j * qubit.raisingOp))) systemParams.create_full_Ham() systemParams.measurement = np.diag([0.72, 0.70, 0.69, 0.685, 0.6825, 0.68125]) #Define the initial state as the ground state rhoIn = qubit.levelProjector(0) #Some parameters for the pulse timeStep = 1 / 1.2e9 pulseAmps = 250e6 * np.linspace(-1, 1, 81)
class TwoQubit(unittest.TestCase): def setUp(self): #Setup a simple non-coupled two qubit system self.systemParams = SystemParams() self.Q1 = SCQubit(2, 5e9, name='Q1') self.systemParams.add_sub_system(self.Q1) self.Q2 = SCQubit(2, 6e9, name='Q2') self.systemParams.add_sub_system(self.Q2) X = 0.5*(self.Q1.loweringOp + self.Q1.raisingOp) Y = 0.5*(-1j*self.Q1.loweringOp + 1j*self.Q2.raisingOp) self.systemParams.add_control_ham(inphase = Hamiltonian(self.systemParams.expand_operator('Q1', X)), quadrature = Hamiltonian(self.systemParams.expand_operator('Q1', Y))) self.systemParams.add_control_ham(inphase = Hamiltonian(self.systemParams.expand_operator('Q2', X)), quadrature = Hamiltonian(self.systemParams.expand_operator('Q2', Y))) self.systemParams.measurement = self.systemParams.expand_operator('Q1', self.Q1.pauliZ) + self.systemParams.expand_operator('Q2', self.Q2.pauliZ) self.systemParams.create_full_Ham() #Define Rabi frequency and pulse lengths self.rabiFreq = 10e6 #Define the initial state as the ground state self.rhoIn = np.zeros((self.systemParams.dim, self.systemParams.dim)) self.rhoIn[0,0] = 1 def tearDown(self): pass def testZZGate(self): '''Test whether the ZZ interaction performs as expected''' #Take the bare Hamiltonian as the interaction Hamiltonian H_int = Hamiltonian(self.systemParams.Hnat.matrix) #First add a 2MHz ZZ interaction and add it to the system self.systemParams.add_interaction('Q1', 'Q2', 'ZZ', 2e6) self.systemParams.create_full_Ham() #Setup the pulseSequences delays = np.linspace(0,4e-6,100) pulseSeqs = [] for delay in delays: tmpPulseSeq = PulseSequence() tmpPulseSeq.add_control_line(freq=-5.0e9, phase=0) tmpPulseSeq.add_control_line(freq=-6.0e9, phase=0) tmpPulseSeq.controlAmps = self.rabiFreq*np.array([[1, 0], [0,0]], dtype=np.float64) tmpPulseSeq.timeSteps = np.array([25e-9, delay]) tmpPulseSeq.maxTimeStep = np.Inf tmpPulseSeq.H_int = H_int pulseSeqs.append(tmpPulseSeq) self.systemParams.measurement = np.kron(self.Q1.pauliX, self.Q2.pauliZ) resultsXZ = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='unitary')[0] self.systemParams.measurement = np.kron(self.Q1.pauliY, self.Q2.pauliZ) resultsYZ = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='unitary')[0] if plotResults: plt.figure() plt.plot(delays*1e6, resultsXZ) plt.plot(delays*1e6, resultsYZ, 'g') plt.legend(('XZ','YZ')) plt.xlabel('Coupling Time') plt.ylabel('Operator Expectation Value') plt.title('ZZ Coupling Evolution After a X90 on Q1') plt.show()
def setup_system(): ''' Should probably take in some parameters, but for now hard-code things. ''' #Setup the system systemParams = SystemParams() #First the two qubits defined in the lab frame Q1 = SCQubit(numLevels=3, omega=4.279e9, delta=-239e6, name='Q1', T1=10e-6) systemParams.add_sub_system(Q1) Q2 = SCQubit(numLevels=3, omega=4.06e9, delta=-224e6, name='Q2', T1=10e-6) systemParams.add_sub_system(Q2) #Add an interaction between the qubits to get the the cross-resonance effect systemParams.add_interaction('Q1', 'Q2', 'FlipFlop', 2e6) #Create the full Hamiltonian systemParams.create_full_Ham() #Calculate the eigenframe for the natural Hamiltonian d,v = eigh(systemParams.Hnat.matrix) #Reorder the transformation matrix to maintain the computational basis ordering sortOrder = np.argsort(np.argmax(np.abs(v),axis=0)) v = v[:, sortOrder] systemParams.Hnat.matrix = np.complex128(np.diag(d[sortOrder])) #Some operators for the controls X = 0.5*(Q1.loweringOp + Q1.raisingOp) Y = 0.5*(-1j*Q1.loweringOp + 1j*Q1.raisingOp) #The cross-coupling between the drives crossCoupling12 = 5.0/20 crossCoupling21 = 2.0/30 #Add the Q1 drive Hamiltonians inPhaseHam = Hamiltonian(np.dot(v.conj().T, np.dot(systemParams.expand_operator('Q1', X) + crossCoupling12*systemParams.expand_operator('Q2', X), v))) quadratureHam = Hamiltonian(np.dot(v.conj().T, np.dot(systemParams.expand_operator('Q1', Y) + crossCoupling12*systemParams.expand_operator('Q2', Y), v))) systemParams.add_control_ham(inphase = inPhaseHam, quadrature = quadratureHam) systemParams.add_control_ham(inphase = inPhaseHam, quadrature = quadratureHam) #Add the cross-drive Hamiltonians (same drive line as Q1) inPhaseHam = Hamiltonian(np.dot(v.conj().T, np.dot(systemParams.expand_operator('Q1', X) + crossCoupling12*systemParams.expand_operator('Q2', X), v))) quadratureHam = Hamiltonian(np.dot(v.conj().T, np.dot(systemParams.expand_operator('Q1', Y) + crossCoupling12*systemParams.expand_operator('Q2', Y), v))) systemParams.add_control_ham(inphase = inPhaseHam, quadrature = quadratureHam) systemParams.add_control_ham(inphase = inPhaseHam, quadrature = quadratureHam) #Add the Q2 drive Hamiltonians inPhaseHam = Hamiltonian(np.dot(v.conj().T, np.dot(systemParams.expand_operator('Q2', X) + crossCoupling21*systemParams.expand_operator('Q1', X), v))) quadratureHam = Hamiltonian(np.dot(v.conj().T, np.dot(systemParams.expand_operator('Q2', Y) + crossCoupling21*systemParams.expand_operator('Q1', Y), v))) systemParams.add_control_ham(inphase = inPhaseHam, quadrature = quadratureHam) systemParams.add_control_ham(inphase = inPhaseHam, quadrature = quadratureHam) #Setup the measurement operator systemParams.measurement = np.diag(np.array([0.088, 0.082, 0.080, 0.080, 0.78, 0.75, 0.078, 0.074, 0.072])) ##Add the T1 dissipators #systemParams.dissipators.append(Dissipator(systemParams.expand_operator('Q1', Q1.T1Dissipator))) #systemParams.dissipators.append(Dissipator(systemParams.expand_operator('Q2', Q2.T1Dissipator))) # return systemParams, (Q1,Q2)
class TwoQubit(unittest.TestCase): def setUp(self): #Setup a simple non-coupled two qubit system self.systemParams = SystemParams() self.Q1 = SCQubit(2, 5e9, name='Q1') self.systemParams.add_sub_system(self.Q1) self.Q2 = SCQubit(2, 6e9, name='Q2') self.systemParams.add_sub_system(self.Q2) X = 0.5 * (self.Q1.loweringOp + self.Q1.raisingOp) Y = 0.5 * (-1j * self.Q1.loweringOp + 1j * self.Q2.raisingOp) self.systemParams.add_control_ham( inphase=Hamiltonian(self.systemParams.expand_operator('Q1', X)), quadrature=Hamiltonian(self.systemParams.expand_operator('Q1', Y))) self.systemParams.add_control_ham( inphase=Hamiltonian(self.systemParams.expand_operator('Q2', X)), quadrature=Hamiltonian(self.systemParams.expand_operator('Q2', Y))) self.systemParams.measurement = self.systemParams.expand_operator( 'Q1', self.Q1.pauliZ) + self.systemParams.expand_operator( 'Q2', self.Q2.pauliZ) self.systemParams.create_full_Ham() #Define Rabi frequency and pulse lengths self.rabiFreq = 10e6 #Define the initial state as the ground state self.rhoIn = np.zeros((self.systemParams.dim, self.systemParams.dim)) self.rhoIn[0, 0] = 1 def tearDown(self): pass def testZZGate(self): '''Test whether the ZZ interaction performs as expected''' #Take the bare Hamiltonian as the interaction Hamiltonian H_int = Hamiltonian(self.systemParams.Hnat.matrix) #First add a 2MHz ZZ interaction and add it to the system self.systemParams.add_interaction('Q1', 'Q2', 'ZZ', 2e6) self.systemParams.create_full_Ham() #Setup the pulseSequences delays = np.linspace(0, 4e-6, 100) pulseSeqs = [] for delay in delays: tmpPulseSeq = PulseSequence() tmpPulseSeq.add_control_line(freq=-5.0e9, phase=0) tmpPulseSeq.add_control_line(freq=-6.0e9, phase=0) tmpPulseSeq.controlAmps = self.rabiFreq * np.array( [[1, 0], [0, 0]], dtype=np.float64) tmpPulseSeq.timeSteps = np.array([25e-9, delay]) tmpPulseSeq.maxTimeStep = np.Inf tmpPulseSeq.H_int = H_int pulseSeqs.append(tmpPulseSeq) self.systemParams.measurement = np.kron(self.Q1.pauliX, self.Q2.pauliZ) resultsXZ = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='unitary')[0] self.systemParams.measurement = np.kron(self.Q1.pauliY, self.Q2.pauliZ) resultsYZ = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='unitary')[0] if plotResults: plt.figure() plt.plot(delays * 1e6, resultsXZ) plt.plot(delays * 1e6, resultsYZ, 'g') plt.legend(('XZ', 'YZ')) plt.xlabel('Coupling Time') plt.ylabel('Operator Expectation Value') plt.title('ZZ Coupling Evolution After a X90 on Q1') plt.show()
import numpy as np from scipy.constants import pi from scipy.linalg import expm import matplotlib.pyplot as plt from PySim.SystemParams import SystemParams from PySim.PulseSequence import PulseSequence from PySim.Simulation import simulate_sequence_stack from PySim.QuantumSystems import SCQubit, Hamiltonian from copy import deepcopy #Setup the system systemParams = SystemParams() qubit = SCQubit(2, 0e9, delta=200e6, name='Q1', T1=1e-6) systemParams.add_sub_system(qubit) systemParams.add_control_ham(inphase = Hamiltonian(0.5*(qubit.loweringOp + qubit.raisingOp)), quadrature = Hamiltonian(0.5*(-1j*qubit.loweringOp + 1j*qubit.raisingOp))) systemParams.add_control_ham(inphase = Hamiltonian(0.5*(qubit.loweringOp + qubit.raisingOp)), quadrature = Hamiltonian(0.5*(-1j*qubit.loweringOp + 1j*qubit.raisingOp))) systemParams.measurement = qubit.pauliZ systemParams.create_full_Ham() #Define the initial state as the ground state rhoIn = qubit.levelProjector(0) #First the basic sequence basePulseSeq = PulseSequence() basePulseSeq.add_control_line(freq=0e9, phase=0) basePulseSeq.add_control_line(freq=0e9, phase=pi/2)
# #Setup the Hermite polynomial # numPoints = 240 # AWGFreq = 1.2e9 # x = np.linspace(-2,2,numPoints) # #Hermite 180 ## pulseAmps = (1-0.956*x**2)*np.exp(-(x**2)) # #Hermite 90 # pulseAmps = (1-0.677*x**2)*np.exp(-(x**2)) # #Gaussian ## pulseAmps = np.exp(-(x**2)) ''' Try to recreate the Bell-Rabi spectroscopy ''' #Setup the system systemParams = SystemParams() #First the two qubits Q1 = SCQubit(numLevels=3, omega=4.863e9-1e6, delta=-300e6, name='Q1', T1=5.2e-6) systemParams.add_sub_system(Q1) Q2 = SCQubit(numLevels=3, omega=5.193e9-1e6, delta=-313.656e6, name='Q2', T1=4.4e-6) systemParams.add_sub_system(Q2) #Add a 2MHz ZZ interaction systemParams.add_interaction('Q1', 'Q2', 'ZZ', -2e6) #Create the full Hamiltonian systemParams.create_full_Ham() #Some Pauli operators for the controls X = 0.5*(Q1.loweringOp + Q1.raisingOp)
import numpy as np import matplotlib.pyplot as plt from scipy.signal import decimate from scipy.constants import pi from scipy.linalg import eigh, expm from PySim.SystemParams import SystemParams from PySim.QuantumSystems import Hamiltonian, Dissipator from PySim.PulseSequence import PulseSequence from PySim.Simulation import simulate_sequence_stack, simulate_sequence from PySim.QuantumSystems import SCQubit from PySim.OptimalControl import optimize_pulse, PulseParams #Setup the system systemParams = SystemParams() #First the two qubits Q1 = SCQubit(numLevels=3, omega=1e6, delta=-321.7e6, name='Q1', T1=5.2e-6) systemParams.add_sub_system(Q1) Q2 = SCQubit(numLevels=3, omega=329.8e6, delta=-314.4e6, name='Q2', T1=4.4e-6) systemParams.add_sub_system(Q2) #Add a 2MHz ZZ interaction through a flip-flop interaction systemParams.add_interaction('Q1', 'Q2', 'FlipFlop', 4.3e6) #Create the full Hamiltonian systemParams.create_full_Ham() #Calculate the eigenframe for the natural Hamiltonian d, v = eigh(systemParams.Hnat.matrix)
class SingleQubit(unittest.TestCase): def setUp(self): #Setup the system self.systemParams = SystemParams() self.qubit = SCQubit(2,0e9, name='Q1', T1=1e-6) self.systemParams.add_sub_system(self.qubit) #self.systemParams.add_control_ham(inphase = Hamiltonian(0.5*(self.qubit.loweringOp + self.qubit.raisingOp)), quadrature = Hamiltonian(0.5*(-1j*self.qubit.loweringOp + 1j*self.qubit.raisingOp))) self.systemParams.add_control_ham(inphase = Hamiltonian(0.5*self.qubit.pauliX), quadrature = Hamiltonian(0.5*self.qubit.pauliY)) self.systemParams.measurement = self.qubit.pauliZ self.systemParams.create_full_Ham() #Define Rabi frequency and pulse lengths self.rabiFreq = 10e6 self.pulseLengths = np.linspace(0,100e-9,40) #Define the initial state as the ground state self.rhoIn = self.qubit.levelProjector(0) def tearDown(self): pass def testRabiRotatingFrame(self): ''' Test Rabi oscillations in the rotating frame, i.e. with zero drift Hamiltonian drive frequency of zero. ''' #Setup the pulseSequences pulseSeqs = [] for pulseLength in self.pulseLengths: tmpPulseSeq = PulseSequence() tmpPulseSeq.add_control_line(freq=0e9, phase=0) tmpPulseSeq.controlAmps = self.rabiFreq*np.array([[1]], dtype=np.float64) tmpPulseSeq.timeSteps = np.array([pulseLength]) tmpPulseSeq.maxTimeStep = pulseLength tmpPulseSeq.H_int = None pulseSeqs.append(tmpPulseSeq) results = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='unitary')[0] expectedResults = np.cos(2*pi*self.rabiFreq*self.pulseLengths) if plotResults: plt.figure() plt.plot(self.pulseLengths,results) plt.plot(self.pulseLengths, expectedResults, color='r', linestyle='--', linewidth=2) plt.title('10MHz Rabi Oscillations in Rotating Frame') plt.xlabel('Pulse Length') plt.ylabel(r'$\sigma_z$') plt.legend(('Simulated Results', '10MHz Cosine')) plt.show() np.testing.assert_allclose(results, expectedResults , atol = 1e-4) def testRabiInteractionFrame(self): ''' Test Rabi oscillations after moving into an interaction frame that is different to the pulsing frame and with an irrational timestep for good measure. ''' #Setup the system self.systemParams.subSystems[0] = SCQubit(2,5e9, 'Q1') self.systemParams.create_full_Ham() #Setup the pulseSequences pulseSeqs = [] for pulseLength in self.pulseLengths: tmpPulseSeq = PulseSequence() tmpPulseSeq.add_control_line(freq=-5.0e9, phase=0) tmpPulseSeq.controlAmps = self.rabiFreq*np.array([[1]], dtype=np.float64) tmpPulseSeq.timeSteps = np.array([pulseLength]) tmpPulseSeq.maxTimeStep = pi/2*1e-10 tmpPulseSeq.H_int = Hamiltonian(np.array([[0,0], [0, 5.005e9]], dtype = np.complex128)) pulseSeqs.append(tmpPulseSeq) results = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='unitary')[0] expectedResults = np.cos(2*pi*self.rabiFreq*self.pulseLengths) if plotResults: plt.figure() plt.plot(self.pulseLengths,results) plt.plot(self.pulseLengths, expectedResults, color='r', linestyle='--', linewidth=2) plt.title('10MHz Rabi Oscillations in Interaction Frame') plt.xlabel('Pulse Length') plt.ylabel(r'$\sigma_z$') plt.legend(('Simulated Results', '10MHz Cosine')) plt.show() np.testing.assert_allclose(results, expectedResults , atol = 1e-4) def testRamsey(self): ''' Just look at Ramsey decay to make sure we get the off-resonance right. ''' #Setup the system self.systemParams.subSystems[0] = SCQubit(2,5e9, 'Q1') self.systemParams.create_full_Ham() self.systemParams.dissipators = [Dissipator(self.qubit.T1Dissipator)] #Setup the pulseSequences delays = np.linspace(0,8e-6,200) t90 = 0.25*(1/self.rabiFreq) offRes = 0.56789e6 pulseSeqs = [] for delay in delays: tmpPulseSeq = PulseSequence() #Shift the pulsing frequency down by offRes tmpPulseSeq.add_control_line(freq=-(5.0e9-offRes), phase=0) #Pulse sequence is X90, delay, X90 tmpPulseSeq.controlAmps = self.rabiFreq*np.array([[1, 0, 1]], dtype=np.float64) tmpPulseSeq.timeSteps = np.array([t90, delay, t90]) #Interaction frame with some odd frequency tmpPulseSeq.H_int = Hamiltonian(np.array([[0,0], [0, 5.00e9]], dtype = np.complex128)) pulseSeqs.append(tmpPulseSeq) results = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='lindblad')[0] expectedResults = -np.cos(2*pi*offRes*(delays+t90))*np.exp(-delays/(2*self.qubit.T1)) if plotResults: plt.figure() plt.plot(1e6*delays,results) plt.plot(1e6*delays, expectedResults, color='r', linestyle='--', linewidth=2) plt.title('Ramsey Fringes 0.56789MHz Off-Resonance') plt.xlabel('Pulse Spacing (us)') plt.ylabel(r'$\sigma_z$') plt.legend(('Simulated Results', '0.57MHz Cosine with T1 limited decay.')) plt.show() def testYPhase(self): ''' Make sure the frame-handedness matches what we expect: i.e. if the qubit frequency is greater than the driver frequency this corresponds to a positive rotation. ''' #Setup the system self.systemParams.subSystems[0] = SCQubit(2,5e9, 'Q1') self.systemParams.create_full_Ham() #Add a Y control Hamiltonian self.systemParams.add_control_ham(inphase = Hamiltonian(0.5*self.qubit.pauliX), quadrature = Hamiltonian(0.5*self.qubit.pauliY)) #Setup the pulseSequences delays = np.linspace(0,8e-6,200) t90 = 0.25*(1/self.rabiFreq) offRes = 1.2345e6 pulseSeqs = [] for delay in delays: tmpPulseSeq = PulseSequence() #Shift the pulsing frequency down by offRes tmpPulseSeq.add_control_line(freq=-(5.0e9-offRes), phase=0) tmpPulseSeq.add_control_line(freq=-(5.0e9-offRes), phase=-pi/2) #Pulse sequence is X90, delay, Y90 tmpPulseSeq.controlAmps = self.rabiFreq*np.array([[1, 0, 0],[0,0,1]], dtype=np.float64) tmpPulseSeq.timeSteps = np.array([t90, delay, t90]) #Interaction frame with some odd frequency tmpPulseSeq.H_int = Hamiltonian(np.array([[0,0], [0, 5.00e9]], dtype = np.complex128)) pulseSeqs.append(tmpPulseSeq) results = simulate_sequence_stack(pulseSeqs, self.systemParams, self.rhoIn, simType='lindblad')[0] expectedResults = -np.sin(2*pi*offRes*(delays+t90)) if plotResults: plt.figure() plt.plot(1e6*delays,results) plt.plot(1e6*delays, expectedResults, color='r', linestyle='--', linewidth=2) plt.title('Ramsey Fringes {0:.2f} MHz Off-Resonance'.format(offRes/1e6)) plt.xlabel('Pulse Spacing (us)') plt.ylabel(r'$\sigma_z$') plt.legend(('Simulated Results', ' {0:.2f} MHz -Sin.'.format(offRes/1e6) )) plt.show() def testT1Recovery(self): ''' Test a simple T1 recovery without any pulses. Start in the first excited state and watch recovery down to ground state. ''' self.systemParams.dissipators = [Dissipator(self.qubit.T1Dissipator)] #Just setup a series of delays delays = np.linspace(0,5e-6,40) pulseSeqs = [] for tmpDelay in delays: tmpPulseSeq = PulseSequence() tmpPulseSeq.add_control_line() tmpPulseSeq.controlAmps = np.array([[0]]) tmpPulseSeq.timeSteps = np.array([tmpDelay]) tmpPulseSeq.maxTimeStep = tmpDelay tmpPulseSeq.H_int = None pulseSeqs.append(tmpPulseSeq) results = simulate_sequence_stack(pulseSeqs, self.systemParams, np.array([[0,0],[0,1]], dtype=np.complex128), simType='lindblad')[0] expectedResults = 1-2*np.exp(-delays/self.qubit.T1) if plotResults: plt.figure() plt.plot(1e6*delays,results) plt.plot(1e6*delays, expectedResults, color='r', linestyle='--', linewidth=2) plt.xlabel(r'Recovery Time ($\mu$s)') plt.ylabel(r'Expectation Value of $\sigma_z$') plt.title(r'$T_1$ Recovery to the Ground State') plt.legend(('Simulated Results', 'Exponential T1 Recovery')) plt.show() np.testing.assert_allclose(results, expectedResults, atol=1e-4)
def testDRAG(self): ''' Try a unitary inversion pulse on a three level SCQuibt and see if we get something close to DRAG ''' #Setup a three level qubit and a 100MHz delta Q1 = SCQubit(3, 4.987456e9, -150e6, name='Q1') systemParams = SystemParams() systemParams.add_sub_system(Q1) systemParams.add_control_ham( inphase=Hamiltonian(0.5 * (Q1.loweringOp + Q1.raisingOp)), quadrature=Hamiltonian(0.5 * (-1j * Q1.loweringOp + 1j * Q1.raisingOp))) systemParams.add_control_ham( inphase=Hamiltonian(0.5 * (Q1.loweringOp + Q1.raisingOp)), quadrature=Hamiltonian(0.5 * (-1j * Q1.loweringOp + 1j * Q1.raisingOp))) systemParams.create_full_Ham() systemParams.measurement = Q1.levelProjector(1) #Setup the pulse parameters for the optimization numPoints = 30 pulseTime = 15e-9 pulseParams = PulseParams() pulseParams.timeSteps = (pulseTime / numPoints) * np.ones(numPoints) pulseParams.rhoStart = Q1.levelProjector(0) pulseParams.rhoGoal = Q1.levelProjector(1) pulseParams.Ugoal = Q1.pauliX pulseParams.add_control_line(freq=-Q1.omega, bandwidth=300e6, maxAmp=200e6) pulseParams.add_control_line(freq=-Q1.omega, phase=-np.pi / 2, bandwidth=300e6, maxAmp=200e6) pulseParams.H_int = Hamiltonian( (Q1.omega) * np.diag(np.arange(Q1.dim))) pulseParams.optimType = 'unitary' pulseParams.derivType = 'finiteDiff' #Start with a Gaussian tmpGauss = np.exp(-np.linspace(-2, 2, numPoints)**2) tmpScale = 0.5 / (np.sum(pulseParams.timeSteps * tmpGauss)) pulseParams.startControlAmps = np.vstack( (tmpScale * tmpGauss, np.zeros(numPoints))) #Call the optimization optimize_pulse(pulseParams, systemParams) if plotResults: plt.plot( np.cumsum(pulseParams.timeSteps) * 1e9, pulseParams.controlAmps.T / 1e6) plt.ylabel('Pulse Amplitude (MHz)') plt.xlabel('Time (ns)') plt.legend(('X Quadrature', 'Y Quadrature')) plt.title('DRAG Pulse from Optimal Control') plt.show() #Now test the optimized pulse and make sure it does give us the desired unitary result = simulate_sequence(pulseParams, systemParams, pulseParams.rhoStart, simType='unitary') assert np.abs(np.trace(np.dot( result[1].conj().T, pulseParams.Ugoal)))**2 / np.abs( np.trace(np.dot(pulseParams.Ugoal.conj().T, pulseParams.Ugoal)))**2 > 0.99
import matplotlib.pyplot as plt from copy import deepcopy from scipy.constants import pi import scipy.optimize from PySim.SystemParams import SystemParams from PySim.QuantumSystems import Hamiltonian, Dissipator from PySim.PulseSequence import PulseSequence from PySim.Simulation import simulate_sequence_stack, simulate_sequence from PySim.QuantumSystems import SCQubit if __name__ == '__main__': #Setup the system systemParams = SystemParams() #First the two qubits Q1 = SCQubit(numLevels=3, omega=4.8636e9, delta=-321.7e6, name='Q1', T1=5.2e-6) systemParams.add_sub_system(Q1) Q2 = SCQubit(numLevels=3, omega=5.1934e9, delta=-313.656e6, name='Q2', T1=4.4e-6) systemParams.add_sub_system(Q2) #Our carrier frequencies drive1Freq = 4.8626e9 drive2Freq = 5.193e9 #Add a 2MHz ZZ interaction systemParams.add_interaction('Q1', 'Q2', 'FlipFlop', 4.3e6) #Create the full Hamiltonian
import numpy as np from scipy.constants import pi from scipy.linalg import expm import matplotlib.pyplot as plt from PySim.SystemParams import SystemParams from PySim.PulseSequence import PulseSequence from PySim.Simulation import simulate_sequence_stack from PySim.QuantumSystems import SCQubit, Hamiltonian from copy import deepcopy #Setup the system systemParams = SystemParams() qubit = SCQubit(2, 0e9, delta=200e6, name='Q1', T1=1e-6) systemParams.add_sub_system(qubit) systemParams.add_control_ham( inphase=Hamiltonian(0.5 * (qubit.loweringOp + qubit.raisingOp)), quadrature=Hamiltonian(0.5 * (-1j * qubit.loweringOp + 1j * qubit.raisingOp))) systemParams.add_control_ham( inphase=Hamiltonian(0.5 * (qubit.loweringOp + qubit.raisingOp)), quadrature=Hamiltonian(0.5 * (-1j * qubit.loweringOp + 1j * qubit.raisingOp))) systemParams.measurement = qubit.pauliZ systemParams.create_full_Ham() #Define the initial state as the ground state rhoIn = qubit.levelProjector(0)
''' from PySim.SystemParams import SystemParams from PySim.QuantumSystems import SCQubit, Hamiltonian, Dissipator from PySim.PulseSequence import PulseSequence from PySim.Simulation import simulate_sequence_stack, simulate_sequence from PySim.OptimalControl import optimize_pulse, PulseParams import numpy as np import matplotlib.pyplot as plt from scipy.constants import pi '''System Setup''' systemParams = SystemParams() qubit = SCQubit(3, 0e9, -100e6, name='Q1', T1=50e-9) systemParams.add_sub_system(qubit) systemParams.add_control_ham(inphase = Hamiltonian(0.5*(qubit.loweringOp + qubit.raisingOp)), quadrature = Hamiltonian(-0.5*(-1j*qubit.loweringOp + 1j*qubit.raisingOp))) systemParams.add_control_ham(inphase = Hamiltonian(0.5*(qubit.loweringOp + qubit.raisingOp)), quadrature = Hamiltonian(-0.5*(-1j*qubit.loweringOp + 1j*qubit.raisingOp))) systemParams.measurement = qubit.levelProjector(1) systemParams.create_full_Ham() #Add the T1 dissipator systemParams.dissipators = [Dissipator(qubit.T1Dissipator)] ''' Simple Rabi Driving We'll vary the Rabi power (but always keep the time to a calibrated pi pulse. We expect to see a maximum at some intermediate regime