mimiqcircuits.decomposition.rules

Rewrite rules for quantum circuit decomposition.

Available rules:
class mimiqcircuits.decomposition.rules.CanonicalRewrite[source]

Bases: RewriteRule

Rewrite rule that decomposes operations using their built-in decomposition.

This rule delegates to each operation’s _decompose method, which typically reduces gates to a minimal set of primitives (GateU, GateCX, etc.).

The canonical decomposition is the default decomposition defined by each gate class. Most gates decompose down to GateU (arbitrary single-qubit) and GateCX (two-qubit entangling gate).

Example

>>> from mimiqcircuits import GateH
>>> from mimiqcircuits.decomposition import CanonicalRewrite
>>> rule = CanonicalRewrite()
>>> rule.matches(GateH())
True
>>> circ = rule.decompose_step(GateH(), [0], [], [])
>>> print(circ)
1-qubit circuit with 1 instruction:
└── U((1/2)*pi, 0, pi, 0.0) @ q[0]
matches(op)[source]

Check if this rule can decompose the operation.

Matches every operation that has a canonical decomposition, that is whose supports_canonical_rewrite() is true. The answer does not depend on any basis: an operation that CanonicalBasis keeps terminal (such as ResetX) still matches, so other bases can expand it. Primitives without a decomposition (GateU, GateCX, Measure, Reset, Barrier, …) do not match.

Parameters:

op (Operation) – The operation to check.

Returns:

True if the operation should be rewritten by canonical decomposition.

Return type:

bool

decompose_step(op, qubits, bits, zvars)[source]

Decompose the operation using its built-in decomposition.

Parameters:
  • op (Operation) – The operation to decompose.

  • qubits (Sequence[int]) – Qubit indices for the operation.

  • bits (Sequence[int]) – Classical bit indices for the operation.

  • zvars (Sequence[int]) – Z-variable indices for the operation.

Returns:

A Circuit containing the decomposed instructions.

Return type:

Circuit

class mimiqcircuits.decomposition.rules.FlattenContainers[source]

Bases: RewriteRule

Flatten container operations into their constituent instructions.

This rule expands: - GateCall - Block - Inverse(GateCall) - Inverse(Block) (if present)

The rule does not perform gate-level decomposition; it only expands container structure. Decomposition behavior is delegated to CanonicalRewrite.

matches(op)[source]

Check if an operation is a flattenable container.

decompose_step(op, qubits, bits, zvars)[source]

Flatten one container operation.

class mimiqcircuits.decomposition.rules.ZYZRewrite[source]

Bases: RewriteRule

Rewrite rule for ZYZ Euler angle decomposition.

Decomposes single-qubit unitaries into the ZYZ Euler angle form: RZ(phi) * RY(theta) * RZ(lambda)

This is a standard decomposition for arbitrary single-qubit gates, producing only Z and Y rotations (plus a global phase for GateU).

Supported operations:
  • GateU(theta, phi, lambda, gamma) -> RZ(lambda) * RY(theta) * RZ(phi) * Phase(gamma)

  • GateRX(theta) -> S * RY(theta) * Sdg

Identity rotations (angle = 0) are omitted from the output.

Example

>>> from mimiqcircuits import GateU
>>> from mimiqcircuits.decomposition import ZYZRewrite
>>> from symengine import pi
>>> rule = ZYZRewrite()
>>> circ = rule.decompose_step(GateU(pi/2, pi/4, pi/3), [0], [], [])
matches(op)[source]

Check if this rule can decompose the operation.

Matches GateU (unless it’s identity) and GateRX.

Parameters:

op (Operation) – The operation to check.

Returns:

True if this rule can decompose the operation.

Return type:

bool

decompose_step(op, qubits, bits, zvars)[source]

Apply ZYZ decomposition to the operation.

Parameters:
  • op (Operation) – The operation to decompose (GateU or GateRX).

  • qubits (Sequence[int]) – Qubit indices for the operation.

  • bits (Sequence[int]) – Classical bit indices (unused).

  • zvars (Sequence[int]) – Z-variable indices (unused).

Returns:

A Circuit containing the decomposed instructions.

Raises:

DecompositionError – If the operation is not supported.

Return type:

Circuit

class mimiqcircuits.decomposition.rules.SpecialAngleRewrite(only_cliffords=False)[source]

Bases: RewriteRule

Rewrite rule for decomposing rotations with special angles to Clifford+T.

Decomposes single-qubit rotations whose angle is a multiple of pi/4 into explicit Clifford or Clifford+T gates.

This rule only matches rotations with angles k*pi/4 (or k*pi/2 in Clifford-only mode). Generic rotations with arbitrary angles are not matched.

Parameters:

only_cliffords (bool) – If True, only match angles k*pi/2 (Clifford gates only). If False (default), match angles k*pi/4 (Clifford+T).

