Ejemplo 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
Ejemplo 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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
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
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
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()
Ejemplo n.º 7
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)
Ejemplo n.º 8
0
    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()
Ejemplo n.º 9
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()
Ejemplo n.º 10
0
    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()
Ejemplo n.º 11
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)
Ejemplo n.º 12
0
 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)
Ejemplo n.º 13
0
    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)
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)
Ejemplo n.º 15
0
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   
    systemParams.create_full_Ham()
 
    #Some Pauli operators for the controls
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)

#Reorder the transformation matrix to maintain the computational basis ordering
sortOrder = np.argsort(np.argmax(np.abs(v), axis=0))
Ejemplo n.º 17
0
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)
Ejemplo n.º 18
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)
Ejemplo n.º 19
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
Ejemplo n.º 20
0
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
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
d,v = eigh(systemParams.Hnat.matrix)

#Reorder the transformation matrix to maintain the computational basis ordering
Ejemplo n.º 22
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)]
'''
Ejemplo n.º 23
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)
Ejemplo n.º 24
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
#    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)
    Y = 0.5*(-1j*Q1.loweringOp + 1j*Q2.raisingOp)
    #The cross-coupling from Q1 drive to Q2
    crossCoupling = 1
Ejemplo n.º 26
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)
Ejemplo n.º 27
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
where we have a balance between selectivity and T1 decay