From 1045b7605d7b44204d72aa7ac4a8c7b81ee6f121 Mon Sep 17 00:00:00 2001 From: Razin Shaikh Date: Tue, 18 Jun 2024 16:27:50 +0100 Subject: [PATCH 1/7] preserve the _auto_simplify property of multigraph --- pyzx/graph/base.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pyzx/graph/base.py b/pyzx/graph/base.py index 8f6cfec4..ed9773b3 100644 --- a/pyzx/graph/base.py +++ b/pyzx/graph/base.py @@ -145,6 +145,8 @@ def copy(self, adjoint:bool=False, backend:Optional[str]=None) -> 'BaseGraph': if (backend is None): backend = type(self).backend g = Graph(backend = backend) + if backend == 'multigraph': + g.set_auto_simplify(self._auto_simplify) g.track_phases = self.track_phases g.scalar = self.scalar.copy(conjugate=adjoint) g.merge_vdata = self.merge_vdata @@ -391,13 +393,16 @@ def subgraph_from_vertices(self,verts: List[VT]) -> 'BaseGraph': """Returns the subgraph consisting of the specified vertices.""" from .graph import Graph # imported here to prevent circularity g = Graph(backend=type(self).backend) + if type(self).backend == 'multigraph': + g.setself._auto_simplify(self._auto_simplify) ty = self.types() rs = self.rows() qs = self.qubits() phase = self.phases() grounds = self.grounds() - edges = [self.edge(v,w) for v in verts for w in verts if self.connected(v,w)] + edges = [e for e in self.edges() \ + if self.edge_st(e)[0] in verts and self.edge_st(e)[1] in verts] vert_map = dict() for v in verts: From 6062401a4f8bccd2bfc960ca8bc0a6a34ad630d9 Mon Sep 17 00:00:00 2001 From: Razin Shaikh Date: Tue, 18 Jun 2024 16:33:00 +0100 Subject: [PATCH 2/7] typo --- pyzx/graph/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyzx/graph/base.py b/pyzx/graph/base.py index ed9773b3..de3d6d3e 100644 --- a/pyzx/graph/base.py +++ b/pyzx/graph/base.py @@ -394,7 +394,7 @@ def subgraph_from_vertices(self,verts: List[VT]) -> 'BaseGraph': from .graph import Graph # imported here to prevent circularity g = Graph(backend=type(self).backend) if type(self).backend == 'multigraph': - g.setself._auto_simplify(self._auto_simplify) + g.set_auto_simplify(self._auto_simplify) ty = self.types() rs = self.rows() qs = self.qubits() From b6e9d5f9b2d3dd9cbeea7d85fb3e1c0b8d5fc2f8 Mon Sep 17 00:00:00 2001 From: Razin Shaikh Date: Tue, 18 Jun 2024 18:18:03 +0100 Subject: [PATCH 3/7] fixing counter issues --- pyzx/graph/diff.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pyzx/graph/diff.py b/pyzx/graph/diff.py index 5f22057a..b682f023 100644 --- a/pyzx/graph/diff.py +++ b/pyzx/graph/diff.py @@ -14,9 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +import copy import json +from collections import Counter from typing import Any, Callable, Generic, Optional, List, Dict, Tuple -import copy from ..utils import VertexType, EdgeType, FractionLike, FloatInt, phase_to_s from .base import BaseGraph, VT, ET @@ -56,10 +57,10 @@ def calculate_diff(self, g1: BaseGraph[VT,ET], g2: BaseGraph[VT,ET]) -> None: self.new_edges = [] self.removed_edges = [] - for e in (new_edges - old_edges): + for e in Counter(new_edges - old_edges).elements(): self.new_edges.append((g2.edge_st(e), g2.edge_type(e))) - for e in (old_edges - new_edges): + for e in Counter(old_edges - new_edges).elements(): s,t = g1.edge_st(e) if s in self.removed_verts or t in self.removed_verts: continue self.removed_edges.append(e) From 1593d31174dbb06f8ef1319230cb257abefd7186 Mon Sep 17 00:00:00 2001 From: Razin Shaikh Date: Wed, 26 Jun 2024 16:18:38 +0100 Subject: [PATCH 4/7] no need to skip certain removed edges. this can cause weird behaviour down the line --- pyzx/graph/diff.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyzx/graph/diff.py b/pyzx/graph/diff.py index b682f023..512c51c6 100644 --- a/pyzx/graph/diff.py +++ b/pyzx/graph/diff.py @@ -62,7 +62,6 @@ def calculate_diff(self, g1: BaseGraph[VT,ET], g2: BaseGraph[VT,ET]) -> None: for e in Counter(old_edges - new_edges).elements(): s,t = g1.edge_st(e) - if s in self.removed_verts or t in self.removed_verts: continue self.removed_edges.append(e) for v in new_verts: @@ -95,8 +94,8 @@ def calculate_diff(self, g1: BaseGraph[VT,ET], g2: BaseGraph[VT,ET]) -> None: def apply_diff(self,g: BaseGraph[VT,ET]) -> BaseGraph[VT,ET]: g = copy.deepcopy(g) - g.remove_vertices(self.removed_verts) g.remove_edges(self.removed_edges) + g.remove_vertices(self.removed_verts) for v in self.new_verts: g.add_vertex_indexed(v) g.set_position(v,*self.changed_pos[v]) From 86b3df1b7fa76d48e463a6d1a71c0f2a87e8ff2a Mon Sep 17 00:00:00 2001 From: Razin Shaikh Date: Wed, 26 Jun 2024 16:40:41 +0100 Subject: [PATCH 5/7] trying to fix mypy error --- pyzx/graph/base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyzx/graph/base.py b/pyzx/graph/base.py index de3d6d3e..06e65213 100644 --- a/pyzx/graph/base.py +++ b/pyzx/graph/base.py @@ -392,8 +392,9 @@ def merge(self, other: 'BaseGraph') -> Tuple[List[VT],List[ET]]: def subgraph_from_vertices(self,verts: List[VT]) -> 'BaseGraph': """Returns the subgraph consisting of the specified vertices.""" from .graph import Graph # imported here to prevent circularity + from .multigraph import Multigraph g = Graph(backend=type(self).backend) - if type(self).backend == 'multigraph': + if isinstance(self, Multigraph): g.set_auto_simplify(self._auto_simplify) ty = self.types() rs = self.rows() From d1b1f44905d18931084f3dbc19d83b01fab1ea32 Mon Sep 17 00:00:00 2001 From: Razin Shaikh Date: Wed, 26 Jun 2024 16:51:18 +0100 Subject: [PATCH 6/7] mypy please be happy --- pyzx/graph/base.py | 5 +++-- pyzx/graph/multigraph.py | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pyzx/graph/base.py b/pyzx/graph/base.py index 06e65213..20ede56d 100644 --- a/pyzx/graph/base.py +++ b/pyzx/graph/base.py @@ -142,10 +142,11 @@ def copy(self, adjoint:bool=False, backend:Optional[str]=None) -> 'BaseGraph': graph did not. """ from .graph import Graph # imported here to prevent circularity + from .multigraph import Multigraph if (backend is None): backend = type(self).backend g = Graph(backend = backend) - if backend == 'multigraph': + if isinstance(self, Multigraph) and isinstance(g, Multigraph): g.set_auto_simplify(self._auto_simplify) g.track_phases = self.track_phases g.scalar = self.scalar.copy(conjugate=adjoint) @@ -394,7 +395,7 @@ def subgraph_from_vertices(self,verts: List[VT]) -> 'BaseGraph': from .graph import Graph # imported here to prevent circularity from .multigraph import Multigraph g = Graph(backend=type(self).backend) - if isinstance(self, Multigraph): + if isinstance(self, Multigraph) and isinstance(g, Multigraph): g.set_auto_simplify(self._auto_simplify) ty = self.types() rs = self.rows() diff --git a/pyzx/graph/multigraph.py b/pyzx/graph/multigraph.py index 7a2541ce..617b683e 100644 --- a/pyzx/graph/multigraph.py +++ b/pyzx/graph/multigraph.py @@ -102,11 +102,11 @@ def clone(self) -> 'Multigraph': cpy.phase_mult = self.phase_mult.copy() cpy.max_phase_index = self.max_phase_index return cpy - + def set_auto_simplify(self, s: bool): """Automatically remove parallel edges as edges are added""" self._auto_simplify = s - + def multigraph(self): return False From 32f7ef7ce602997e66b3c80d695b237484668ee0 Mon Sep 17 00:00:00 2001 From: Razin Shaikh Date: Wed, 26 Jun 2024 17:12:08 +0100 Subject: [PATCH 7/7] type ignore mypy issue, it is a bug in mypy --- pyzx/graph/base.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyzx/graph/base.py b/pyzx/graph/base.py index 20ede56d..c90d0c5b 100644 --- a/pyzx/graph/base.py +++ b/pyzx/graph/base.py @@ -147,7 +147,8 @@ def copy(self, adjoint:bool=False, backend:Optional[str]=None) -> 'BaseGraph': backend = type(self).backend g = Graph(backend = backend) if isinstance(self, Multigraph) and isinstance(g, Multigraph): - g.set_auto_simplify(self._auto_simplify) + g.set_auto_simplify(self._auto_simplify) # type: ignore + # mypy issue https://github.com/python/mypy/issues/16413 g.track_phases = self.track_phases g.scalar = self.scalar.copy(conjugate=adjoint) g.merge_vdata = self.merge_vdata @@ -396,7 +397,8 @@ def subgraph_from_vertices(self,verts: List[VT]) -> 'BaseGraph': from .multigraph import Multigraph g = Graph(backend=type(self).backend) if isinstance(self, Multigraph) and isinstance(g, Multigraph): - g.set_auto_simplify(self._auto_simplify) + g.set_auto_simplify(self._auto_simplify) # type: ignore + # mypy issue https://github.com/python/mypy/issues/16413 ty = self.types() rs = self.rows() qs = self.qubits()