Pattern data structure

graphix.command module

This module defines standard data structure for pattern commands.

Data validator command classes.

class graphix.command.CommandKind(value)[source]

Tag for command kind.

class graphix.command.N(node: int, state: State = <factory>)[source]

Preparation command.

Parameters:
  • node (int) – Index of the qubit to prepare.

  • state (State, optional) – Initial state, defaults to PLUS.

class graphix.command.M(node: int, measurement: Measurement = Measurement.X, s_domain: set[int] = <factory>, t_domain: set[int] = <factory>)[source]

Measurement command.

Parameters:
  • node (int) – Node index of the measured qubit.

  • measurement (Measurement) – Measurement description.

  • s_domain (set[int], optional) – Domain for the X byproduct operator.

  • t_domain (set[int], optional) – Domain for the Z byproduct operator.

class graphix.command.E(nodes: tuple[int, int])[source]

Entanglement command between two qubits.

Parameters:

nodes (tuple[int, int]) – Pair of nodes to entangle.

class graphix.command.C(node: int, clifford: Clifford)[source]

Local Clifford gate command.

Parameters:
  • node (int) – Node index on which to apply the gate.

  • clifford (Clifford) – Clifford operator to apply.

class graphix.command.X(node: int, domain: set[int] = <factory>)[source]

X correction command.

Parameters:
  • node (int) – Node to correct.

  • domain (set[int], optional) – Domain for the byproduct operator.

class graphix.command.Z(node: int, domain: set[int] = <factory>)[source]

Z correction command.

Parameters:
  • node (int) – Node to correct.

  • domain (set[int], optional) – Domain for the byproduct operator.

graphix.fundamentals module

This module defines standard data structure for Pauli operators.

Fundamental components related to quantum mechanics.

class graphix.fundamentals.Axis(value)[source]

Axis: X, Y or Z.

to_plane_or_axis() Axis[source]

Return the plane or axis of a measurement object.

Return type:

Plane | Axis

class graphix.fundamentals.ComplexUnit(value)[source]

Complex unit: 1, -1, j, -j.

Complex units can be multiplied with other complex units, with Python constants 1, -1, 1j, -1j, and can be negated.

static from_properties(*, sign: Sign = Sign.PLUS, is_imag: bool = False) ComplexUnit[source]

Construct ComplexUnit from its properties.

property is_imag: bool

Return True if j or -j.

property sign: Sign

Return the sign.

static try_from(value: ComplexUnit | SupportsComplex | SupportsFloat | SupportsIndex | complex, rel_tol: float = 1e-09, abs_tol: float = 0.0) ComplexUnit | None[source]

Return the ComplexUnit instance if the value is compatible, None otherwise.

Parameters:
  • value (ComplexUnit | SupportsComplexCtor) – Complex value to convert.

  • rel_tol (float, optional) – Relative tolerance for comparing values, passed to math.isclose(). Default is 1e-9.

  • abs_tol (float, optional) – Absolute tolerance for comparing values, passed to math.isclose(). Default is 0.0.

Returns:

  • ComplexUnit | None

  • Complex unit close to value, or None otherwise.

class graphix.fundamentals.Sign(value)[source]

Sign, plus or minus.

static minus_if(b: bool) Sign[source]

Return - if b is True, + otherwise.

static plus_if(b: bool) Sign[source]

Return + if b is True, - otherwise.

graphix.fundamentals.IXYZ

alias of Literal[I] | Axis

class graphix.fundamentals.Plane(value)[source]

Plane: XY, YZ or XZ.

property axes: tuple[Axis, Axis]

Return the pair of axes that carry the plane.

property cos: Axis

Return the axis of the plane that conventionally carries the cos.

static from_axes(a: Axis, b: Axis) Plane[source]

Return the plane carried by the given axes.

property orth: Axis

Return the axis orthogonal to the plane.

polar(angle: float) tuple[float, float, float][source]
polar(angle: Expression) tuple[Expression, Expression, Expression]

Return the Cartesian coordinates of the point of module 1 at the given angle, following the conventional orientation for cos and sin.

property sin: Axis

Return the axis of the plane that conventionally carries the sin.

