From 0947f34f86b71bae898ac8bffdb55dff0cddeb75 Mon Sep 17 00:00:00 2001 From: Boldi Date: Mon, 15 Jul 2024 23:18:19 +0100 Subject: [PATCH 1/3] Fix paralell edges --- pyzx/tensor.py | 6 ++---- tests/test_tensor.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/pyzx/tensor.py b/pyzx/tensor.py index 1e931fc9..ef6da703 100644 --- a/pyzx/tensor.py +++ b/pyzx/tensor.py @@ -85,9 +85,7 @@ def W_to_tensor(arity: int) -> np.ndarray: return m def pop_and_shift(verts, indices): - res = [] - for v in verts: - res.append(indices[v].pop()) + res = [indices[v].pop() for v in verts] for i in sorted(res,reverse=True): for w,l in indices.items(): l2 = [] @@ -131,7 +129,7 @@ def tensorfy(g: 'BaseGraph[VT,ET]', preserve_scalar:bool=True) -> np.ndarray: for i,r in enumerate(sorted(verts_row.keys())): for v in sorted(verts_row[r]): - neigh = list(g.neighbors(v)) + neigh = [list(set(g.edge_st(e)) - {v})[0] for e in g.incident_edges(v)] d = len(neigh) if v in inputs: if types[v] != VertexType.BOUNDARY: raise ValueError("Wrong type for input:", v, types[v]) diff --git a/tests/test_tensor.py b/tests/test_tensor.py index d7e1d966..778d9174 100644 --- a/tests/test_tensor.py +++ b/tests/test_tensor.py @@ -21,10 +21,12 @@ from types import ModuleType from typing import Optional + if __name__ == '__main__': sys.path.append('..') sys.path.append('.') from pyzx.graph import Graph +from pyzx.graph.multigraph import Multigraph from pyzx.generate import cliffords from pyzx.circuit import Circuit @@ -132,6 +134,22 @@ def test_adjoint(self): circ_adj = tensorfy(circ.adjoint()) self.assertTrue(compare_tensors(t_adj,circ_adj)) + def test_multiedge_scalar(self): + g = Multigraph() + g._auto_simplify = False + i1 = g.add_vertex(1,0,0) + i2 = g.add_vertex(2,1,0) + g.add_edges([(i1, i2)] * 3) + self.assertTrue(compare_tensors(g, np.array([np.sqrt(2)**(-1)]), preserve_scalar=True)) + + def test_self_loop_scalar(self): + g = Multigraph() + g.set_auto_simplify(False) + i1 = g.add_vertex(1,0,0) + g.add_edge((i1, i1)) + self.assertTrue(compare_tensors(g, np.array([0]), preserve_scalar=True)) + + if __name__ == '__main__': unittest.main() From e49c74c7e4914fc3fca0e8c8a65966963daddd8c Mon Sep 17 00:00:00 2001 From: Boldi Date: Tue, 16 Jul 2024 10:57:15 +0100 Subject: [PATCH 2/3] Fix self loops, add more tests --- pyzx/tensor.py | 17 ++++++++++++++--- tests/test_tensor.py | 29 ++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/pyzx/tensor.py b/pyzx/tensor.py index ef6da703..85c08bd9 100644 --- a/pyzx/tensor.py +++ b/pyzx/tensor.py @@ -27,6 +27,7 @@ 'adjoint', 'is_unitary','tensor_to_matrix', 'find_scalar_correction'] +import itertools from math import pi, sqrt from typing import Optional @@ -85,7 +86,7 @@ def W_to_tensor(arity: int) -> np.ndarray: return m def pop_and_shift(verts, indices): - res = [indices[v].pop() for v in verts] + res = [indices[v].pop() for v in verts if v in indices] for i in sorted(res,reverse=True): for w,l in indices.items(): l2 = [] @@ -129,8 +130,11 @@ def tensorfy(g: 'BaseGraph[VT,ET]', preserve_scalar:bool=True) -> np.ndarray: for i,r in enumerate(sorted(verts_row.keys())): for v in sorted(verts_row[r]): - neigh = [list(set(g.edge_st(e)) - {v})[0] for e in g.incident_edges(v)] - d = len(neigh) + neigh = list(itertools.chain.from_iterable( + set(g.edge_st(e)) - {v} for e in g.incident_edges(v) + )) + self_loops = [e for e in g.incident_edges(v) if g.edge_s(e) == g.edge_t(e)] + d = len(neigh) + len(self_loops) * 2 if v in inputs: if types[v] != VertexType.BOUNDARY: raise ValueError("Wrong type for input:", v, types[v]) continue # inputs already taken care of @@ -159,6 +163,13 @@ def tensorfy(g: 'BaseGraph[VT,ET]', preserve_scalar:bool=True) -> np.ndarray: t = Z_box_to_tensor(d, label) else: raise ValueError("Vertex %s has non-ZXH type but is not an input or output" % str(v)) + for sl in self_loops: + if g.edge_type(sl) == EdgeType.HADAMARD: + t = np.tensordot(t,had) + elif g.edge_type(sl) == EdgeType.SIMPLE: + t = np.trace(t) + else: + raise NotImplementedError(f"Tensor contraction for {repr(sl)} self loops are not implemented.") nn = list(filter(lambda n: rows[n] Date: Tue, 16 Jul 2024 14:04:25 +0100 Subject: [PATCH 3/3] Fix error message --- pyzx/tensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyzx/tensor.py b/pyzx/tensor.py index 85c08bd9..cad0e6f3 100644 --- a/pyzx/tensor.py +++ b/pyzx/tensor.py @@ -169,7 +169,7 @@ def tensorfy(g: 'BaseGraph[VT,ET]', preserve_scalar:bool=True) -> np.ndarray: elif g.edge_type(sl) == EdgeType.SIMPLE: t = np.trace(t) else: - raise NotImplementedError(f"Tensor contraction for {repr(sl)} self loops are not implemented.") + raise NotImplementedError(f"Tensor contraction with {repr(sl)} self-loops is not implemented.") nn = list(filter(lambda n: rows[n]