gate.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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, unitary=True):
  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 unitary:
  23. if (not np.allclose(np.eye(gate.shape[0]), np.dot(gate.conjugate().transpose(), gate))):
  24. raise ValueError("gate is not unitary.")
  25. self.a = complex(gate[0, 0])
  26. self.b = complex(gate[0, 1])
  27. self.c = complex(gate[1, 0])
  28. self.d = complex(gate[1, 1])
  29. def __repr__(self):
  30. return '[{:.4f}, {:.4f}]\n[{:.4f}, {:.4f}]'.format(self.a, self.b, self.c, self.d)
  31. @memoize
  32. def h():
  33. return Gate(np.array([[1, 1], [1, -1]]) / np.sqrt(2))
  34. @memoize
  35. def x():
  36. return Gate(np.array([[0, 1], [1, 0]]))
  37. @memoize
  38. def y():
  39. return Gate(np.array([[0, -1j], [1j, 0]]))
  40. @memoize
  41. def z():
  42. return Gate(np.array([[1, 0], [0, -1]]))
  43. @memoize
  44. def s():
  45. return Gate(np.array([[1, 0], [0, 1j]]))
  46. @memoize
  47. def t():
  48. return Gate(np.array([[1, 0], [0, np.exp(np.pi * 1j / 4)]]))
  49. @memoize
  50. def sqrt_x():
  51. return Gate(0.5 * np.array([[1+1j, 1-1j], [1-1j, 1+1j]]))