normalize state
This commit is contained in:
parent
67cd000f5a
commit
6ae883d818
@ -115,7 +115,8 @@ def test_krisi_measurement_3():
|
||||
# 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))
|
||||
meas = MeasurementOperator(P_s.m).on(q1q2_st)
|
||||
post_state = State(State.normalize(meas))
|
||||
|
||||
if case == CASE_ID_ID:
|
||||
assert post_state == q1q2_st
|
||||
@ -123,7 +124,7 @@ def test_krisi_measurement_3():
|
||||
assert post_state != q1q2_st
|
||||
|
||||
q3 = State.from_bloch_angles(theta2, phi2)
|
||||
meas = State(post_state * q3).measure(basis=basis)
|
||||
meas = State(State.normalize(post_state * q3)).measure(basis=basis)
|
||||
|
||||
# # TODO: This part measures the first two qubits in Bell basis, then:
|
||||
# # 1. constructs a new pure state
|
||||
|
10
grover.py
10
grover.py
@ -34,7 +34,7 @@ def classical_func_search_single_rv(func, input_range):
|
||||
return rv
|
||||
|
||||
|
||||
def _3sat_old(params):
|
||||
def _3sat(params):
|
||||
# 3-SAT from here: https://qiskit.org/textbook/ch-applications/satisfiability-grover.html
|
||||
x1, x2, x3 = params
|
||||
return (not x1 or not x2 or not x3) and \
|
||||
@ -43,7 +43,8 @@ def _3sat_old(params):
|
||||
(x1 or not x2 or not x3) and \
|
||||
(not x1 or x2 or x3)
|
||||
|
||||
def _3sat(params):
|
||||
|
||||
def _3sat_2(params):
|
||||
# 3-SAT from here: https://cstheory.stackexchange.com/questions/38538/oracle-construction-for-grovers-algorithm
|
||||
x1, x2, x3, x4 = params
|
||||
return (not x1 or not x3 or not x4) and \
|
||||
@ -52,9 +53,10 @@ def _3sat(params):
|
||||
(x1 or x3 or x4) and \
|
||||
(not x1 or x2 or not x3)
|
||||
|
||||
|
||||
def classical_3sat(func):
|
||||
# Generate all possible true/false tupples for the 3-sat problem
|
||||
input_range = list(itertools.product([True, False], repeat=4))
|
||||
# Generate all possible true/false tuples for the 3-sat problem
|
||||
input_range = list(itertools.product([True, False], repeat=3))
|
||||
random.shuffle(input_range)
|
||||
return classical_func_search_multi_rv(func, input_range)
|
||||
|
||||
|
66
lib.py
66
lib.py
@ -130,21 +130,32 @@ class Matrix(object):
|
||||
return str(self.m)
|
||||
|
||||
|
||||
MatrixOrList = Union[Matrix, ListOrNdarray]
|
||||
|
||||
|
||||
class HorizontalVector(Matrix):
|
||||
"""Horizontal vector is basically a list"""
|
||||
|
||||
def __init__(self, m: ListOrNdarray = None, *args, **kwargs):
|
||||
def __init__(self, m: MatrixOrList = None, *args, **kwargs):
|
||||
super().__init__(m, *args, **kwargs)
|
||||
if not self._is_vector():
|
||||
raise TypeError("Not a vector")
|
||||
if type(m) in [Matrix]:
|
||||
super().__init__(m.m, *args, **kwargs)
|
||||
else:
|
||||
super().__init__(m, *args, **kwargs)
|
||||
if not self._is_horizontal_vector():
|
||||
raise TypeError("Not a horizontal vector")
|
||||
|
||||
def _is_vector(self):
|
||||
def _is_horizontal_vector(self):
|
||||
return len(self.m.shape) == 1
|
||||
|
||||
|
||||
class Vector(Matrix):
|
||||
def __init__(self, m: ListOrNdarray = None, *args, **kwargs):
|
||||
def __init__(self, m: MatrixOrList = None, *args, **kwargs):
|
||||
super().__init__(m, *args, **kwargs)
|
||||
if type(m) in [Matrix]:
|
||||
super().__init__(m.m, *args, **kwargs)
|
||||
else:
|
||||
super().__init__(m, *args, **kwargs)
|
||||
if not self._is_vector():
|
||||
raise TypeError("Not a vector")
|
||||
|
||||
@ -152,13 +163,14 @@ class Vector(Matrix):
|
||||
return self.m.shape[1] == 1
|
||||
|
||||
|
||||
VectorOrList = Union[Vector, Matrix, ListOrNdarray]
|
||||
VectorOrList = Union[Vector, MatrixOrList]
|
||||
|
||||
|
||||
class State(Vector):
|
||||
def __init__(self, m: VectorOrList = None, name: str = '', *args, **kwargs):
|
||||
def __init__(self, m: VectorOrList = None, name: str = '',
|
||||
allow_unnormalized=False, *args, **kwargs):
|
||||
"""State vector representing quantum state"""
|
||||
if type(m) in [Vector, Matrix]:
|
||||
if type(m) in [Vector, Matrix, State]:
|
||||
super().__init__(m.m, *args, **kwargs)
|
||||
else:
|
||||
super().__init__(m, *args, **kwargs)
|
||||
@ -166,8 +178,18 @@ class State(Vector):
|
||||
self.measurement_result = None
|
||||
self.last_basis = None
|
||||
# TODO: SHOULD WE NORMALIZE?
|
||||
# if not self._is_normalized():
|
||||
# raise TypeError("Not a normalized state vector")
|
||||
if not allow_unnormalized and not self._is_normalized():
|
||||
raise TypeError("Not a normalized state vector")
|
||||
|
||||
@staticmethod
|
||||
def normalize(vector: Vector):
|
||||
"""Normalize a state by dividing by the square root of sum of the
|
||||
squares of states"""
|
||||
norm_coef = np.sqrt(np.sum(np.abs(vector.m ** 2)))
|
||||
if norm_coef == 0:
|
||||
raise TypeError("zero-sum vector")
|
||||
new_m = vector.m / norm_coef
|
||||
return State(new_m)
|
||||
|
||||
def _is_normalized(self):
|
||||
return np.isclose(np.sum(np.abs(self.m ** 2)), 1.0)
|
||||
@ -324,7 +346,7 @@ class State(Vector):
|
||||
weights += [prob]
|
||||
|
||||
empty_choices, empty_weights = [], []
|
||||
if allow_empty == True:
|
||||
if allow_empty:
|
||||
empty_prob = 1.0 - sum(weights)
|
||||
empty_weights = [empty_prob]
|
||||
empty_choices = [REPR_EMPTY_SET]
|
||||
@ -332,7 +354,7 @@ class State(Vector):
|
||||
# TODO: This may be wrong
|
||||
# normalize the weights
|
||||
weights = list(np.array(weights) / sum(weights))
|
||||
# assert np.isclose(sum(weights), 1.0)
|
||||
assert np.isclose(sum(weights), 1.0)
|
||||
|
||||
format_str = self.get_fmt_of_element()
|
||||
choices = empty_choices + [format_str.format(i) for i in
|
||||
@ -424,20 +446,6 @@ class Ket(State):
|
||||
State.__init__(self, *args, **kwargs)
|
||||
|
||||
|
||||
def test_measure_partial():
|
||||
state = b_phi_p
|
||||
state.measure_partial(1)
|
||||
|
||||
|
||||
def normalize_state(vector: Vector):
|
||||
"""Normalize a state by dividing by the square root of sum of the squares
|
||||
of states"""
|
||||
norm_coef = np.sqrt(np.sum(np.array(vector.m) ** 2))
|
||||
if norm_coef == 0:
|
||||
raise TypeError("zero-sum vector")
|
||||
return State(vector.m / norm_coef)
|
||||
|
||||
|
||||
def s(q, name=None):
|
||||
"""Helper method for creating state easily"""
|
||||
if type(q) == str:
|
||||
@ -741,7 +749,7 @@ Define States and Operators
|
||||
"""
|
||||
|
||||
# EMPTY STATE
|
||||
_E = State([[0],
|
||||
_E = Vector([[0],
|
||||
[0]],
|
||||
name=REPR_EMPTY_SET)
|
||||
|
||||
@ -1516,7 +1524,7 @@ def test_light():
|
||||
def random_light():
|
||||
random_pol = Vector(
|
||||
[[np.random.uniform(0, 1)], [np.random.uniform(0, 1)]])
|
||||
return normalize_state(random_pol)
|
||||
return State.normalize(random_pol)
|
||||
|
||||
def experiment(id, random_ls, filters):
|
||||
total_light = defaultdict(int)
|
||||
@ -1528,7 +1536,7 @@ def test_light():
|
||||
st = filters[0].on(r)
|
||||
for filter in filters:
|
||||
st = filter.on(st)
|
||||
st = State(st)
|
||||
st = State(st, allow_unnormalized=True)
|
||||
total_light[st.measure(allow_empty=True)] += 1
|
||||
print("{}. {}:\n {}".format(id, human_state, dict(total_light)))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user