begin exceptions
This commit is contained in:
parent
af11de0c6a
commit
ab1dbcf7cb
4 changed files with 118 additions and 5 deletions
|
|
@ -9,6 +9,11 @@ I = complex(0, 1)
|
||||||
|
|
||||||
class MuBit:
|
class MuBit:
|
||||||
def __init__(self, n: int=2) -> None:
|
def __init__(self, n: int=2) -> None:
|
||||||
|
if type(n) is not int:
|
||||||
|
raise TypeError(f"number of state must be an intergers, not {type(n)}")
|
||||||
|
if not n >= 2:
|
||||||
|
raise ValueError("a MuBit must have at least two intricated QuBit")
|
||||||
|
|
||||||
self.__n = n
|
self.__n = n
|
||||||
self.__state: list[complex] = [0]*(2**self.__n)
|
self.__state: list[complex] = [0]*(2**self.__n)
|
||||||
self.__state[0] = 1
|
self.__state[0] = 1
|
||||||
|
|
@ -34,8 +39,14 @@ class MuBit:
|
||||||
|
|
||||||
def __set(self, i: int, value: int) -> None:
|
def __set(self, i: int, value: int) -> None:
|
||||||
"""Set the nth QuBit into value"""
|
"""Set the nth QuBit into value"""
|
||||||
assert(value in {0, 1})
|
if type(i) is not int:
|
||||||
|
raise TypeError(f"MuBit indices must be integers, not {type(i)}")
|
||||||
|
if i > self.__n:
|
||||||
|
raise IndexError("MuBit index out of range")
|
||||||
|
if not value in {0, 1}:
|
||||||
|
raise ValueError(f"QuBit state must be 0 or 1, not {value}")
|
||||||
|
|
||||||
|
i = i%self.__n
|
||||||
M = Matrix([[1]])
|
M = Matrix([[1]])
|
||||||
for j in range(self.__n):
|
for j in range(self.__n):
|
||||||
if j == i:
|
if j == i:
|
||||||
|
|
@ -50,12 +61,26 @@ class MuBit:
|
||||||
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) -> "QuBit":
|
def __getitem__(self, item: int) -> "QuBit":
|
||||||
|
if type(item) is not int:
|
||||||
|
raise TypeError(f"MuBit indices must be integers, not {type(item)}")
|
||||||
|
if item > self.__n:
|
||||||
|
raise IndexError("MuBit index out of range")
|
||||||
|
|
||||||
|
item = item%self.__n
|
||||||
return IQuBit(item, self)
|
return IQuBit(item, self)
|
||||||
|
|
||||||
def __apply(self, i: int, matrix: Matrix) -> None:
|
def __apply(self, i: int, matrix: Matrix) -> None:
|
||||||
|
if type(i) is not int:
|
||||||
|
raise TypeError(f"MuBit indices must be integers, not {type(i)}")
|
||||||
|
if i > self.__n:
|
||||||
|
raise IndexError("MuBit index out of range")
|
||||||
|
if type(matrix) is not Matrix:
|
||||||
|
raise TypeError(f"can only manipulate MuBit with Matrix, not {type(matrix)}")
|
||||||
|
i = i%self.__n
|
||||||
|
|
||||||
M = Matrix([[1]])
|
M = Matrix([[1]])
|
||||||
|
|
||||||
for j in range(self.n):
|
for j in range(self.__n):
|
||||||
if j == i:
|
if j == i:
|
||||||
M *= matrix
|
M *= matrix
|
||||||
else:
|
else:
|
||||||
|
|
@ -64,6 +89,14 @@ class MuBit:
|
||||||
self.__state = M._Matrix__apply(self.__state)
|
self.__state = M._Matrix__apply(self.__state)
|
||||||
|
|
||||||
def __mapply(self, matrix: Matrix, i: int) -> None:
|
def __mapply(self, matrix: Matrix, i: int) -> None:
|
||||||
|
if type(i) is not int:
|
||||||
|
raise TypeError(f"MuBit indices must be integers, not {type(i)}")
|
||||||
|
if i > self.__n:
|
||||||
|
raise IndexError("MuBit index out of range")
|
||||||
|
if type(matrix) is not Matrix:
|
||||||
|
raise TypeError(f"can only manipulate MuBit with Matrix, not {type(matrix)}")
|
||||||
|
i = i%self.__n
|
||||||
|
|
||||||
M = Matrix([[1]])
|
M = Matrix([[1]])
|
||||||
j = 0
|
j = 0
|
||||||
while j < self.__n:
|
while j < self.__n:
|
||||||
|
|
@ -77,6 +110,12 @@ class MuBit:
|
||||||
|
|
||||||
def __getProb(self, i: int) -> float:
|
def __getProb(self, i: int) -> float:
|
||||||
"""Probs for i to be zero"""
|
"""Probs for i to be zero"""
|
||||||
|
if type(i) is not int:
|
||||||
|
raise TypeError(f"MuBit indices must be integers, not {type(i)}")
|
||||||
|
if i > self.__n:
|
||||||
|
raise IndexError("MuBit index out of range")
|
||||||
|
i = i%self.__n
|
||||||
|
|
||||||
M = Matrix([[1]])
|
M = Matrix([[1]])
|
||||||
|
|
||||||
for j in range(self.__n):
|
for j in range(self.__n):
|
||||||
|
|
@ -94,10 +133,33 @@ class MuBit:
|
||||||
l.append(IQuBit(i, self).observe())
|
l.append(IQuBit(i, self).observe())
|
||||||
return l
|
return l
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def intricateThem(*args: "QuBit") -> "MuBit":
|
||||||
|
for q in args:
|
||||||
|
if type(q) is IQuBit:
|
||||||
|
raise TypeError("cannot intricate QuBit that are already intricated")
|
||||||
|
if type(q) is not QuBit:
|
||||||
|
raise TypeError(f"cannot intricate QuBit and {type(q)}")
|
||||||
|
if len(args) < 2:
|
||||||
|
raise ValueError("cannot intricate less than two QuBits")
|
||||||
|
|
||||||
|
S = Matrix([[1]])
|
||||||
|
for q in args:
|
||||||
|
S *= Matrix([q._QuBit__state])
|
||||||
|
|
||||||
|
mq = MuBit(len(args))
|
||||||
|
mq._MuBit__state = S._Matrix__m[0]
|
||||||
|
return mq
|
||||||
|
|
||||||
class QuBit:
|
class QuBit:
|
||||||
def __init__(self, alpha: complex=1, beta: complex=0):
|
def __init__(self, alpha: complex=1, beta: complex=0):
|
||||||
|
if type(alpha) not in {int, float, complex}:
|
||||||
|
TypeError(f"QuBit state must be int, float or complex, not {type(alpha)}")
|
||||||
|
if type(beta) not in {int, float, complex}:
|
||||||
|
TypeError(f"QuBit state must be int, float or complex, not {type(alpha)}")
|
||||||
if abs(alpha)**2 + abs(beta)**2 != 1:
|
if abs(alpha)**2 + abs(beta)**2 != 1:
|
||||||
raise Exception("The initial state must be normalized")
|
raise ValueError(f"the initial state must be normalized. Here, |alpha|**2+|beta|**2={abs(alpha)**2 + abs(beta)**2}")
|
||||||
|
|
||||||
self.__state = [alpha, beta]
|
self.__state = [alpha, beta]
|
||||||
self.__intricated = False
|
self.__intricated = False
|
||||||
|
|
||||||
|
|
@ -111,6 +173,9 @@ class QuBit:
|
||||||
return f"{round(self.__state[0], 3)} |0> + {round(self.__state[1], 3)} |1>"
|
return f"{round(self.__state[0], 3)} |0> + {round(self.__state[1], 3)} |1>"
|
||||||
|
|
||||||
def __apply(self, matrix: Matrix) -> None:
|
def __apply(self, matrix: Matrix) -> None:
|
||||||
|
if type(matrix) is not Matrix:
|
||||||
|
raise TypeError(f"can only manipulate QuBit with Matrix, not {type(matrix)}")
|
||||||
|
|
||||||
self.__state = matrix._Matrix__apply(self.__state)
|
self.__state = matrix._Matrix__apply(self.__state)
|
||||||
|
|
||||||
def observe(self) -> list[int]:
|
def observe(self) -> list[int]:
|
||||||
|
|
@ -123,6 +188,14 @@ class QuBit:
|
||||||
|
|
||||||
class IQuBit(QuBit):
|
class IQuBit(QuBit):
|
||||||
def __init__(self, n: int, mb: MuBit) -> None:
|
def __init__(self, n: int, mb: MuBit) -> None:
|
||||||
|
if type(n) is not int:
|
||||||
|
raise TypeError(f"MuBit indices must be interger, not {type(n)}")
|
||||||
|
if n > mb._MuBit__n:
|
||||||
|
raise ValueError(f"MuBit index out of range")
|
||||||
|
if type(mb) is not MuBit:
|
||||||
|
TypeError(f"an intricate QuBit should be associated with a MuBit, not a {type(mb)}")
|
||||||
|
n = n%mb._MuBit__n
|
||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.__n = n
|
self.__n = n
|
||||||
self.__muBit = mb
|
self.__muBit = mb
|
||||||
|
|
@ -139,6 +212,9 @@ class IQuBit(QuBit):
|
||||||
return str(QuBit(math.sqrt(p), math.sqrt(1-p)))
|
return str(QuBit(math.sqrt(p), math.sqrt(1-p)))
|
||||||
|
|
||||||
def __apply(self, matrix: Matrix) -> None:
|
def __apply(self, matrix: Matrix) -> None:
|
||||||
|
if type(matrix) is not Matrix:
|
||||||
|
raise TypeError(f"can only manipulate QuBit with Matrix, not {type(matrix)}")
|
||||||
|
|
||||||
self.__muBit._MuBit__apply(self.__n, matrix)
|
self.__muBit._MuBit__apply(self.__n, matrix)
|
||||||
|
|
||||||
def observe(self) -> int:
|
def observe(self) -> int:
|
||||||
|
|
@ -160,62 +236,98 @@ def H(q: QuBit) -> None:
|
||||||
q._IQuBit__apply(Matrix.H())
|
q._IQuBit__apply(Matrix.H())
|
||||||
elif type(q) == QuBit:
|
elif type(q) == QuBit:
|
||||||
q._QuBit__apply(Matrix.H())
|
q._QuBit__apply(Matrix.H())
|
||||||
|
else:
|
||||||
|
raise TypeError(f"a QuBit was expected, but a {type(q)} was given")
|
||||||
|
|
||||||
def X(q: QuBit) -> None:
|
def X(q: QuBit) -> None:
|
||||||
if type(q) == IQuBit:
|
if type(q) == IQuBit:
|
||||||
q._IQuBit__apply(Matrix.X())
|
q._IQuBit__apply(Matrix.X())
|
||||||
elif type(q) == QuBit:
|
elif type(q) == QuBit:
|
||||||
q._QuBit__apply(Matrix.X())
|
q._QuBit__apply(Matrix.X())
|
||||||
|
else:
|
||||||
|
raise TypeError(f"a QuBit was expected, but a {type(q)} was given")
|
||||||
|
|
||||||
def Y(q: QuBit) -> None:
|
def Y(q: QuBit) -> None:
|
||||||
if type(q) == IQuBit:
|
if type(q) == IQuBit:
|
||||||
q._IQuBit__apply(Matrix.Y())
|
q._IQuBit__apply(Matrix.Y())
|
||||||
elif type(q) == QuBit:
|
elif type(q) == QuBit:
|
||||||
q._QuBit__apply(Matrix.Y())
|
q._QuBit__apply(Matrix.Y())
|
||||||
|
else:
|
||||||
|
raise TypeError(f"a QuBit was expected, but a {type(q)} was given")
|
||||||
|
|
||||||
def Z(q: QuBit) -> None:
|
def Z(q: QuBit) -> None:
|
||||||
if type(q) == IQuBit:
|
if type(q) == IQuBit:
|
||||||
q._IQuBit__apply(Matrix.Z())
|
q._IQuBit__apply(Matrix.Z())
|
||||||
elif type(q) == QuBit:
|
elif type(q) == QuBit:
|
||||||
q._QuBit__apply(Matrix.Z())
|
q._QuBit__apply(Matrix.Z())
|
||||||
|
else:
|
||||||
|
raise TypeError(f"a QuBit was expected, but a {type(q)} was given")
|
||||||
|
|
||||||
def S(q: QuBit) -> None:
|
def S(q: QuBit) -> None:
|
||||||
if type(q) == IQuBit:
|
if type(q) == IQuBit:
|
||||||
q._IQuBit__apply(Matrix.S())
|
q._IQuBit__apply(Matrix.S())
|
||||||
elif type(q) == QuBit:
|
elif type(q) == QuBit:
|
||||||
q._QuBit__apply(Matrix.S())
|
q._QuBit__apply(Matrix.S())
|
||||||
|
else:
|
||||||
|
raise TypeError(f"a QuBit was expected, but a {type(q)} was given")
|
||||||
|
|
||||||
def T(q: QuBit) -> None:
|
def T(q: QuBit) -> None:
|
||||||
if type(q) == IQuBit:
|
if type(q) == IQuBit:
|
||||||
q._IQuBit__apply(Matrix.T())
|
q._IQuBit__apply(Matrix.T())
|
||||||
elif type(q) == QuBit:
|
elif type(q) == QuBit:
|
||||||
q._QuBit__apply(Matrix.T())
|
q._QuBit__apply(Matrix.T())
|
||||||
|
else:
|
||||||
|
raise TypeError(f"a QuBit was expected, but a {type(q)} was given")
|
||||||
|
|
||||||
def Rx(q: QuBit, phi: float) -> None:
|
def Rx(q: QuBit, phi: float) -> None:
|
||||||
|
if type(phi) not in {int, float}:
|
||||||
|
TypeError(f"an angle must be integer or float, not {type(phi)}")
|
||||||
|
|
||||||
if type(q) == QuBit:
|
if type(q) == QuBit:
|
||||||
q._QuBit__apply(Matrix.Rx(phi))
|
q._QuBit__apply(Matrix.Rx(phi))
|
||||||
elif type(q) == IQuBit:
|
elif type(q) == IQuBit:
|
||||||
q._IQuBit__apply(Matrix.Rx(phi))
|
q._IQuBit__apply(Matrix.Rx(phi))
|
||||||
|
else:
|
||||||
|
raise TypeError(f"a QuBit was expected, but a {type(q)} was given")
|
||||||
|
|
||||||
def Ry(q: QuBit, phi: float) -> None:
|
def Ry(q: QuBit, phi: float) -> None:
|
||||||
|
if type(phi) not in {int, float}:
|
||||||
|
TypeError(f"an angle must be integer or float, not {type(phi)}")
|
||||||
|
|
||||||
if type(q) == QuBit:
|
if type(q) == QuBit:
|
||||||
q._QuBit__apply(Matrix.Ry(phi))
|
q._QuBit__apply(Matrix.Ry(phi))
|
||||||
elif type(q) == IQuBit:
|
elif type(q) == IQuBit:
|
||||||
q._IQuBit__apply(Matrix.Ry(phi))
|
q._IQuBit__apply(Matrix.Ry(phi))
|
||||||
|
else:
|
||||||
|
raise TypeError(f"a QuBit was expected, but a {type(q)} was given")
|
||||||
|
|
||||||
def Rz(q: QuBit, phi: float) -> None:
|
def Rz(q: QuBit, phi: float) -> None:
|
||||||
|
if type(phi) not in {int, float}:
|
||||||
|
TypeError(f"an angle must be integer or float, not {type(phi)}")
|
||||||
|
|
||||||
if type(q) == QuBit:
|
if type(q) == QuBit:
|
||||||
q._QuBit__apply(Matrix.Rz(phi))
|
q._QuBit__apply(Matrix.Rz(phi))
|
||||||
elif type(q) == IQuBit:
|
elif type(q) == IQuBit:
|
||||||
q._IQuBit__apply(Matrix.Rz(phi))
|
q._IQuBit__apply(Matrix.Rz(phi))
|
||||||
|
else:
|
||||||
|
raise TypeError(f"a QuBit was expected, but a {type(q)} was given")
|
||||||
|
|
||||||
def R1(q: QuBit, phi: float) -> None:
|
def R1(q: QuBit, phi: float) -> None:
|
||||||
|
if type(phi) not in {int, float}:
|
||||||
|
TypeError(f"an angle must be integer or float, not {type(phi)}")
|
||||||
|
|
||||||
if type(q) == QuBit:
|
if type(q) == QuBit:
|
||||||
q._QuBit__apply(Matrix.R1(phi))
|
q._QuBit__apply(Matrix.R1(phi))
|
||||||
elif type(q) == IQuBit:
|
elif type(q) == IQuBit:
|
||||||
q._IQuBit__apply(Matrix.R1(phi))
|
q._IQuBit__apply(Matrix.R1(phi))
|
||||||
|
else:
|
||||||
|
raise TypeError(f"a QuBit was expected, but a {type(q)} was given")
|
||||||
|
|
||||||
def CNOT(q: MuBit, n1: int, n2: int) -> None:
|
def CNOT(q: MuBit, n1: int, n2: int) -> None:
|
||||||
|
if type(q) is not MuBit:
|
||||||
|
TypeError(f"a MuBit was expected, but a {type(q)} was given")
|
||||||
|
if type()
|
||||||
|
|
||||||
SWAP(q, 0, n1)
|
SWAP(q, 0, n1)
|
||||||
SWAP(q, 1, n2)
|
SWAP(q, 1, n2)
|
||||||
q._MuBit__mapply(Matrix.CNOT(), 0)
|
q._MuBit__mapply(Matrix.CNOT(), 0)
|
||||||
|
|
@ -246,5 +358,6 @@ def test(q: QuBit) -> None:
|
||||||
print(varName)
|
print(varName)
|
||||||
|
|
||||||
if __name__=="__main__":
|
if __name__=="__main__":
|
||||||
q = MuBit(3)
|
q = MuBit(2)
|
||||||
s = q[1].get_Mubit()
|
|
||||||
|
print(q[0])
|
||||||
BIN
QElephant/__pycache__/Matrix.cpython-311.pyc
Normal file
BIN
QElephant/__pycache__/Matrix.cpython-311.pyc
Normal file
Binary file not shown.
BIN
QElephant/__pycache__/QuBit.cpython-311.pyc
Normal file
BIN
QElephant/__pycache__/QuBit.cpython-311.pyc
Normal file
Binary file not shown.
BIN
QElephant/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
QElephant/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
Loading…
Reference in a new issue