first commit
This commit is contained in:
commit
17ff8eae49
5 changed files with 355 additions and 0 deletions
155
Matrix.py
Normal file
155
Matrix.py
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
import math
|
||||
|
||||
I = complex(0, 1)
|
||||
|
||||
class Matrix:
|
||||
def __init__(self, l: list[list[complex]]=[]) -> None:
|
||||
self.__m = l
|
||||
if l == []:
|
||||
self.__m = [[0, 0], [0, 0]]
|
||||
self.__size = (len(self.__m), len(self.__m[0]))
|
||||
|
||||
def __mul__(self, __value: "Matrix") -> "Matrix":
|
||||
l: list[list[complex]] = []
|
||||
for i in range(self.__size[0]*__value.__size[0]):
|
||||
l.append([0]*(self.__size[1]*__value.__size[1]))
|
||||
|
||||
for i in range(self.__size[0]):
|
||||
for j in range(self.__size[1]):
|
||||
for x in range(__value.__size[0]):
|
||||
for y in range(__value.__size[1]):
|
||||
pos = (i*__value.__size[0]+x, j*__value.__size[1]+y)
|
||||
l[pos[0]][pos[1]] = self.__m[i][j]*__value.__m[x][y]
|
||||
|
||||
return Matrix(l)
|
||||
|
||||
def __apply(self, x: list[complex]) -> list[complex]:
|
||||
assert(self.__size[1] == len(x))
|
||||
|
||||
y: list[complex] = [0]*self.__size[0]
|
||||
for i in range(self.__size[0]):
|
||||
for j in range(self.__size[1]):
|
||||
y[i] += self.__m[i][j]*x[j]
|
||||
return y
|
||||
|
||||
def __str__(self) -> str:
|
||||
return str(self.__m)
|
||||
|
||||
@staticmethod
|
||||
def I() -> "Matrix":
|
||||
return Matrix([
|
||||
[1, 0],
|
||||
[0, 1]
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def H() -> "Matrix":
|
||||
s = 1/math.sqrt(2)
|
||||
return Matrix([
|
||||
[s, s],
|
||||
[s, -s]
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def X() -> "Matrix":
|
||||
return Matrix([
|
||||
[0, 1],
|
||||
[1, 0]
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def Y() -> "Matrix":
|
||||
return Matrix([
|
||||
[0, -I],
|
||||
[I, 0]
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def Z() -> "Matrix":
|
||||
return Matrix([
|
||||
[1, 0],
|
||||
[0, -1]
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def S() -> "Matrix":
|
||||
return Matrix([
|
||||
[1, 0],
|
||||
[0, I]
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def T() -> "Matrix":
|
||||
s = math.e**(I*math.pi/4)
|
||||
return Matrix([
|
||||
[1, 0],
|
||||
[0, s]
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def Rx(phi: float) -> "Matrix":
|
||||
c = math.cos(phi/2)
|
||||
s = math.sin(phi/2)
|
||||
return Matrix([
|
||||
[c, -I*s],
|
||||
[-I*s, c]
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def Ry(phi: float) -> "Matrix":
|
||||
c = math.cos(phi/2)
|
||||
s = math.sin(phi/2)
|
||||
return Matrix([
|
||||
[c, -s],
|
||||
[s, c]
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def Rz(phi: float) -> "Matrix":
|
||||
s = math.e**(I*phi/2)
|
||||
return Matrix([
|
||||
[1/s, 0],
|
||||
[0, s]
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def R1(phi: float) -> "Matrix":
|
||||
s = math.e**(I*phi)
|
||||
return Matrix([
|
||||
[1, 0],
|
||||
[0, s]
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def CNOT() -> "Matrix":
|
||||
return Matrix([
|
||||
[1, 0, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, 0, 1],
|
||||
[0, 0, 1, 0]
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def SWAP() -> "Matrix":
|
||||
return Matrix([
|
||||
[1, 0, 0, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, 0, 1]
|
||||
])
|
||||
|
||||
@staticmethod
|
||||
def Cu(u: "Matrix") -> "Matrix":
|
||||
assert(u.size == (2, 2))
|
||||
l = [
|
||||
[1, 0, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, u[0][0], u[0][1]],
|
||||
[0, 0, u[1][0], u[1][1]]
|
||||
]
|
||||
|
||||
if __name__=="__main__":
|
||||
m1 = Matrix([[1]])
|
||||
m2 = Matrix([[1, 1], [0, 1]])
|
||||
|
||||
print(m1*m2)
|
||||
200
QuBit.py
Normal file
200
QuBit.py
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
import math
|
||||
import random as rd
|
||||
|
||||
from 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
|
||||
|
||||
class MuBit:
|
||||
def __init__(self, n: int) -> None:
|
||||
self.__n = n
|
||||
self.__state: list[complex] = [0]*(2**self.__n)
|
||||
self.__state[0] = 1
|
||||
|
||||
def __str__(self) -> str:
|
||||
def next(N: str) -> str:
|
||||
if N == "":
|
||||
return ""
|
||||
if N[-1] == "0":
|
||||
return N[:-1]+"1"
|
||||
else:
|
||||
return (next(N[:-1]))+"0"
|
||||
|
||||
txt = ""
|
||||
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
|
||||
|
||||
def __set(self, i: int, value: int) -> None:
|
||||
"""Set the nth QuBit into value"""
|
||||
assert(value in {0, 1})
|
||||
|
||||
M = Matrix([[1]])
|
||||
for j in range(self.__n):
|
||||
if j == i:
|
||||
M *= Matrix([[1-value, 0], [0, value]])
|
||||
else:
|
||||
M *= Matrix([[1, 0], [0, 1]])
|
||||
self.__state = M._Matrix__apply(self.__state)
|
||||
norm = math.sqrt(sum([abs(x)**2 for x in self.__state]))
|
||||
self.__state = [x/norm for x in self.__state]
|
||||
|
||||
def __iter__(self):
|
||||
return iter([IQuBit(i, self) for i in range(self.__n)])
|
||||
|
||||
def __getitem__(self, item: int) -> "IQuBit":
|
||||
return IQuBit(item, self)
|
||||
|
||||
def __apply(self, i: int, matrix: Matrix) -> None:
|
||||
M = Matrix([[1]])
|
||||
|
||||
for j in range(self.__n):
|
||||
if j == i:
|
||||
M *= matrix
|
||||
else:
|
||||
M *= Matrix.I()
|
||||
|
||||
self.__state = M._Matrix__apply(self.__state)
|
||||
|
||||
def __mapply(self, matrix: Matrix) -> None:
|
||||
self.__state = matrix.__MuBit__apply(self.__state)
|
||||
|
||||
def __getProb(self, i: int) -> float:
|
||||
"""Probs for i to be zero"""
|
||||
M = Matrix([[1]])
|
||||
|
||||
for j in range(self.__n):
|
||||
if j == i:
|
||||
M *= Matrix([[1, 0], [0, 0]])
|
||||
else:
|
||||
M *= Matrix.I()
|
||||
|
||||
l = M._Matrix__apply(self.__state)
|
||||
return sum([abs(x)**2 for x in l])
|
||||
|
||||
def observe(self) -> list[0]:
|
||||
l = []
|
||||
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
|
||||
|
||||
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)
|
||||
return 0
|
||||
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:
|
||||
q._IQuBit__apply(Matrix.H())
|
||||
|
||||
def X(q: (QuBit | IQuBit)) -> None:
|
||||
if type(q) == QuBit:
|
||||
q._Qubit__apply(Matrix.X())
|
||||
elif type(q) == IQuBit:
|
||||
q._IQuBit__apply(Matrix.X())
|
||||
|
||||
def Y(q: (QuBit | IQuBit)) -> None:
|
||||
if type(q) == QuBit:
|
||||
q._Qubit__apply(Matrix.Y())
|
||||
elif type(q) == IQuBit:
|
||||
q._IQuBit__apply(Matrix.Y())
|
||||
|
||||
def Z(q: (QuBit | IQuBit)) -> None:
|
||||
if type(q) == QuBit:
|
||||
q._Qubit__apply(Matrix.Z())
|
||||
elif type(q) == IQuBit:
|
||||
q._IQuBit__apply(Matrix.Z())
|
||||
|
||||
def S(q: (QuBit | IQuBit)) -> None:
|
||||
if type(q) == QuBit:
|
||||
q._Qubit__apply(Matrix.S())
|
||||
elif type(q) == IQuBit:
|
||||
q._IQuBit__apply(Matrix.S())
|
||||
|
||||
def T(q: (QuBit | IQuBit)) -> None:
|
||||
if type(q) == QuBit:
|
||||
q._Qubit__apply(Matrix.T())
|
||||
elif type(q) == IQuBit:
|
||||
q._IQuBit__apply(Matrix.T())
|
||||
|
||||
def Rx(q: (QuBit | IQuBit), 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:
|
||||
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:
|
||||
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:
|
||||
if type(q) == QuBit:
|
||||
q._Qubit__apply(Matrix.R1(phi))
|
||||
elif type(q) == IQuBit:
|
||||
q._IQuBit__apply(Matrix.R1(phi))
|
||||
|
||||
def CNOT(q: MuBit) -> None:
|
||||
q._MuBit__mapply(Matrix.CNOT())
|
||||
|
||||
def SWAP(q: MuBit) -> None:
|
||||
q._MuBit__mapply(Matrix.SWAP())
|
||||
|
||||
def Cu(q: MuBit, u: list[list[complex]]) -> None:
|
||||
q._MuBit__mapply(Matrix.Cu(u))
|
||||
|
||||
def test(q: QuBit) -> None:
|
||||
varName = None
|
||||
|
||||
for name, value in locals().items():
|
||||
if value == q:
|
||||
varName = name
|
||||
print(varName)
|
||||
|
||||
if __name__=="__main__":
|
||||
q1 = QuBit()
|
||||
q2 = QuBit()
|
||||
|
||||
test(q1)
|
||||
0
__init__.py
Normal file
0
__init__.py
Normal file
BIN
__pycache__/Matrix.cpython-311.pyc
Normal file
BIN
__pycache__/Matrix.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/QuBit.cpython-311.pyc
Normal file
BIN
__pycache__/QuBit.cpython-311.pyc
Normal file
Binary file not shown.
Loading…
Reference in a new issue