Newer
Older
q / CompactMatrix.py
from sympy import sqrt, I, pi, exp, N, simplify
from math import log2

class Matrix:
  def __init__(self, m=None):
    if m is None:
      self.state = [{}]
    else:
      #print(matrix)
      self.shape = (len(m), len(m[0]))
      #self.state = [{}] * self.shape[1]
      self.state = []
      for i in range(self.shape[1]):
        self.state.append({})
      #print(self.state[0])
      for i in range(self.shape[0]):
        for j in range(self.shape[1]):
          #print(self.state, m[i][j])
          if m[i][j] != 0:
            self.state[j][i] = m[i][j]
  def __repr__(self):
    str = '['
    for i in range(self.shape[1]):
      str += '{\n'
      for j in sorted(self.state[i]):
        str += f'  |{j:0{int(log2(self.shape[0]))}b}>: {N(abs(self.state[i][j]) ** 2) * 100:8.4f}% [{self.state[i][j]}],\n'
      str = str.strip(',\n')
      str += '\n}, \n'
    str = str.strip(', \n')
    str += ']'
    return str
  def get_matrix(self):
    m = [[0 for j in range(self.shape[1])] for i in range(self.shape[0])]
    for i in range(self.shape[0]):
      for j in range(self.shape[1]):
        if i in self.state[j]:
          m[i][j] = self.state[j][i]
    return m
  def kron(self, m):
    #print(m.state)
    #print(n.state)
    #print(m.shape[0], m.shape[1], n.shape[0], n.shape[1])
    C = zeros(self.shape[0] * m.shape[0], self.shape[1] * m.shape[1])
    for i in range(self.shape[0]):
      for j in self.state[i]: # range(m.shape[1]):
        for k in range(m.shape[0]):
          for l in m.state[k]: # range(n.shape[1]):
            #print(i,j,k,l)
            #if i in m.state[j] and k in n.state[l]:
            C.state[i * m.shape[0] + k][j * m.shape[1] + l] = self.state[i][j] * m.state[k][l]
            #print(C.state)
    return C
  def dot(self, m):
    #print(self.shape[0], self.shape[1], m.shape[0], m.shape[1])
    C = zeros(self.shape[0], m.shape[1])
    for j in range(m.shape[1]):
      for k in m.state[j]: #range(m.shape[1]):
        for i in self.state[k]: # range(m.shape[0]):
          #print(i,j,k)
          #if i in m.state[k] and k in n.state[j]:
          if not i in C.state[j]:
            C.state[j][i] = 0
          C.state[j][i] += self.state[k][i] * m.state[j][k]
          C.state[j][i] = simplify(C.state[j][i])
          if C.state[j][i] == 0:
            del C.state[j][i]
    #print(C.state)
    return C

