def single_selection_ops(self, rho, targets, ancillas, sigma): """ Single selection round. Uses 2 ancilla qubits. Parameters ---------- rho : (densmat) density matrix targets : (list) list with the positions of the qubits to be purified by the protocol ancillas : (list) list with the positions of the ancilla qubits sigma : (string) X or Z parity used in the purification """ # Reset number of steps counter self._reset_check() N = len(rho.dims[0]) H = [qt.snot(N, targets[0]), qt.snot(N, targets[1])] rho = self._apply_single_qubit_gates(rho, H, targets) # Apply two qubit gates controls = ancillas rho = self._apply_two_qubit_gates(rho, targets, controls, sigma) # Calculate the probability of success p_success = ps.single_sel(rho, N, controls) # Measure ancillas in X basis projections = [0, 0] _, rho = self._collapse_ancillas_X(rho, controls, projections) return p_success, self.check, rho
def double_selection22(self, sigma): """ Double selection round. Uses 4 ancilla qubits. Parameters ---------- rho : (densmat) density matrix operation_pos : (list) list with the positions of the qubits to be purified by the protocol sigma : (string) X or Z parity used in the purification """ # Reset number of steps counter self._reset_check() # Generate raw bell pair _, _, rho = self.start_epl() rho = self._append_epl(rho) N = len(rho.dims[0]) operation_qubits = [0, 1] H = [qt.snot(N, operation_qubits[0]), qt.snot(N, operation_qubits[1])] rho = self._apply_single_qubit_gates(rho, H, operation_qubits) # Apply two qubit gates controls = [N - 1, N - 2] # self._swap_pair(rho, controls) # rho = self._apply_two_qubit_gates(rho, controls, # operation_qubits, sigma) rho = self._apply_two_qubit_gates(rho, operation_qubits, controls, "Z") # Calculate the probability of success p_success1 = ps.single_sel(rho, N, controls) # Measure ancillas in X basis projections = [0, 0] _, rho = self._collapse_ancillas_X(rho, controls, projections) rho = self._append_epl(rho) N = len(rho.dims[0]) H = [qt.snot(N, operation_qubits[0]), qt.snot(N, operation_qubits[1])] rho = self._apply_single_qubit_gates(rho, H, operation_qubits) # Apply two qubit gates controls = [N - 1, N - 2] # self._swap_pair(rho, controls) # rho = self._apply_two_qubit_gates(rho, controls, # operation_qubits, sigma) rho = self._apply_two_qubit_gates(rho, operation_qubits, controls, sigma) # Calculate the probability of success p_success2 = ps.single_sel(rho, N, controls) # Measure ancillas in X basis projections = [0, 0] _, rho = self._collapse_ancillas_X(rho, controls, projections) p_success = p_success1 * p_success2 return p_success, self.check, rho
def testHadamardUnitaryMulti(self): H = constructHadamardH(2, [0, 1]) UH1 = snot(N=2, target=0) UH2 = snot(N=2, target=1) U2 = deriveUnitary(H, np.pi) Ucorr = constructHadamardCorr(2, [0, 1]) assert Ucorr*U2 == UH1*UH2 assert H.isherm
def generate_noisy_plus(self): """Generate single noisy qubit in the |+> state.""" plus = qt.snot() * qt.basis(2, 0) plus = plus * plus.dag() minus = qt.snot() * qt.basis(2, 1) minus = minus * minus.dag() plus = (1 - self.pm) * plus + self.pm * minus return plus
def circuitDecodingSimulation(psi0, c_ops=[]): N = 8 schedule = [] # decoding, stage 1, 2 schedule += [snot(N=N, target=i) for i in [5, 7]] # decoding, stage 3 schedule += [ controlled_gate(sigmaz(), N=N, control=4, target=5), controlled_gate(sigmaz(), N=N, control=6, target=7) ] # decoding, stage 4, 5 schedule += [snot(N=N, target=i) for i in [4, 5, 6]] # perform time evolution and return the final state return scheduledUnitaryEvolution(psi0, schedule)
def _generate_noisy_plus(self): # Prepare a noisy |+> state, error is the same # as measurement error. # This circuit time # NOTE: Used time of a single qubit gate time = self.time_lookup["single_qubit_gate"] # Generate noisy plus plus = qt.snot() * qt.basis(2, 0) plus = plus * plus.dag() minus = qt.snot() * qt.basis(2, 1) minus = minus * minus.dag() plus = (1 - self.pm) * plus + self.pm * minus return time, plus
def test_p_measurement_Zbasis(self): print("----------Test p measurement Z basis----------") psi = qt.snot() * qt.basis(2, 1) rho = qt.tensor(psi, psi) rho = rho * rho.dag() p = p_measurement_single_Zbasis(rho, 0, 2, 0) self.assertEqual(round(p, 5), 0.5)
def testHadamardUnitary(self): H = constructHadamardH(1, [0]) U = snot() U2 = deriveUnitary(H, np.pi) Ucorr = constructHadamardCorr(1, [0]) assert Ucorr*U2 == U assert H.isherm
def test_measurement_Xbasis(self): print("----------Test measurement X basis----------") psi = qt.snot() * qt.basis(2, 1) rho = qt.tensor(psi, psi) rho = rho * rho.dag() measurement, rho = random_measure_single_Xbasis(rho, 2, 1, True) rho_ref = psi * psi.dag() self.assertEqual(rho, rho_ref)
def projector_single_qubit_Xbasis(project, N=1, pos=0): # NOTE: This projector is |x><x| if project != 0 and project != 1: raise ValueError("projector: measurement value invalid") p = qt.snot() * qt.basis(2, project) p = p * p.dag() return tensor_single_operator(p, N, pos)
def generate_noisy_pair(F): a = qt.bell_state('00') * qt.bell_state('00').dag() b = qt.bell_state('01') * qt.bell_state('01').dag() \ + qt.bell_state('10') * qt.bell_state('10').dag() \ + qt.bell_state('11') * qt.bell_state('11').dag() W = F * a + (1 - F) / 3. * b H = qt.snot(2, 1) return H * W * H.dag()
def test_measurement_error(self): print("----------Test measurement error-----------") p = .5 psi = qt.snot() * qt.basis(2, 0) rho = psi * psi.dag() m, rho_coll = errs.measure_single_Xbasis_random(rho, p) print("Measurement: ", m) print("Error: p = ", p) print(rho_coll)
def damp_correction(rho, damped_qubit, n, E): # Apply error correction as in arXiv:0710.1052 (2007): # Apply a Hadamard gate on the damped qubit. # With damped qubit as the control, apply a CNOT gate to every other qubit # Flip the damped qubit # In our case, we apply controlled-z instead of CNOT X = qt.Qobj([[0, 1], [1, 0]]) rho = apply_gate(rho, qt.snot(), range(1, n + 1)) for ii in range(1, n + 1): if ii != damped_qubit: rho = permute_matrix(damped_qubit, ii, create_noisy_cz(E), rho) rho = apply_gate(rho, qt.snot(), range(1, n + 1)) rho = apply_gate(rho, qt.snot(), [damped_qubit]) rho = apply_gate(rho, X, [damped_qubit]) return rho
def collapse_single_Xbasis_ket(psi, project, N=1, pos=0, dimRed=False): """ Collapse the state in the postion of a single qubit in X basis. """ H = qt.snot(N, pos) collapsed_psi = H * psi collapsed_psi = collapse_single_Zbasis_ket(collapsed_psi, project, N, pos, dimRed) if not dimRed: collapsed_psi = H * collapsed_psi return collapsed_psi
def testHadamardHamiltonian(self): t = np.pi H = constructHadamardH(1, [0]) U = snot() Ucorr = constructHadamardCorr(1, [0]) for psi0 in [z0, z1, xp, xm, yp, ym, rand_ket(2)]: psiu = U*psi0 psif = evolve(H, t/2., psi0) psic = Ucorr*psif overl = psiu.overlap(psic) assert are_close(overl, 1.) assert H.isherm
def circuitTeleportationSimulation(psi, c_ops=[]): N = 8 psi0 = tensor([basis(2, 0), psi] + [basis(2, 0) for i in range(N - 2)]) schedule = [] # encoding, Hadamards stage 1, 2 schedule += [snot(N=N, target=i) for i in range(N)] # encoding, CZs, stage 3 schedule += [ controlled_gate(sigmaz(), N=N, control=0, target=1), controlled_gate(sigmaz(), N=N, control=2, target=3), controlled_gate(sigmaz(), N=N, control=4, target=5) ] # encoding, Hadamards, stage 4, 5 schedule += [snot(N=N, target=i) for i in [1, 3, 5]] # teleportation, stage 6 schedule += [ry(np.pi / 2., N=N, target=i) for i in [1, 2, 3, 4]] # teleportation, stage 7 schedule += [rz(-np.pi / 2., N=N, target=i) for i in [1, 2, 3, 4]] # teleportation, stage 8 schedule += [ controlled_gate(sigmaz(), N=N, control=1, target=2), controlled_gate(sigmaz(), N=N, control=3, target=4) ] # teleportation, stage 9 schedule += [ry(-np.pi / 2., N=N, target=i) for i in [1, 2, 3, 4]] # decoding, stage 10, 11 schedule += [snot(N=N, target=i) for i in [1, 3]] # decoding, stage 12 schedule += [ controlled_gate(sigmaz(), N=N, control=0, target=1), controlled_gate(sigmaz(), N=N, control=2, target=3) ] # decoding, stage 13, 14 schedule += [snot(N=N, target=i) for i in [0, 1, 2, 3]] # perform time evolution and return the final state return scheduledUnitaryEvolution(psi0, schedule)
def _parity_projection_ket(self, psi, targets, measurement): plus = qt.snot() * qt.basis(2, 0) full_psi = qt.tensor(psi, plus) N = len(full_psi.dims[0]) control = N-1 if self.basis_parity == "X": for t in targets: full_psi = qt.cnot(N, control, t) * full_psi if self.basis_parity == "Z": for t in targets: full_psi = qt.cphase(np.pi, N, control, t) * full_psi # NOTE: Parity projection is not a channel collapsed_psi = ops.collapse_single_Xbasis_ket(full_psi, measurement, N, control, True) if collapsed_psi.norm() != 0: collapsed_psi = collapsed_psi/collapsed_psi.norm() return collapsed_psi
def random_measure_single_Xbasis(rho, N=1, pos=0, dimRed=False): """ Measure a single qubit in the X basis. Parameters ---------- rho : (densmat) density matrix. N : (int) system size. pos : (int) position of qubit to be measured. dimRed : (bool) is the collapsed state has reduced to the dimentions N - 1 """ H = qt.snot(N, pos) # H operation to rotate the state and use Z measurement rho = H * rho * H.dag() measurement, collapsed_rho = random_measure_single_Zbasis( rho, N, pos, dimRed) if not dimRed: collapsed_rho = H * rho * H.dag() return measurement, collapsed_rho
CNOT2 = qt.cnot(4, 3, 1) GATE = CNOT1 * CNOT2 # CPHASE1 = qt.cphase(np.pi, 4, 0, 2) # CPHASE2 = qt.cphase(np.pi, 4, 1, 3) # GATE = CPHASE1 * CPHASE2 rho = GATE * rho_i * GATE.dag() p1, rho = ops.forced_measure_single_Xbasis(rho, 4, 2, 0, True) print("p1: ", p1) p2, rho = ops.forced_measure_single_Xbasis(rho, 3, 2, 0, True) print("p2: ", p2, p_ref(1 - p)) print("F: ", qt.fidelity(ref, rho)**2, single_selection(1 - p, 1 - p)) print("--------------------") print(qt.fidelity(ref, rho)**2) H = qt.snot(2, 0) * qt.snot(2, 1) rho = H * rho rho2i = qt.tensor(rho, errs.bell_pair_phi(p)) # rho2i = qt.tensor(rho, rho) # CPHASE1 = qt.cphase(np.pi, 4, 2, 0) # CPHASE2 = qt.cphase(np.pi, 4, 3, 1) # GATE = CPHASE1 * CPHASE2 CNOT1 = qt.cnot(4, 2, 0) CNOT2 = qt.cnot(4, 3, 1) GATE = CNOT1 * CNOT2 rho2 = GATE * rho2i * GATE.dag() p1, rho2 = ops.forced_measure_single_Xbasis(rho2, 4, 2, 0, True) print("p1: ", p1) p2, rho2 = ops.forced_measure_single_Xbasis(rho2, 3, 2, 0, True) print("p2: ", p2, p_ref(0.9263959390862941))
import qutip as qt import numpy as np """ fredkin hadamard ancilla---------O---------H------------Measure f1---------X---------------------- f2---------X---------------------- """ up = qt.qstate('u') #qstate down is (1,0), qstate up is (0,1) down = qt.qstate('d') ancilla = 1 / np.sqrt(2) * (up + down) hadamard = qt.tensor(qt.snot(), qt.qeye(2), qt.qeye(2)) fredkin = qt.fredkin() #fredkin swapes f1 and f2 if ancilla = 1 #------------------------------------------------------------------------ #Define Input f1 = 1 / np.sqrt(2) * (up + down) f2 = up #------------------------------------------------------------------------ psi0 = qt.tensor(ancilla, f1, f2) output = hadamard * fredkin * psi0 measure = qt.tensor(down, f1, f2).dag() * output #if f1 = f2 the output is (down,f1,f2) #therefore measure is 1 if f1 = f2 #measure is 0.5 if f1, f2 are orthogonal print(measure)
def evolute(state): return qt.snot(N=3, target=0)*qt.cnot(N=3, control=0, target=1) * state
return H * W * H.dag() def generate_werner(F): a = qt.bell_state('00') a = a * a.dag() return F * a + (1 - F) / 4. * qt.qeye(4) Fi = .9 State_initial = generate_noisy_pair(Fi) State = qt.tensor(State_initial, State_initial) CNOT = qt.cnot(4, 0, 2) * qt.cnot(4, 3, 1) State = CNOT * State * CNOT.dag() H = qt.snot(4, 1) * qt.snot(4, 3) State = H * State * H.dag() m1, State_collapsed1 = operations.measure_single(State, 4, 2) m2, State_collapsed = operations.measure_single(State_collapsed1, 3, 2) print(m1, m2) State_final = qt.snot(2, 1) * State_collapsed * qt.snot(2, 1).dag() State_ref = qt.snot(2, 1) * qt.bell_state('00') State_ref = State_ref * State_ref.dag() # initial Fidelity F_initial = (State_ref * State_initial).tr() F_final = (State_ref * State_final).tr()
rho = dephasing_single_qubit(rho, deph[0], ii) # Append ancilla qubits and add depolarizing noise rho = qt.tensor(rho, plus, plus) for ii in range(4, 7): rho = depolarizing_single_qubit(rho, state_prep, ii) # CZ for parity check Z1Z2 rho = permute_matrix(1, 5, create_noisy_cz(E), rho) rho = permute_matrix(2, 5, create_noisy_cz(E), rho) # CZ for parity check Z3Z4 rho = permute_matrix(3, 6, create_noisy_cz(E), rho) rho = permute_matrix(4, 6, create_noisy_cz(E), rho) # Apply hadamards rho = apply_gate(rho, qt.snot(), [5, 6]) # Add time-dependent noise for t_2 for ii in range(1, 7): rho = amp_damping_single_qubit(rho, gamma[1], ii) rho = depolarizing_single_qubit(rho, depol[1], ii) rho = dephasing_single_qubit(rho, deph[1], ii) # Perform measurements and correction. Supply error parameters for # the time-dependent noise and projectors for the measurements list_of_rhos = measurement_and_correction(rho, proj, E, gamma[2], depol[2], deph[2]) # Create empty list of probabilities and fidelities list_of_probabilities = [] list_of_fidelities = []