Liking cljdoc? Tell your friends :D

org.soulspace.qclojure.domain.gate-optimization

Gate optimization functions for quantum circuits

This namespace provides functions to optimize quantum circuits by removing redundant gates and simplifying gate sequences. The primary optimization implemented is cancellation of consecutive self-inverse gates.

Self-inverse gates include:

  • Single-qubit gates: X, Y, Z, H (Pauli gates and Hadamard)
  • Two-qubit gates: CNOT (controlled-X gate), CX, CY, CZ, SWAP
  • Three-qubit gates: Toffoli (CCX), Fredkin (CSWAP)

When two identical self-inverse gates are applied consecutively to the same qubit(s), they cancel out and can be removed from the circuit without changing the quantum computation.

Additionally, rotation folding is implemented to combine consecutive rotation gates on the same axis, such as RX(θ₁) followed by RX(θ₂) becoming RX(θ₁+θ₂). This optimization reduces circuit depth and can eliminate rotations that sum to multiples of 2π (effectively identity operations).

Gate optimization functions for quantum circuits

This namespace provides functions to optimize quantum circuits by removing
redundant gates and simplifying gate sequences. The primary optimization
implemented is cancellation of consecutive self-inverse gates.

Self-inverse gates include:
- Single-qubit gates: X, Y, Z, H (Pauli gates and Hadamard)
- Two-qubit gates: CNOT (controlled-X gate), CX, CY, CZ, SWAP
- Three-qubit gates: Toffoli (CCX), Fredkin (CSWAP)
 
When two identical self-inverse gates are applied consecutively to the same
qubit(s), they cancel out and can be removed from the circuit without
changing the quantum computation.

Additionally, rotation folding is implemented to combine consecutive rotation
gates on the same axis, such as RX(θ₁) followed by RX(θ₂) becoming RX(θ₁+θ₂).
This optimization reduces circuit depth and can eliminate rotations that
sum to multiples of 2π (effectively identity operations).
raw docstring

angle-equivalent?clj

(angle-equivalent? angle1 angle2)

Check if two angles are equivalent within tolerance.

This function handles the periodic nature of rotations by comparing angles modulo 2π and considering floating-point precision.

Parameters:

  • angle1: First angle in radians
  • angle2: Second angle in radians

Returns: Boolean indicating if angles are equivalent within tolerance

Check if two angles are equivalent within tolerance.

This function handles the periodic nature of rotations by comparing
angles modulo 2π and considering floating-point precision.

Parameters:
- angle1: First angle in radians
- angle2: Second angle in radians

Returns:
Boolean indicating if angles are equivalent within tolerance
sourceraw docstring

angle-toleranceclj

source

apply-rotation-foldingclj

(apply-rotation-folding operations folding-pairs)

Apply rotation folding transformations to circuit operations.

Takes operations and folding pairs, then returns new operations with rotation gates folded together or removed (if they sum to identity).

Parameters:

  • operations: Vector of gate operations
  • folding-pairs: Vector of [[i j] combined-gate] pairs

Returns: New vector of operations with rotation folding applied

Apply rotation folding transformations to circuit operations.

Takes operations and folding pairs, then returns new operations with
rotation gates folded together or removed (if they sum to identity).

Parameters:
- operations: Vector of gate operations
- folding-pairs: Vector of [[i j] combined-gate] pairs

Returns:
New vector of operations with rotation folding applied
sourceraw docstring

combine-rotation-gatesclj

(combine-rotation-gates gate1 gate2)

Combine two rotation gates on the same axis into a single rotation.

Combines rotation gates on the same axis by adding their angles. Phase gates (:s, :s-dag, :t, :t-dag, :phase) are treated as Z-axis rotations and can combine with each other and with :rz gates.

The result is always returned as the more general parametric form:

  • X-axis rotations → :rx gate
  • Y-axis rotations → :ry gate
  • Z-axis rotations → :rz gate (even for combined phase gates)

Parameters:

  • gate1: First rotation gate with angle θ₁
  • gate2: Second rotation gate with angle θ₂

Returns: New parametric rotation gate with combined angle θ₁ + θ₂, or nil if result is identity

Examples: (combine-rotation-gates {:operation-type :s, :operation-params {:target 0}} {:operation-type :t, :operation-params {:target 0}}) ;=> {:operation-type :rz, :operation-params {:target 0, :angle 2.356...}} ; π/2 + π/4 = 3π/4

Combine two rotation gates on the same axis into a single rotation.

Combines rotation gates on the same axis by adding their angles.
Phase gates (:s, :s-dag, :t, :t-dag, :phase) are treated as Z-axis
rotations and can combine with each other and with :rz gates.

