Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,4 @@ docs/source/benchmarks
docs/source/gallery
graphix/_version.py
docs/source/sg_execution_times.rst
/.benchmarks/
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased

### Added

- New module `graphix.find_pauliflow` with the $O(N^3)$ Pauli-flow finding algorithm introduced in Mitosek and Backens, 2024 (arXiv:2410.23439).
### Fixed

### Changed
Expand Down
610 changes: 610 additions & 0 deletions graphix/find_pflow.py

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions graphix/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

from typing import TYPE_CHECKING

import graphix.gflow
from graphix.command import E, M, N, X, Z
from graphix.fundamentals import Plane
from graphix.gflow import find_flow, find_gflow, find_odd_neighbor, find_pauliflow, get_layers
from graphix.pattern import Pattern

if TYPE_CHECKING:
Expand Down Expand Up @@ -78,24 +78,24 @@ def generate_from_graph(
meas_planes = dict.fromkeys(measuring_nodes, Plane.XY) if not meas_planes else dict(meas_planes)

# search for flow first
f, l_k = find_flow(graph, inputs_set, outputs_set, meas_planes=meas_planes)
f, l_k = graphix.gflow.find_flow(graph, inputs_set, outputs_set, meas_planes=meas_planes)
if f is not None:
# flow found
pattern = _flow2pattern(graph, angles, inputs, f, l_k)
pattern.reorder_output_nodes(outputs)
return pattern

# no flow found - we try gflow
g, l_k = find_gflow(graph, inputs_set, outputs_set, meas_planes=meas_planes)
if g is not None:
g, l_k = graphix.gflow.find_gflow(graph, inputs_set, outputs_set, meas_planes=meas_planes)
if g is not None and l_k is not None:
# gflow found
pattern = _gflow2pattern(graph, angles, inputs, meas_planes, g, l_k)
pattern.reorder_output_nodes(outputs)
return pattern

# no flow or gflow found - we try pflow
p, l_k = find_pauliflow(graph, inputs_set, outputs_set, meas_planes=meas_planes, meas_angles=angles)
if p is not None:
p, l_k = graphix.gflow.find_pauliflow(graph, inputs_set, outputs_set, meas_planes=meas_planes, meas_angles=angles)
if p is not None and l_k is not None:
# pflow found
pattern = _pflow2pattern(graph, angles, inputs, meas_planes, p, l_k)
pattern.reorder_output_nodes(outputs)
Expand All @@ -112,7 +112,7 @@ def _flow2pattern(
l_k: Mapping[int, int],
) -> Pattern:
"""Construct a measurement pattern from a causal flow according to the theorem 1 of [NJP 9, 250 (2007)]."""
depth, layers = get_layers(l_k)
depth, layers = graphix.gflow.get_layers(l_k)
pattern = Pattern(input_nodes=inputs)
for i in set(graph.nodes) - set(inputs):
pattern.add(N(node=i))
Expand Down Expand Up @@ -143,7 +143,7 @@ def _gflow2pattern(
l_k: Mapping[int, int],
) -> Pattern:
"""Construct a measurement pattern from a generalized flow according to the theorem 2 of [NJP 9, 250 (2007)]."""
depth, layers = get_layers(l_k)
depth, layers = graphix.gflow.get_layers(l_k)
pattern = Pattern(input_nodes=inputs)
for i in set(graph.nodes) - set(inputs):
pattern.add(N(node=i))
Expand All @@ -152,7 +152,7 @@ def _gflow2pattern(
for i in range(depth, 0, -1): # i from depth, depth-1, ... 1
for j in layers[i]:
pattern.add(M(node=j, plane=meas_planes[j], angle=angles[j]))
odd_neighbors = find_odd_neighbor(graph, g[j])
odd_neighbors = graphix.gflow.find_odd_neighbor(graph, g[j])
for k in odd_neighbors - {j}:
pattern.add(Z(node=k, domain={j}))
for k in g[j] - {j}:
Expand All @@ -169,7 +169,7 @@ def _pflow2pattern(
l_k: Mapping[int, int],
) -> Pattern:
"""Construct a measurement pattern from a Pauli flow according to the theorem 4 of [NJP 9, 250 (2007)]."""
depth, layers = get_layers(l_k)
depth, layers = graphix.gflow.get_layers(l_k)
pattern = Pattern(input_nodes=inputs)
for i in set(graph.nodes) - set(inputs):
pattern.add(N(node=i))
Expand All @@ -178,7 +178,7 @@ def _pflow2pattern(
for i in range(depth, 0, -1): # i from depth, depth-1, ... 1
for j in layers[i]:
pattern.add(M(node=j, plane=meas_planes[j], angle=angles[j]))
odd_neighbors = find_odd_neighbor(graph, p[j])
odd_neighbors = graphix.gflow.find_odd_neighbor(graph, p[j])
future_nodes: set[int] = set.union(
*(nodes for (layer, nodes) in layers.items() if layer < i)
) # {k | k > j}, with "j" last corrected node and ">" the Pauli flow ordering
Expand Down
Loading
Loading