to_plane() Plane[source]

Return the plane.

Return type:

Plane

to_plane_or_axis() Plane[source]

Return the plane.

Return type:

Plane

graphix.pauli module

This module defines standard data structure for Pauli operators.

Pauli gates ± {1,j} × {I, X, Y, Z}.

class graphix.pauli.Pauli(symbol: IXYZ = SingletonI.I, unit: ComplexUnit = ComplexUnit.ONE)[source]

Pauli gate: u * {I, X, Y, Z} where u is a complex unit.

Pauli gates can be multiplied with other Pauli gates (with @), with complex units and unit constants (with *), and can be negated.

graphix.measurements module

This module defines data structures for single-qubit measurements in MBQC.

Data structure for single-qubit measurements in MBQC.

class graphix.measurements.Measurement[source]

An MBQC measurement.

Base class for BlochMeasurement and PauliMeasurement.

This class contains three class variables X, Y, and Z for the positive Pauli measurements on the three axes, and three static methods XY, YZ, and XZ, each parameterized by an angle and returning a Bloch measurement on each of the three planes.

The three static methods XY, YZ, and XZ are capitalized, contrary to what PEP 8 prescribes, to remain consistent with the names of the Pauli measurements and to match the names of the planes in the Plane enum.

static XY(angle: Expression | float) BlochMeasurement[source]

Return a Bloch measurement on the XY plane.

static XZ(angle: Expression | float) BlochMeasurement[source]

Return a Bloch measurement on the XZ plane.

static YZ(angle: Expression | float) BlochMeasurement[source]

Return a Bloch measurement on the YZ plane.

__init__() None
abstractmethod clifford(clifford_gate: Clifford) Self[source]

Return a new measurement command with a Clifford applied.

Parameters:

clifford_gate (Clifford) – Clifford gate to apply before the measurement.

Returns:

Equivalent measurement representing the pattern MC.

Return type:

Self

Notes

  • The return type is Self, meaning that a Clifford applied to a Bloch measurement returns a Bloch measurement, and a Clifford applied to a Pauli measurement returns a Pauli measurement.

  • The method Measurement.clifford() does not always commute with the method Measurement.to_bloch(): the underlying Pauli measurement will be the same but the Bloch representation can be on different planes.

Examples

>>> from graphix.clifford import Clifford
>>> from graphix.measurements import Measurement, PauliMeasurement
>>> Measurement.XY(0.25).clifford(Clifford.H)
Measurement.YZ(1.75)
>>> Measurement.X.clifford(Clifford.S)
-Measurement.Y
>>> for pauli in PauliMeasurement:
...     for clifford in Clifford:
...         assert pauli.to_bloch().clifford(clifford).try_to_pauli() == pauli.clifford(clifford)
>>> Measurement.Y.clifford(Clifford.H).to_bloch()
Measurement.XY(1.5)
>>> Measurement.Y.to_bloch().clifford(Clifford.H)
Measurement.YZ(1.5)
abstractmethod downcast_bloch() BlochMeasurement[source]

Return the measurement description if it is already given as an angle and a plane on the Bloch sphere; raise TypeError otherwise.

Examples

>>> from graphix.measurements import Measurement
>>> Measurement.XY(0).downcast_bloch()
Measurement.XY(0)
>>> Measurement.X.downcast_bloch()
Traceback (most recent call last):
    ...
TypeError: Bloch measurement expected, but Pauli measurement was found.
abstractmethod subs(variable: Parameter, substitute: ExpressionOrSupportsFloat) Self[source]

Substitute a parameter with a value or expression in measurement angles.

abstractmethod to_bloch() BlochMeasurement[source]

Return the measurement description as an angle and a plane on the Bloch sphere.

There is no unique Bloch representation for each Pauli measurement. For instance,

>>> from graphix.measurements import Measurement
>>> Measurement.XY(0.5).try_to_pauli() == Measurement.YZ(0.5).try_to_pauli() == Measurement.Y
True

This method follows the convention illustrated below:

