Anders and Briegel in Python
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

123 行
3.8KB

  1. import numpy as np
  2. from tqdm import tqdm
  3. import itertools as it
  4. from abp import clifford
  5. from abp import build_tables
  6. from abp import qi
  7. import nose
  8. from nose.tools import raises
  9. def identify_pauli(m):
  10. """ Given a signed Pauli matrix, name it. """
  11. for sign in (+1, -1):
  12. for pauli_label, pauli in zip("xyz", qi.paulis):
  13. if np.allclose(sign * pauli, m):
  14. return sign, pauli_label
  15. def test_find_clifford():
  16. """ Test that slightly suspicious function """
  17. assert build_tables.find_clifford(qi.id, clifford.unitaries) == 0
  18. assert build_tables.find_clifford(qi.px, clifford.unitaries) == 1
  19. @raises(IndexError)
  20. def test_find_non_clifford():
  21. """ Test that looking for a non-Clifford gate fails """
  22. build_tables.find_clifford(qi.t, clifford.unitaries)
  23. def get_action(u):
  24. """ What does this unitary operator do to the Paulis? """
  25. return [identify_pauli(u.dot(p.dot(qi.hermitian_conjugate(u)))) for p in qi.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 clifford.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. for name, u in qi.by_name.items():
  35. build_tables.find_clifford(u, clifford.unitaries)
  36. def test_group():
  37. """ Test we are really in a group """
  38. matches = set()
  39. for a, b in tqdm(it.combinations(clifford.unitaries, 2), "Testing this is a group"):
  40. i = build_tables.find_clifford(a.dot(b), clifford.unitaries)
  41. matches.add(i)
  42. assert len(matches) == 24
  43. def test_conjugation_table():
  44. """ Check that the table of Hermitian conjugates is okay """
  45. assert len(set(clifford.conjugation_table)) == 24
  46. def test_cz_table_makes_sense():
  47. """ Test the CZ table is symmetric """
  48. hadamard = clifford.hadamard
  49. assert all(clifford.cz_table[0, 0, 0] == [1, 0, 0])
  50. assert all(clifford.cz_table[1, 0, 0] == [0, 0, 0])
  51. assert all(
  52. clifford.cz_table[0, hadamard, hadamard] == [0, hadamard, hadamard])
  53. def test_commuters():
  54. """ Test that commutation is good """
  55. assert len(build_tables.get_commuters(clifford.unitaries)) == 4
  56. def test_conjugation():
  57. """ Test that clifford.conugate() agrees with graphsim.LocCliffOp.conjugate """
  58. try:
  59. from anders_briegel import graphsim
  60. except ImportError:
  61. raise nose.SkipTest("Original C++ is not available, skipping test")
  62. for operation_index, transform_index in it.product(range(4), range(24)):
  63. transform = graphsim.LocCliffOp(transform_index)
  64. operation = graphsim.LocCliffOp(operation_index)
  65. phase = operation.conjugate(transform).ph
  66. phase = [1, 0, -1][phase]
  67. new_operation = operation.op
  68. NEW_OPERATION, PHASE = clifford.conjugate(
  69. operation_index, transform_index)
  70. assert new_operation == NEW_OPERATION
  71. assert PHASE == phase
  72. def test_cz_table():
  73. """ Does the CZ code work good? """
  74. state_table = build_tables.get_state_table(clifford.unitaries)
  75. rows = it.product([0, 1], it.combinations_with_replacement(range(24), 2))
  76. for bond, (c1, c2) in rows:
  77. # Pick the input state
  78. input_state = state_table[bond, c1, c2]
  79. # Go and compute the output
  80. computed_output = np.dot(qi.cz, input_state)
  81. computed_output = qi.normalize_global_phase(computed_output)
  82. # Now look up the answer in the table
  83. bondp, c1p, c2p = clifford.cz_table[bond, c1, c2]
  84. table_output = state_table[bondp, c1p, c2p]
  85. assert np.allclose(computed_output, table_output)