Supported operations:
  • GateRX(theta) where theta = k*pi/4

  • GateRY(theta) where theta = k*pi/4

  • GateRZ(lambda) where lambda = k*pi/4

Example

>>> from mimiqcircuits import GateRZ
>>> from mimiqcircuits.decomposition import SpecialAngleRewrite
>>> from symengine import pi
>>> rule = SpecialAngleRewrite()
>>> rule.matches(GateRZ(pi/4))  # True, decomposes to T
True
>>> rule.matches(GateRZ(0.123))  # False, not a special angle
False
only_cliffords: bool
matches(op)[source]

Check if this rule can decompose the operation.

Parameters:

op (Operation) – The operation to check.

Returns:

True if the operation is a rotation with a special angle.

Return type:

bool

decompose_step(op, qubits, bits, zvars)[source]

Decompose the rotation to Clifford+T gates.

Parameters:
  • op (Operation) – The rotation operation to decompose.

  • qubits (Sequence[int]) – Qubit indices for the operation.

  • bits (Sequence[int]) – Classical bit indices (unused).

  • zvars (Sequence[int]) – Z-variable indices (unused).

Returns:

A Circuit containing the decomposed instructions.

Raises:

DecompositionError – If the operation cannot be decomposed.

Return type:

Circuit

__init__(only_cliffords=False)
class mimiqcircuits.decomposition.rules.ToZRotationRewrite[source]

Bases: RewriteRule

Rewrite rule that converts RX and RY rotations to RZ + Clifford gates.

This is useful for gate sets where only Z-rotations are available as the parametric rotation (e.g., some hardware native gate sets).

Transformations:
  • RX(theta) -> H * RZ(theta) * H

  • RY(theta) -> Sdg * H * RZ(theta) * H * S

Example

>>> from mimiqcircuits import GateRX, GateRY
>>> from mimiqcircuits.decomposition import ToZRotationRewrite
>>> from symengine import pi
>>> rule = ToZRotationRewrite()
>>> circ = rule.decompose_step(GateRX(pi/3), [0], [], [])
matches(op)[source]

Check if this rule can decompose the operation.

Parameters:

op (Operation) – The operation to check.

Returns:

True for GateRX and GateRY operations.

Return type:

bool

decompose_step(op, qubits, bits, zvars)[source]

Convert RX or RY to RZ + Clifford gates.

Parameters:
  • op (Operation) – The rotation operation (GateRX or GateRY).

  • qubits (Sequence[int]) – Qubit indices for the operation.

  • bits (Sequence[int]) – Classical bit indices (unused).

  • zvars (Sequence[int]) – Z-variable indices (unused).

Returns:

A Circuit containing the decomposed instructions.

Raises:

DecompositionError – If the operation is not supported.

Return type:

Circuit

class mimiqcircuits.decomposition.rules.ToffoliToCliffordTRewrite[source]

Bases: RewriteRule

Decompose GateCCX into an explicit Clifford+T sequence.

matches(op)[source]

Return True for Toffoli (CCX) gates.

decompose_step(op, qubits, bits, zvars)[source]

Apply the standard 7-T Toffoli decomposition.

class mimiqcircuits.decomposition.rules.SolovayKitaevRewrite(depth=3, simplify=True, net_max_depth=10, net_max_points=50000, net_min_dist=0.02)[source]

Bases: RewriteRule

Rewrite rule using the Solovay-Kitaev algorithm.

Approximates arbitrary single-qubit unitaries using a sequence of Clifford+T gates. The algorithm recursively refines an initial approximation using group commutators, achieving ε-approximation with O(log^c(1/ε)) gates.

Parameters:
  • depth (int) – Recursion depth (default: 3). Higher = better precision, more gates.

  • simplify (bool) – Whether to simplify the resulting sequence (default: True).

  • net_max_depth (int) – Maximum depth for epsilon-net generation (default: 15).

  • net_max_points (int) – Maximum points in epsilon-net (default: 100,000).

  • net_min_dist (float) – Minimum distance between epsilon-net points (default: 0.01).

Supported operations:
  • GateRZ(λ): Z-rotation by angle λ

  • GateRY(θ): Y-rotation by angle θ

  • GateRX(θ): X-rotation by angle θ

  • GateU(θ, φ, λ, γ): General single-qubit unitary

Symbolic parameters are NOT supported.

Example

>>> from mimiqcircuits import GateRZ
>>> from mimiqcircuits.decomposition import SolovayKitaevRewrite
>>> rule = SolovayKitaevRewrite(depth=0)
>>> circ = rule.decompose_step(GateRZ(0.123), [0], [], [])

Note

The first call may be slow due to epsilon-net generation. Subsequent calls reuse the cached net.

depth: int = 3
simplify: bool = True
net_max_depth: int = 10
net_max_points: int = 50000
net_min_dist: float = 0.02
matches(op)[source]

Check if this rule can decompose the operation.