>>> from graphix.measurements import PauliMeasurement
>>> for pm in PauliMeasurement:
...     print(f"{pm}.to_bloch() == {pm.to_bloch()}")
+X.to_bloch() == Measurement.XY(0)
-X.to_bloch() == Measurement.XY(1)
+Y.to_bloch() == Measurement.XY(0.5)
-Y.to_bloch() == Measurement.XY(1.5)
+Z.to_bloch() == Measurement.YZ(0)
-Z.to_bloch() == Measurement.YZ(1)
abstractmethod to_pauli_or_bloch(rel_tol: float = 1e-09, abs_tol: float = 0.0) PauliMeasurement | BlochMeasurement[source]

Return the measurement description as a Pauli measurement if possible, a Bloch measurement otherwise.

Parameters:
  • rel_tol (float, optional) – Relative tolerance for comparing angles, passed to math.isclose(). Default is 1e-9.

  • abs_tol (float, optional) – Absolute tolerance for comparing angles, passed to math.isclose(). Default is 0.0.

Returns:

If self is already an instance of PauliMeasurement, the function returns self. If self is an instance of BlochMeasurement, then either the measurement is close to a Pauli measurement (i.e., the angle is close to an integer multiple of π/2) and the corresponding Pauli measurement is returned, or it is not and self is returned.

Return type:

PauliMeasurement | BlochMeasurement

Examples

>>> from graphix.measurements import Measurement
>>> Measurement.XY(0.5).to_pauli_or_bloch()
Measurement.Y
>>> Measurement.XY(0.25).to_pauli_or_bloch()
Measurement.XY(0.25)
abstractmethod try_to_pauli(rel_tol: float = 1e-09, abs_tol: float = 0.0) PauliMeasurement | None[source]

Return the measurement description as a Pauli measurement if possible, or None otherwise.

Parameters:
  • rel_tol (float, optional) – Relative tolerance for comparing angles, passed to math.isclose(). Default is 1e-9.

  • abs_tol (float, optional) – Absolute tolerance for comparing angles, passed to math.isclose(). Default is 0.0.

Returns:

If self is already an instance of PauliMeasurement, the function returns self. If self is an instance of BlochMeasurement, then either the measurement is close to a Pauli measurement (i.e., the angle is close to an integer multiple of π/2) and the corresponding Pauli measurement is returned, or it is not and None is returned.

Return type:

PauliMeasurement | None

Notes

A measurement with a parameterized angle is not considered as Pauli, but can become a Pauli measurement after substitution.

Examples

>>> from graphix.measurements import Measurement
>>> Measurement.XY(0.5).try_to_pauli()
Measurement.Y
>>> Measurement.Y.try_to_pauli()
Measurement.Y
>>> Measurement.XY(0.25).try_to_pauli() is None
True
>>> from graphix.parameter import Placeholder
>>> alpha = Placeholder("alpha")
>>> Measurement.XY(alpha).try_to_pauli() is None
True
>>> Measurement.XY(alpha).subs(alpha, 0.5).try_to_pauli()
Measurement.Y
abstractmethod xreplace(assignment: Mapping[Parameter, ExpressionOrSupportsFloat]) Self[source]

Perform parallel substitution of multiple parameters in measurement angles.

class graphix.measurements.BlochMeasurement(angle: Expression | float, plane: Plane)[source]

An MBQC measurement described by an angle and a plane.

angle

The angle of the measurement in units of \(\pi\). Should be between [0, 2).

Type:

ExpressionOrFloat

plane

The measurement plane.

Type:

graphix.fundamentals.Plane

__init__(angle: Expression | float, plane: Plane) None
clifford(clifford_gate: Clifford) BlochMeasurement[source]

Return a new measurement command with a Clifford applied.

Parameters:

clifford_gate (Clifford) – Clifford gate to apply before the measurement.

Returns:

Equivalent measurement representing the pattern MC.

Return type:

Self

Notes

  • The return type is Self, meaning that a Clifford applied to a Bloch measurement returns a Bloch measurement, and a Clifford applied to a Pauli measurement returns a Pauli measurement.

  • The method Measurement.clifford() does not always commute with the method Measurement.to_bloch(): the underlying Pauli measurement will be the same but the Bloch representation can be on different planes.

