Anders and Briegel in Python
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

102 lignes
2.9KB

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """
  4. Exposes a few basic QI operators
  5. """
  6. import numpy as np
  7. from scipy.linalg import sqrtm
  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 = 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. sqy = sqrtm(1j * py)
  23. msqy = np.array(sqrtm(-1j * py))
  24. sqz = np.array(sqrtm(1j * pz))
  25. msqz = np.array(sqrtm(-1j * pz))
  26. sqx = np.array(sqrtm(1j * px))
  27. msqx = np.array(sqrtm(-1j * px))
  28. paulis = (px, py, pz)
  29. # CZ gate
  30. cz = np.array(np.eye(4), dtype=complex)
  31. cz[3,3]=-1
  32. # States
  33. plus = np.array([[1],[1]], dtype=complex) / np.sqrt(2)
  34. bond = cz.dot(np.kron(plus, plus))
  35. nobond = np.kron(plus, plus)
  36. # Labelling stuff
  37. common_us = id, px, py, pz, ha, ph, sqz, msqz, sqy, msqy, sqx, msqx
  38. names = "identity", "px", "py", "pz", "hadamard", "phase", "sqz", "msqz", "sqy", "msqy", "sqx", "msqx"
  39. by_name = dict(zip(names, common_us))
  40. paulis = px, py, pz
  41. class CircuitModel(object):
  42. def __init__(self, nqubits):
  43. self.nqubits = nqubits
  44. self.d = 2**nqubits
  45. self.state = np.zeros((self.d, 1), dtype=complex)
  46. self.state[0, 0]=1
  47. def act_cz(self, control, target):
  48. """ Act a CU somewhere """
  49. control = 1 << control
  50. target = 1 << control
  51. for i in xrange(self.d):
  52. if (i & control) and (i & target):
  53. self.state[i, 0] *= -1
  54. def act_hadamard(self, qubit):
  55. """ Act a hadamard somewhere """
  56. where = 1 << qubit
  57. output = np.zeros((self.d, 1), dtype=complex)
  58. for i, v in enumerate(self.state):
  59. if (i & where) == 0:
  60. output[i] += v*ir2
  61. output[i ^ where] += v*ir2
  62. if (i & where) == 1:
  63. output[i ^ where] += v*ir2
  64. output[i] -= v*ir2
  65. self.state = output
  66. def act_local_rotation(self, qubit, u):
  67. """ Act a local unitary somwhere """
  68. where = 1 << qubit
  69. output = np.zeros((self.d, 1), dtype=complex)
  70. for i, v in enumerate(self.state):
  71. if (i & where) == 0:
  72. output[i] += v*u[0, 0]
  73. output[i ^ where] += v*u[0, 1]
  74. if (i & where) == 1:
  75. output[i ^ where] += v*u[1, 0]
  76. output[i] += v*u[1, 1]
  77. self.state = output
  78. def __str__(self):
  79. s = ""
  80. for i in range(self.d):
  81. label = bin(i)[2:].rjust(self.nqubits, "0")
  82. if abs(self.state[i, 0])>0.00001:
  83. s += "|{}>: {}\n".format(label, self.state[i, 0])
  84. return s