The result is always returned as the more general parametric form:
- X-axis rotations → :rx gate  
- Y-axis rotations → :ry gate
- Z-axis rotations → :rz gate (even for combined phase gates)

Parameters:
- gate1: First rotation gate with angle θ₁
- gate2: Second rotation gate with angle θ₂

Returns:
New parametric rotation gate with combined angle θ₁ + θ₂, or nil if result is identity

Examples:
(combine-rotation-gates 
  {:operation-type :s, :operation-params {:target 0}}
  {:operation-type :t, :operation-params {:target 0}})
;=> {:operation-type :rz, :operation-params {:target 0, :angle 2.356...}} ; π/2 + π/4 = 3π/4
sourceraw docstring

find-cancellation-pairsclj

(find-cancellation-pairs operations)

Find consecutive gate pairs that cancel each other in a circuit.

This function finds pairs of self-inverse gates that can cancel each other, but ONLY when there are no intervening gates that act on any of the same qubits. This ensures quantum mechanical correctness.

Key principle: Two gates can only cancel if all gates between them commute with both canceling gates. In practice, this means no intervening gates can share ANY qubits with the canceling gates.

The algorithm works by:

  1. For each self-inverse operation, finding the next operation on the same qubits
  2. Ensuring no intervening operations share qubits with the canceling gates
  3. Checking if both operations are equivalent self-inverse gates
  4. Collecting pairs that can safely cancel each other
  5. Ensuring no operation is used in multiple pairs

Parameters:

  • operations: Vector of gate operations from a quantum circuit

Returns: Vector of [i j] index pairs where operations i and j cancel each other

Examples: ;; Literally adjacent gates - CAN cancel (find-cancellation-pairs [{:operation-type :h, :operation-params {:target 0}} {:operation-type :h, :operation-params {:target 0}}]) ;=> [[0 1]]

;; Gates separated by operations on different qubits - CAN cancel (find-cancellation-pairs [{:operation-type :h, :operation-params {:target 0}} {:operation-type :x, :operation-params {:target 1}} {:operation-type :h, :operation-params {:target 0}}]) ;=> [[0 2]]

;; Gates separated by operations on shared qubits - CANNOT cancel (find-cancellation-pairs [{:operation-type :h, :operation-params {:target 0}} {:operation-type :cnot, :operation-params {:control 0, :target 1}} {:operation-type :h, :operation-params {:target 0}}]) ;=> [] (no cancellation - CNOT shares qubit 0 with H gates)

Find consecutive gate pairs that cancel each other in a circuit.

This function finds pairs of self-inverse gates that can cancel each other,
but ONLY when there are no intervening gates that act on any of the same
qubits. This ensures quantum mechanical correctness.

Key principle: Two gates can only cancel if all gates between them commute
with both canceling gates. In practice, this means no intervening gates
can share ANY qubits with the canceling gates.

The algorithm works by:
1. For each self-inverse operation, finding the next operation on the same qubits
2. Ensuring no intervening operations share qubits with the canceling gates
3. Checking if both operations are equivalent self-inverse gates
4. Collecting pairs that can safely cancel each other
5. Ensuring no operation is used in multiple pairs

Parameters:
- operations: Vector of gate operations from a quantum circuit

Returns:
Vector of [i j] index pairs where operations i and j cancel each other

Examples:
;; Literally adjacent gates - CAN cancel
(find-cancellation-pairs 
  [{:operation-type :h, :operation-params {:target 0}}
   {:operation-type :h, :operation-params {:target 0}}])
;=> [[0 1]]

;; Gates separated by operations on different qubits - CAN cancel
(find-cancellation-pairs 
  [{:operation-type :h, :operation-params {:target 0}}
   {:operation-type :x, :operation-params {:target 1}}
   {:operation-type :h, :operation-params {:target 0}}])
;=> [[0 2]]

;; Gates separated by operations on shared qubits - CANNOT cancel
(find-cancellation-pairs 
  [{:operation-type :h, :operation-params {:target 0}}
   {:operation-type :cnot, :operation-params {:control 0, :target 1}}
   {:operation-type :h, :operation-params {:target 0}}])
;=> [] (no cancellation - CNOT shares qubit 0 with H gates)
sourceraw docstring

find-inverse-cancellation-pairsclj

(find-inverse-cancellation-pairs operations)

Find consecutive gate pairs that are inverses of each other.

This function identifies pairs of gates that cancel each other through inverse relationships (G₁ · G₂ = I), including both self-inverse gates and explicit inverse pairs like S+S†, T+T†.

Like other cancellation functions, this only finds pairs when no intervening gates act on the same qubits.

Parameters:

  • operations: Vector of gate operations from a quantum circuit

Returns: Vector of [i j] index pairs where operations i and j are inverses