Examples

>>> from graphix.clifford import Clifford
>>> from graphix.measurements import Measurement, PauliMeasurement
>>> Measurement.XY(0.25).clifford(Clifford.H)
Measurement.YZ(1.75)
>>> Measurement.X.clifford(Clifford.S)
-Measurement.Y
>>> for pauli in PauliMeasurement:
...     for clifford in Clifford:
...         assert pauli.to_bloch().clifford(clifford).try_to_pauli() == pauli.clifford(clifford)
>>> Measurement.Y.clifford(Clifford.H).to_bloch()
Measurement.XY(1.5)
>>> Measurement.Y.to_bloch().clifford(Clifford.H)
Measurement.YZ(1.5)
downcast_bloch() BlochMeasurement[source]

Return self (overridden from Measurement).

isclose(other: AbstractMeasurement, rel_tol: float = 1e-09, abs_tol: float = 0.0) bool[source]

Determine whether two measurements are close in angle and share the same plane.

This method compares the angle of the current measurement with that of another measurement, using math.isclose() when both angles are floats. The planes must match exactly for the measurements to be considered close. A measurement represented as BlochMeasurement is never considered to be close to a measurement represented as PauliMeasurement.

Parameters:
  • other (AbstractMeasurement) – The measurement to compare against.

  • rel_tol (float, optional) – Relative tolerance for comparing angles, passed to math.isclose(). Default is 1e-9.

  • abs_tol (float, optional) – Absolute tolerance for comparing angles, passed to math.isclose(). Default is 0.0.

Returns:

  • bool

  • True if both measurements lie in the same plane and their angles

  • are equal or close within the given tolerances; False otherwise.

Examples

>>> from graphix.measurements import Measurement
>>> from graphix.fundamentals import Plane
>>> Measurement.XY(0).isclose(Measurement.XY(0))
True
>>> Measurement.XY(0).isclose(Measurement.YZ(0))
False
>>> Measurement.XY(0.1).isclose(Measurement.XY(0))
False
>>> Measurement.XY(0).isclose(Measurement.X)
False
subs(variable: Parameter, substitute: ExpressionOrSupportsFloat) BlochMeasurement[source]

Substitute a parameter with a value or expression in measurement angles.

to_bloch() BlochMeasurement[source]

Return self (overridden from Measurement).

to_pauli_or_bloch(rel_tol: float = 1e-09, abs_tol: float = 0.0) PauliMeasurement | BlochMeasurement[source]

Return the measurement description as a Pauli measurement if possible, a Bloch measurement otherwise.

Parameters:
  • rel_tol (float, optional) – Relative tolerance for comparing angles, passed to math.isclose(). Default is 1e-9.

  • abs_tol (float, optional) – Absolute tolerance for comparing angles, passed to math.isclose(). Default is 0.0.

Returns:

If self is already an instance of PauliMeasurement, the function returns self. If self is an instance of BlochMeasurement, then either the measurement is close to a Pauli measurement (i.e., the angle is close to an integer multiple of π/2) and the corresponding Pauli measurement is returned, or it is not and self is returned.

Return type:

PauliMeasurement | BlochMeasurement

Examples

>>> from graphix.measurements import Measurement
>>> Measurement.XY(0.5).to_pauli_or_bloch()
Measurement.Y
>>> Measurement.XY(0.25).to_pauli_or_bloch()
Measurement.XY(0.25)
to_plane() Plane[source]

Return the plane of a measurement object.

Return type:

Plane

try_to_pauli(rel_tol: float = 1e-09, abs_tol: float = 0.0) PauliMeasurement | None[source]

Return the measurement description as a Pauli measurement if possible, or None otherwise.

Parameters:
  • rel_tol (float, optional) – Relative tolerance for comparing angles, passed to math.isclose(). Default is 1e-9.

  • abs_tol (float, optional) – Absolute tolerance for comparing angles, passed to math.isclose(). Default is 0.0.

Returns:

If self is already an instance of PauliMeasurement, the function returns self. If self is an instance of BlochMeasurement, then either the measurement is close to a Pauli measurement (i.e., the angle is close to an integer multiple of π/2) and the corresponding Pauli measurement is returned, or it is not and None is returned.