class GateMatrix:
  def __init__(self, m=None):
    if m is None:
      self.state = [eye(2)]
    else:
      #print(matrix)
      self.shape = (len(m), 2, 2)
      #self.state = [{}] * self.shape[1]
      self.state = m
      #for i in range(self.shape[1]):
      #  self.state.append({})
      #print(self.state[0])
      #for i in range(self.shape[0]):
      #  for j in range(self.shape[1]):
          #print(self.state, m[i][j])
      #    if m[i][j] != 0:
      #      self.state[j][i] = m[i][j]
  def __repr__(self):
    s = str(self.state)
  #  str = '['
  #  for i in range(self.shape[1]):
  #    str += '{\n'
  #    for j in self.state[i]:
  #      str += f'  |{j:0{int(log2(self.shape[0]))}b}>: {self.state[i][j]},\n'
  #    str = str.strip(',\n')
  #    str += '\n}, \n'
  #  str = str.strip(', \n')
  #  str += ']'
    return s
  def get_matrix(self):
    m = [[0 for j in range(self.shape[1])] for i in range(self.shape[0])]
    for i in range(self.shape[0]):
      for j in range(self.shape[1]):
        if i in self.state[j]:
          m[i][j] = self.state[j][i]
    return m
  def kron(self, m):
    #print(m.state)
    #print(n.state)
    #print(m.shape[0], m.shape[1], n.shape[0], n.shape[1])
    C = zeros(self.shape[0] * m.shape[0], self.shape[1] * m.shape[1])
    for i in range(self.shape[0]):
      for j in self.state[i]: # range(m.shape[1]):
        for k in range(m.shape[0]):
          for l in m.state[k]: # range(n.shape[1]):
            #print(i,j,k,l)
            #if i in m.state[j] and k in n.state[l]:
            C.state[i * m.shape[0] + k][j * m.shape[1] + l] = self.state[i][j] * m.state[k][l]
            #print(C.state)
    return C
  def dot(self, m):
    #print(self.shape[0], self.shape[1], m.shape[0], m.shape[1])
    C = zeros(self.shape[0], m.shape[1])
    for j in range(m.shape[1]):
      for k in m.state[j]: #range(m.shape[1]):
        for i in self.state[k]: # range(m.shape[0]):
          #print(i,j,k)
          #if i in m.state[k] and k in n.state[j]:
          if not i in C.state[j]:
            C.state[j][i] = 0
          C.state[j][i] += self.state[k][i] * m.state[j][k]
          if C.state[j][i] == 0:
            del C.state[j][i]
    #print(C.state)
    return C

def zeros(x, y):
  m = Matrix()
  m.shape = (x, y)
  m.state = []
  for i in range(y):
    m.state.append({})
  return m

def eye(x):
  m = Matrix()
  m.shape = (x, x)
  m.state = []
  for i in range(x):
    m.state.append({})
    m.state[i][i] = 1
  return m

#def kron(m, n):
#  #print(m.state)
#  #print(n.state)
#  #print(m.shape[0], m.shape[1], n.shape[0], n.shape[1])
#  C = zeros(m.shape[0] * n.shape[0], m.shape[1] * n.shape[1])
#  for i in range(m.shape[0]):
#    for j in m.state[i]: # range(m.shape[1]):
#      for k in range(n.shape[0]):
#        for l in n.state[k]: # range(n.shape[1]):
#          #print(i,j,k,l)
#          #if i in m.state[j] and k in n.state[l]:
#          C.state[i * n.shape[0] + k][j * n.shape[1] + l] = m.state[i][j] * n.state[k][l]
#          #print(C.state)
#  return C

#def dot(m, n):
#  #print(m.shape[0], m.shape[1], n.shape[0], n.shape[1])
#  C = zeros(m.shape[0], n.shape[1])
#  for j in range(n.shape[1]):
#    for k in n.state[j]: #range(m.shape[1]):
#      for i in m.state[k]: # range(m.shape[0]):
#        #print(i,j,k)
#        #if i in m.state[k] and k in n.state[j]:
#        if not i in C.state[j]:
#          C.state[j][i] = 0
#        C.state[j][i] += m.state[k][i] * n.state[j][k]
#        if C.state[j][i] == 0:
#          del C.state[j][i]
#  #print(C.state)
#  return C

#I = eye(2)
#X = Matrix([[0,1],[1,0]])

GATES = {
  'I':   Matrix([[1, 0], [0, 1]]),
  'X':   Matrix([[0, 1], [1, 0]]),
  'Y':   Matrix([[0, -I], [I, 0]]), 
  'Z':   Matrix([[1, 0], [0, -1]]),
  'S':   Matrix([[1, 0], [0, I]]),
  'SDG': Matrix([[1, 0], [0, -I]]),
  'T':   Matrix([[1, 0], [0, exp(I * pi / 4)]]),
  'TDG': Matrix([[1, 0], [0, exp(-I * pi / 4)]]),
  'H':   Matrix([[sqrt(2) / 2, sqrt(2) / 2], [sqrt(2) / 2, -sqrt(2) / 2]]),
}