Find consecutive gate pairs that are inverses of each other.

This function identifies pairs of gates that cancel each other through
inverse relationships (G₁ · G₂ = I), including both self-inverse gates
and explicit inverse pairs like S+S†, T+T†.

Like other cancellation functions, this only finds pairs when no
intervening gates act on the same qubits.

Parameters:
- operations: Vector of gate operations from a quantum circuit

Returns:
Vector of [i j] index pairs where operations i and j are inverses
sourceraw docstring

find-next-gate-on-same-qubitsclj

(find-next-gate-on-same-qubits operations start-index target-qubits)

Find the next gate that acts on the same qubits with no interfering gates.

This function looks ahead from a given position to find the next operation that affects the same set of qubits, but ONLY if there are no intervening gates that act on ANY of those qubits. This ensures that gates can only cancel when they are truly consecutive in quantum mechanical terms.

The key insight: Gates can only cancel if ALL intervening gates commute with both canceling gates. In practice, this means no intervening gates can share ANY qubits with the canceling gates.

Parameters:

  • operations: Vector of gate operations
  • start-index: Index to start searching from
  • target-qubits: Set of qubits to match

Returns: Index of next gate acting on same qubits with no interference, or nil if none found

Find the next gate that acts on the same qubits with no interfering gates.

This function looks ahead from a given position to find the next operation
that affects the same set of qubits, but ONLY if there are no intervening
gates that act on ANY of those qubits. This ensures that gates can only
cancel when they are truly consecutive in quantum mechanical terms.

The key insight: Gates can only cancel if ALL intervening gates commute
with both canceling gates. In practice, this means no intervening gates
can share ANY qubits with the canceling gates.

Parameters:
- operations: Vector of gate operations
- start-index: Index to start searching from
- target-qubits: Set of qubits to match

Returns:
Index of next gate acting on same qubits with no interference, or nil if none found
sourceraw docstring

find-rotation-folding-pairsclj

(find-rotation-folding-pairs operations)

Find consecutive rotation gate pairs that can be combined into single rotations.

This function identifies pairs of rotation gates (RX, RY, RZ) on the same qubit that can be combined into a single rotation with the sum of their angles. Like gate cancellation, rotation folding only occurs when no intervening gates act on the same qubit.

Algorithm:

  1. For each rotation gate, find the next rotation gate of the same type on the same qubit
  2. Ensure no intervening gates act on the same qubit
  3. Check if both gates can be combined
  4. Collect pairs and ensure no gate is used in multiple pairs

Parameters:

  • operations: Vector of gate operations from a quantum circuit

Returns: Vector of [i j] index pairs where operations i and j can be folded together, along with the combined gate operation that should replace them

Examples: (find-rotation-folding-pairs [{:operation-type :rx, :operation-params {:target 0, :angle 0.5}} {:operation-type :rx, :operation-params {:target 0, :angle 1.0}}]) ;=> [[[0 1] {:operation-type :rx, :operation-params {:target 0, :angle 1.5}}]]

Find consecutive rotation gate pairs that can be combined into single rotations.

This function identifies pairs of rotation gates (RX, RY, RZ) on the same qubit
that can be combined into a single rotation with the sum of their angles.
Like gate cancellation, rotation folding only occurs when no intervening
gates act on the same qubit.

Algorithm:
1. For each rotation gate, find the next rotation gate of the same type on the same qubit
2. Ensure no intervening gates act on the same qubit
3. Check if both gates can be combined
4. Collect pairs and ensure no gate is used in multiple pairs

Parameters:
- operations: Vector of gate operations from a quantum circuit

Returns:
Vector of [i j] index pairs where operations i and j can be folded together,
along with the combined gate operation that should replace them

Examples:
(find-rotation-folding-pairs
  [{:operation-type :rx, :operation-params {:target 0, :angle 0.5}}
   {:operation-type :rx, :operation-params {:target 0, :angle 1.0}}])
;=> [[[0 1] {:operation-type :rx, :operation-params {:target 0, :angle 1.5}}]]
sourceraw docstring

gate-qubitsclj

(gate-qubits operation)

Extract the qubits that a gate operation acts upon.

Returns a set of qubit indices for comparison purposes. This function handles both single-qubit and multi-qubit gates by extracting the relevant qubit parameters from the operation.

Parameters:

  • operation: Gate operation map with :operation-type and :operation-params

Returns: Set of qubit indices that the gate operates on

Examples: (gate-qubits {:operation-type :x, :operation-params {:target 0}}) ;=> #{0}

(gate-qubits {:operation-type :cnot, :operation-params {:control 0, :target 1}}) ;=> #{0 1}

Extract the qubits that a gate operation acts upon.

