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, [])

single qubit gate decomposition 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, [])

two qubit gate decomposition Figure 2: two-qubit gate decomposition