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.

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.
raw docstring

circuit-optimization-statsclj

(circuit-optimization-stats original-circuit optimized-circuit)

Calculate optimization statistics for a circuit transformation.

Compares the original and optimized circuits to provide metrics about the effectiveness of the optimization process.

Parameters:

  • original-circuit: Circuit before optimization
  • optimized-circuit: Circuit after optimization

Returns: Map containing optimization statistics:

  • :original-gate-count: Number of gates before optimization
  • :optimized-gate-count: Number of gates after optimization
  • :gates-removed: Number of gates eliminated
  • :reduction-percentage: Percentage of gates removed

Example: (circuit-optimization-stats original optimized) ;=> {:original-gate-count 10, :optimized-gate-count 6, ; :gates-removed 4, :reduction-percentage 40.0}

Calculate optimization statistics for a circuit transformation.

Compares the original and optimized circuits to provide metrics about
the effectiveness of the optimization process.

Parameters:
- original-circuit: Circuit before optimization
- optimized-circuit: Circuit after optimization

Returns:
Map containing optimization statistics:
- :original-gate-count: Number of gates before optimization
- :optimized-gate-count: Number of gates after optimization
- :gates-removed: Number of gates eliminated
- :reduction-percentage: Percentage of gates removed

Example:
(circuit-optimization-stats original optimized)
;=> {:original-gate-count 10, :optimized-gate-count 6, 
;    :gates-removed 4, :reduction-percentage 40.0}
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-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

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

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

optimize-gate-cancellationsclj

(optimize-gate-cancellations circuit)

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

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

  1. Identifies consecutive gates that cancel each other (e.g., H-H, X-X)
  2. Ensures no intervening gates share qubits with the canceling gates
  3. Removes these safe-to-cancel gate pairs
  4. Repeats until no more cancellations are possible
  5. 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:

  • circuit: Quantum circuit to optimize

Returns: Optimized quantum circuit with redundant gates removed

Example: (optimize-gate-cancellations {:operations [{:operation-type :h, :operation-params {:target 0}} {:operation-type :h, :operation-params {:target 0}} {:operation-type :x, :operation-params {:target 1}} {:operation-type :x, :operation-params {:target 1}}] :num-qubits 2}) ;=> {:operations [], :num-qubits 2} ; All gates cancelled

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

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

1. Identifies consecutive gates that cancel each other (e.g., H-H, X-X)
2. Ensures no intervening gates share qubits with the canceling gates  
3. Removes these safe-to-cancel gate pairs
4. Repeats until no more cancellations are possible
5. 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:
- circuit: Quantum circuit to optimize

Returns:
Optimized quantum circuit with redundant gates removed

Example:
(optimize-gate-cancellations
  {:operations [{:operation-type :h, :operation-params {:target 0}}
                {:operation-type :h, :operation-params {:target 0}}
                {:operation-type :x, :operation-params {:target 1}}
                {:operation-type :x, :operation-params {:target 1}}]
   :num-qubits 2})
;=> {:operations [], :num-qubits 2}  ; All gates cancelled
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

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 is a website building & hosting documentation for Clojure/Script libraries

× close