Returns a set of qubit indices for comparison purposes. This function
handles both single-qubit and multi-qubit gates by extracting the
relevant qubit parameters from the operation.

Parameters:
- operation: Gate operation map with :operation-type and :operation-params

Returns:
Set of qubit indices that the gate operates on

Examples:
(gate-qubits {:operation-type :x, :operation-params {:target 0}})
;=> #{0}

(gate-qubits {:operation-type :cnot, :operation-params {:control 0, :target 1}})
;=> #{0 1}
sourceraw docstring

gate-rotation-angleclj

(gate-rotation-angle operation)

Extract the rotation angle from a gate operation.

For parametric rotation gates (:rx, :ry, :rz, :phase), extracts the :angle parameter. For fixed-angle phase gates, returns the equivalent rotation angle:

  • :s → π/2 (S gate)
  • :s-dag → -π/2 (S† gate)
  • :t → π/4 (T gate)
  • :t-dag → -π/4 (T† gate)

Parameters:

  • operation: Gate operation map

Returns: Rotation angle in radians, or nil if not a rotation gate

Examples: (gate-rotation-angle {:operation-type :rx, :operation-params {:target 0, :angle 1.5}}) ;=> 1.5

(gate-rotation-angle {:operation-type :s, :operation-params {:target 0}}) ;=> 1.5707963267948966 (π/2)

(gate-rotation-angle {:operation-type :t-dag, :operation-params {:target 0}}) ;=> -0.7853981633974483 (-π/4)

Extract the rotation angle from a gate operation.

For parametric rotation gates (:rx, :ry, :rz, :phase), extracts the :angle parameter.
For fixed-angle phase gates, returns the equivalent rotation angle:
- :s → π/2 (S gate)
- :s-dag → -π/2 (S† gate)  
- :t → π/4 (T gate)
- :t-dag → -π/4 (T† gate)

Parameters:
- operation: Gate operation map

Returns:
Rotation angle in radians, or nil if not a rotation gate

Examples:
(gate-rotation-angle {:operation-type :rx, :operation-params {:target 0, :angle 1.5}})
;=> 1.5

(gate-rotation-angle {:operation-type :s, :operation-params {:target 0}})
;=> 1.5707963267948966 (π/2)

(gate-rotation-angle {:operation-type :t-dag, :operation-params {:target 0}})
;=> -0.7853981633974483 (-π/4)
sourceraw docstring

gate-rotation-axisclj

(gate-rotation-axis operation)

Determine the rotation axis for a gate operation.

Returns the axis of rotation for rotation gates:

  • :rx → :x
  • :ry → :y
  • :rz, :phase, :s, :s-dag, :t, :t-dag → :z (all phase gates are Z-axis rotations)

Parameters:

  • operation: Gate operation map

Returns: Keyword representing rotation axis (:x, :y, :z), or nil if not a rotation gate

Determine the rotation axis for a gate operation.

Returns the axis of rotation for rotation gates:
- :rx → :x
- :ry → :y  
- :rz, :phase, :s, :s-dag, :t, :t-dag → :z (all phase gates are Z-axis rotations)

Parameters:
- operation: Gate operation map

Returns:
Keyword representing rotation axis (:x, :y, :z), or nil if not a rotation gate
sourceraw docstring

gates-are-inverses?clj

(gates-are-inverses? gate1 gate2)

Check if two gates are inverses of each other (G₁ · G₂ = I).

This checks both self-inverse gates (where G₁ = G₂) and explicit inverse pairs (where G₁ ≠ G₂ but they cancel each other).

Parameters:

  • gate1: First gate operation
  • gate2: Second gate operation

Returns: Boolean indicating whether the gates are inverses and can cancel

Check if two gates are inverses of each other (G₁ · G₂ = I).

This checks both self-inverse gates (where G₁ = G₂) and explicit
inverse pairs (where G₁ ≠ G₂ but they cancel each other).

Parameters:
- gate1: First gate operation
- gate2: Second gate operation

Returns:
Boolean indicating whether the gates are inverses and can cancel
sourceraw docstring

gates-equivalent?clj

(gates-equivalent? gate1 gate2)

Check if two gate operations are equivalent for cancellation purposes.

Two gates are considered equivalent if they:

  1. Have the same operation type
  2. Act on the same set of qubits with the same roles
  3. Have the same parameters (for parametric gates)
  4. Are self-inverse gates (gates that cancel when applied twice)

Special handling for symmetric gates:

  • SWAP gates: SWAP(a,b) is equivalent to SWAP(b,a)

This function is used to identify consecutive gates that can cancel each other.

Parameters:

  • gate1: First gate operation map
  • gate2: Second gate operation map