Return type:

PauliMeasurement | None

Notes

A measurement with a parameterized angle is not considered as Pauli, but can become a Pauli measurement after substitution.

Examples

>>> from graphix.measurements import Measurement
>>> Measurement.XY(0.5).try_to_pauli()
Measurement.Y
>>> Measurement.Y.try_to_pauli()
Measurement.Y
>>> Measurement.XY(0.25).try_to_pauli() is None
True
>>> from graphix.parameter import Placeholder
>>> alpha = Placeholder("alpha")
>>> Measurement.XY(alpha).try_to_pauli() is None
True
>>> Measurement.XY(alpha).subs(alpha, 0.5).try_to_pauli()
Measurement.Y
xreplace(assignment: Mapping[Parameter, ExpressionOrSupportsFloat]) BlochMeasurement[source]

Perform parallel substitution of multiple parameters in measurement angles.

class graphix.measurements.PauliMeasurement(axis: Axis, sign: Sign = Sign.PLUS)[source]

Pauli measurement.

__init__(axis: Axis, sign: Sign = Sign.PLUS) None
clifford(clifford_gate: Clifford) PauliMeasurement[source]

Return a new measurement command with a Clifford applied.

Parameters:

clifford_gate (Clifford) – Clifford gate to apply before the measurement.

Returns:

Equivalent measurement representing the pattern MC.

Return type:

Self

Notes

  • The return type is Self, meaning that a Clifford applied to a Bloch measurement returns a Bloch measurement, and a Clifford applied to a Pauli measurement returns a Pauli measurement.

  • The method Measurement.clifford() does not always commute with the method Measurement.to_bloch(): the underlying Pauli measurement will be the same but the Bloch representation can be on different planes.

Examples

>>> from graphix.clifford import Clifford
>>> from graphix.measurements import Measurement, PauliMeasurement
>>> Measurement.XY(0.25).clifford(Clifford.H)
Measurement.YZ(1.75)
>>> Measurement.X.clifford(Clifford.S)
-Measurement.Y
>>> for pauli in PauliMeasurement:
...     for clifford in Clifford:
...         assert pauli.to_bloch().clifford(clifford).try_to_pauli() == pauli.clifford(clifford)
>>> Measurement.Y.clifford(Clifford.H).to_bloch()
Measurement.XY(1.5)
>>> Measurement.Y.to_bloch().clifford(Clifford.H)
Measurement.YZ(1.5)
downcast_bloch() BlochMeasurement[source]

Raise TypeError (overridden from Measurement).

isclose(other: AbstractMeasurement, rel_tol: float = 1e-09, abs_tol: float = 0.0) bool[source]

Determine whether this measurement is close to another.

Subclasses should implement a notion of “closeness” between two measurements, comparing measurement-specific attributes. The default comparison for float values involves checking equality within given relative or absolute tolerances.

Parameters:
  • other (AbstractMeasurement) – The measurement to compare against.

  • rel_tol (float, optional) – Relative tolerance for determining closeness. Relevant for comparing angles in the Measurement subclass. Default is 1e-9.

  • abs_tol (float, optional) – Absolute tolerance for determining closeness. Relevant for comparing angles in the Measurement subclass. Default is 0.0.

Returns:

True if this measurement is considered close to other according to the subclass’s comparison rules; False otherwise.

Return type:

bool

subs(variable: Parameter, substitute: ExpressionOrSupportsFloat) Self[source]

Substitute a parameter with a value or expression in measurement angles.

to_bloch() BlochMeasurement[source]

Return the measurement description as an angle and a plane on the Bloch sphere.

There is no unique Bloch representation for each Pauli measurement. For instance,

>>> from graphix.measurements import Measurement
>>> Measurement.XY(0.5).try_to_pauli() == Measurement.YZ(0.5).try_to_pauli() == Measurement.Y
True

This method follows the convention illustrated below:

