Anders and Briegel in Python
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

111 строки
3.5KB

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """
  4. Exposes a few basic QI operators
  5. And a circuit-model simulator
  6. """
  7. import numpy as np
  8. import itertools as it
  9. def hermitian_conjugate(u):
  10. """ Shortcut to the Hermitian conjugate """
  11. return np.conjugate(np.transpose(u))
  12. # Constants
  13. ir2 = 1/np.sqrt(2)
  14. # Operators
  15. id = np.array(np.eye(2, dtype=complex))
  16. px = np.array([[0, 1], [1, 0]], dtype=complex)
  17. py = np.array([[0, -1j], [1j, 0]], dtype=complex)
  18. pz = np.array([[1, 0], [0, -1]], dtype=complex)
  19. ha = hadamard = np.array([[1, 1], [1, -1]], dtype=complex) * ir2
  20. ph = np.array([[1, 0], [0, 1j]], dtype=complex)
  21. t = np.array([[1, 0], [0, np.exp(1j*np.pi/4)]], dtype=complex)
  22. sqx = np.array([[ 1.+0.j, -0.+1.j], [-0.+1.j, 1.-0.j]], dtype=complex)*ir2
  23. msqx = np.array([[ 1.+0.j, 0.-1.j], [ 0.-1.j, 1.-0.j]], dtype=complex)*ir2
  24. sqy = np.array([[ 1.+0.j, 1.+0.j], [-1.-0.j, 1.-0.j]], dtype=complex)*ir2
  25. msqy = np.array([[ 1.+0.j, -1.-0.j], [ 1.+0.j, 1.-0.j]], dtype=complex)*ir2
  26. sqz = np.array([[ 1.+1.j, 0.+0.j], [ 0.+0.j, 1.-1.j]], dtype=complex)*ir2
  27. msqz = np.array([[ 1.-1.j, 0.+0.j], [ 0.+0.j, 1.+1.j]], dtype=complex)*ir2
  28. # CZ gate
  29. cz = np.array(np.eye(4), dtype=complex)
  30. cz[3,3]=-1
  31. # States
  32. plus = np.array([[1],[1]], dtype=complex) / np.sqrt(2)
  33. bond = cz.dot(np.kron(plus, plus))
  34. nobond = np.kron(plus, plus)
  35. # Labelling stuff
  36. common_us = id, px, py, pz, ha, ph, sqz, msqz, sqy, msqy, sqx, msqx
  37. names = "identity", "px", "py", "pz", "hadamard", "phase", "sqz", "msqz", "sqy", "msqy", "sqx", "msqx"
  38. by_name = dict(zip(names, common_us))
  39. paulis = px, py, pz
  40. def normalize_global_phase(m):
  41. """ Normalize the global phase of a matrix """
  42. v = (x for x in m.flatten() if np.abs(x) > 0.001).next()
  43. phase = np.arctan2(v.imag, v.real) % np.pi
  44. rot = np.exp(-1j * phase)
  45. return rot * m if rot * v > 0 else -rot * m
  46. class CircuitModel(object):
  47. def __init__(self, nqubits):
  48. self.nqubits = nqubits
  49. self.d = 2**nqubits
  50. self.state = np.zeros((self.d, 1), dtype=complex)
  51. self.state[0, 0]=1
  52. def act_cz(self, control, target):
  53. """ Act a CU somewhere """
  54. control = 1 << control
  55. target = 1 << target
  56. for i in xrange(self.d):
  57. if (i & control) and (i & target):
  58. self.state[i, 0] *= -1
  59. def act_hadamard(self, qubit):
  60. """ Act a hadamard somewhere """
  61. where = 1 << qubit
  62. output = np.zeros((self.d, 1), dtype=complex)
  63. for i, v in enumerate(self.state):
  64. q = i & where > 0
  65. output[i] += v*ha[q, q]
  66. output[i ^ where] += v*ha[not q, q]
  67. self.state = output
  68. def act_local_rotation(self, qubit, u):
  69. """ Act a local unitary somwhere """
  70. where = 1 << qubit
  71. output = np.zeros((self.d, 1), dtype=complex)
  72. for i, v in enumerate(self.state):
  73. q = i & where > 0
  74. output[i] += v*u[q, q] # TODO this is probably wrong
  75. output[i ^ where] += v*u[not q, q]
  76. self.state = output
  77. def __eq__(self, other):
  78. """ Check whether two quantum states are the same or not
  79. UP TO A GLOBAL PHASE """
  80. a = normalize_global_phase(self.state)
  81. b = normalize_global_phase(other.state)
  82. return np.allclose(a, b)
  83. def __str__(self):
  84. s = ""
  85. for i in range(self.d):
  86. label = bin(i)[2:].rjust(self.nqubits, "0")
  87. if abs(self.state[i, 0])>0.00001:
  88. s += "|{}>: {}\n".format(label, self.state[i, 0].round(3))
  89. return s