Anders and Briegel in Python
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

106 satır
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)