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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- #556, #563: Added a context variable `default_output_format` to unify the default output format for displaying `PauliFlow`, `XZCorrections`, `Pattern`, and `StateVec`.

- #568:
- Added the following methods to `Pattern`. By default, they modify the pattern in place, with an optional `copy` parameter. If `copy=True`, a modified copy is returned instead.
- `apply`, an in-place variant of `map`,
- `blochify`, an in-place variant of `to_bloch`.
- All classes that have `subs` and `xreplace` methods (`Pattern`, `Circuit`, `OpenGraph`, `Measurement`, `PauliFlow`, `XZCorrections`, `DensityMatrix`) now derive from the `Parameterizable` class, which exposes the method `with_parameter` and `with_parameters`, with `subs` and `xreplace` as their respective aliases.
- `Pattern` and `Circuit` now derive from the `InplaceParameterizable` subclass, which additionally provides the following methods:
- `replace_parameter`, an in-place variant of `with_parameter` (or `subs`),
- `replace_parameters`, an in-place variant of `with_parameters` (or `xreplace`).

### Fixed

- #454, #481: Ensure `Pattern.minimize_space` only reduces max-space and does not increase it.
Expand Down Expand Up @@ -128,6 +137,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Dropped support for symbolic simulation and removed `Statevector.xreplace` and `Statevector.subs` methods.
- Added method `DenseState.project_qubit` which defaults to calling `evolve_single` and `remove_qubit`. Added specialized code for this method in `Statevector` class.
- Unified `test_statevec.py` and `test_statevec_backend.py` into a single file.

- #568: Method `Pattern.infer_pauli_measurements` and function `transpile_swaps` now operate in place by default, with an optional `copy` parameter. If `copy=True`, a modified copy is returned instead.

## [0.3.5] - 2026-03-26

Expand Down
7 changes: 1 addition & 6 deletions COMPATIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,4 @@ Graphix does not guarantee backwards compatibility between 0.x version releases.
| `MatGF2.compute_rank` | `MatGF2.rank` |
| `Statevec` | `Statevector` |







- #568: Method `Pattern.infer_pauli_measurements` and function `transpile_swaps` now operate in place by default, with an optional `copy` parameter. If `copy=True`, a modified copy is returned instead.
2 changes: 1 addition & 1 deletion examples/deutsch_jozsa.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
# %%
# Now we preprocess all Pauli measurements, which requires that we move inputs to N commands

