diff --git a/lib_q_computer_math.py b/lib_q_computer_math.py index adb546f..72c90ca 100644 --- a/lib_q_computer_math.py +++ b/lib_q_computer_math.py @@ -14,9 +14,20 @@ from load_test import sizeof_fmt 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): - """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): """ @@ -39,7 +50,7 @@ class Matrix(object): def __eq__(self, other): if isinstance(other, Complex): return bool(np.allclose(self.m, other)) - elif isinstance(other, TwoQubitGate): + elif isinstance(other, TwoQubitPartial): return False return np.allclose(self.m, other.m) @@ -99,7 +110,7 @@ class Matrix(object): class Vector(Matrix): def __init__(self, m: ListOrNdarray = None, *args, **kwargs): - super().__init__(m) + super().__init__(m, *args, **kwargs) if not self._is_vector(): raise TypeError("Not a vector") @@ -110,7 +121,7 @@ class Vector(Matrix): class State(Vector): def __init__(self, m: ListOrNdarray = None, name: str = '', *args, **kwargs): """State vector representing quantum state""" - super().__init__(m) + super().__init__(m, *args, **kwargs) self.name = name if not self._is_normalized(): raise TypeError("Not a normalized state vector") @@ -121,7 +132,16 @@ class State(Vector): def __repr__(self): if 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): """Norm/Length of the vector = sqrt()""" @@ -240,6 +260,16 @@ _1 = State([[0], [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], [0, 1]], 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) # _0.x(_0) * Matrix(I.m) + _1.x(_1) * Matrix(X.m) -class TwoQubitGate(object): +class TwoQubitPartial(object): def __init__(self, rpr): self.rpr = rpr self.operator = None @@ -287,12 +317,12 @@ class TwoQubitGate(object): return str("-{}-".format(self.rpr)) -C_ = TwoQubitGate("C") -x_ = TwoQubitGate("x") +C_ = TwoQubitPartial("C") +x_ = TwoQubitPartial("x") 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): super().__init__(m, *args, **kwargs) A.operator, B.operator = self, self @@ -327,8 +357,8 @@ CNOT = TwoQubitOperator([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0], ], - TwoQubitGate("C"), - TwoQubitGate("x"), + TwoQubitPartial("C"), + TwoQubitPartial("x"), I, X) @@ -340,8 +370,6 @@ C, x = CNOT.A, CNOT.B def test(): - _p = State([[1 / np.sqrt(2)], [1 / np.sqrt(2)]], name='+') - # Test properties of Hilbert vector space # The four postulates of Quantum Mechanics # I: States | Associated to any physical system is a complex vector space @@ -526,8 +554,8 @@ class QuantumProcessor(object): self.add_row(row_data) def compose_quantum_state(self, step): - if any([type(s) is TwoQubitGate for s in step]): - two_qubit_gates = filter(lambda s: type(s) is TwoQubitGate, step) + if any([type(s) is TwoQubitPartial for s in step]): + two_qubit_gates = filter(lambda s: type(s) is TwoQubitPartial, step) state = [] for two_qubit_gate in two_qubit_gates: two_qubit_gate.operator.verify_step(step)