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:
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.
(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:
Returns: Map containing optimization statistics:
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}
(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:
Parameters:
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)
(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:
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
(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:
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}
(gates-equivalent? gate1 gate2)
Check if two gate operations are equivalent for cancellation purposes.
Two gates are considered equivalent if they:
Special handling for symmetric gates:
This function is used to identify consecutive gates that can cancel each other.
Parameters:
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)
(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:
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:
Parameters:
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
(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:
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}}]
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:
Two-qubit self-inverse gates:
Three-qubit self-inverse gates:
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.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close