Returns: Boolean indicating whether the gates are equivalent and can cancel

Examples: (gates-equivalent? {:operation-type :x, :operation-params {:target 0}} {:operation-type :x, :operation-params {:target 0}}) ;=> true

(gates-equivalent? {:operation-type :cnot, :operation-params {:control 0, :target 1}} {:operation-type :cnot, :operation-params {:control 0, :target 1}}) ;=> true

(gates-equivalent? {:operation-type :swap, :operation-params {:qubit1 0, :qubit2 1}} {:operation-type :swap, :operation-params {:qubit1 1, :qubit2 0}}) ;=> true (SWAP is symmetric)

(gates-equivalent? {:operation-type :rx, :operation-params {:target 0, :angle 1.5708}} {:operation-type :rx, :operation-params {:target 0, :angle 1.5708}}) ;=> false (RX is not self-inverse)

Check if two gate operations are equivalent for cancellation purposes.

Two gates are considered equivalent if they:
1. Have the same operation type
2. Act on the same set of qubits with the same roles
3. Have the same parameters (for parametric gates)
4. Are self-inverse gates (gates that cancel when applied twice)

Special handling for symmetric gates:
- SWAP gates: SWAP(a,b) is equivalent to SWAP(b,a)

This function is used to identify consecutive gates that can cancel each other.

Parameters:
- gate1: First gate operation map
- gate2: Second gate operation map

Returns:
Boolean indicating whether the gates are equivalent and can cancel

Examples:
(gates-equivalent? 
  {:operation-type :x, :operation-params {:target 0}}
  {:operation-type :x, :operation-params {:target 0}})
;=> true

(gates-equivalent?
  {:operation-type :cnot, :operation-params {:control 0, :target 1}}
  {:operation-type :cnot, :operation-params {:control 0, :target 1}})
;=> true

(gates-equivalent?
  {:operation-type :swap, :operation-params {:qubit1 0, :qubit2 1}}
  {:operation-type :swap, :operation-params {:qubit1 1, :qubit2 0}})
;=> true (SWAP is symmetric)

(gates-equivalent?
  {:operation-type :rx, :operation-params {:target 0, :angle 1.5708}}
  {:operation-type :rx, :operation-params {:target 0, :angle 1.5708}})
;=> false (RX is not self-inverse)
sourceraw docstring

inverse-gate-pairsclj

Map of quantum gates to their inverse gates.

These are gates where G₁ · G₂ = I but G₁ ≠ G₂. This allows cancellation of different gates that are inverses of each other.

Inverse pairs included:

  • S and S† (S-dagger): S gate and its inverse
  • T and T† (T-dagger): T gate and its inverse

Note: Rotation gates RX(θ)/RX(-θ) are handled by rotation folding, not by this mechanism, since they can combine more generally.

Map of quantum gates to their inverse gates.

These are gates where G₁ · G₂ = I but G₁ ≠ G₂. This allows cancellation
of different gates that are inverses of each other.

Inverse pairs included:
- S and S† (S-dagger): S gate and its inverse
- T and T† (T-dagger): T gate and its inverse

Note: Rotation gates RX(θ)/RX(-θ) are handled by rotation folding,
not by this mechanism, since they can combine more generally.
sourceraw docstring

is-identity-rotation?clj

(is-identity-rotation? operation)

Check if a rotation gate is effectively an identity operation.

A rotation gate is considered an identity operation if its angle is normalized to 0.0, which includes:

  • Explicit zero angles (0.0)
  • Angles that are multiples of 2π (e.g., 2π, 4π, -2π)
  • Angles very close to zero or multiples of 2π (within tolerance)

Parameters:

  • operation: Gate operation to check

Returns: Boolean indicating whether the rotation is an identity operation

Check if a rotation gate is effectively an identity operation.

A rotation gate is considered an identity operation if its angle
is normalized to 0.0, which includes:
- Explicit zero angles (0.0)
- Angles that are multiples of 2π (e.g., 2π, 4π, -2π)
- Angles very close to zero or multiples of 2π (within tolerance)

Parameters:
- operation: Gate operation to check

Returns:
Boolean indicating whether the rotation is an identity operation
sourceraw docstring

normalize-angleclj

(normalize-angle angle)

Normalize angle to [0, 2π) range and handle near-zero values.

Parameters:

  • angle: Angle in radians

Returns: Normalized angle, with values within tolerance of 0 or 2π set to 0

Normalize angle to [0, 2π) range and handle near-zero values.

Parameters:
- angle: Angle in radians

Returns:
Normalized angle, with values within tolerance of 0 or 2π set to 0
sourceraw docstring

optimize-gatesclj

(optimize-gates ctx)

