def all_bell_states(self, q, ix): Gates.H(q, 0) if ix >= 2: Gates.X(q, 1) Gates.CNOT(q, 0, 1) if ix % 2 == 1: Gates.Z(q, 0)
def mZX(q, ix, iy): Gates.H(q, iy) Gates.CNOT(q, iy, ix) m = Measurement.measure(q, ix) Gates.CNOT(q, iy, ix) Gates.H(q, iy) print m, q
def mZZ(q, ix, iy): Gates.CNOT(q, iy, ix) print q m = Measurement.measure(q, ix) print m, q Gates.CNOT(q, iy, ix) print m, q
def controlled_x(self, q, rnd): Gates.Z(q, 0) if Measurement.rr_measurement(q, [PauliZ(), PauliX()], [0, 1], rnd) == -1: Gates.Z(q, 1) Gates.H(q, 1) Gates.Z(q, 0)
def bell_state(self, q, index): assert q.length == 2 Gates.H(q, 0) Gates.CNOT(q, 0, 1) if index % 2 == 1: Gates.Z(q, 1) if index >= 2: Gates.X(q, 1)
def test_103_check_plus_minus(self): q = Qubits(1) Gates.H(q, 0) assert self.check_plus_minus(q) == True q = Qubits(1) Gates.X(q, 0) Gates.H(q, 0) assert self.check_plus_minus(q) == False
def check_bell(self, q): Gates.CNOT(q, 0, 1) Gates.H(q, 0) m = Measurement.measure(q, 0) mm = Measurement.measure(q, 1) i = 0 if m == 1 else 1 ii = 0 if mm == 1 else 1 return i + 2 * ii
def check_state(self, q): Gates.H(q, 0) Gates.H(q, 1) m = Measurement.measure(q, 0) mm = Measurement.measure(q, 1) ii = 0 if m == 1 else 1 i = 0 if mm == 1 else 1 return i + 2 * ii
def oracle(self, qs): assert qs.length == (len(self.b) + 1), "incorrect qubit length" for ix, b in enumerate(self.b): if b: Gates.CNOT(qs, ix, qs.length - 1) else: Gates.X(qs, ix) Gates.CNOT(qs, ix, qs.length - 1) Gates.X(qs, ix)
def superposition_bitstrings(self, q, bits1, bits2): ix, bitsa, bitsb = self.__find_one_zero(bits1, bits2) Gates.H(q, ix) for ii in range(0, len(bits1)): if ix == ii: continue if bitsb[ii]: Gates.X(q, ii) Gates.CNOT(q, ix, ii) if bitsa[ii]: Gates.CNOT(q, ix, ii)
def check_bva(self, n, oracle): q = Qubits(n + 1) Gates.X(q, n) for ix in xrange(n + 1): Gates.H(q, ix) oracle(q) for ix in xrange(n): Gates.H(q, ix) r = [True] * n for ix in xrange(n): m = Measurement.measure(q, ix) if m == -1: Gates.X(q, ix) r[ix] = (m != 1) return r
def test_teleportation(self): q = Qubits(3) alice = 0 bob = 1 message = 2 Gates.H(q, message) # entangle alice with bob Gates.H(q, alice) Gates.CNOT(q, alice, bob) # entangle message with alice print Gates.CNOT(q, message, alice) print Gates.H(q, message) am = Measurement.measure(q, alice) mm = Measurement.measure(q, message) print am == -1, mm == -1, q
def test_phase_flip(self): q = Qubits(1) self.phase_flip(q) self.assert_signs(q, [(0, 1)]) Gates.X(q, 0) self.phase_flip(q) self.assert_signs(q, [(1, I)])
def test_add_CNOT_remove(self): q = Qubits.random_qubits(2) qq = q.clone() q.add_qubit() Gates.CNOT(q, 1, 0) q.remove_qubit() self.assert_qubits(q, qq)
def oracle(self, qs): assert qs.length == (len(self.b) + 1), "incorrect qubit length" assert self.called == False, "can only call oracle once" for ix, b in enumerate(self.b): if b: Gates.CNOT(qs, ix, qs.length - 1) self.called = True
def test_102_reset_qubit(self): q = Qubits(1) self.reset_qubit(q) self.assert_signs(q, [(0, 1)]) q = Qubits(1) Gates.X(q, 0) self.reset_qubit(q) self.assert_signs(q, [(0, 1)])
def test_phase_change(self): aaa = symbols('aaa') q = Qubits(1) self.phase_change(q, aaa) self.assert_signs(q, [(0, 1)]) Gates.X(q, 0) self.phase_change(q, aaa) self.assert_signs(q, [(1, exp(I * aaa))])
def test_fredkin_gate(self): q = Qubits(3) Gates.X(q, 0) Gates.X(q, 1) self.fredkin_gate(q) self.assert_signs(q, [(5, 1)]) q = Qubits(3) Gates.X(q, 0) Gates.X(q, 2) self.fredkin_gate(q) self.assert_signs(q, [(6, 1)]) for x in [True, False]: for y in [True, False]: for z in [True, False]: if x and (y ^ z): continue q = Qubits(3) if x: Gates.X(q, 0) if y: Gates.X(q, 1) if z: Gates.X(q, 2) self.fredkin_gate(q) self.assert_signs(q, q.monomials())
def test_amplitude_change(self): q = Qubits(1) self.amplitude_change(q, pi / 3) self.assert_signs(q, [(0, half), (1, half * sqrt(3))]) q = Qubits(1) Gates.X(q, 0) self.amplitude_change(q, pi / 3) self.assert_signs(q, [(0, -half * sqrt(3)), (1, half)])
def test_two_qubit_gate(self): q = Qubits(2) Gates().H(q, 0) self.two_qubit_gate(q) self.assert_signs(q, [(0, 1), (3, 1)]) q = Qubits(2) self.two_qubit_gate(q) self.assert_signs(q, [(0, 1)])
def test_toffoli_gate(self): for x in [True, False]: for y in [True, False]: for z in [True, False]: q = Qubits(3) m = 0 if x: Gates.X(q, 0) m = m + 4 if y: Gates.X(q, 1) m = m + 2 if z: Gates.X(q, 2) if x and y: if not z: m = m + 1 elif z: m = m + 1 self.toffoli_gate(q) self.assert_signs(q, [(m, 1)])
def test_two_qubit_gate_3(self): q = Qubits(2) # Assert that |01> -> |10> Gates.X(q, 1) self.two_qubit_gate_3(q) self.assert_signs(q, [(2, 1)]) # Assert that |10> -> |01> self.two_qubit_gate_3(q) self.assert_signs(q, [(1, 1)]) # Assert that |00> -> |00> q = Qubits(2) self.two_qubit_gate_3(q) self.assert_signs(q, [(0, 1)]) # Assert that |11> -> |11> Gates.X(q, 0) Gates.X(q, 1) self.assert_signs(q, [(3, 1)]) self.two_qubit_gate_3(q) self.assert_signs(q, [(3, 1)])
def check_state(self, q, rnd): l = q.length if l % 2 == 1: m = Measurement.rr_measure(q, l - 1, rnd) if m == -1: m = Measurement.measure(q, 0) if m == 1: return 1 if m == -1: return 0 return l = l - 1 for ix in xrange(1, l): Gates.CNOT(q, ix, 0) for ix in xrange(1, l): Gates.CNOT(q, 0, ix) # if l % 2 == 1: # Gates.H(q, 0) m = Measurement.measure(q, 0) if m == -1: return 1 else: return 0
def test_06_controlled_x(self): """// Task 6. Controlled X gate with |0⟩ target // Input: Two unentangled qubits (stored in an array of length 2). // The first qubit will be in state |ψ⟩ = α |0⟩ + β |1⟩, the second - in state |0⟩ // (this can be written as two-qubit state (α|0⟩ + β|1⟩) ⊕ |0⟩). // Goal: Change the two-qubit state to α |00⟩ + β |11⟩ using only single-qubit gates and joint measurements. // Do not use two-qubit gates. // You do not need to allocate extra qubits.""" for _ in range(20): for rnd in [0.1, 0.9]: a, b = self.random_unit_vector(2) q = Qubits.create(2, [(0, a), (2, b)]) qq = q.clone() Gates.CNOT(qq, 0, 1) self.controlled_x(q, rnd) self.assert_qubits(q, qq)
def w_state(self, q): Gates.X(q, 0) power = 1 while power < q.length: oldpower = power power = power * 2 Gates.H(q, power - 1) for ix in range(oldpower - 1): index = oldpower + ix Gates.CCNOT(q, ix, power - 1, index) Gates.CNOT(q, index, ix) Gates.CNOT(q, index, power - 1) Gates.CNOT(q, power - 1, oldpower - 1) return q
def controlled_x_general(self, q): # Gates.CNOT(q, 0, 1) items = [0.1, 0.9] r1, r2, r3 = choice(items), choice(items), choice(items) bad = [[0.1, 0.9, 0.9], [0.9, 0.9, 0.1]] if [r1, r2, r3] in bad: r1, r2, r3 = [0.1, 0.1, 0.1] print r1, r2, r3 q.add_qubit() #print "before measurement", q p1 = self.copy_qubit(q, 1, 0, r1) #print "after measurement", q Gates.H(q, 0) Gates.H(q, 2) p2 = Measurement.rr_measurement(q, [PauliZ(), PauliZ()], [0, 2], r2) Gates.H(q, 0) Gates.H(q, 2) if p2 == -1: Gates.Z(q, 1) if p1 != Measurement.rr_measurement(q, [PauliZ()], [0], r3): Gates.X(q, 2) #print "after CNOT", q q.remove_qubit()
def copy_qubit(self, q, source, target, r): Gates.H(q, target) return Measurement.rr_measurement(q, [PauliZ(), PauliZ()], [target, source], r)
def generate_superposition(self, qs): for ix in range(qs.length): Gates.H(qs, ix)
def ghz_state(self, q): l = q.length Gates.H(q, 0) for ix in xrange(1, l): Gates.CNOT(q, 0, ix)
def plus_minus_state(self, q, sign): assert q.length == 1 if sign < 0: Gates.X(q, 0) Gates.H(q, 0)