repr for q state

This commit is contained in:
Daniel Tsvetkov 2019-12-18 12:53:05 +01:00
parent d0d4156f5f
commit fae34da41a

View File

@ -14,9 +14,20 @@ from load_test import sizeof_fmt
ListOrNdarray = Union[list, np.ndarray] ListOrNdarray = Union[list, np.ndarray]
REPR_TENSOR_OP = ""
REPR_GREEK_PSI = "ψ"
REPR_GREEK_PHI = "φ"
REPR_MATH_KET = ""
REPR_MATH_BRA = ""
REPR_MATH_SQRT = ""
REPR_MATH_SUBSCRIPT_NUMBERS = "₀₁₂₃₄₅₆₇₈₉"
# Keep a reference to already used states for naming
UNIVERSE_STATES = []
class Matrix(object): class Matrix(object):
"""Represents a quantum state as a vector in Hilbert space""" """Wraps a Matrix... it's for my understanding, this could easily probably be np.array"""
def __init__(self, m: ListOrNdarray = None, *args, **kwargs): def __init__(self, m: ListOrNdarray = None, *args, **kwargs):
""" """
@ -39,7 +50,7 @@ class Matrix(object):
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, Complex): if isinstance(other, Complex):
return bool(np.allclose(self.m, other)) return bool(np.allclose(self.m, other))
elif isinstance(other, TwoQubitGate): elif isinstance(other, TwoQubitPartial):
return False return False
return np.allclose(self.m, other.m) return np.allclose(self.m, other.m)
@ -99,7 +110,7 @@ class Matrix(object):
class Vector(Matrix): class Vector(Matrix):
def __init__(self, m: ListOrNdarray = None, *args, **kwargs): def __init__(self, m: ListOrNdarray = None, *args, **kwargs):
super().__init__(m) super().__init__(m, *args, **kwargs)
if not self._is_vector(): if not self._is_vector():
raise TypeError("Not a vector") raise TypeError("Not a vector")
@ -110,7 +121,7 @@ class Vector(Matrix):
class State(Vector): class State(Vector):
def __init__(self, m: ListOrNdarray = None, name: str = '', *args, **kwargs): def __init__(self, m: ListOrNdarray = None, name: str = '', *args, **kwargs):
"""State vector representing quantum state""" """State vector representing quantum state"""
super().__init__(m) super().__init__(m, *args, **kwargs)
self.name = name self.name = name
if not self._is_normalized(): if not self._is_normalized():
raise TypeError("Not a normalized state vector") raise TypeError("Not a normalized state vector")
@ -121,7 +132,16 @@ class State(Vector):
def __repr__(self): def __repr__(self):
if self.name: if self.name:
return '|{}>'.format(self.name) return '|{}>'.format(self.name)
return str(self.m) for well_known_state in well_known_states:
if self == well_known_state:
return repr(well_known_state)
for used_state in UNIVERSE_STATES:
if self.m == used_state:
return repr(used_state)
next_state_sub = ''.join([REPR_MATH_SUBSCRIPT_NUMBERS[int(d)] for d in str(len(UNIVERSE_STATES))])
state_name = '|{}{}>'.format(REPR_GREEK_PSI, next_state_sub)
UNIVERSE_STATES.append(self.m)
return state_name
def norm(self): def norm(self):
"""Norm/Length of the vector = sqrt(<self|self>)""" """Norm/Length of the vector = sqrt(<self|self>)"""
@ -240,6 +260,16 @@ _1 = State([[0],
[1]], [1]],
name='1') name='1')
_p = State([[1 / np.sqrt(2)],
[1 / np.sqrt(2)]],
name='+')
_m = State([[1 / np.sqrt(2)],
[- 1 / np.sqrt(2)]],
name='-')
well_known_states = [_0, _1, _p, _m]
_ = I = UnitaryOperator([[1, 0], _ = I = UnitaryOperator([[1, 0],
[0, 1]], [0, 1]],
name="-") name="-")
@ -278,7 +308,7 @@ H = UnitaryOperator([[1 / np.sqrt(2), 1 / np.sqrt(2)],
# np.kron(np.outer(_0.m, _0.m), np.eye(2)) + np.kron(np.outer(_1.m, _1.m), X.m) # np.kron(np.outer(_0.m, _0.m), np.eye(2)) + np.kron(np.outer(_1.m, _1.m), X.m)
# _0.x(_0) * Matrix(I.m) + _1.x(_1) * Matrix(X.m) # _0.x(_0) * Matrix(I.m) + _1.x(_1) * Matrix(X.m)
class TwoQubitGate(object): class TwoQubitPartial(object):
def __init__(self, rpr): def __init__(self, rpr):
self.rpr = rpr self.rpr = rpr
self.operator = None self.operator = None
@ -287,12 +317,12 @@ class TwoQubitGate(object):
return str("-{}-".format(self.rpr)) return str("-{}-".format(self.rpr))
C_ = TwoQubitGate("C") C_ = TwoQubitPartial("C")
x_ = TwoQubitGate("x") x_ = TwoQubitPartial("x")
class TwoQubitOperator(UnitaryOperator): class TwoQubitOperator(UnitaryOperator):
def __init__(self, m: ListOrNdarray, A: TwoQubitGate, B: TwoQubitGate, def __init__(self, m: ListOrNdarray, A: TwoQubitPartial, B: TwoQubitPartial,
A_p: UnitaryOperator, B_p:UnitaryOperator, *args, **kwargs): A_p: UnitaryOperator, B_p:UnitaryOperator, *args, **kwargs):
super().__init__(m, *args, **kwargs) super().__init__(m, *args, **kwargs)
A.operator, B.operator = self, self A.operator, B.operator = self, self
@ -327,8 +357,8 @@ CNOT = TwoQubitOperator([[1, 0, 0, 0],
[0, 1, 0, 0], [0, 1, 0, 0],
[0, 0, 0, 1], [0, 0, 0, 1],
[0, 0, 1, 0], ], [0, 0, 1, 0], ],
TwoQubitGate("C"), TwoQubitPartial("C"),
TwoQubitGate("x"), TwoQubitPartial("x"),
I, I,
X) X)
@ -340,8 +370,6 @@ C, x = CNOT.A, CNOT.B
def test(): def test():
_p = State([[1 / np.sqrt(2)], [1 / np.sqrt(2)]], name='+')
# Test properties of Hilbert vector space # Test properties of Hilbert vector space
# The four postulates of Quantum Mechanics # The four postulates of Quantum Mechanics
# I: States | Associated to any physical system is a complex vector space # I: States | Associated to any physical system is a complex vector space
@ -526,8 +554,8 @@ class QuantumProcessor(object):
self.add_row(row_data) self.add_row(row_data)
def compose_quantum_state(self, step): def compose_quantum_state(self, step):
if any([type(s) is TwoQubitGate for s in step]): if any([type(s) is TwoQubitPartial for s in step]):
two_qubit_gates = filter(lambda s: type(s) is TwoQubitGate, step) two_qubit_gates = filter(lambda s: type(s) is TwoQubitPartial, step)
state = [] state = []
for two_qubit_gate in two_qubit_gates: for two_qubit_gate in two_qubit_gates:
two_qubit_gate.operator.verify_step(step) two_qubit_gate.operator.verify_step(step)