Anders and Briegel in Python
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

79 行
2.6KB

  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 tables as clifford
  7. class GraphState(object):
  8. def __init__(self):
  9. self.ngbh = defaultdict(set)
  10. self.vops = defaultdict(int)
  11. def add_edge(self, v1, v2):
  12. """ Add an edge between two vertices in the self """
  13. if not v1 in self.ngbh: self.vops[v1] = clifford.by_name["hadamard"]
  14. if not v2 in self.ngbh: self.vops[v2] = clifford.by_name["hadamard"]
  15. self.ngbh[v1].add(v2)
  16. self.ngbh[v2].add(v1)
  17. def del_edge(self, v1, v2):
  18. """ Delete an edge between two vertices in the self """
  19. self.ngbh[v1].remove(v2)
  20. self.ngbh[v2].remove(v1)
  21. def has_edge(self, v1, v2):
  22. """ Test existence of an edge between two vertices in the self """
  23. return v2 in self.ngbh[v1]
  24. def toggle_edge(self, v1, v2):
  25. """ Toggle an edge between two vertices in the self """
  26. if self.has_edge(v1, v2):
  27. self.del_edge(v1, v2)
  28. else:
  29. self.add_edge(v1, v2)
  30. def edgelist(self):
  31. """ Describe a graph as an edgelist """
  32. edges = frozenset(frozenset((i, n))
  33. for i, v in enumerate(self.ngbh.values())
  34. for n in v)
  35. return [tuple(e) for e in edges]
  36. def remove_vop(self, a, avoid):
  37. """ Reduces VOP[a] to the identity, avoiding (if possible) the use of vertex b as a swapping partner """
  38. others = self.ngbh[a] - {avoid}
  39. swap_qubit = others.pop() if others else avoid
  40. for v in reversed(clifford.decompositions[self.vops[a]]):
  41. self.local_complementation(a if v == "x" else swap_qubit)
  42. def cphase(self, a, b):
  43. """ Act a controlled-phase gate on two qubits """
  44. if self.ngbh[a] - {b}:
  45. self.remove_vop(a, b)
  46. if self.ngbh[b] - {a}:
  47. self.remove_vop(b, a)
  48. if self.ngbh[a] - {b}:
  49. self.remove_vop(a, b)
  50. edge = self.has_edge(a, b)
  51. new_edge, vops[a], vops[b] = cphase_table[edge, vops[a], vops[b]]
  52. if new_edge != edge:
  53. self.toggle_edge(a, b)
  54. def local_complementation(self, v):
  55. """ As defined in LISTING 1 of Anders & Briegel """
  56. for i, j in it.combinations(self.ngbh[v], 2):
  57. self.toggle_edge(i, j)
  58. # Update VOPs
  59. self.vops[v] = clifford.times_table[self.vops[v]][clifford.by_name["sqx"]]
  60. for i in self.ngbh[v]:
  61. self.vops[i] = clifford.times_table[self.vops[i]][clifford.by_name["msqz"]]