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.

il y a 8 ans
il y a 8 ans
il y a 8 ans
il y a 8 ans
il y a 8 ans
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. zero = np.array([[1],[0]], dtype=complex)
  33. one = np.array([[0],[1]], dtype=complex)
  34. plus = np.array([[1],[1]], dtype=complex) / np.sqrt(2)
  35. bond = cz.dot(np.kron(plus, plus))
  36. nobond = np.kron(plus, plus)
  37. # Labelling stuff
  38. common_us = id, px, py, pz, ha, ph, sqz, msqz, sqy, msqy, sqx, msqx
  39. names = "identity", "px", "py", "pz", "hadamard", "phase", "sqz", "msqz", "sqy", "msqy", "sqx", "msqx"
  40. by_name = dict(zip(names, common_us))
  41. paulis = px, py, pz
  42. operators = id, px, py, pz
  43. def normalize_global_phase(m):
  44. """ Normalize the global phase of a matrix """
  45. v = (x for x in m.flatten() if np.abs(x) > 0.001).next()
  46. phase = np.arctan2(v.imag, v.real) % np.pi
  47. rot = np.exp(-1j * phase)
  48. return rot * m if rot * v > 0 else -rot * m
  49. class CircuitModel(object):
  50. def __init__(self, nqubits):
  51. self.nqubits = nqubits
  52. self.d = 2**nqubits
  53. self.state = np.zeros((self.d, 1), dtype=complex)
  54. self.state[0, 0]=1
  55. def act_cz(self, control, target):
  56. """ Act a CU somewhere """
  57. control = 1 << control
  58. target = 1 << target
  59. for i in xrange(self.d):
  60. if (i & control) and (i & target):
  61. self.state[i, 0] *= -1
  62. def act_cnot(self, control, target):
  63. """ Act a CNOT """
  64. self.act_hadamard(target)
  65. self.act_cz(control, target)
  66. self.act_hadamard(target)
  67. def act_hadamard(self, qubit):
  68. """ Act a hadamard somewhere """
  69. where = 1 << qubit
  70. output = np.zeros((self.d, 1), dtype=complex)
  71. for i, v in enumerate(self.state):
  72. q = i & where > 0
  73. output[i] += v*ha[q, q]
  74. output[i ^ where] += v*ha[not q, q]
  75. self.state = output
  76. def act_local_rotation(self, qubit, u):
  77. """ Act a local unitary somwhere """
  78. where = 1 << qubit
  79. output = np.zeros((self.d, 1), dtype=complex)
  80. for i, v in enumerate(self.state):
  81. q = i & where > 0
  82. output[i] += v*u[q, q] # TODO this is probably wrong
  83. output[i ^ where] += v*u[not q, q]
  84. self.state = output
  85. def __eq__(self, other):
  86. """ Check whether two quantum states are the same or not
  87. UP TO A GLOBAL PHASE """
  88. a = normalize_global_phase(self.state)
  89. b = normalize_global_phase(other.state)
  90. return np.allclose(a, b)
  91. def __str__(self):
  92. s = ""
  93. for i in range(self.d):
  94. label = bin(i)[2:].rjust(self.nqubits, "0")
  95. if abs(self.state[i, 0])>0.00001:
  96. s += "|{}>: {}\n".format(label, self.state[i, 0].round(3))
  97. return s