update IQuBit and added getter

This commit is contained in:
Didictateur 2023-10-20 08:17:23 +02:00
parent d4208308bc
commit 7653379aec

View file

@ -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)
s = q[1].get_Mubit()