gate.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import numpy as np
  2. import functools
  3. def memoize(func):
  4. cache = func.cache = {}
  5. @functools.wraps(func)
  6. def memoized_func():
  7. key = 'a'
  8. if key not in cache:
  9. cache[key] = func()
  10. return cache[key]
  11. return memoized_func
  12. class Gate:
  13. def __init__(self, gate):
  14. gate = np.array(gate)
  15. if gate.shape != (2, 2):
  16. raise ValueError(
  17. "Gate is not a 2x2 matrix. " +
  18. "For larger gates, please decompose into 2x2 matrices " +
  19. "and/or use the controlled gate functionality."
  20. )
  21. # Check the gate is unitary
  22. if (not np.allclose(np.eye(gate.shape[0]), np.dot(gate.conjugate().transpose(), gate))):
  23. raise ValueError("gate is not unitary.")
  24. self.a = complex(gate[0, 0])
  25. self.b = complex(gate[0, 1])
  26. self.c = complex(gate[1, 0])
  27. self.d = complex(gate[1, 1])
  28. def __repr__(self):
  29. return '[{:.4f}, {:.4f}]\n[{:.4f}, {:.4f}]'.format(self.a, self.b, self.c, self.d)
  30. @memoize
  31. def h():
  32. return Gate(np.array([[1, 1], [1, -1]]) / np.sqrt(2))
  33. @memoize
  34. def x():
  35. return Gate(np.array([[0, 1], [1, 0]]))
  36. @memoize
  37. def y():
  38. return Gate(np.array([[0, -1j], [1j, 0]]))
  39. @memoize
  40. def z():
  41. return Gate(np.array([[1, 0], [0, -1]]))
  42. @memoize
  43. def s():
  44. return Gate(np.array([[1, 0], [0, 1j]]))
  45. @memoize
  46. def t():
  47. return Gate(np.array([[1, 0], [0, np.exp(np.pi * 1j / 4)]]))
  48. @memoize
  49. def sqrt_x():
  50. return Gate(0.5 * np.array([[1+1j, 1-1j], [1-1j, 1+1j]]))