Optimize a quantum circuit by removing consecutive self-canceling gates and folding consecutive rotation gates.

This is the main optimization function that repeatedly applies gate cancellation and rotation folding optimizations until no more improvements can be made. The function:

  1. Applies inverse pair cancellation (S+S†, T+T†) for direct cancellations
  2. Applies rotation folding to combine consecutive rotations (RX, RY, RZ, phase gates)
  3. Removes identity rotations (gates with angle 0 or 2π)
  4. Identifies consecutive gates that cancel each other (e.g., H-H, X-X)
  5. Ensures no intervening gates share qubits with the canceling gates
  6. Removes these safe-to-cancel gate pairs
  7. Repeats until no more optimizations are possible
  8. Returns the optimized circuit

IMPORTANT: Gates can only cancel when all intervening gates act on completely different qubits. This ensures quantum mechanical correctness and prevents incorrect optimizations like canceling H gates across CNOT gates.

The optimization preserves the quantum computation while reducing the number of gates, which can improve:

  • Circuit depth and execution time
  • Gate fidelity on noisy quantum devices
  • Resource requirements for simulation

Parameters:

  • ctx: Map containing: :circuit - Quantum circuit to optimize :options - Map with optimization options, including: :optimize-gates? - Boolean to enable/disable gate optimization (default: true) :optimize-rotations? - Boolean to enable/disable rotation folding (default: true) :optimize-inverse-pairs? - Boolean to enable/disable inverse pair cancellation (default: true)

Returns: Updated context map with optimized circuit under :circuit key

Example: (optimize-gates {:circuit my-circuit, :options {:optimize-gates? true}}) ;=> {:circuit <optimized-circuit>, :options {...}}

Optimize a quantum circuit by removing consecutive self-canceling gates
and folding consecutive rotation gates.

This is the main optimization function that repeatedly applies gate
cancellation and rotation folding optimizations until no more improvements
can be made. The function:

1. Applies inverse pair cancellation (S+S†, T+T†) for direct cancellations
2. Applies rotation folding to combine consecutive rotations (RX, RY, RZ, phase gates)
3. Removes identity rotations (gates with angle 0 or 2π)
4. Identifies consecutive gates that cancel each other (e.g., H-H, X-X)
5. Ensures no intervening gates share qubits with the canceling gates  
6. Removes these safe-to-cancel gate pairs
7. Repeats until no more optimizations are possible
8. Returns the optimized circuit

IMPORTANT: Gates can only cancel when all intervening gates act on completely
different qubits. This ensures quantum mechanical correctness and prevents
incorrect optimizations like canceling H gates across CNOT gates.

The optimization preserves the quantum computation while reducing the
number of gates, which can improve:
- Circuit depth and execution time
- Gate fidelity on noisy quantum devices
- Resource requirements for simulation

Parameters:
- ctx: Map containing:
    :circuit - Quantum circuit to optimize
    :options - Map with optimization options, including:
        :optimize-gates? - Boolean to enable/disable gate optimization (default: true)
        :optimize-rotations? - Boolean to enable/disable rotation folding (default: true)
        :optimize-inverse-pairs? - Boolean to enable/disable inverse pair cancellation (default: true)

Returns:
Updated context map with optimized circuit under :circuit key

Example:
(optimize-gates {:circuit my-circuit, :options {:optimize-gates? true}})
;=> {:circuit <optimized-circuit>, :options {...}}
sourceraw docstring

optimize-inverse-cancellationsclj

(optimize-inverse-cancellations operations)

Optimize gates by canceling inverse pairs.

This function repeatedly finds and removes inverse gate pairs until no more cancellations are possible.

Parameters:

  • operations: Vector of gate operations

Returns: Vector of optimized operations with inverse pairs canceled

Optimize gates by canceling inverse pairs.

This function repeatedly finds and removes inverse gate pairs until
no more cancellations are possible.

Parameters:
- operations: Vector of gate operations

Returns:
Vector of optimized operations with inverse pairs canceled
sourceraw docstring

optimize-rotationsclj

(optimize-rotations operations)

Optimize rotation gates by folding consecutive rotations on same axis.

This function repeatedly applies rotation folding until no more improvements can be made. It combines consecutive rotation gates of the same type on the same qubit, reducing circuit depth and eliminating identity rotations.

Parameters:

  • operations: Vector of gate operations

Returns: Vector of optimized operations with rotation folding applied

Optimize rotation gates by folding consecutive rotations on same axis.

This function repeatedly applies rotation folding until no more improvements
can be made. It combines consecutive rotation gates of the same type on the
same qubit, reducing circuit depth and eliminating identity rotations.

Parameters:
- operations: Vector of gate operations

Returns:
Vector of optimized operations with rotation folding applied
sourceraw docstring

