From 7653379aec911f83f019eca8cff89ffbd0e1a506 Mon Sep 17 00:00:00 2001 From: Didictateur Date: Fri, 20 Oct 2023 08:17:23 +0200 Subject: [PATCH] update IQuBit and added getter --- QElephant/QuBit.py | 166 ++++++++++++++++++++++++++------------------- 1 file changed, 95 insertions(+), 71 deletions(-) diff --git a/QElephant/QuBit.py b/QElephant/QuBit.py index 7ea992d..ce791f3 100644 --- a/QElephant/QuBit.py +++ b/QElephant/QuBit.py @@ -5,32 +5,17 @@ from QElephant.Matrix import * I = complex(0, 1) -class QuBit: - def __init__(self, alpha: complex=1, beta: complex=0): - if abs(alpha)**2 + abs(beta)**2 != 1: - raise Exception("The initial state must be normalized") - self.__state = [alpha, beta] - - def __str__(self) -> str: - return f"{round(self.__state[0], 3)} |0> + {round(self.__state[1], 3)} |1>" - - def __apply(self, matrix: Matrix) -> None: - self.__state = matrix._Matrix__apply(self.__state) - - def observe(self) -> list[int]: - r = rd.random() - if r < abs(self.__state[0])**2: - self.__state = [1, 0] - return 0 - self.__state = [0, 1] - return 1 +## Classes class MuBit: def __init__(self, n: int) -> None: - self.n = n - self.__state: list[complex] = [0]*(2**self.n) + self.__n = n + self.__state: list[complex] = [0]*(2**self.__n) self.__state[0] = 1 + def get_size(self) -> int: + return self.__n + def __str__(self) -> str: def next(N: str) -> str: if N == "": @@ -41,8 +26,8 @@ class MuBit: return (next(N[:-1]))+"0" txt = "" - N = "0"*self.n - for i in range(2**self.n): + N = "0"*self.__n + for i in range(2**self.__n): txt += f"{round(self.__state[i], 3)} |{N}>\n" N = next(N) return txt @@ -52,7 +37,7 @@ class MuBit: assert(value in {0, 1}) M = Matrix([[1]]) - for j in range(self.n): + for j in range(self.__n): if j == i: M *= Matrix([[1-value, 0], [0, value]]) else: @@ -62,9 +47,9 @@ class MuBit: self.__state = [x/norm for x in self.__state] def __iter__(self): - return iter([IQuBit(i, self) for i in range(self.n)]) + return iter([IQuBit(i, self) for i in range(self.__n)]) - def __getitem__(self, item: int) -> "IQuBit": + def __getitem__(self, item: int) -> "QuBit": return IQuBit(item, self) def __apply(self, i: int, matrix: Matrix) -> None: @@ -81,7 +66,7 @@ class MuBit: def __mapply(self, matrix: Matrix, i: int) -> None: M = Matrix([[1]]) j = 0 - while j < self.n: + while j < self.__n: if j == i: M *= matrix j += 2 @@ -108,78 +93,123 @@ class MuBit: for i in range(self.n): l.append(IQuBit(i, self).observe()) return l - -class IQuBit: - def __init__(self, n: int, mb: MuBit) -> None: - self.n = n - self.__muBit = mb + +class QuBit: + def __init__(self, alpha: complex=1, beta: complex=0): + if abs(alpha)**2 + abs(beta)**2 != 1: + raise Exception("The initial state must be normalized") + self.__state = [alpha, beta] + self.__intricated = False + + def is_intricated(self) -> bool: + return self.__intricated + + def get_Mubit(self) -> None: + return None + + def __str__(self) -> str: + return f"{round(self.__state[0], 3)} |0> + {round(self.__state[1], 3)} |1>" def __apply(self, matrix: Matrix) -> None: - self.__muBit._MuBit__apply(self.n, matrix) + self.__state = matrix._Matrix__apply(self.__state) + + def observe(self) -> list[int]: + r = rd.random() + if r < abs(self.__state[0])**2: + self.__state = [1, 0] + return 0 + self.__state = [0, 1] + return 1 + +class IQuBit(QuBit): + def __init__(self, n: int, mb: MuBit) -> None: + super().__init__() + self.__n = n + self.__muBit = mb + self.__intricated = True + + def is_intricated(self) -> bool: + return self.__intricated + + def get_Mubit(self) -> tuple[MuBit, int]: + return (self.__muBit, self.__n) + + def __str__(self) -> str: + p = self.__muBit._MuBit__getProb(self.__n) + return str(QuBit(math.sqrt(p), math.sqrt(1-p))) + + def __apply(self, matrix: Matrix) -> None: + self.__muBit._MuBit__apply(self.__n, matrix) def observe(self) -> int: r = rd.random() - if r < self.__muBit._MuBit__getProb(self.n): - self.__muBit._MuBit__set(self.n, 0) + if r < self.__muBit._MuBit__getProb(self.__n): + self.__muBit._MuBit__set(self.__n, 0) return 0 - self.__muBit._MuBit__set(self.n, 1) + self.__muBit._MuBit__set(self.__n, 1) return 1 -def H(q: (QuBit | IQuBit)) -> None: - if type(q) == QuBit: - q._QuBit__apply(Matrix.H()) - elif type(q) == IQuBit: + + + + +## Fonctions + +def H(q: QuBit) -> None: + if type(q) == IQuBit: q._IQuBit__apply(Matrix.H()) + elif type(q) == QuBit: + q._QuBit__apply(Matrix.H()) -def X(q: (QuBit | IQuBit)) -> None: - if type(q) == QuBit: - q._QuBit__apply(Matrix.X()) - elif type(q) == IQuBit: +def X(q: QuBit) -> None: + if type(q) == IQuBit: q._IQuBit__apply(Matrix.X()) + elif type(q) == QuBit: + q._QuBit__apply(Matrix.X()) -def Y(q: (QuBit | IQuBit)) -> None: - if type(q) == QuBit: - q._QuBit__apply(Matrix.Y()) - elif type(q) == IQuBit: +def Y(q: QuBit) -> None: + if type(q) == IQuBit: q._IQuBit__apply(Matrix.Y()) + elif type(q) == QuBit: + q._QuBit__apply(Matrix.Y()) -def Z(q: (QuBit | IQuBit)) -> None: - if type(q) == QuBit: - q._QuBit__apply(Matrix.Z()) - elif type(q) == IQuBit: +def Z(q: QuBit) -> None: + if type(q) == IQuBit: q._IQuBit__apply(Matrix.Z()) + elif type(q) == QuBit: + q._QuBit__apply(Matrix.Z()) -def S(q: (QuBit | IQuBit)) -> None: - if type(q) == QuBit: - q._QuBit__apply(Matrix.S()) - elif type(q) == IQuBit: +def S(q: QuBit) -> None: + if type(q) == IQuBit: q._IQuBit__apply(Matrix.S()) + elif type(q) == QuBit: + q._QuBit__apply(Matrix.S()) -def T(q: (QuBit | IQuBit)) -> None: - if type(q) == QuBit: - q._QuBit__apply(Matrix.T()) - elif type(q) == IQuBit: +def T(q: QuBit) -> None: + if type(q) == IQuBit: q._IQuBit__apply(Matrix.T()) + elif type(q) == QuBit: + q._QuBit__apply(Matrix.T()) -def Rx(q: (QuBit | IQuBit), phi: float) -> None: +def Rx(q: QuBit, phi: float) -> None: if type(q) == QuBit: q._QuBit__apply(Matrix.Rx(phi)) elif type(q) == IQuBit: q._IQuBit__apply(Matrix.Rx(phi)) -def Ry(q: (QuBit | IQuBit), phi: float) -> None: +def Ry(q: QuBit, phi: float) -> None: if type(q) == QuBit: q._QuBit__apply(Matrix.Ry(phi)) elif type(q) == IQuBit: q._IQuBit__apply(Matrix.Ry(phi)) -def Rz(q: (QuBit | IQuBit), phi: float) -> None: +def Rz(q: QuBit, phi: float) -> None: if type(q) == QuBit: q._QuBit__apply(Matrix.Rz(phi)) elif type(q) == IQuBit: q._IQuBit__apply(Matrix.Rz(phi)) -def R1(q: (QuBit | IQuBit), phi: float) -> None: +def R1(q: QuBit, phi: float) -> None: if type(q) == QuBit: q._QuBit__apply(Matrix.R1(phi)) elif type(q) == IQuBit: @@ -217,10 +247,4 @@ def test(q: QuBit) -> None: if __name__=="__main__": q = MuBit(3) - H(q[0]) - # H(q[1]) - print(q) - - CNOT(q, 0, 1) - - print(q) \ No newline at end of file + s = q[1].get_Mubit() \ No newline at end of file