attempt at 3qubits game

This commit is contained in:
Daniel Tsvetkov 2020-03-27 19:48:18 +01:00
parent 124edad8e3
commit 53f4c3e628
2 changed files with 152 additions and 80 deletions

136
10_krisi_3qubits_game.py Normal file
View File

@ -0,0 +1,136 @@
import random
from collections import defaultdict
import numpy as np
from lib import State, b_phi_p, b_phi_m, b_psi_p, b_psi_m, s, generate_bins
def test_krisi_measurement_2():
CASE_IDENTICAL = "identical"
CASE_ORTHOGONAL = "orthogonal"
def perform_exp(case):
# produce angles with uniform distribution on the sphere
t = round(np.random.uniform(0, 1), 10)
theta0 = np.arccos(1 - 2 * t)
phi0 = round(np.random.uniform(0, 2 * np.pi), 10)
# rotate the 0th qubit in (theta, phi)
q0 = State.from_bloch_angles(theta0, phi0)
# rotate the 1st qubit depending on the case we are exploring...
if case == CASE_IDENTICAL:
# ... for identical we are rotating the 1st qubit the same angles as
# the 0th
theta1, phi1 = theta0, phi0
else:
# for orthogonal we rotate the 1st qubit in 90 degrees
# orthogonal to the first
theta1, phi1 = theta0 + np.pi, phi0
q1 = State.from_bloch_angles(theta1, phi1)
# Measure in the Bell's basis
st = State(q0 * q1)
meas = st.measure(basis=[b_phi_p, b_phi_m, b_psi_p, b_psi_m])
return meas
correct = 0
cases = defaultdict(int)
results = defaultdict(int)
for i in range(1000):
case = random.choice([CASE_IDENTICAL, CASE_ORTHOGONAL])
cases[case] += 1
result = perform_exp(case=case)
results[result] += 1
if result == '11':
guess = CASE_ORTHOGONAL
assert guess == case
else:
guess = CASE_IDENTICAL
if guess == case:
correct += 1
print("Correct: {}".format(correct))
# print("Results: {}".format(results))
# print("Cases: {}".format(cases))
def test_krisi_measurement_3():
CASE_ID_ID = "id_id"
CASE_ID_ORT = "id_ort"
CASE_ORT_ID = "ort_id"
CASE_ORT_ORT = "ort_ort"
beta = 0
b_0 = State(1 / np.sqrt(2) * (s("|100>") - s("|010>")))
b_1 = State(1 / np.sqrt(2) * (s("|011>") - s("|101>")))
basis = [
s("|000>"),
State(np.cos(beta) * b_0 + np.sin(beta) * s("|001>")),
State(-np.sin(beta) * b_0 + np.cos(beta) * s("|001>")),
b_0,
b_1,
State(np.cos(beta) * b_1 + np.sin(beta) * s("|001>")),
State(-np.sin(beta) * b_1 + np.cos(beta) * s("|001>")),
s("|111>"),
]
def perform_exp(case):
# produce angles with uniform distribution on the sphere
t = round(np.random.uniform(0, 1), 10)
theta0 = np.arccos(1 - 2 * t)
phi0 = round(np.random.uniform(0, 2 * np.pi), 10)
# rotate the 0th qubit in (theta, phi)
q0 = State.from_bloch_angles(theta0, phi0)
# rotate the 1st qubit depending on the case we are exploring...
if case == CASE_ID_ID:
theta1, phi1 = theta0, phi0
theta2, phi2 = theta0, phi0
elif case == CASE_ID_ORT:
theta1, phi1 = theta0, phi0
theta2, phi2 = theta0 + np.pi, phi0
elif case == CASE_ORT_ID:
theta1, phi1 = theta0 + np.pi, phi0
theta2, phi2 = theta0, phi0
else:
# CASE_ORT_ORT
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)
# Measure in the arbitrary basis
st = State(q0 * q1 * q2)
meas = st.measure(basis=basis)
return meas
def krisi_3_format_results(results):
all_pos = generate_bins(8)
print("Results:")
for case, rv in results.items():
print("{}:".format(case))
print(" raw : {}".format(sorted(rv.items())))
case_total = sum(rv.values())
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))
results = defaultdict(lambda: defaultdict(int))
for i in range(1000):
case = random.choice([CASE_ID_ID, CASE_ID_ORT, CASE_ORT_ID, CASE_ORT_ORT])
result = perform_exp(case=case)
results[case][result] += 1
krisi_3_format_results(results)
if __name__ == "__main__":
# test_krisi_measurement_2()
test_krisi_measurement_3()

96
lib.py
View File

