trying to simulate 3 polarization filters with quantum computer

This commit is contained in:
Daniel Tsvetkov 2020-02-04 17:43:09 +01:00
parent 00274ae217
commit 5d43e985cb
2 changed files with 58 additions and 23 deletions

View File

@ -29,7 +29,7 @@ def print_all_samples(name, all_samples):
print("==============================================")
def math_sim(q2func=State.from_angles, iterations=1000, sample_count=1):
def math_sim(q2func=State.from_bloch_angles, iterations=1000, sample_count=1):
all_samples = defaultdict(int)
for i in range(iterations):
# print("Running iteration {}".format(i))
@ -45,7 +45,7 @@ def math_sim(q2func=State.from_angles, iterations=1000, sample_count=1):
# print("theta: {:.2f} ({:.2f} deg) | phi: {:.2f} ({:.2f} deg)".format(
# theta, np.rad2deg(theta),
# phi, np.rad2deg(phi)))
q1 = State.from_angles(theta, phi)
q1 = State.from_bloch_angles(theta, phi)
q2 = q2func(theta, phi)
qc = QuantumCircuit(2, [[q1, q2], ])
@ -131,7 +131,7 @@ def cirq_sim(q1func, q2func, iterations=1000, sample_count=1):
def math_sim_0(*args, **kwargs):
math_sim(q2func=State.from_angles, *args, **kwargs)
math_sim(q2func=State.from_bloch_angles, *args, **kwargs)
def math_sim_1(*args, **kwargs):

View File

@ -155,16 +155,18 @@ class State(Vector):
return theta, phi
@classmethod
def from_angles(cls, theta, phi):
def from_bloch_angles(cls, theta, phi):
"""Creates a state from angles in Bloch sphere"""
theta, phi = cls._normalize_angles(theta, phi)
m0 = np.cos(theta / 2)
m1 = np.sin(theta / 2) * np.power(np.e, (1j * phi))
m = m0 * _0 + m1 * _1
return cls(m.m)
def to_angles(self):
def to_bloch_angles(self):
"""Returns the angles of this state on the Bloch sphere"""
if not self.m.shape == (2, 1):
raise Exception("State needs to be 2x1 matrix")
raise Exception("State needs to describe only 1 qubit on the bloch sphere (2x1 matrix)")
m0, m1 = self.m[0][0], self.m[1][0]
# theta is between 0 and pi
@ -303,23 +305,33 @@ class State(Vector):
return theta, phi
def get_bloch_coordinates(self):
theta, phi = self.to_angles()
theta, phi = self.to_bloch_angles()
x = np.sin(theta) * np.cos(phi)
y = np.sin(theta) * np.sin(phi)
z = np.cos(theta)
return [x, y, z]
def s(q):
def normalize_state(state_vector: ListOrNdarray):
"""Normalize a state by dividing by the square root of sum of the squares of states"""
norm_coef = np.sqrt(np.sum(np.array(state_vector) ** 2))
if norm_coef == 0:
raise TypeError("zero-sum vector")
return state_vector / norm_coef
def s(q, name=None):
"""Helper method for creating state easily"""
if type(q) == str:
# e.g. |000>
if q[0] == '|' and q[-1] == '>':
return State.from_string(q)
state = State.from_string(q)
state.name = name
return state
elif type(q) == list:
# e.g. s([1,0]) => |0>
return State(np.reshape(q, (len(q), 1)))
return State(q)
return State(np.reshape(q, (len(q), 1)), name=name)
return State(q, name=name)
def humanize_num(fl, tolerance=1e-3):
@ -714,13 +726,13 @@ def test_unitary_hermitian():
assert_raises(TypeError, "Not a Unitary matrix", UnitaryMatrix, not_u_not_h)
class MeasurementOpeartor(HermitianOperator):
class MeasurementOperator(HermitianOperator):
"""Measurement operators are Hermitians: <ψ|M†_m M_m|ψ>"""
@classmethod
def create_from_prob(cls, matrix: Matrix):
def create_from_prob(cls, matrix: Matrix, *args, **kwargs):
"""returns |M†_m><M_m|"""
return cls(matrix.conjugate_transpose().x(matrix).m)
return cls(matrix.conjugate_transpose().x(matrix).m, *args, **kwargs)
def get_prob(self, state: State):
"""Returns result of <ψ|M†_m M_m|ψ>
@ -732,8 +744,8 @@ class MeasurementOpeartor(HermitianOperator):
def test_measurement_ops():
m0 = MeasurementOpeartor.create_from_prob(Matrix([1, 0]))
m1 = MeasurementOpeartor.create_from_prob(Matrix([0, 1]))
m0 = MeasurementOperator.create_from_prob(Matrix([1, 0]))
m1 = MeasurementOperator.create_from_prob(Matrix([0, 1]))
assert m0 == Matrix([[1, 0],
[0, 0]])
assert m1 == Matrix([[0, 0],
@ -893,21 +905,21 @@ def test():
def test_to_from_angles():
for q in [_0, _1, _p, _m]:
angles = q.to_angles()
s = State.from_angles(*angles)
angles = q.to_bloch_angles()
s = State.from_bloch_angles(*angles)
assert q == s
assert State.from_angles(0, 0) == _0
assert State.from_angles(np.pi, 0) == _1
assert State.from_angles(np.pi / 2, 0) == _p
assert State.from_angles(np.pi / 2, np.pi) == _m
assert State.from_bloch_angles(0, 0) == _0
assert State.from_bloch_angles(np.pi, 0) == _1
assert State.from_bloch_angles(np.pi / 2, 0) == _p
assert State.from_bloch_angles(np.pi / 2, np.pi) == _m
for theta, phi, qbit in [
(0, 0, _0),
(np.pi, 0, _1),
(np.pi / 2, 0, _p),
(np.pi / 2, np.pi, _m),
]:
s = State.from_angles(theta, phi)
s = State.from_bloch_angles(theta, phi)
assert s == qbit
@ -1140,6 +1152,29 @@ def test_quantum_processor():
qp.print_sample(qp.get_sample(100))
def test_light():
global UNIVERSE_STATES
UNIVERSE_STATES = []
hor = s('|0>', name='')
ver = s('|1>', name='')
diag1 = hor + ver
diag1.name = '🡕'
hor_filter = MeasurementOperator.create_from_prob(Matrix(hor.m), name='h')
diag_filter = MeasurementOperator.create_from_prob(Matrix(diag1.m), name='d')
ver_filter = MeasurementOperator.create_from_prob(Matrix(ver.m), name='v')
for i in range(10):
random_pol = [[np.random.uniform(0, 1)], [np.random.uniform(0, 1)]]
random_light = State(normalize_state(random_pol))
qc = QuantumCircuit(1, initial_steps=[[random_light]])
qc.add_row([hor_filter, diag_filter, ver_filter])
qc.print()
qp = QuantumProcessor(qc)
# TODO: Dealing with non-normalized state vectors
qp.print_sample(qp.get_sample(100))
if __name__ == "__main__":
test()
test_quantum_processor()
# test_light()