trying to simulate 3 polarization filters with quantum computer
This commit is contained in:
parent
00274ae217
commit
5d43e985cb
@ -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):
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user