@ -2,7 +2,6 @@ import random
from collections import defaultdict
from functools import reduce
from numbers import Complex
from pprint import pprint
from typing import Union
import numpy as np
@ -273,7 +272,7 @@ class State(Vector):
def get_fmt_of_element(self):
return "{:0" + str(int(np.ceil(np.log2(len(self))))) + "b}"
def measure(self, basis=None):
def measure(self, basis=None, allow_empty=False):
"""
m_ops: a set of MeasurementOperators.
e.g. for computational basis, the m_ops is [|0><0|, |1><1|]
@ -310,10 +309,18 @@ class State(Vector):
prob = self.get_prob_from_measurement_op(m_op)
weights += [prob]
empty_prob = 1.0 - sum(weights)
empty_choices, empty_weights = [], []
if allow_empty == True:
empty_prob = 1.0 - sum(weights)
empty_weights = [empty_prob]
empty_choices = [REPR_EMPTY_SET]
else:
# normalize the weights
weights = list(np.array(weights) / sum(weights))
format_str = self.get_fmt_of_element()
choices = [REPR_EMPTY_SET] + [format_str.format(i) for i in range(len(weights))]
weights = [empty_prob] + weights
choices = empty_choices + [format_str.format(i) for i in range(len(weights))]
weights = empty_weights + weights
self.measurement_result = random.choices(choices, weights)[0]
return self.measurement_result
@ -1278,7 +1285,7 @@ def test_light():
for filter in filters:
st = filter.on(st)
st = State(st)
total_light[st.measure()] += 1
total_light[st.measure(allow_empty=True)] += 1
print("{}. {}:\n {}".format(id, human_state, dict(total_light)))
its = 100
@ -1295,83 +1302,12 @@ def test_light():
experiment(3, random_lights, [ver_filter, diag_filter, hor_filter])
def test_krisi_measurement_2():
from qiskit import (
QuantumCircuit,
execute,
Aer)
simulator = Aer.get_backend('qasm_simulator')
CASE_IDENTICAL = "identical"
CASE_ORTHOGONAL = "orthogonal"
def perform_exp(case):
# produce angles with uniform distribution on the sphere
t = round(np.random.uniform(0, 1), 10)
theta0 = np.arccos(1 - 2 * t)
phi0 = round(np.random.uniform(0, 2 * np.pi), 10)
# rotate the 0th qubit in (theta, phi)
q0 = State.from_bloch_angles(theta0, phi0)
# rotate the 1st qubit depending on the case we are exploring...
if case == CASE_IDENTICAL:
# ... for identical we are rotating the 1st qubit the same angles as
# the 0th
theta1, phi1 = theta0, phi0
else:
# for orthogonal we rotate the 1st qubit in 90 degrees
# orthogonal to the first
theta1, phi1 = theta0 + np.pi, phi0
q1 = State.from_bloch_angles(theta1, phi1)
# Measure in the Bell's basis
st = State(q0 * q1)
meas = st.measure(basis=[b_phi_p, b_phi_m, b_psi_p, b_psi_m])
return meas
correct = 0
cases = defaultdict(int)
results = defaultdict(int)
for i in range(1000):
case = random.choice([CASE_IDENTICAL, CASE_ORTHOGONAL])
cases[case] += 1
result = perform_exp(case=case)
results[result] += 1
if result == '11':
guess = CASE_ORTHOGONAL
assert guess == case
else:
guess = CASE_IDENTICAL
if guess == case:
correct += 1
print("Correct: {}".format(correct))
# print("Results: {}".format(results))
# print("Cases: {}".format(cases))
def test_krisi_measurement_3():
beta = 2.6
b_0 = State(1 / np.sqrt(2) * (s("|100>") - s("|010>")))
b_1 = State(1 / np.sqrt(2) * (s("|011>") - s("|101>")))
meas = s("|000>").measure(basis=[
s("|000>"),
State(np.cos(beta) * b_0 + np.sin(beta) * s("|001>")),
State(-np.sin(beta) * b_0 + np.cos(beta) * s("|001>")),
b_0,
b_1,
State(np.cos(beta) * b_1 + np.sin(beta) * s("|001>")),
State(-np.sin(beta) * b_1 + np.cos(beta) * s("|001>")),
s("|111>"),
])
print(meas)
def generate_bins(count):
format_str = "{:0" + str(int(np.ceil(np.log2(count)))) + "b}"
return [format_str.format(i) for i in range(count)]
if __name__ == "__main__":
test()
test_quantum_processor()
test_light()
test_krisi_measurement_2()
# TODO:
test_krisi_measurement_3()