Anders and Briegel in Python
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

95 lignes
3.1KB

  1. """
  2. Provides an extremely basic graph structure, based on neighbour lists
  3. """
  4. from collections import defaultdict
  5. import itertools as it
  6. import clifford
  7. class GraphState(object):
  8. def __init__(self):
  9. self.ngbh = defaultdict(set)
  10. self.vops = defaultdict(int)
  11. def add_vertex(self, v):
  12. """ Add a vertex if it doesn't already exist """
  13. if not v in self.ngbh:
  14. self.ngbh[v] = set()
  15. self.vops[v] = clifford.by_name["hadamard"]
  16. def add_edge(self, v1, v2):
  17. """ Add an edge between two vertices in the self """
  18. if not v1 in self.ngbh:
  19. self.vops[v1] = clifford.by_name["hadamard"]
  20. if not v2 in self.ngbh:
  21. self.vops[v2] = clifford.by_name["hadamard"]
  22. self.ngbh[v1].add(v2)
  23. self.ngbh[v2].add(v1)
  24. def del_edge(self, v1, v2):
  25. """ Delete an edge between two vertices in the self """
  26. self.ngbh[v1].remove(v2)
  27. self.ngbh[v2].remove(v1)
  28. def has_edge(self, v1, v2):
  29. """ Test existence of an edge between two vertices in the self """
  30. return v2 in self.ngbh[v1]
  31. def toggle_edge(self, v1, v2):
  32. """ Toggle an edge between two vertices in the self """
  33. if self.has_edge(v1, v2):
  34. self.del_edge(v1, v2)
  35. else:
  36. self.add_edge(v1, v2)
  37. def edgelist(self):
  38. """ Describe a graph as an edgelist """
  39. edges = frozenset(tuple(sorted((i, n)))
  40. for i, v in self.ngbh.items()
  41. for n in v)
  42. return [tuple(e) for e in edges]
  43. def remove_vop(self, a, avoid):
  44. """ Reduces VOP[a] to the identity """
  45. others = self.ngbh[a] - {avoid}
  46. swap_qubit = others.pop() if others else avoid
  47. for v in reversed(clifford.decompositions[self.vops[a]]):
  48. self.local_complementation(a if v == "x" else swap_qubit)
  49. def local_complementation(self, v):
  50. """ As defined in LISTING 1 of Anders & Briegel """
  51. for i, j in it.combinations(self.ngbh[v], 2):
  52. self.toggle_edge(i, j)
  53. # Update VOPs
  54. self.vops[v] = clifford.times_table[
  55. self.vops[v]][clifford.by_name["sqx"]]
  56. for i in self.ngbh[v]:
  57. self.vops[i] = clifford.times_table[
  58. self.vops[i]][clifford.by_name["msqz"]]
  59. def local(self, a, op):
  60. """ Act a local rotation """
  61. self.vops[a] = clifford.times_table[op,self.vops[a]]
  62. def cphase(self, a, b):
  63. """ Act a controlled-phase gate on two qubits """
  64. if self.ngbh[a] - {b}:
  65. self.remove_vop(a, b)
  66. if self.ngbh[b] - {a}:
  67. self.remove_vop(b, a)
  68. if self.ngbh[a] - {b}:
  69. self.remove_vop(a, b)
  70. edge = self.has_edge(a, b)
  71. new_edge, self.vops[a], self.vops[b] = clifford.cz_table[edge, self.vops[a], self.vops[b]]
  72. if new_edge != edge:
  73. self.toggle_edge(a, b)
  74. def __str__(self):
  75. """ Represent as a string for quick debugging """
  76. return "graph:\n vops: {}\n ngbh: {}\n"\
  77. .format(str(dict(self.vops)), str(dict(self.ngbh)))