Projective measurements with hermitians
This commit is contained in:
parent
8811e7b8e3
commit
71d3e13030
@ -236,6 +236,14 @@ class State(Vector):
|
|||||||
choices = [format_str.format(i) for i in range(len(weights))]
|
choices = [format_str.format(i) for i in range(len(weights))]
|
||||||
return random.choices(choices, weights)[0]
|
return random.choices(choices, weights)[0]
|
||||||
|
|
||||||
|
def measure_with_op(self, mo):
|
||||||
|
"""
|
||||||
|
Measures with a measurement operator mo
|
||||||
|
TODO: Can't define mo: MeasurementOperator because in python you can't declare classes before defining them
|
||||||
|
"""
|
||||||
|
m = mo.on(self) / np.sqrt(mo.get_prob(self))
|
||||||
|
return State(m)
|
||||||
|
|
||||||
def measure_n(self, n=1):
|
def measure_n(self, n=1):
|
||||||
"""measures n times"""
|
"""measures n times"""
|
||||||
measurements = defaultdict(int)
|
measurements = defaultdict(int)
|
||||||
@ -402,6 +410,24 @@ class UnitaryOperator(LinearOperator, UnitaryMatrix):
|
|||||||
return str(self.m)
|
return str(self.m)
|
||||||
|
|
||||||
|
|
||||||
|
class HermitianOperator(LinearOperator, HermitianMatrix):
|
||||||
|
def __init__(self, m: ListOrNdarray, name: str = '', *args, **kwargs):
|
||||||
|
"""HermitianMatrix inherits from both LinearOperator and a Hermitian matrix
|
||||||
|
It is used to act on a State vector by defining the operator to be the dot product"""
|
||||||
|
self.name = name
|
||||||
|
HermitianMatrix.__init__(self, m=m, *args, **kwargs)
|
||||||
|
LinearOperator.__init__(self, func=self.operator_func, *args, **kwargs)
|
||||||
|
|
||||||
|
def operator_func(self, other):
|
||||||
|
"""This might not return a normalized state vector so don't wrap it in State"""
|
||||||
|
return np.dot(self.m, other.m)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
if self.name:
|
||||||
|
return '-{}-'.format(self.name)
|
||||||
|
return str(self.m)
|
||||||
|
|
||||||
|
|
||||||
# TODO - How to add a CNOT gate to the Quantum Processor?
|
# TODO - How to add a CNOT gate to the Quantum Processor?
|
||||||
# Imagine if I have to act on a 3-qubit computer and CNOT(q1, q3)
|
# Imagine if I have to act on a 3-qubit computer and CNOT(q1, q3)
|
||||||
#
|
#
|
||||||
@ -597,8 +623,8 @@ def assert_not_raises(exception, msg, callable, *args, **kwargs):
|
|||||||
def test_unitary_hermitian():
|
def test_unitary_hermitian():
|
||||||
# Unitary is UU+ = I; Hermitian is U = U+
|
# Unitary is UU+ = I; Hermitian is U = U+
|
||||||
# Matrixes could be either, neither or both
|
# Matrixes could be either, neither or both
|
||||||
# Quantum operators are described *only* by unitary transformations
|
# Quantum operators (gates) are described *only* by unitary transformations
|
||||||
# TODO: What are Hermitians?
|
# Hermitian operators are used for measurement operators - https://towardsdatascience.com/understanding-basics-of-measurements-in-quantum-computation-4c885879eba0
|
||||||
h_not_u = [
|
h_not_u = [
|
||||||
[1, 0],
|
[1, 0],
|
||||||
[0, 2],
|
[0, 2],
|
||||||
@ -628,6 +654,40 @@ def test_unitary_hermitian():
|
|||||||
assert_raises(TypeError, "Not a Unitary matrix", UnitaryMatrix, not_u_not_h)
|
assert_raises(TypeError, "Not a Unitary matrix", UnitaryMatrix, not_u_not_h)
|
||||||
|
|
||||||
|
|
||||||
|
class MeasurementOpeartor(HermitianOperator):
|
||||||
|
"""Measurement operators are Hermitians: <ψ|M†_m M_m|ψ>"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_from_prob(cls, matrix: Matrix):
|
||||||
|
"""returns |M†_m><M_m|"""
|
||||||
|
return cls(matrix.conjugate_transpose().x(matrix).m)
|
||||||
|
|
||||||
|
def get_prob(self, state: State):
|
||||||
|
state_ct = state.conjugate_transpose()
|
||||||
|
return np.asscalar(state_ct.m.dot(self.m.dot(state.m)))
|
||||||
|
|
||||||
|
|
||||||
|
def test_measurement_ops():
|
||||||
|
m0 = MeasurementOpeartor.create_from_prob(Matrix([1, 0]))
|
||||||
|
m1 = MeasurementOpeartor.create_from_prob(Matrix([0, 1]))
|
||||||
|
assert m0 == Matrix([[1, 0],
|
||||||
|
[0, 0]])
|
||||||
|
assert m1 == Matrix([[0, 0],
|
||||||
|
[0, 1]])
|
||||||
|
|
||||||
|
# p(0) -> probability of measurement to yield a 0
|
||||||
|
assert m0.get_prob(_0) == 1.0
|
||||||
|
assert m1.get_prob(_0) == 0.0
|
||||||
|
assert m0.get_prob(_1) == 0.0
|
||||||
|
assert m1.get_prob(_1) == 1.0
|
||||||
|
|
||||||
|
# Post-state measurement of qubit with operator
|
||||||
|
assert _p.measure_with_op(m0) == _0
|
||||||
|
assert _p.measure_with_op(m1) == _1
|
||||||
|
assert _m.measure_with_op(m0) == _0
|
||||||
|
assert _m.measure_with_op(m1) == s([0, -1])
|
||||||
|
|
||||||
|
|
||||||
def abs_squared(x):
|
def abs_squared(x):
|
||||||
return np.abs(x) ** 2
|
return np.abs(x) ** 2
|
||||||
|
|
||||||
@ -703,6 +763,9 @@ def test():
|
|||||||
assert np.isclose(_p.get_prob(0), 0.5) # Probability for |+> in 0 is 0.5
|
assert np.isclose(_p.get_prob(0), 0.5) # Probability for |+> in 0 is 0.5
|
||||||
assert np.isclose(_p.get_prob(1), 0.5) # Probability for |+> in 1 is 0.5
|
assert np.isclose(_p.get_prob(1), 0.5) # Probability for |+> in 1 is 0.5
|
||||||
|
|
||||||
|
# Test measurement operators
|
||||||
|
test_measurement_ops()
|
||||||
|
|
||||||
# IV: Compositing | The state space of a composite physical system
|
# IV: Compositing | The state space of a composite physical system
|
||||||
# is the tensor product of the state spaces
|
# is the tensor product of the state spaces
|
||||||
# of the component physical systems.
|
# of the component physical systems.
|
||||||
|
@ -9,7 +9,7 @@ cryptography==2.8
|
|||||||
cvxopt==1.2.4
|
cvxopt==1.2.4
|
||||||
cycler==0.10.0
|
cycler==0.10.0
|
||||||
Cython==0.29.14
|
Cython==0.29.14
|
||||||
dataclasses==0.7
|
dataclasses==0.6
|
||||||
decorator==4.4.0
|
decorator==4.4.0
|
||||||
dill==0.3.1.1
|
dill==0.3.1.1
|
||||||
dlx==1.0.4
|
dlx==1.0.4
|
||||||
|
Loading…
Reference in New Issue
Block a user