def test_superposition(self): x = qc.positive_superposition() y1 = (qc.zeros() + qc.ones()) / np.sqrt(2) y2 = (qc.zeros() + qc.ones()) * (1 / np.sqrt(2)) y3 = (1 / np.sqrt(2)) * (qc.ones() + qc.zeros()) y4 = (1 / np.sqrt(2)) * qc.ones() + qc.zeros() / np.sqrt(2) self.assertLess(max_absolute_difference(y1, x), epsilon) self.assertLess(max_absolute_difference(y2, x), epsilon) self.assertLess(max_absolute_difference(y3, x), epsilon) self.assertLess(max_absolute_difference(y4, x), epsilon) self.assertLess( max_absolute_difference(np.sqrt(2) * x - qc.ones(), qc.zeros()), epsilon)
def quantum_parallelism(f): U_f = qc.U_f(f, d=2) H = qc.Hadamard() phi = qc.zeros(2) phi = H(phi, qubit_indices=[0]) phi = U_f(phi)
def deutsch_algorithm(f): U_f = qc.U_f(f, d=2) H = qc.Hadamard() phi = H(qc.zeros()) * H(qc.ones()) phi = U_f(phi) phi = H(phi, qubit_indices=[0]) measurement = phi.measure(qubit_indices=0) return measurement
def deutsch_jozsa_algorithm(d, f): # The operators we will need U_f = qc.U_f(f, d=d + 1) H_d = qc.Hadamard(d) H = qc.Hadamard() state = qc.zeros(d) * qc.ones(1) state = (H_d * H)(state) state = U_f(state) state = H_d(state, qubit_indices=range(d)) measurements = state.measure(qubit_indices=range(d)) return measurements
def test_U_f_basis_measurement(self): num_tests = 10 for test_i in range(num_tests): d = np.random.randint(1, 8) f = random_boolean_function(d) U = qc.U_f(f, d=d+1) bits = tuple(np.random.choice([0, 1], size=d, replace=True)) input_qubits = qc.bitstring(*bits) ans_qubit = qc.zeros() state = input_qubits * ans_qubit state = U(state) answer = f(*bits) measured_ans = state.measure(qubit_indices=d) self.assertEqual(answer, measured_ans)
def phase_estimation(d=2, t=8): # a d-qubit gate U = unitary_group.rvs(2**d) eigvals, eigvecs = np.linalg.eig(U) U = qc.Operator.from_matrix(U) # an eigenvector u and the phase of its eigenvalue, phi phi = np.real(np.log(eigvals[0]) / (2j * np.pi)) if phi < 0: phi += 1 u = eigvecs[:, 0] u = qc.State.from_column_vector(u) # add the t-qubit register state = qc.zeros(t) * u state = stage_1(state, U, t, d) state = inv_QFT(t)(state, qubit_indices=range(t)) measurement = state.measure(qubit_indices=range(t)) phi_estimate = sum(measurement[i] * 2**(-i - 1) for i in range(t)) return phi, phi_estimate
def grover_algorithm(d, f): # The operators we will need Oracle = qc.U_f(f, d=d+1) H_d = qc.Hadamard(d) H = qc.Hadamard() N = 2**d zero_projector = np.zeros((N, N)) zero_projector[0, 0] = 1 Inversion = H_d((2 * qc.Operator.from_matrix(zero_projector) - qc.Identity(d))(H_d)) Grover = Inversion(Oracle, qubit_indices=range(d)) # Initial state state = qc.zeros(d) * qc.ones(1) state = (H_d * H)(state) # Number of Grover iterations angle_to_rotate = np.arccos(np.sqrt(1 / N)) rotation_angle = 2 * np.arcsin(np.sqrt(1 / N)) iterations = int(round(angle_to_rotate / rotation_angle)) for i in range(iterations): state = Grover(state) measurements = state.measure(qubit_indices=range(d)) return measurements