>>> from graphix.measurements import PauliMeasurement
>>> for pm in PauliMeasurement:
...     print(f"{pm}.to_bloch() == {pm.to_bloch()}")
+X.to_bloch() == Measurement.XY(0)
-X.to_bloch() == Measurement.XY(1)
+Y.to_bloch() == Measurement.XY(0.5)
-Y.to_bloch() == Measurement.XY(1.5)
+Z.to_bloch() == Measurement.YZ(0)
-Z.to_bloch() == Measurement.YZ(1)
to_pauli() Pauli[source]

Return the Pauli gate.

This method returns an instance of Pauli and should not be confused with try_to_pauli(), which overrides the method from Measurement, and returns self.

Examples

>>> from graphix.measurements import Measurement
>>> Measurement.X.to_pauli()
Pauli.X
>>> (-Measurement.Y).to_pauli()
-Pauli.Y
to_pauli_or_bloch(rel_tol: float = 1e-09, abs_tol: float = 0.0) PauliMeasurement[source]

Return self (overridden from Measurement).

to_plane_or_axis() Axis[source]

Return self.axis (overridden from Measurement).

try_to_pauli(rel_tol: float = 1e-09, abs_tol: float = 0.0) PauliMeasurement[source]

Return self (overridden from Measurement).

xreplace(assignment: Mapping[Parameter, ExpressionOrSupportsFloat]) Self[source]

Perform parallel substitution of multiple parameters in measurement angles.

graphix.instruction module

This module defines standard data structure for gate seqence (circuit model) used for graphix.transpiler.Circuit.

Instruction classes.

class graphix.instruction.InstructionKind(value)[source]

Tag for instruction kind.

class graphix.instruction.RX(target: int, angle: Expression | float)[source]

X rotation circuit instruction.

class graphix.instruction.RZ(target: int, angle: Expression | float)[source]

Z rotation circuit instruction.

class graphix.instruction.RY(target: int, angle: Expression | float)[source]

Y rotation circuit instruction.

class graphix.instruction.M(target: int, axis: Axis)[source]

M circuit instruction.

class graphix.instruction.X(target: int)[source]

X circuit instruction.

class graphix.instruction.Y(target: int)[source]

Y circuit instruction.

class graphix.instruction.Z(target: int)[source]

Z circuit instruction.

class graphix.instruction.S(target: int)[source]

S circuit instruction.

class graphix.instruction.H(target: int)[source]

H circuit instruction.

class graphix.instruction.SWAP(targets: tuple[int, int])[source]

SWAP circuit instruction.

class graphix.instruction.CNOT(target: int, control: int)[source]

CNOT circuit instruction.

graphix.parameter module

This module defines parameter objects and parameterized expressions. Parameterized expressions can appear in measurement angles in patterns and rotation angles in circuits, and they can be substituted with actual values.

The module provides generic interfaces for parameters and expressions, as well as a simple Placeholder class that can be used in affine expressions (AffineExpression). Affine expressions are sufficient for transpiling and pattern optimizations (such as standardization, minimization, signal shifting, and Pauli preprocessing), but they do not support simulation.

Parameter objects that support symbolic simulation with sympy are available in a separate package: https://github.com/TeamGraphix/graphix-symbolic.

class graphix.parameter.Expression[source]

Expression with parameters.

class graphix.parameter.Parameter[source]

Abstract class for substituable parameter.

class graphix.parameter.AffineExpression(a: float, x: Parameter, b: float)[source]

Affine expression.

An affine expression is of the form a*x+b where a and b are numbers and x is a parameter.

class graphix.parameter.Placeholder(name: str)[source]

Placeholder for measurement angles.

These placeholder may appear in affine expressions. Placeholders and affine expressions may be used as angles in rotation gates of Circuit class or for the measurement angle of the measurement commands. Pattern optimizations such that standardization, signal shifting and Pauli preprocessing can be applied to patterns with placeholders.

These placeholders and affine expressions do not support arbitrary computation and are not suitable for simulation. You may use Circuit.subs() or Pattern.subs() with an actual value before the computation.

graphix.states module

Quantum states and operators.

class graphix.states.State[source]

Abstract base class for single qubit states objects.

Only requirement for concrete classes is to have a to_statevector() method that returns the statevector representation of the state