From 71d3e130304c50ed41e7f367a10f7acfd00ed1ca Mon Sep 17 00:00:00 2001 From: Daniel Tsvetkov Date: Mon, 3 Feb 2020 14:22:42 +0100 Subject: [PATCH] Projective measurements with hermitians --- lib_q_computer_math.py | 67 ++++++++++++++++++++++++++++++++++++++++-- requirements.txt | 2 +- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/lib_q_computer_math.py b/lib_q_computer_math.py index 16b2847..034bf30 100644 --- a/lib_q_computer_math.py +++ b/lib_q_computer_math.py @@ -236,6 +236,14 @@ class State(Vector): choices = [format_str.format(i) for i in range(len(weights))] 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): """measures n times""" measurements = defaultdict(int) @@ -402,6 +410,24 @@ class UnitaryOperator(LinearOperator, UnitaryMatrix): 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? # 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(): # Unitary is UU+ = I; Hermitian is U = U+ # Matrixes could be either, neither or both - # Quantum operators are described *only* by unitary transformations - # TODO: What are Hermitians? + # Quantum operators (gates) are described *only* by unitary transformations + # Hermitian operators are used for measurement operators - https://towardsdatascience.com/understanding-basics-of-measurements-in-quantum-computation-4c885879eba0 h_not_u = [ [1, 0], [0, 2], @@ -628,6 +654,40 @@ def test_unitary_hermitian(): 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> 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): 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(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 # is the tensor product of the state spaces # of the component physical systems. diff --git a/requirements.txt b/requirements.txt index c014b97..366f029 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,7 +9,7 @@ cryptography==2.8 cvxopt==1.2.4 cycler==0.10.0 Cython==0.29.14 -dataclasses==0.7 +dataclasses==0.6 decorator==4.4.0 dill==0.3.1.1 dlx==1.0.4