Matches single-qubit rotations with concrete (non-symbolic) angles.

Parameters:

op (Operation) – The operation to check.

Returns:

True if this rule can decompose the operation.

Return type:

bool

decompose_step(op, qubits, bits, zvars)[source]

Decompose the operation using Solovay-Kitaev.

Parameters:
  • op (Operation) – The operation to decompose.

  • qubits (Sequence[int]) – Qubit indices for the operation.

  • bits (Sequence[int]) – Classical bit indices (unused).

  • zvars (Sequence[int]) – Z-variable indices (unused).

Returns:

A Circuit containing the Clifford+T approximation.

Raises:

DecompositionError – If the operation cannot be decomposed.

Return type:

Circuit

__init__(depth=3, simplify=True, net_max_depth=10, net_max_points=50000, net_min_dist=0.02)
class mimiqcircuits.decomposition.rules.GridSynthRewrite(epsilon=1e-10, seed=0)[source]

Bases: RewriteRule

Rewrite rule that approximates GateRZ with a Clifford+T sequence, using the Ross–Selinger gridsynth algorithm.

For GateRZ(λ) the rule emits a sequence of GateH, GateS, GateSDG, GateZ, GateT and GateX whose unitary V satisfies min_φ ‖RZ(λ) − e^{iφ}V‖ ≤ epsilon in operator norm. The approximation holds up to a global phase, which is dropped. The T-count is about 3·log₂(1/epsilon) and, except for rare failures of the integer factoring step, optimal among ancilla-free Clifford+T circuits with this error. Angles that are multiples of π/4 give their exact short decomposition.

The factoring step is randomized. For a fixed seed, the same angle and tolerance always give the same sequence. Results are cached per angle, since circuits often repeat the same rotation.

The synthesis runs in the compiled mimiqcircuits._core extension without holding the GIL, so several threads can synthesize in parallel.

Parameters:
  • epsilon (float) – Operator-norm tolerance, 1e-100 <= epsilon < 1 (default 1e-10). A rotation takes a few milliseconds at 1e-10 and up to about a second at 1e-100.

  • seed (int) – Seed of the randomized factoring step, an integer in [0, 2**64) (default 0).

Raises:
  • ValueError – If epsilon or seed is out of range.

  • TypeError – If epsilon is not a real number or seed is not an integer.

Supported operations:
  • GateRZ(λ) with a numeric angle λ.

Symbolic angles are not matched. GateRX, GateRY and GateU must first be reduced to Z-rotations, for example with ZYZRewrite and ToZRotationRewrite. CliffordTBasis does this and uses this rule by default.

Example

>>> from mimiqcircuits import GateRZ, GateT
>>> from mimiqcircuits.decomposition import GridSynthRewrite
>>> def tcount(c):
...     return sum(isinstance(i.operation, GateT) for i in c)
>>> # Approximate one rotation to the default tolerance 1e-10
>>> circ = GridSynthRewrite().decompose_step(GateRZ(0.123), [0], [], [])
>>> # A coarser tolerance gives fewer T gates
>>> coarse = GridSynthRewrite(epsilon=1e-4).decompose_step(GateRZ(0.123), [0], [], [])
>>> tcount(coarse) < tcount(circ)
True

References

N. J. Ross and P. Selinger, “Optimal ancilla-free Clifford+T approximation of z-rotations”, Quantum Inf. Comput. 16, 901 (2016), arXiv:1403.2975.

epsilon: float = 1e-10
seed: int = 0
matches(op)[source]

Check if this rule can decompose the operation.

Parameters:

op (Operation) – The operation to check.

Returns:

True if the operation is a GateRZ with a numeric angle.

Return type:

bool

decompose_step(op, qubits, bits, zvars)[source]

Decompose the Z-rotation into Clifford+T gates.

Parameters:
  • op (Operation) – The GateRZ to decompose.

  • qubits (Sequence[int]) – Qubit indices for the operation.

  • bits (Sequence[int]) – Classical bit indices (unused).

  • zvars (Sequence[int]) – Z-variable indices (unused).

Returns:

A Circuit containing the Clifford+T approximation.

Raises:
Return type:

Circuit

__init__(epsilon=1e-10, seed=0)

Modules

canonical

Canonical rewrite rule for decomposing operations to GateU and GateCX.

flatten_containers

Rewrite rule for flattening container operations.

gridsynth

Ross–Selinger gridsynth: Clifford+T approximation of Z-rotations.

solovay_kitaev

Solovay-Kitaev algorithm for approximating arbitrary unitaries with Clifford+T.

special_angle

Special angle rewrite rule for Clifford+T decomposition.

to_z_rotation

Rewrite rule for converting X and Y rotations to Z rotations.

toffoli_to_clifford_t

Rewrite rule for decomposing Toffoli into Clifford+T.

zyz

ZYZ Euler angle decomposition rewrite rule.