diff --git a/10_krisi_3qubits_game.py b/10_krisi_3qubits_game.py index 9f0912a..8e57fad 100644 --- a/10_krisi_3qubits_game.py +++ b/10_krisi_3qubits_game.py @@ -3,7 +3,7 @@ from collections import defaultdict import numpy as np -from lib import State, bell_basis, s, generate_bins +from lib import * def test_krisi_measurement_2(): @@ -87,7 +87,7 @@ def test_krisi_measurement_3(): phi0 = round(np.random.uniform(0, 2 * np.pi), 10) # rotate the 0th qubit in (theta, phi) - q0 = State.from_bloch_angles(theta0, phi0) + q1 = State.from_bloch_angles(theta0, phi0) # rotate the 1st qubit depending on the case we are exploring... if case == CASE_ID_ID: @@ -104,27 +104,45 @@ def test_krisi_measurement_3(): theta1, phi1 = theta0 + np.pi, phi0 theta2, phi2 = theta0 + np.pi, phi0 - q1 = State.from_bloch_angles(theta1, phi1) - q2 = State.from_bloch_angles(theta2, phi2) + q2 = State.from_bloch_angles(theta1, phi1) - # TODO: This part measures the first two qubits in Bell basis, then: - # 1. constructs a new pure state - # (e.g. if result was 11, constructs |11>) - # 2. Combines this new pure state with the third qubit - MEASURE_FIRST_BELL = False - if MEASURE_FIRST_BELL: - # Measure in the Bell's basis - st = State(q0 * q1) - meas = st.measure(basis=bell_basis) - new_st = s("|" + meas + ">") - st = State(new_st * q2) - else: - # TODO: -OR- alternatively - measure all three without measuring in - # Bell first - st = State(q0 * q1 * q2) + q1q2_st = State(q1*q2) + meas1 = q1q2_st.measure(basis=bell_basis) + if meas1 == '11': + return 'discarded' - # Measure in the 8D basis - meas = st.measure(basis=basis) + # TODO: + # P_minus = b_psi_m.x(b_psi_m) + P_s = b_psi_p.x(b_psi_p) + b_phi_m.x(b_phi_m) + b_phi_p.x(b_phi_p) + + post_state = State(MeasurementOperator(P_s.m).on(q1q2_st)) + + if case == CASE_ID_ID: + assert post_state == q1q2_st + elif case in [CASE_ORT_ID, CASE_ORT_ORT]: + assert post_state != q1q2_st + + q3 = State.from_bloch_angles(theta2, phi2) + meas = State(post_state * q3).measure(basis=basis) + + # # TODO: This part measures the first two qubits in Bell basis, then: + # # 1. constructs a new pure state + # # (e.g. if result was 11, constructs |11>) + # # 2. Combines this new pure state with the third qubit + # MEASURE_FIRST_BELL = False + # if MEASURE_FIRST_BELL: + # # Measure in the Bell's basis + # st = State(q1 * q2) + # meas = st.measure(basis=bell_basis) + # new_st = s("|" + meas + ">") + # st = State(new_st * q3) + # else: + # # TODO: -OR- alternatively - measure all three without measuring in + # # Bell first + # st = State(q1 * q2 * q3) + # + # # Measure in the 8D basis + # meas = st.measure(basis=basis) return meas def krisi_3_format_results(results): @@ -138,8 +156,8 @@ def test_krisi_measurement_3(): print(" total: {}".format(case_total)) for pos in all_pos: value = rv.get(pos, 0) - percent = value / case_total - print(" {} : {:3d} ({:.2f}%)".format(pos, value, percent)) + percent = (value / case_total)*100 + print(" {} : {:3d} ({:.1f}%)".format(pos, value, percent)) results = defaultdict(lambda: defaultdict(int)) for i in range(iterations): diff --git a/lib.py b/lib.py index 0f69938..875d333 100644 --- a/lib.py +++ b/lib.py @@ -279,7 +279,6 @@ class State(Vector): e.g. for computational basis, the m_ops is [|0><0|, |1><1|] Measures in the computational basis. Irreversable operation. Measuring again will result in the same result - TODO: Generalize the method so it takes a basis TODO: Should we memoize per basis? If it's measured twice, should it return the same state? What about if measured twice but in different bases? @@ -289,8 +288,8 @@ class State(Vector): measure4 -> +/- basis -> should it return B again or random weighted? :return: binary representation of the measured qubit (e.g. "011") """ - if self.measurement_result: - return self.measurement_result + # if self.measurement_result: + # return self.measurement_result weights, m_ops = [], [] if not basis: for j in range(len(self)): @@ -316,6 +315,7 @@ class State(Vector): empty_weights = [empty_prob] empty_choices = [REPR_EMPTY_SET] else: + # TODO: This may be wrong # normalize the weights weights = list(np.array(weights) / sum(weights))