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.

130 lignes
4.1KB

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """
  4. This program generates lookup tables
  5. """
  6. import os, json
  7. from functools import reduce
  8. import itertools as it
  9. import qi
  10. import numpy as np
  11. from tqdm import tqdm
  12. from clifford import decompositions
  13. def find_clifford(needle, haystack):
  14. """ Find the index of a given u within a list of unitaries, up to a global phase """
  15. needle = normalize_global_phase(needle)
  16. for i, t in enumerate(haystack):
  17. if np.allclose(t, needle):
  18. return i
  19. raise IndexError
  20. def normalize_global_phase(m):
  21. """ Normalize the global phase of a matrix """
  22. v = [x for x in m.flatten() if np.abs(x)>0.001][0]
  23. phase = np.arctan2(v.imag, v.real) % np.pi
  24. rot = np.exp(-1j*phase)
  25. return rot * m if rot * v > 0 else -rot*m
  26. def find_cz(bond, c1, c2, commuters, state_table):
  27. """ Find the output of a CZ operation """
  28. # Figure out the target state
  29. state = qi.bond if bond else qi.nobond
  30. target = qi.cz.dot(state_table[bond, c1, c2])
  31. target = normalize_global_phase(target)
  32. # Choose the sets to search over
  33. s1 = commuters if c1 in commuters else xrange(24)
  34. s2 = commuters if c2 in commuters else xrange(24)
  35. # Find a match
  36. for bond, c1p, c2p in it.product([0, 1], s1, s2):
  37. trial = state_table[bond, c1p, c2p]
  38. if np.allclose(target, trial):
  39. return bond, c1p, c2p
  40. # Didn't find anything - this should never happen
  41. raise IndexError
  42. def compose_u(decomposition):
  43. """ Get the unitary representation of a particular decomposition """
  44. matrices = ({"x": qi.sqx, "z": qi.msqz}[c] for c in decomposition)
  45. output = reduce(np.dot, matrices, np.eye(2, dtype=complex))
  46. return normalize_global_phase(output)
  47. def get_unitaries():
  48. """ The Clifford group """
  49. return [compose_u(d) for d in decompositions]
  50. def get_by_name(unitaries):
  51. """ Get a lookup table of cliffords by name """
  52. return {name: find_clifford(u, unitaries)
  53. for name, u in qi.by_name.items()}
  54. def get_conjugation_table(unitaries):
  55. """ Construct the conjugation table """
  56. return np.array([find_clifford(qi.hermitian_conjugate(u), unitaries) for u in unitaries])
  57. def get_times_table(unitaries):
  58. """ Construct the times-table """
  59. return np.array([[find_clifford(u.dot(v), unitaries) for v in unitaries]
  60. for u in tqdm(unitaries, desc="Building times-table")])
  61. def get_state_table(unitaries):
  62. """ Cache a table of state to speed up a little bit """
  63. state_table = np.zeros((2, 24, 24, 4), dtype=complex)
  64. params = list(it.product([0, 1], range(24), range(24)))
  65. for bond, i, j in tqdm(params, desc="Building state table"):
  66. state = qi.bond if bond else qi.nobond
  67. kp = np.kron(unitaries[i], unitaries[j])
  68. state_table[bond, i, j, :] = normalize_global_phase(np.dot(kp, state).T)
  69. return state_table
  70. def get_cz_table(unitaries):
  71. """ Compute the lookup table for the CZ (A&B eq. 9) """
  72. commuters = (qi.id, qi.px, qi.pz, qi.ph, qi.hermitian_conjugate(qi.ph))
  73. commuters = [find_clifford(u, unitaries) for u in commuters]
  74. state_table = get_state_table(unitaries)
  75. # TODO: it's symmetric. this can be much faster
  76. cz_table = np.zeros((2, 24, 24, 3))
  77. rows = list(it.product([0, 1], range(24), range(24)))
  78. for bond, c1, c2 in tqdm(rows, desc="Building CZ table"):
  79. cz_table[bond, c1, c2] = find_cz(bond, c1, c2, commuters, state_table)
  80. return cz_table
  81. if __name__ == "__main__":
  82. # Spend time loading the stuff
  83. unitaries = get_unitaries()
  84. by_name = get_by_name(unitaries)
  85. conjugation_table = get_conjugation_table(unitaries)
  86. times_table = get_times_table(unitaries)
  87. cz_table = get_cz_table(unitaries)
  88. # Write it all to disk
  89. #print __file__
  90. #directory = os.path.dirname(os.path.realpath(__file__))
  91. #print directory
  92. #where = os.path.join(directory, "tables/")
  93. #os.chdir(where)
  94. #np.save("unitaries.npy", unitaries)
  95. #np.save("conjugation_table.npy", conjugation_table)
  96. #np.save("times_table.npy", times_table)
  97. # np.save("cz_table.npy", cz_table)
  98. #with open("by_name.json", "wb") as f:
  99. #json.dump(by_name, f)