#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 = 12.0/24
crossCoupling21 = 0.5/12

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

#Add the cross-drive Hamiltonians (same drive line as Q2)
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)
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()
Beispiel #3
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)
Beispiel #4
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()
Beispiel #5
0
    systemParams.add_interaction('Q1', 'Q2', 'FlipFlop', 4.3e6)

    #Create the full Hamiltonian
    systemParams.create_full_Ham()

    #Some Pauli operators for the controls
    X = 0.5 * (Q1.loweringOp + Q1.raisingOp)
    Y = 0.5 * (-1j * Q1.loweringOp + 1j * Q2.raisingOp)
    #The cross-coupling from Q1 drive to Q2
    crossCoupling12 = 0.67
    crossCoupling21 = 0.67

    #Add the Q1 drive Hamiltonians
    systemParams.add_control_ham(
        inphase=Hamiltonian(
            systemParams.expand_operator('Q1', X) +
            crossCoupling12 * systemParams.expand_operator('Q2', X)),
        quadrature=Hamiltonian(
            systemParams.expand_operator('Q1', Y) +
            crossCoupling12 * systemParams.expand_operator('Q2', Y)))
    systemParams.add_control_ham(
        inphase=Hamiltonian(
            systemParams.expand_operator('Q1', X) +
            crossCoupling12 * systemParams.expand_operator('Q2', X)),
        quadrature=Hamiltonian(
            systemParams.expand_operator('Q1', Y) +
            crossCoupling12 * systemParams.expand_operator('Q2', Y)))

    #Add the Q2 drive Hamiltonians
    systemParams.add_control_ham(
        inphase=Hamiltonian(crossCoupling21 *
    #Add a 2MHz ZZ interaction 
    systemParams.add_interaction('Q1', 'Q2', 'FlipFlop', 4.3e6)
   
    #Create the full Hamiltonian   
    systemParams.create_full_Ham()
 
    #Some Pauli operators for the controls
    X = 0.5*(Q1.loweringOp + Q1.raisingOp)
    Y = 0.5*(-1j*Q1.loweringOp + 1j*Q2.raisingOp)
    #The cross-coupling from Q1 drive to Q2
    crossCoupling12 = 0.67
    crossCoupling21 = 0.67
    
    #Add the Q1 drive Hamiltonians
    systemParams.add_control_ham(inphase = Hamiltonian(systemParams.expand_operator('Q1', X) + crossCoupling12*systemParams.expand_operator('Q2', X)),
                                  quadrature = Hamiltonian(systemParams.expand_operator('Q1', Y) + crossCoupling12*systemParams.expand_operator('Q2', Y)))
    systemParams.add_control_ham(inphase = Hamiltonian(systemParams.expand_operator('Q1', X) + crossCoupling12*systemParams.expand_operator('Q2', X)),
                                  quadrature = Hamiltonian(systemParams.expand_operator('Q1', Y) + crossCoupling12*systemParams.expand_operator('Q2', Y)))
    
    #Add the Q2 drive Hamiltonians
    systemParams.add_control_ham(inphase = Hamiltonian(crossCoupling21*systemParams.expand_operator('Q1', X) + systemParams.expand_operator('Q2', X)),
                                  quadrature = Hamiltonian(crossCoupling21*systemParams.expand_operator('Q1', Y) + systemParams.expand_operator('Q2', Y)))
    systemParams.add_control_ham(inphase = Hamiltonian(crossCoupling21*systemParams.expand_operator('Q1', X) + systemParams.expand_operator('Q2', X)),
                                  quadrature = Hamiltonian(crossCoupling21*systemParams.expand_operator('Q1', Y) + systemParams.expand_operator('Q2', Y)))
    
    
    #Setup the measurement operator
#    systemParams.measurement = -systemParams.expand_operator('Q1', Q1.pauliZ)
    systemParams.measurement = np.diag(np.array([0.55, 0.7, 0.75, 0.72, 0.76, 0.76, 0.76, 0.78, 0.80]))
Beispiel #7
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)
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 from Q1 drive to Q2
crossCoupling12 = 0.67
crossCoupling21 = 0.67

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

#Add the Q1 drive Hamiltonians
systemParams.add_control_ham(inphase=inPhaseHam, quadrature=quadratureHam)
systemParams.add_control_ham(inphase=inPhaseHam, quadrature=quadratureHam)

#Add the Q2 drive Hamiltonians
#systemParams.add_control_ham(inphase = Hamiltonian(crossCoupling21*systemParams.expand_operator('Q1', X) + systemParams.expand_operator('Q2', X)),
#                              quadrature = Hamiltonian(crossCoupling21*systemParams.expand_operator('Q1', Y) + systemParams.expand_operator('Q2', Y)))
    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)
    Y = 0.5*(-1j*Q1.loweringOp + 1j*Q2.raisingOp)
    #The cross-coupling from Q1 drive to Q2
    crossCoupling = 1
    
    #Add the Q1 drive Hamiltonians
    systemParams.add_control_ham(inphase = Hamiltonian(systemParams.expand_operator('Q1', X) + crossCoupling*systemParams.expand_operator('Q2', X)),
                                  quadrature = Hamiltonian(systemParams.expand_operator('Q1', Y) + crossCoupling*systemParams.expand_operator('Q2', Y)))
    
    #Setup the measurement operator
#    systemParams.measurement = np.kron(Q1.levelProjector(1), Q2.levelProjector(1))
    systemParams.measurement = 0.5*np.kron(Q1.levelProjector(0), Q2.levelProjector(0)) + 0.67*np.kron(Q1.levelProjector(1), Q2.levelProjector(0)) + \
                                0.64*np.kron(Q1.levelProjector(0), Q2.levelProjector(1)) + 0.72*np.kron(Q1.levelProjector(0), Q2.levelProjector(2)) + \
                                0.75*np.kron(Q1.levelProjector(1), Q2.levelProjector(1)) + 0.78*np.kron(Q1.levelProjector(1), Q2.levelProjector(2)) 

    #Add the T1 dissipators
    systemParams.dissipators.append(Dissipator(systemParams.expand_operator('Q1', Q1.T1Dissipator)))
    systemParams.dissipators.append(Dissipator(systemParams.expand_operator('Q2', Q2.T1Dissipator)))
    
    #Setup the initial state as the ground state
    rhoIn = np.zeros((systemParams.dim, systemParams.dim))
    rhoIn[0,0] = 1