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.

116 lines
3.5KB

  1. import numpy as np
  2. import itertools as it
  3. from abp import clifford
  4. from abp import build_tables
  5. from abp import qi
  6. import pytest
  7. def identify_pauli(m):
  8. """ Given a signed Pauli matrix, name it. """
  9. for sign in (+1, -1):
  10. for pauli_label, pauli in zip("xyz", qi.paulis):
  11. if np.allclose(sign * pauli, m):
  12. return sign, pauli_label
  13. def test_find_clifford():
  14. """ Test that slightly suspicious function """
  15. assert build_tables.find_clifford(qi.id, clifford.unitaries) == 0
  16. assert build_tables.find_clifford(qi.px, clifford.unitaries) == 1
  17. def get_action(u):
  18. """ What does this unitary operator do to the Paulis? """
  19. return [identify_pauli(u.dot(p.dot(qi.hermitian_conjugate(u)))) for p in qi.paulis]
  20. def format_action(action):
  21. return "".join("{}{}".format("+" if s >= 0 else "-", p) for s, p in action)
  22. def test_we_have_24_matrices():
  23. """ Check that we have 24 unique actions on the Bloch sphere """
  24. actions = set(tuple(get_action(u)) for u in clifford.unitaries)
  25. assert len(set(actions)) == 24
  26. def test_we_have_all_useful_gates():
  27. """ Check that all the interesting gates are included up to a global phase """
  28. for name, u in list(qi.by_name.items()):
  29. build_tables.find_clifford(u, clifford.unitaries)
  30. def test_group():
  31. """ Test we are really in a group """
  32. matches = set()
  33. for a, b in it.combinations(clifford.unitaries, 2):
  34. i = build_tables.find_clifford(a.dot(b), clifford.unitaries)
  35. matches.add(i)
  36. assert len(matches) == 24
  37. def test_conjugation_table():
  38. """ Check that the table of Hermitian conjugates is okay """
  39. assert len(set(clifford.conjugation_table)) == 24
  40. def test_cz_table_makes_sense():
  41. """ Test the CZ table is symmetric """
  42. hadamard = clifford.hadamard
  43. assert all(clifford.cz_table[0, 0, 0] == [1, 0, 0])
  44. assert all(clifford.cz_table[1, 0, 0] == [0, 0, 0])
  45. assert all(
  46. clifford.cz_table[0, hadamard, hadamard] == [0, hadamard, hadamard])
  47. def test_commuters():
  48. """ Test that commutation is good """
  49. assert len(build_tables.get_commuters(clifford.unitaries)) == 4
  50. def test_conjugation():
  51. """ Test that clifford.conugate() agrees with graphsim.LocCliffOp.conjugate """
  52. try:
  53. from anders_briegel import graphsim
  54. except ImportError:
  55. pytest.skip("Original C++ is not available, skipping test")
  56. for operation_index, transform_index in it.product(list(range(4)), list(range(24))):
  57. transform = graphsim.LocCliffOp(transform_index)
  58. operation = graphsim.LocCliffOp(operation_index)
  59. phase = operation.conjugate(transform).ph
  60. phase = [1, 0, -1][phase]
  61. new_operation = operation.op
  62. NEW_OPERATION, PHASE = clifford.conjugate(
  63. operation_index, transform_index)
  64. assert new_operation == NEW_OPERATION
  65. assert PHASE == phase
  66. def test_cz_table():
  67. """ Does the CZ code work good? """
  68. state_table = build_tables.get_state_table(clifford.unitaries)
  69. rows = it.product([0, 1], it.combinations_with_replacement(list(range(24)), 2))
  70. for bond, (c1, c2) in rows:
  71. # Pick the input state
  72. input_state = state_table[bond, c1, c2]
  73. # Go and compute the output
  74. computed_output = np.dot(qi.cz, input_state)
  75. computed_output = qi.normalize_global_phase(computed_output)
  76. # Now look up the answer in the table
  77. bondp, c1p, c2p = clifford.cz_table[bond, c1, c2]
  78. table_output = state_table[bondp, c1p, c2p]
  79. assert np.allclose(computed_output, table_output)