1. Compilation/
  2. Two-qubit Synthesis

Two-qubit Synthesis

Two-qubit gate synthesis takes in a 4×44 \times 4 unitary matrix UU and synthesizes a circuit with an optimal CNOT\text{CNOT} gate count. This pass is implemented as qml.ops.two_qubit_decomposition in PennyLane.

The resulting circuits can take one of the following four forms, depending on how many CNOT gates are necessary.

CNOTs0123
Circuit -A-
-B-
-C--╭●--A-
-D--╰X--B-
-A--╭X--RZ(α)--╭X--C-
-B--╰●--RX(β)--╰●--D-
-C--╭X--RZ(δ)--╭●---------╭X--A-
-D--╰●--RY(β)--╰X--RY(α)--╰●--B-

A,B,C,DSU(2)A, B, C, D \in \text{SU}(2) are general single-qubit gates and, together with the angles α,β,δR\alpha, \beta, \delta \in \mathbb{R}, can be determined algebraically directly from the input matrix UU (the exact process is described in the details tab).

In a NISQ setting, where costs for CNOT gates dominate, applying this pass to two-qubit gates may reduce the overall CNOT gate count.

Inputs

  • Unitary matrix UC4×4U \in \mathbb{C}^{4\times 4}

Outputs

  • Decomposed circuit with an optimal CNOT\text{CNOT} gate count

Example

A tensor product of two operators requires 00 CNOT gates.

import pennylane as qml
import numpy as np

U = qml.matrix(qml.exp(-1j * 0.5 * X(0)), wire_order=range(2))
U @= qml.matrix(qml.exp(-1j * 0.5 * Y(1)), wire_order=range(2))
ops = qml.ops.two_qubit_decomposition(U, range(2))
circ = qml.tape.QuantumScript(ops, [])
assert np.allclose(U, qml.matrix(circ, wire_order=range(2)))

print(qml.drawer.tape_text(circ))
0: ──RZ──RY──RZ─┤  
1: ──RZ──RY──RZ─┤  

Note that a ZYZ decomposition is used to represent the SU(2)\text{SU}(2) gate on each wire. This leads to a redundancy because the input matrix on wire 1 is already a RYR_Y rotation.

A general SU(4)\text{SU}(4) element requires 33 CNOT gates.

SU4_generators = list(qml.pauli.pauli_group(2))
arbitrary_op = qml.dot(np.arange(16), SU4_generators)
U = qml.matrix(qml.exp(-1j * arbitrary_op))

ops = qml.ops.two_qubit_decomposition(U, range(2))
circ = qml.tape.QuantumScript(ops, [])

print(qml.drawer.tape_text(circ))
0: ──RZ──RY──RZ─╭X──RZ─╭●─────╭X──RZ──RY──RZ─┤  
1: ──RZ──RY──RZ─╰●──RY─╰X──RY─╰●──RZ──RY──RZ─┤ 

There are intermediate cases with 11 and 22 CNOTs, respectively. Here is an example where 22 CNOT gates are required.

U = qml.matrix(qml.exp(-1j * 0.5 * X(0) @ Y(1)), wire_order=range(2))
ops = qml.ops.two_qubit_decomposition(U, range(2))
circ = qml.tape.QuantumScript(ops, [])
assert np.allclose(U, qml.matrix(circ, wire_order=range(2)))

print(qml.drawer.tape_text(circ))
0: ──RZ──RY──RZ─╭X──RZ─╭X──RZ──RY──RZ─┤  
1: ──RZ──RY──RZ─╰●──RX─╰●──RZ──RY──RZ─┤ 

While the CNOT count is optimal, the overall decomposition may not be. This is because this pass always targets a fixed ansatz structure and may introduce some redundant single-qubit gates, as illustrated by this example.

>>> def circ():
...     qml.CNOT((0, 1))
...     qml.RX(0.5, 0)
...     qml.RY(0.5, 1)

>>> U = qml.matrix(circ, wire_order=range(2))()
>>> print("Input circuit:\n")
>>> print(qml.draw(circ)(), "\n")
Input circuit:

0: ─╭●──RX(0.50)─┤  
1: ─╰X──RY(0.50)─┤   

>>> ops = qml.ops.two_qubit_decomposition(U, range(2))
>>> circ_re = qml.tape.QuantumScript(ops, [])
>>> assert np.allclose(U, qml.matrix(circ_re, wire_order=range(2)))

>>> print("Synthesized circuit:\n")
>>> print(qml.drawer.tape_text(circ_re, decimals=2))
Synthesized circuit:

0: ──RZ(2.01)──RY(0.00)──RZ(9.44)─╭●──RZ(8.96)──RY(0.50)──RZ(11.00)─┤  
1: ──RZ(4.71)──RY(1.02)──RZ(1.57)─╰X──RZ(1.00)──RY(1.09)──RZ(11.28)─┤ 

Typical usage

This pass is necessary when the input unitary is provided as a matrix rather than a gate decomposition. In a NISQ setting, where costs for CNOT gates dominate, applying this pass to two-qubit gates may reduce the overall CNOT gate count.

References

[1] "Minimal Universal Two-qubit Quantum Circuits", Vivek V. Shende, Igor L. Markov, Stephen S. Bullock, arxiv:quant-ph/0308033, 2003

[2] "Recognizing Small-Circuit Structure in Two-Qubit Operators and Timing Hamiltonians to Compute Controlled-Not Gates", Vivek V. Shende, Stephen S. Bullock, Igor L. Markov, arXiv:quant-ph/0308045, 2003

[3] "Finding Small Two-Qubit Circuits", Vivek V. Shende, Igor L. Markov, and Stephen S. Bullock, preprint, 2004

Cite this page

@misc{PennyLane-2QSynthesis,
title={Two-qubit Synthesis},
howpublished={\url{https://pennylane.ai/compilation/two-qubit-synthesis}},
year={2025}
}

Page author(s)

Korbinian Kottmann

Korbinian Kottmann

Quantum simulation & open source software