Gate decompositions: single- and two-qubit
Gate decomposition in quantum computing refers to the process of breaking down a gate into a set of single- and two-qubit gates. In general, the user will create a quantum circuit using a quantum algorithm, which is hardware-agnostic. While this quantum circuit can usually be simulated on many backends (e.g. qoqo-quest, qoqo-qiskit, qoqo-for-braket) without any recompilation, running it on a real quantum device requires adapting to the restricted set of natively available gates. Therefore, it is important to be able to decompose the gates present in the circuit into the gates available on the hardware. Additionally, different types of quantum computers have distinct set of native gate making decomposition even more essential.
Gate decomposition also plays a crucial role when modeling the noise of a quantum device. As noise often occurs during each gate operation, ensuring that the circuit contains the correct sequence of gates is vital for the correctness of the computation.
Pyqonvert
offers the SingleQubitGateDecomposer
and TwoQubitGateDecomposer
converters for this purpose. They are applied to circuits and quantum programs using the convert
function.
Single-qubit gate decompositions
Functionality
The SingleQubitGateDecomposer
converter decomposes any single-qubit gates into a set of specified single-qubit gates. It takes as input a quantum circuit or a quantum program and the device specifications, which specifies the available gate operations. The converter then matches the circuit's single-qubit gates with the operations supported by the device. If a single-qubit gate is not supported, the converter computes various possible decompositions, each weighted by their gate counts. Finally, the decomposition with the fewest gates is selected to replace the original gate in the circuit.
For details on the available decompositions, please refer to the Python API
Initalizing the SingleQubitGateDecomposer
Class.
The SingleQubitGateDecomposer
class is imported from the pyqonvert.decompositions
module.
from pyqonvert.decompositions import SingleQubitGateDecomposer
# initialize noise inserter
decomposer = SingleQubitGateDecomposer()
# Ready to use for noise addition.
Example
We give an example to show the single-qubit decomposer's functionality. Figure 1 contains the resulting circuit.
from pyqonvert.decompositions import SingleQubitGateDecomposer
from qoqo import devices, Circuit
from qoqo import operations as ops
decomposer = SingleQubitGateDecomposer()
# Initialize device
number_qubits = 3
device = devices.AllToAllDevice(
number_qubits,
[
"RotateY",
"RotateZ",
"SqrtPauliX",
"InvSqrtPauliX",
],
[],
1.0,
)
# Initialize circuit
circuit = Circuit()
circuit += ops.DefinitionBit("ro", 1, True)
circuit += ops.CNOT(0, 1)
circuit += ops.CNOT(0, 2)
circuit += ops.Hadamard(0)
circuit += ops.MeasureQubit(0, "ro", 0)
# Decomposition
circuit = decomposer.convert(circuit, device, [])
Figure 1: Single-qubit gate decomposition
Two-qubit gate decompositions
The TwoQubitGateDecomposer
converter decomposes general two-qubit gates into native two-qubit gates and generic single-qubit gates. It takes a quantum circuit and the device specifications as input. The device specifies the available gate operations. The converter then matches the circuit's gates with the operations supported by the device. If a two-qubit gate is not supported, the converter explores various possible decompositions, each weighted by their gate counts. Finally, the decomposition with the fewest gates is selected to replace the original gate in the circuit.
For details on the available decompositions, please refer to the Python API
Initalizing the TwoQubitGateDecomposer
Class.
The TwoQubitGateDecomposer
class is imported from the pyqonvert.decompositions
module.
from pyqonvert.decompositions import TwoQubitGateDecomposer
# initialize noise inserter
decomposer = TwoQubitGateDecomposer()
# Ready to use for noise addition.
Example
We provide an example to demonstrate the functionality of the two-qubit decomposer, as illustrated in Figure 2, which shows the resulting circuit. It is important to note that the two-qubit decomposer produces single-qubit rotation gates that may not be natively supported by the device. Therefore, in practice, it is essential to subsequently apply the single-qubit decomposition converter.
from pyqonvert.decompositions import TwoQubitGateDecomposer
from qoqo import devices, Circuit
from qoqo import operations as ops
decomposer = TwoQubitGateDecomposer()
# Initialize device
number_qubits = 3
device = devices.AllToAllDevice(
number_qubits,
[],
[
"CNOT",
"ControlledPauliZ",
"PhaseShiftedControlledZ",
],
1.0,
)
# Initialize circuit
circuit = Circuit()
circuit += ops.DefinitionBit("ro", 1, True)
circuit += ops.PauliX(0)
circuit += ops.SWAP(0, 1)
circuit += ops.Hadamard(0)
circuit += ops.MeasureQubit(0, "ro", 0)
# Decomposition
circuit = decomposer.convert(circuit, device, [])
Figure 2: two-qubit gate decomposition