Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
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()
Esempio n. 4
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()
Esempio n. 5
0
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
Esempio n. 6
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
Esempio n. 7
0
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()
Esempio n. 8
0
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)
Esempio n. 9
0
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)
basePulseSeq.H_int = None
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
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))
Esempio n. 11
0
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()
Esempio n. 12
0
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 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
Esempio n. 14
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
Esempio n. 15
0
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)
Esempio n. 16
0
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)