pattern = pattern.infer_pauli_measurements()
pattern.infer_pauli_measurements()
pattern.remove_pauli_measurements()
print(
pattern.to_ascii(
Expand Down
2 changes: 1 addition & 1 deletion examples/mbqc_vqe.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def build_mbqc_pattern(self, params: Iterable[ParameterizedAngle]) -> Pattern:
pattern = circuit.transpile().pattern
pattern.standardize()
pattern.shift_signals()
pattern = pattern.infer_pauli_measurements()
pattern.infer_pauli_measurements()
pattern.remove_pauli_measurements()
pattern.minimize_space()
return pattern
Expand Down
2 changes: 1 addition & 1 deletion examples/qaoa.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
# %%
# perform Pauli measurements and plot the new (minimal) graph to perform the same quantum computation

pattern = pattern.infer_pauli_measurements()
pattern.infer_pauli_measurements()
pattern.remove_pauli_measurements()
pattern.draw(flow_from_pattern=False)

Expand Down
2 changes: 1 addition & 1 deletion examples/qft_with_tn.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def qft(circuit: Circuit, n: int) -> None:
# Using graph rewriting rules, we can classically preprocess Pauli measurements.
# We are currently improving the speed of this process by using rust-based graph manipulation backend.
pattern.remove_input_nodes()
pattern = pattern.infer_pauli_measurements()
pattern.infer_pauli_measurements()
pattern.remove_pauli_measurements(standardize=True)


Expand Down
4 changes: 2 additions & 2 deletions examples/tn_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def ansatz(
# %%
# Optimizing by removing Pauli measurements in the pattern.
pattern.remove_input_nodes()
pattern = pattern.infer_pauli_measurements()
pattern.infer_pauli_measurements()
pattern.remove_pauli_measurements(standardize=True)

# %%
Expand Down Expand Up @@ -204,7 +204,7 @@ def cost(
pattern.standardize()
pattern.shift_signals()
pattern.remove_input_nodes()
pattern = pattern.infer_pauli_measurements()
pattern.infer_pauli_measurements()
pattern.remove_pauli_measurements(standardize=True)
mbqc_tn = pattern.simulate(backend="tensornetwork", graph_prep="parallel")
exp_val: float = 0
Expand Down
2 changes: 1 addition & 1 deletion examples/visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

# %%
# next, show the gflow:
pattern = pattern.infer_pauli_measurements()
pattern.infer_pauli_measurements()
pattern.remove_pauli_measurements()
pattern.draw(flow_from_pattern=False, measurement_labels=True)

Expand Down
27 changes: 17 additions & 10 deletions graphix/flow/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
)
from graphix.fundamentals import AbstractMeasurement, AbstractPlanarMeasurement, Axis, Plane
from graphix.measurements import Measurement
from graphix.parameter import Parameterizable
from graphix.pretty_print import OutputFormat, flow_to_str, xzcorr_to_str

if TYPE_CHECKING:
Expand Down Expand Up @@ -74,7 +75,7 @@


@dataclass(frozen=True)
class XZCorrections(Generic[_AM_co]):
class XZCorrections(Parameterizable, Generic[_AM_co]):
"""An unmutable dataclass providing a representation of XZ-corrections.

Attributes
Expand Down Expand Up @@ -518,7 +519,10 @@ def draw(self, **options: Unpack[DrawKwargs]) -> None:
gv = GraphVisualizer.from_xzcorrections(xz_corr=self, **options)
gv.visualize()

def subs(self: XZCorrections[_M], variable: Parameter, substitute: ExpressionOrSupportsFloat) -> XZCorrections[_M]:
@override
def with_parameter(
self: XZCorrections[_M], variable: Parameter, substitute: ExpressionOrSupportsFloat
) -> XZCorrections[_M]:
"""Substitute a parameter with a value or expression in all measurement angles of the open graph.

Parameters
Expand All @@ -537,10 +541,11 @@ def subs(self: XZCorrections[_M], variable: Parameter, substitute: ExpressionOrS
-----
See notes and examples in :func:`OpenGraph.subs`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
See notes and examples in :func:`OpenGraph.subs`.
See notes and examples in :meth:`OpenGraph.with_parameter`.

"""
new_og = self.og.subs(variable, substitute)
new_og = self.og.with_parameter(variable, substitute)
return dataclasses.replace(self, og=new_og)

def xreplace(
@override
def with_parameters(
self: XZCorrections[_M], assignment: Mapping[Parameter, ExpressionOrSupportsFloat]
) -> XZCorrections[_M]:
"""Perform parallel substitution of multiple parameters in measurement angles of the open graph.
Expand All @@ -559,12 +564,12 @@ def xreplace(
-----
See notes and examples in :func:`OpenGraph.xreplace`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
See notes and examples in :func:`OpenGraph.xreplace`.
See notes and examples in :meth:`OpenGraph.with_parameters`.

"""
new_og = self.og.xreplace(assignment)
new_og = self.og.with_parameters(assignment)
return dataclasses.replace(self, og=new_og)


@dataclass(frozen=True)
class PauliFlow(Generic[_AM_co]):
class PauliFlow(Parameterizable, Generic[_AM_co]):
"""An unmutable dataclass providing a representation of a Pauli flow.

Attributes
Expand Down Expand Up @@ -858,7 +863,8 @@ def draw(self, **options: Unpack[DrawKwargs]) -> None:
gv = GraphVisualizer.from_flow(flow=self, **options)
gv.visualize()

def subs( # noqa: PYI019 Annotating with ``Self`` is not possible since ``self`` must be of parametric type ``Measurement``.
@override
def with_parameter( # noqa: PYI019 Annotating with ``Self`` is not possible since ``self`` must be of parametric type ``Measurement``.
self: _T_PauliFlowMeasurement, variable: Parameter, substitute: ExpressionOrSupportsFloat
) -> _T_PauliFlowMeasurement:
"""Substitute a parameter with a value or expression in all measurement angles of the open graph.
Expand All @@ -879,10 +885,11 @@ def subs( # noqa: PYI019 Annotating with ``Self`` is not possible since ``self`
-----
See notes and examples in :func:`OpenGraph.subs`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
See notes and examples in :func:`OpenGraph.subs`.
See notes and examples in :meth:`OpenGraph.with_parameter`.

"""
new_og = self.og.subs(variable, substitute)
new_og = self.og.with_parameter(variable, substitute)
return dataclasses.replace(self, og=new_og)

def xreplace( # noqa: PYI019
@override
def with_parameters( # noqa: PYI019
self: _T_PauliFlowMeasurement, assignment: Mapping[Parameter, ExpressionOrSupportsFloat]
) -> _T_PauliFlowMeasurement:
"""Perform parallel substitution of multiple parameters in measurement angles of the open graph.
Expand All @@ -901,7 +908,7 @@ def xreplace( # noqa: PYI019
-----
See notes and examples in :func:`OpenGraph.xreplace`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
See notes and examples in :func:`OpenGraph.xreplace`.
See notes and examples in :meth:`OpenGraph.with_parameters`.

"""
new_og = self.og.xreplace(assignment)
new_og = self.og.with_parameters(assignment)
return dataclasses.replace(self, og=new_og)

def is_focused(self) -> bool:
Expand Down
Loading
Loading