Anders and Briegel in Python
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.7KB

  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. q = i & where > 0
  60. output[i] += v*ha[q, q]
  61. output[i ^ where] += v*ha[not q, q]
  62. self.state = output
  63. def act_local_rotation(self, qubit, u):
  64. """ Act a local unitary somwhere """
  65. where = 1 << qubit
  66. output = np.zeros((self.d, 1), dtype=complex)
  67. for i, v in enumerate(self.state):
  68. q = i & where > 0
  69. output[i] += v*u[q, q]
  70. output[i ^ where] += v*u[not q, q]
  71. self.state = output
  72. def __str__(self):
  73. s = ""
  74. for i in range(self.d):
  75. label = bin(i)[2:].rjust(self.nqubits, "0")
  76. if abs(self.state[i, 0])>0.00001:
  77. s += "|{}>: {}\n".format(label, self.state[i, 0])
  78. return s