4.3. Decomposition of gates with many controls#
4.3.1. Background#
Most quantum computer systems can only perform operations that act on a small number of qubits, i.e. the elementary gates of these systems are limited to one or two qubits in most cases. However, in many applications, operations that have many control qubits are necessary. Therefore, it is necessary to decompose the gates with many control qubits into a sequence of gates where each gate has a smaller number of control qubits.
In this following, a decomposition of a PauliX
gate, which has several control qubits, into a sequence of Toffoli
gates (a PauliX
gate with two control qubits) is obtained by the function controlledXGate
of geqo. This allows to replace a gate acting on many qubits with a sequence of gates, which act on three qubits each. This function allows to turn a gate, which cannot be performed on a quantum computer directly, into a sequence of gates that are more suitable for many hardware implementations.
4.3.1.1. Example: A simple Toffoli gate#
The basis gate for the reduction of PauliX
gates with many control qubits is the Toffoli
gate, which acts on three qubits. The corresponding unitary is obtained with the geqo backend simulatorUnitarySymPy
. Since the Toffoli
gate is internally decomposed into several gates, the prepareBackend
function must be called before using the simulator.
from geqo.gates import Toffoli
from geqo.simulators import simulatorUnitarySymPy
tof = Toffoli()
sim = simulatorUnitarySymPy(3)
sim.prepareBackend([tof])
sim.apply(tof, [0, 1, 2])
sim.u.simplify()
sim.u
4.3.1.2. Example: Three control qubits#
The Toffoli
gate is a PauliX
gate with two control qubits. The following example uses the controlledXGate
function to
obtain a sequence of Toffoli
and PauliX
gates with at most one control qubits each. The constructed circuit uses one ancilla qubit.
The function controlledXGate
returns two values. The first is an instance of the internally used Toffoli
gate and the second value is a Sequence
, which contains a sequence consisting of the returned Toffoli
gate and controlled PauliX
gates.
from geqo.algorithms import controlledXGate
tof, cg = controlledXGate(3, "TestPrefix.")
The instance of the Toffoli
gate and the Sequence
for the example with 3 control qubits are shown in the following.
print(tof)
print(cg)
Toffoli("TestPrefix.")
Sequence([], [0, 1, 2, 3, 4], [(QuantumControl([1], PauliX()), [0, 2]), (Toffoli("TestPrefix."), [1, 2, 4]), (QuantumControl([1], PauliX()), [0, 2]), (Toffoli("TestPrefix."), [1, 2, 4]), (Toffoli("TestPrefix."), [2, 4, 3]), (QuantumControl([1], PauliX()), [0, 2]), (Toffoli("TestPrefix."), [1, 2, 4]), (QuantumControl([1], PauliX()), [0, 2]), (Toffoli("TestPrefix."), [1, 2, 4]), (Toffoli("TestPrefix."), [2, 4, 3])])
The backend simulatorUnitarySymPy
can be used to calculate the resulting unitary of the Sequence
corresponding to the PauliX
gate with 3 control qubits. Note that the circuit uses 4 qubits. Note that the prepareBackend
function can be used with the returned instance of Toffoli
.
sim = simulatorUnitarySymPy(3 + 2)
sim.prepareBackend([tof])
sim.apply(cg, [0, 1, 2, 3, 4])
sim.u.simplify()
sim.u
The following step directly simulates PauliX
gate with 3 control qubits. The result is compared with the result from controlledXGate
.
from geqo.operations import QuantumControl
from geqo.gates import PauliX
sim2 = simulatorUnitarySymPy(5)
sim2.prepareBackend([tof])
sim2.apply(QuantumControl([1, 1, 1], PauliX()), [0, 1, 2, 3])
sim2.u.simplify()
# sim2.u
The following calculation shows that the norm of the difference of the matrices is 0.
uDiff = sim.u - sim2.u
uDiff.norm()