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.

75 lines
2.7KB

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. """
  4. Generates and enumerates the 24 elements of the local Clifford group
  5. Following the prescription of Anders (thesis pg. 26):
  6. > Table 2.1: The 24 elements of the local Clifford group. The row index (here called the “sign symbol”) shows how the operator
  7. > U permutes the Pauli operators σ = X, Y, Z under the conjugation σ = ±UσU† . The column index (the “permutation
  8. > symbol”) indicates the sign obtained under the conjugation: For operators U in the I column it is the sign of the permutation
  9. > (indicated on the left). For elements in the X, Y and Z columns, it is this sign only if the conjugated Pauli operator is the one
  10. > indicated by the column header and the opposite sign otherwise.
  11. """
  12. from numpy import *
  13. # Some two-qubit matrices
  14. i = matrix(eye(2, dtype=complex))
  15. px = matrix([[0, 1], [1, 0]], dtype=complex)
  16. py = matrix([[0, -1j], [1j, 0]], dtype=complex)
  17. pz = matrix([[1, 0], [0, -1]], dtype=complex)
  18. h = matrix([[1, 1], [1, -1]], dtype=complex) / sqrt(2)
  19. p = matrix([[1, 0], [0, 1j]], dtype=complex)
  20. paulis = (px, py, pz)
  21. # More two-qubit matrices
  22. s_rotations = [i, p, p*p, p*p*p]
  23. s_names = ["i", "p", "pp", "ppp"]
  24. c_rotations = [i, h, h*p, h*p*p, h*p*p*p, h*p*p*h]
  25. c_names = ["i", "h", "hp", "hpp", "hppp", "hpph"]
  26. def get_sign(x):
  27. """ Get the sign of a number """
  28. return "+" if x>=0 else "-"
  29. def identify_pauli(m):
  30. """ Given a signed Pauli matrix, name it. """
  31. for sign_label, sign in (("+", +1), ("-", -1)):
  32. for pauli_label, pauli in zip("xyz", paulis):
  33. if allclose(sign*pauli, m):
  34. return "{}{}".format(sign_label, pauli_label)
  35. def get_action(u):
  36. """ Get the action of a Pauli matrix on three qubits """
  37. return tuple(identify_pauli(u*p*u.H) for p in paulis)
  38. def cliff_action(permutation, op):
  39. """ Computes the action of a particular local Clifford """
  40. if __name__ == '__main__':
  41. labels = ("a" , "b" , "c" , "d" , "e" , "f")
  42. signs = (+1 , -1 , -1 , -1 , +1 , +1)
  43. permutations = ("xyz" , "yxz" , "zyx" , "xzy" , "yzx" , "zxy")
  44. anders = {}
  45. anders_inv = {}
  46. for label, sign, permutation in zip(labels, signs, permutations):
  47. for op in "ixyz":
  48. signs = [sign if (a == op or op == "i") else -sign for a in "xyz"]
  49. effect = "".join("{}{}".format(get_sign(x), y)
  50. for x, y in zip(signs, permutation))
  51. anders["{}{}".format(op, label)] = effect
  52. anders_inv[effect] = "{}{}".format(op, label)
  53. print anders
  54. print anders_inv
  55. for s, sn in zip(s_rotations, s_names):
  56. for c, cn in zip(c_rotations, c_names):
  57. action = "".join(get_action(s*c))
  58. print anders_inv[action]