Anders and Briegel in Python
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

106 linhas
3.4KB

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """
  4. This program generates lookup tables
  5. """
  6. import qi
  7. import numpy as np
  8. from tqdm import tqdm
  9. from functools import reduce
  10. import itertools as it
  11. DECOMPOSITIONS = ("xxxx", "xx", "zzxx", "zz", "zxx", "z", "zzz", "xxz",
  12. "xzx", "xzxxx", "xzzzx", "xxxzx", "xzz", "zzx", "xxx", "x",
  13. "zzzx", "xxzx", "zx", "zxxx", "xxxz", "xzzz", "xz", "xzxx")
  14. def find_clifford(needle, haystack):
  15. """ Find the index of a given u within a list of unitaries, up to a global phase """
  16. for i, t in enumerate(haystack):
  17. for phase in range(8):
  18. if np.allclose(t, np.exp(1j * phase * np.pi / 4.) * needle):
  19. return i
  20. raise IndexError
  21. def find_cz(bond, c1, c2, z, krontable):
  22. """ Find the output of a CZ operation """
  23. # Figure out the target state
  24. state = qi.bond if bond else qi.nobond
  25. target = qi.cz.dot(krontable[c1, c2].dot(state))
  26. # Choose the sets to search over
  27. s1 = z if c1 in z else xrange(24)
  28. s2 = z if c2 in z else xrange(24)
  29. # Find a match
  30. for bond, c1p, c2p in it.product([0, 1], s1, s2):
  31. state = qi.bond if bond else qi.nobond
  32. trial = krontable[c1p, c2p].dot(state)
  33. for phase in range(8):
  34. if np.allclose(target, np.exp(1j * phase * np.pi / 4.) * trial):
  35. return bond, c1p, c2p
  36. # Didn't find anything - this should never happen
  37. raise IndexError
  38. def compose_u(decomposition):
  39. """ Get the unitary representation of a particular decomposition """
  40. matrices = ({"x": qi.sqx, "z": qi.msqz}[c] for c in decomposition)
  41. return reduce(np.dot, matrices, np.matrix(np.eye(2, dtype=complex)))
  42. def get_unitaries(decompositions):
  43. """ The Clifford group """
  44. return [compose_u(d) for d in decompositions]
  45. def hermitian_conjugate(u):
  46. """ Get the hermitian conjugate """
  47. return np.conjugate(np.transpose(u))
  48. def get_conjugation_table(unitaries):
  49. """ Construct the conjugation table """
  50. return np.array([find_clifford(hermitian_conjugate(u), unitaries) for u in unitaries])
  51. def get_times_table(unitaries):
  52. """ Construct the times-table """
  53. return np.array([[find_clifford(u.dot(v), unitaries) for v in unitaries]
  54. for u in tqdm(unitaries)])
  55. def get_krontable():
  56. """ Cache a table of Kronecker products to speed up a little bit """
  57. krontable = np.zeros((24, 24, 4, 4), dtype=complex)
  58. for i, j in it.product(range(24), range(24)):
  59. krontable[i, j,:,:] = np.kron(unitaries[i], unitaries[j])
  60. return krontable
  61. def get_cz_table(unitaries):
  62. """ Compute the lookup table for the CZ (A&B eq. 9) """
  63. z = (qi.id, qi.px, qi.pz, qi.ph, hermitian_conjugate(qi.ph))
  64. z = [find_clifford(u, unitaries) for u in z]
  65. krontable = get_krontable()
  66. cz_table = np.zeros((2, 24, 24, 3))
  67. for bond, c1, c2 in tqdm(list(it.product([0, 1], range(24), range(24)))):
  68. cz_table[bond, c1, c2] = find_cz(bond, c1, c2, z, krontable)
  69. return cz_table
  70. if __name__ == '__main__':
  71. unitaries = get_unitaries(DECOMPOSITIONS)
  72. conjugation_table = get_conjugation_table(unitaries)
  73. times_table = get_times_table(unitaries)
  74. cz_table = get_cz_table(unitaries)
  75. np.save("tables/unitaries.npy", unitaries)
  76. np.save("tables/conjugation_table.npy", conjugation_table)
  77. np.save("tables/times_table.npy", times_table)
  78. np.save("cz_table.npy", cz_table)