155 lines
No EOL
3.5 KiB
Python
155 lines
No EOL
3.5 KiB
Python
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) |