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.3KB

  1. import clifford as lc
  2. from numpy import *
  3. from scipy.linalg import sqrtm
  4. sqy = sqrtm(1j * lc.py)
  5. msqy = sqrtm(-1j * lc.py)
  6. sqz = sqrtm(1j * lc.pz)
  7. msqz = sqrtm(-1j * lc.pz)
  8. sqx = sqrtm(1j * lc.px)
  9. msqx = sqrtm(-1j * lc.px)
  10. paulis = (lc.px, lc.py, lc.pz)
  11. def find_u(u, unitaries):
  12. """ Find the index of a given u within a list of unitaries """
  13. for i, t in enumerate(unitaries):
  14. if allclose(t, u):
  15. return i
  16. return -1
  17. def identify_pauli(m):
  18. """ Given a signed Pauli matrix, name it. """
  19. for sign in (+1, -1):
  20. for pauli_label, pauli in zip("xyz", paulis):
  21. if allclose(sign * pauli, m):
  22. return sign, pauli_label
  23. def get_action(u):
  24. """ What does this unitary operator do to the Paulis? """
  25. return [identify_pauli(u * p * u.H) for p in paulis]
  26. def format_action(action):
  27. return "".join("{}{}".format("+" if s >= 0 else "-", p) for s, p in action)
  28. def test_we_have_24_matrices():
  29. """ Check that we have 24 unique actions on the Bloch sphere """
  30. actions = set(tuple(get_action(u)) for u in lc.unitaries)
  31. assert len(set(actions)) == 24
  32. def test_we_have_all_useful_gates():
  33. """ Check that all the interesting gates are included up to a global phase """
  34. names = "i", "px", "py", "pz", "h", "p"
  35. unitaries = lc.i, lc.px, lc.py, lc.pz, lc.h, lc.p
  36. for name, unitary in zip(names, unitaries):
  37. i = find_u(unitary, lc.unitaries)
  38. assert i >= 0
  39. print "{}\t=\tlc.unitaries[{}]".format(name, i)
  40. names = "sqrt(ix)", "sqrt(-ix)", "sqrt(iy)", "sqrt(-iy)", "sqrt(iz)", "sqrt(-iz)",
  41. unitaries = sqz, msqz, sqy, msqy, sqx, msqx
  42. for name, unitary in zip(names, unitaries):
  43. rotated = [exp(1j * phase * pi / 4.) * unitary for phase in range(8)]
  44. results = [find_u(r, lc.unitaries) for r in rotated]
  45. assert any(x > 0 for x in results)
  46. phase, index = [(i, r) for i, r in enumerate(results) if r>=0][0]
  47. print "exp(1j*{}*pi/4) . {}\t=\tlc.unitaries[{}]".format(phase, name, index)
  48. def test_group():
  49. """ Test we are really in a group """
  50. for a in lc.unitaries:
  51. for b in lc.unitaries:
  52. unitary = a*b
  53. rotated = [exp(1j * phase * pi / 4.) * unitary for phase in range(8)]
  54. results = [find_u(r, lc.unitaries) for r in rotated]
  55. assert len([x for x in results if x>=0])==1