def RabiAmp_NQubits(qubits: qreg, amps, phase=0, measChans: qreg = None, docals=False, calRepeats=2): """ Variable amplitude Rabi nutation experiment for an arbitrary number of qubits simultaneously Parameters ---------- qubits : tuple of logical channels to implement sequence (LogicalChannel) amps : pulse amplitudes to sweep over for all qubits (iterable) phase : phase of the pulses (radians) measChans : tuple of qubits to be measured (use qubits if not specified) (LogicalChannel) docals, calRepeats: enable calibration sequences, repeated calRepeats times """ if measChans is None: measChans = qubits allChans = QRegister(qubits, measChans) for amp in amps: init(allChans) Utheta(qubits, amp=amp, phase=phase) measConcurrently(measChans) if docals: create_cal_seqs(qubits, calRepeats, measChans)
def PiRabi(controlQ: qreg, targetQ: qreg, lengths, riseFall=40e-9, amp=1, phase=0, calRepeats=2): """ Variable length CX experiment. Parameters ---------- controlQ : logical channel for the control qubit (LogicalChannel) targetQ: logical channel for the target qubit (LogicalChannel) lengths : pulse lengths of the CR pulse to sweep over (iterable) riseFall : rise/fall time of the CR pulse (s) amp : amplitude of the CR pulse phase : phase of the CR pulse (rad) calRepeats : number repetitions of calibration sequences (int) """ # Rather than do EdgeFactory and regular flat_top_gaussian, # define a new QGL2 stub where the QGL1 implementation does that, # so QGL2 can avoid dealing with the edge # CRchan = EdgeFactory(controlQ, targetQ) # flat_top_gaussian is an addition of 3 UTheta pulses cNt = QRegister(controlQ, targetQ) # Sequence 1: Id(control), gaussian(l), measure both for l in lengths: init(cNt) Id(controlQ) flat_top_gaussian_edge(controlQ, targetQ, riseFall, length=l, amp=amp, phase=phase) measConcurrently(cNt) # Sequence 2: X(control), gaussian(l), X(control), measure both for l in lengths: init(cNt) X(controlQ) flat_top_gaussian_edge(controlQ, targetQ, riseFall, length=l, amp=amp, phase=phase) X(controlQ) measConcurrently(cNt) # Then do calRepeats calibration sequences create_cal_seqs(cNt, calRepeats)
def SimultaneousRB_AC(qubits: qreg, seqs, add_cals=True): """ Simultaneous randomized benchmarking on multiple qubits using atomic Clifford pulses. Parameters ---------- qubits : QRegister of logical channels to implement seqs on seqs : a tuple of sequences created for each qubit in qubits Example ------- >>> q1 = QubitFactory('q1') >>> q2 = QubitFactory('q2') >>> seqs1 = create_RB_seqs(1, [2, 4, 8, 16]) >>> seqs2 = create_RB_seqs(1, [2, 4, 8, 16]) >>> qr = QRegister(q1, q2) >>> SimultaneousRB_AC(qr, (seqs1, seqs2)) """ # Original: # seqsBis = [] # for seq in zip(*seqs): # seqsBis.append([reduce(operator.__mul__, [AC(q,c) for q,c in zip(qubits, # pulseNums)]) for pulseNums in zip(*seq)]) # # Add the measurement to all sequences # for seq in seqsBis: # seq.append(reduce(operator.mul, [MEAS(q) for q in qubits])) # axis_descriptor = [{ # 'name': 'length', # 'unit': None, # 'points': list(map(len, seqs)), # 'partition': 1 # }] # # Tack on the calibration sequences # if add_cals: # seqsBis += create_cal_seqs((qubits), 2) # axis_descriptor.append(cal_descriptor((qubits), 2)) # metafile = compile_to_hardware(seqsBis, 'RB/RB', axis_descriptor = axis_descriptor, extra_meta = {'sequences':seqs}) for seq in zip(*seqs): # Start sequence init(qubits) for pulseNums in zip(*seq): Barrier(qubits) for q, c in zip(qubits, pulseNums): AC(q, c) # Measure at end of each sequence measConcurrently(qubits) if add_cals: # Tack on calibration create_cal_seqs(qubits, 2)
def EchoCRAmp(controlQ: qreg, targetQ: qreg, amps, riseFall=40e-9, length=50e-9, phase=0, calRepeats=2): """ Variable amplitude CX experiment, with echo pulse sandwiched between two CR opposite-phase pulses. Parameters ---------- controlQ : logical channel for the control qubit (LogicalChannel) targetQ: logical channel for the target qubit (LogicalChannel) amps : pulse amplitudes of the CR pulse to sweep over (iterable) riseFall : rise/fall time of the CR pulse (s) length : duration of each of the two flat parts of the CR pulse (s) phase : phase of the CR pulse (rad) calRepeats : number of repetitions of readout calibrations for each 2-qubit state """ cNt = QRegister(controlQ, targetQ) # Sequence 1 for a in amps: init(cNt) Id(controlQ) echoCR(controlQ, targetQ, length=length, phase=phase, riseFall=riseFall, amp=a) Id(controlQ) measConcurrently(cNt) # Sequence 2 for a in amps: init(cNt) X(controlQ) echoCR(controlQ, targetQ, length=length, phase=phase, riseFall=riseFall, amp=a) X(controlQ) measConcurrently(cNt) # Then do calRepeats calibration sequences create_cal_seqs(cNt, calRepeats)
def EchoCRPhase(controlQ: qreg, targetQ: qreg, phases, riseFall=40e-9, amp=1, length=100e-9, calRepeats=2, canc_amp=0, canc_phase=np.pi/2): """ Variable phase CX experiment, with echo pulse sandwiched between two CR opposite-phase pulses. Parameters ---------- controlQ : logical channel for the control qubit (LogicalChannel) targetQ : logical channel for the cross-resonance pulse (LogicalChannel) phases : pulse phases of the CR pulse to sweep over (iterable) riseFall : rise/fall time of the CR pulse (s) amp : amplitude of the CR pulse length : duration of each of the two flat parts of the CR pulse (s) calRepeats : number of repetitions of readout calibrations for each 2-qubit state """ # Original: # seqs = [[Id(controlQ)] + echoCR(controlQ, targetQ, length=length, phase=ph, riseFall=riseFall) + [X90(targetQ)*Id(controlQ), MEAS(targetQ)*MEAS(controlQ)] \ # for ph in phases]+[[X(controlQ)] + echoCR(controlQ, targetQ, length=length, phase= ph, riseFall = riseFall) + [X90(targetQ)*X(controlQ), MEAS(targetQ)*MEAS(controlQ)] \ # for ph in phases]+create_cal_seqs((targetQ,controlQ), calRepeats, measChans=(targetQ,controlQ)) cNt = QRegister(controlQ, targetQ) # Sequence 1 for ph in phases: init(cNt) Id(controlQ) echoCR(controlQ, targetQ, length=length, phase=ph, riseFall=riseFall, canc_amp=canc_amp, canc_phase=canc_phase) Barrier(cNt) X90(targetQ) Id(controlQ) measConcurrently(cNt) # Sequence 2 for ph in phases: init(cNt) X(controlQ) echoCR(controlQ, targetQ, length=length, phase=ph, riseFall=riseFall, canc_amp=canc_amp, canc_phase=canc_phase) Barrier(cNt) X90(targetQ) X(controlQ) measConcurrently(cNt) # Then do calRepeats calibration sequences create_cal_seqs(cNt, calRepeats)
def EchoCRLen(controlQ: qreg, targetQ: qreg, lengths, riseFall=40e-9, amp=1, phase=0, calRepeats=2, canc_amp=0, canc_phase=np.pi/2): """ Variable length CX experiment, with echo pulse sandwiched between two CR opposite-phase pulses. Parameters ---------- controlQ : logical channel for the control qubit (LogicalChannel) targetQ: logical channel for the target qubit (LogicalChannel) lengths : pulse lengths of the CR pulse to sweep over (iterable) riseFall : rise/fall time of the CR pulse (s) amp : amplitude of the CR pulse phase : phase of the CR pulse (rad) calRepeats : number of repetitions of readout calibrations for each 2-qubit state """ # Original: # seqs = [[Id(controlQ)] + echoCR(controlQ, targetQ, length=l, phase=phase, riseFall=riseFall) + [Id(controlQ), MEAS(targetQ)*MEAS(controlQ)] \ # for l in lengths]+ [[X(controlQ)] + echoCR(controlQ, targetQ, length=l, phase= phase, riseFall=riseFall) + [X(controlQ), MEAS(targetQ)*MEAS(controlQ)] \ # for l in lengths] + create_cal_seqs((targetQ,controlQ), calRepeats, measChans=(targetQ,controlQ)) cNt = QRegister(controlQ, targetQ) # Sequence1: for l in lengths: init(cNt) Id(controlQ) echoCR(controlQ, targetQ, length=l, phase=phase, amp=amp, riseFall=riseFall, canc_amp=canc_amp, canc_phase=canc_phase) Id(controlQ) measConcurrently(cNt) # Sequence 2 for l in lengths: init(cNt) X(controlQ) echoCR(controlQ, targetQ, length=l, phase=phase, amp=amp, riseFall=riseFall, canc_amp=canc_amp, canc_phase=canc_phase) X(controlQ) measConcurrently(cNt) # Then do calRepeats calibration sequences create_cal_seqs(cNt, calRepeats)
def TwoQubitRB(q1: qreg, q2: qreg, seqs, add_cals=True): """ Two qubit randomized benchmarking using 90 and 180 single qubit generators and ZX90 Parameters ---------- q1,q2 : logical channels to implement sequence (LogicalChannel) seqs : list of lists of Clifford group integers """ # Original: # seqsBis = [] # for seq in seqs: # seqsBis.append(reduce(operator.add, [clifford_seq(c, q1, q2) for c in seq])) # # Add the measurement to all sequences # for seq in seqsBis: # seq.append(MEAS(q1, q2)) # # Tack on the calibration sequences # if add_cals: # seqsBis += create_cal_seqs((q1,q2), 2) # axis_descriptor = [{ # 'name': 'length', # 'unit': None, # 'points': list(map(len, seqs)), # 'partition': 1 # }] # metafile = compile_to_hardware(seqsBis, 'RB/RB', axis_descriptor = axis_descriptor, suffix = suffix, extra_meta = {'sequences':seqs}) bothQs = QRegister(q1, q2) for seq in seqs: init(bothQs) for c in seq: clifford_seq(c, q2, q1) measConcurrently(bothQs) # Tack on the calibration sequences if add_cals: create_cal_seqs((q1, q2), 2)
def Swap(qubit: qreg, delays, mqubit: qreg = None): # Note: Not a QGL1 basic sequence any more, but preserving this anyhow # Original: # seqs = [[X(qubit), X(mqubit), Id(mqubit, d), MEAS(mqubit)*MEAS(qubit)] for d in delays] + create_cal_seqs((mqubit,qubit), 2, measChans=(mqubit,qubit)) # fileNames = compile_to_hardware(seqs, 'Rabi/Rabi') # print(fileNames) # if showPlot: # plotWin = plot_pulse_files(fileNames) # return plotWin if mqubit is None: mqubit = qubit allChans = QRegister(qubit, mqubit) for d in delays: init(allChans) X(qubit) X(mqubit) Id(mqubit, length=d) measConcurrently(allChans) create_cal_seqs(allChans, 2)