remove-cancellation-pairsclj

(remove-cancellation-pairs operations pairs)

Remove consecutive canceling gate pairs from circuit operations.

Takes a vector of operations and a collection of index pairs representing gates that cancel each other, then returns a new operations vector with those pairs removed.

The function processes pairs in reverse order to maintain correct indices during removal operations.

Parameters:

  • operations: Vector of gate operations
  • pairs: Collection of [i j] index pairs to remove

Returns: New vector of operations with canceling pairs removed

Example: (remove-cancellation-pairs [{:operation-type :h, :operation-params {:target 0}} {:operation-type :h, :operation-params {:target 0}} {:operation-type :x, :operation-params {:target 1}}] [[0 1]]) ;=> [{:operation-type :x, :operation-params {:target 1}}]

Remove consecutive canceling gate pairs from circuit operations.

Takes a vector of operations and a collection of index pairs representing
gates that cancel each other, then returns a new operations vector with
those pairs removed.

The function processes pairs in reverse order to maintain correct indices
during removal operations.

Parameters:
- operations: Vector of gate operations
- pairs: Collection of [i j] index pairs to remove

Returns:
New vector of operations with canceling pairs removed

Example:
(remove-cancellation-pairs
  [{:operation-type :h, :operation-params {:target 0}}
   {:operation-type :h, :operation-params {:target 0}}
   {:operation-type :x, :operation-params {:target 1}}]
  [[0 1]])
;=> [{:operation-type :x, :operation-params {:target 1}}]
sourceraw docstring

remove-identity-rotationsclj

(remove-identity-rotations operations)

Remove rotation gates that are effectively identity operations.

This function filters out rotation gates (RX, RY, RZ) that have angles normalized to zero, which means they don't change the quantum state and can be safely removed from the circuit.

This optimization is particularly useful after rotation folding, where consecutive rotations may combine to create identity operations.

Parameters:

  • operations: Vector of gate operations

Returns: Vector of operations with identity rotations removed

Examples: (remove-identity-rotations [{:operation-type :h, :operation-params {:target 0}} {:operation-type :rx, :operation-params {:target 0, :angle 0.0}} {:operation-type :cnot, :operation-params {:control 0, :target 1}}]) ;=> [{:operation-type :h, :operation-params {:target 0}} ; {:operation-type :cnot, :operation-params {:control 0, :target 1}}]

Remove rotation gates that are effectively identity operations.

This function filters out rotation gates (RX, RY, RZ) that have angles
normalized to zero, which means they don't change the quantum state and
can be safely removed from the circuit.

This optimization is particularly useful after rotation folding, where
consecutive rotations may combine to create identity operations.

Parameters:
- operations: Vector of gate operations

Returns:
Vector of operations with identity rotations removed

Examples:
(remove-identity-rotations
  [{:operation-type :h, :operation-params {:target 0}}
   {:operation-type :rx, :operation-params {:target 0, :angle 0.0}}
   {:operation-type :cnot, :operation-params {:control 0, :target 1}}])
;=> [{:operation-type :h, :operation-params {:target 0}}
;    {:operation-type :cnot, :operation-params {:control 0, :target 1}}]
sourceraw docstring

rotation-gatesclj

Set of rotation gates that can be folded together when applied consecutively on the same qubit and same rotation axis.

Rotation gates that can be combined:

  • :rx (X-axis rotation): RX(θ₁) · RX(θ₂) = RX(θ₁ + θ₂)
  • :ry (Y-axis rotation): RY(θ₁) · RY(θ₂) = RY(θ₁ + θ₂)
  • :rz (Z-axis rotation): RZ(θ₁) · RZ(θ₂) = RZ(θ₁ + θ₂)

Phase gates (Z-axis rotations with specific angles):

  • :phase (General phase): Phase(θ₁) · Phase(θ₂) = Phase(θ₁ + θ₂) = RZ(θ₁ + θ₂)
  • :s (S gate): S = RZ(π/2) = Phase(π/2)
  • :s-dag (S† gate): S† = RZ(-π/2) = Phase(-π/2)
  • :t (T gate): T = RZ(π/4) = Phase(π/4)
  • :t-dag (T† gate): T† = RZ(-π/4) = Phase(-π/4)

All phase gates can be combined with each other and with RZ gates since they are all rotations around the Z-axis.

Set of rotation gates that can be folded together when applied consecutively
on the same qubit and same rotation axis.

Rotation gates that can be combined:
- :rx (X-axis rotation): RX(θ₁) · RX(θ₂) = RX(θ₁ + θ₂)
- :ry (Y-axis rotation): RY(θ₁) · RY(θ₂) = RY(θ₁ + θ₂)  
- :rz (Z-axis rotation): RZ(θ₁) · RZ(θ₂) = RZ(θ₁ + θ₂)

