def test_104_check_a_b(self): for aaa in [pi / 6, pi / 3, pi, pi + pi / 3, pi + pi / 6]: q = Qubits.create(1, [(0, cos(aaa)), (1, sin(aaa))]) assert self.check_a_b(q, aaa) == True q = Qubits.create(1, [(0, -sin(aaa)), (1, cos(aaa))]) assert self.check_a_b(q, aaa) == False
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 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_07_controlled_x_general(self): for ix in range(20): a, b, c, d = self.random_unit_vector(4) q = Qubits.create(2, [(0, a), (1, b), (2, c), (3, d)]) target = Qubits.create(2, [(0, a), (1, b), (2, d), (3, c)]) print "before", q self.controlled_x_general(q) print "after", q self.assert_qubits(q, target)
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_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 s_state(self, ix): s = [ [half, -half, -half, -half], [-half, half, -half, -half], [-half, -half, half, -half], [-half, -half, -half, half], ] q = Qubits(2) v = Matrix(s[ix]) q.v = v return q
def test_basis_change(self): q = Qubits(1) self.basis_change(q) self.assert_signs(q, [(0, 1), (1, 1)]) self.basis_change(q) self.assert_signs(q, [(0, 1)]) q.v[0] = 0 q.v[1] = 1 self.basis_change(q) self.assert_signs(q, [(0, 1), (1, -1)]) self.basis_change(q) self.assert_signs(q, [(1, 1)])
def test_superposition(self): q = Qubits(5) self.superposition_bitstrings(q, [True, False, False, True, True], [True, True, False, False, True]) self.assert_signs(q, [(19, 1), (25, 1)]) q = Qubits(5) self.superposition_bitstrings(q, [False, False, False, True, True], [False, True, False, False, True]) self.assert_signs(q, [(3, 1), (9, 1)]) q = Qubits(1) self.superposition_bitstrings(q, [True], [False]) self.assert_signs(q, [(0, 1), (1, 1)])
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 test_superposition(self): for ix in range(1, 5): print "superposition for {0:d}".format(ix) qs = Qubits(ix) self.generate_superposition(qs) print qs self.assert_qubits(qs)
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_plus_minus_state(self): print("generating plus minus states") expectations = [[(0, 1), (1, 1)], [(0, 1), (1, -1)]] for exp, sign in zip(expectations, [1, -1]): q = Qubits(1) self.plus_minus_state(q, sign) self.assert_signs(q, exp) print("plus minus states solved")
def test_bva(self): bits = [True, True, False] oracle = OracleE2(bits).oracle value = self.check_bva(len(bits), oracle) voracle = OracleE2(value).oracle q = Qubits(len(bits) + 1) vv = voracle(q) bv = oracle(q) assert vv == bv, "incorrect returned bitstring" bits = [True, True, False, True] oracle = OracleE2(bits).oracle value = self.check_bva(len(bits), oracle) voracle = OracleE2(value).oracle q = Qubits(len(bits) + 1) vv = voracle(q) bv = oracle(q) assert vv == bv, "incorrect returned bitstring"
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_04_ghz_or_w_state(self): """// Task 4. |0..0⟩ + |1..1⟩ or W state ? // Input: An even number of qubits (stored in an array) which are guaranteed to be // either in superposition of states |0..0⟩ and |1..1⟩ // or in W state ( https://en.wikipedia.org/wiki/W_state ). // Output: 0 if qubits were in W state, // 1 if they were in the second superposition. // The state of the qubits at the end of the operation should be the same as the starting state.""" for ix in range(2, 8, 2): for tp in [0, 1]: if tp == 1: q = Qubits.w(ix) else: q = Qubits.ghz(ix) qq = q.clone() m = self.ghz_or_w_state(q) assert m == tp, "wrong superposition chosen" self.assert_qubits(q, qq)
def check_bva(self, n, oracle): q = Qubits(n + 1) oracle(q) m = Measurement.measure(q, n) v = 1 if m == -1 else 0 r = [True] * n if n % 2 != v: r[-1] = False return r
def test_check_state(self): for size in [3, 4]: for rnd in [0.1, 0.9]: q = Qubits.w(size) print("w{0:d} state for rnd = {1:f}".format(size, rnd)) assert self.check_state( q, rnd) == 1, "incorrect w{0:d} state for m = {1:f}".format( size, rnd) for size in [3, 4]: for rnd in [0.1, 0.9]: q = Qubits.ghz(size) print("ghz{0:d} state".format(size)) assert self.check_state( q, rnd) == 0, "incorrect w{0:d} state for m = {1:f}".format( size, rnd)
def test_ghz_states(self): print("testing ghz states") total = 5 expectations = map(lambda x: [(0, 1), (2**x - 1, 1)], xrange(1, total + 1)) for exp, ix in zip(expectations, xrange(1, total + 1)): q = Qubits(ix) self.ghz_state(q) print q print exp self.assert_signs(q, exp) print("ghz states equal")
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 test_bell_states(self): print("checking bell states") expectations = [ [(0, 1), (3, 1)], [(0, 1), (3, -1)], [(1, 1), (2, 1)], [(1, 1), (2, -1)], ] for ix, ex in enumerate(expectations): q = Qubits(2) self.bell_state(q, ix) self.assert_signs(q, ex) print("bell states equal")
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_10_superposition_bitstring(self): self.assert_qubits(self.superposition_bitstring(Qubits(1), [True]), self.plus_state(Qubits(1))) self.assert_qubits( self.superposition_bitstring(Qubits(2), [True, True]), self.bell_state(Qubits(2))) self.assert_qubits( self.superposition_bitstring(Qubits(3), [True, True, True]), self.ghz_state(Qubits(3))) q = Qubits(2) b = [True, False] self.assert_signs(self.superposition_bitstring(q, b), [(0, 1), (2, 1)]) q = Qubits(3) b = [True, False, True] self.assert_signs(self.superposition_bitstring(q, b), [(0, 1), (5, 1)]) q = Qubits(6) b = [True, False, True, True, False, False] self.assert_signs(self.superposition_bitstring(q, b), [(0, 1), (44, 1)])
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 test_05_different_basis(self): """// Task 5. Parity measurement in different basis // Input: Two qubits (stored in an array) which are guaranteed to be // either in superposition α|00⟩ + β|01⟩ + β|10⟩ + α|11⟩ // or in superposition α|00⟩ - β|01⟩ + β|10⟩ - α|11⟩. // Output: 0 if qubits were in the first superposition, // 1 if they were in the second superposition. // The state of the qubits at the end of the operation should be the same as the starting state.""" for _ in range(10): for mul in [1, -1]: a, b = self.random_unit_vector(2) a = a / sqrt(2.0) b = b / sqrt(2.0) q = Qubits.create(2, [(0, a), (1, mul * b), (2, b), (3, mul * a)]) qq = q.clone() d = self.different_basis(q) self.assert_qubits(q, qq) expected = 0 if mul == 1 else 1 assert d == expected
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_add_remove(self): q = Qubits.random_qubits(2) qq = q.clone() q.add_qubit() q.remove_qubit() self.assert_qubits(q, qq)
def test_check_bell(self): for ix in xrange(4): q = Qubits.bell(ix) assert self.check_bell(q) == ix, "incorrect for {0:d}".format(ix)