Phase gates (Z-axis rotations with specific angles):
- :phase (General phase): Phase(θ₁) · Phase(θ₂) = Phase(θ₁ + θ₂) = RZ(θ₁ + θ₂)
- :s (S gate): S = RZ(π/2) = Phase(π/2)
- :s-dag (S† gate): S† = RZ(-π/2) = Phase(-π/2)  
- :t (T gate): T = RZ(π/4) = Phase(π/4)
- :t-dag (T† gate): T† = RZ(-π/4) = Phase(-π/4)

All phase gates can be combined with each other and with RZ gates since
they are all rotations around the Z-axis.
sourceraw docstring

rotation-gates-combinable?clj

(rotation-gates-combinable? gate1 gate2)

Check if two rotation gates can be combined into a single rotation.

Two rotation gates can be combined if:

  1. They are both rotation gates on the same axis (X, Y, or Z)
  2. They act on the same target qubit
  3. No intervening gates act on the same qubit

Phase gates (:s, :s-dag, :t, :t-dag, :phase) can combine with each other and with :rz gates since they are all Z-axis rotations.

Parameters:

  • gate1: First rotation gate operation
  • gate2: Second rotation gate operation

Returns: Boolean indicating whether gates can be combined

Check if two rotation gates can be combined into a single rotation.

Two rotation gates can be combined if:
1. They are both rotation gates on the same axis (X, Y, or Z)
2. They act on the same target qubit
3. No intervening gates act on the same qubit

Phase gates (:s, :s-dag, :t, :t-dag, :phase) can combine with each other
and with :rz gates since they are all Z-axis rotations.

Parameters:
- gate1: First rotation gate operation
- gate2: Second rotation gate operation

Returns:
Boolean indicating whether gates can be combined
sourceraw docstring

self-inverse-gatesclj

Set of quantum gates that are their own inverse.

These gates satisfy the property G² = I, meaning applying the same gate twice in succession results in the identity operation and can be removed from the circuit without affecting the quantum computation.

Single-qubit self-inverse gates:

  • :x (Pauli-X): Bit flip gate, X² = I
  • :y (Pauli-Y): Bit and phase flip gate, Y² = I
  • :z (Pauli-Z): Phase flip gate, Z² = I
  • :h (Hadamard): Superposition gate, H² = I

Two-qubit self-inverse gates:

  • :cnot (Controlled-NOT): Controlled bit flip, CNOT² = I
  • :cx (Controlled-X): Alias for CNOT, CX² = I
  • :cy (Controlled-Y): Controlled bit and phase flip, CY² = I
  • :cz (Controlled-Z): Controlled phase flip, CZ² = I
  • :swap (SWAP): Exchange states of two qubits, SWAP² = I

Three-qubit self-inverse gates:

  • :toffoli (Toffoli/CCX): Controlled-controlled-X gate, Toffoli² = I
  • :ccx (CCX): Alias for Toffoli, CCX² = I
  • :fredkin (Fredkin/CSWAP): Controlled SWAP gate, Fredkin² = I
  • :cswap (CSWAP): Alias for Fredkin, CSWAP² = I

Note: iSWAP is NOT self-inverse (iSWAP² ≠ I) and is not included.

Set of quantum gates that are their own inverse.

These gates satisfy the property G² = I, meaning applying the same gate
twice in succession results in the identity operation and can be removed
from the circuit without affecting the quantum computation.

Single-qubit self-inverse gates:
- :x (Pauli-X): Bit flip gate, X² = I
- :y (Pauli-Y): Bit and phase flip gate, Y² = I  
- :z (Pauli-Z): Phase flip gate, Z² = I
- :h (Hadamard): Superposition gate, H² = I

Two-qubit self-inverse gates:
- :cnot (Controlled-NOT): Controlled bit flip, CNOT² = I
- :cx (Controlled-X): Alias for CNOT, CX² = I  
- :cy (Controlled-Y): Controlled bit and phase flip, CY² = I
- :cz (Controlled-Z): Controlled phase flip, CZ² = I
- :swap (SWAP): Exchange states of two qubits, SWAP² = I

Three-qubit self-inverse gates:
- :toffoli (Toffoli/CCX): Controlled-controlled-X gate, Toffoli² = I
- :ccx (CCX): Alias for Toffoli, CCX² = I
- :fredkin (Fredkin/CSWAP): Controlled SWAP gate, Fredkin² = I  
- :cswap (CSWAP): Alias for Fredkin, CSWAP² = I

Note: iSWAP is NOT self-inverse (iSWAP² ≠ I) and is not included.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close