2.3. Additional unitary gates#
Besides the gates, which are presented in the previous secion, geqo also has additional unitary gates, which are internally decomposed into a sequence of the elementary gates above are the following:
PCCM and InversePCCM
PermuteQubits
QFT and InverseQFT
QubitReversal
Toffoli
Some of the gates of the internally used sequences have parameters, e.g. QFT
uses internally a phase gate Phase("Ph1")
. For a simulator, the value corresponding to the name of the phase can be set with the function prepareBackend
of the simulator. However, if there are several instances of QFT
with different numbers of qubits, then Phase("Ph1")
does not necessarily correspond to the same value in all cases. To avoid this problem, a name space prefix can be provided to the relevant gates, e.g. QFT(2,"prefix.")
leads to the internal name prefix.Ph1
instead of Ph1
.
More information on the usage of name spaces can be found in the corresponding tutorial in section 3.1.
2.3.1. PCCM and InversePCCM#
The PCCM is the Phase-Covariant Cloning Machine and it can be used to clone a qubit approximately. The structure of the circuit, the meaning of the parameter and the application of the circuit can be found in T. Decker, M. Gallezot, S. F. Kerstan, A. Paesano, A. Ginter, W. Wormsbecher, “QKD as a Quantum Machine Learning task”, arXiv:2410.01904.
The PCCM and its inverse are internally composed of several other gates, including rotation gates. Therefore, the method prepareBackend
has to be called before applying the gate.
To avoid problems with the same names for gates, the PCCM and InversePCCM gate support name space prefixes. This means that all internally used gates obtain the provided prefix for its names.
from geqo.algorithms.algorithms import PCCM, InversePCCM
from geqo.simulators.sympy import simulatorUnitarySymPy
gate = PCCM("φ")
sim = simulatorUnitarySymPy(2)
sim.prepareBackend([gate])
sim.apply(gate, [0, 1])
# display(sim.u)
Applying the InversePCCM
after the PCCM
gate with the same angle leads to the identity.
gate2 = InversePCCM("φ")
sim.apply(gate2, [0, 1])
# display(sim.u[1,1])
2.3.2. QFT and InverseQFT#
The Quantum Fourier Transform (QFT) and its inverse are internally composed of several other gates, including rotation gates. Therefore, the method prepareBackend
has to be called before applying the gate.
To avoid problems with the same names for gates, the QFT and InverseQFT gate support name space prefixes. This means that all internally used gates obtain the provided prefix for its names.
from geqo.algorithms.algorithms import QFT, InverseQFT
from geqo.simulators.sympy import simulatorUnitarySymPy
gate = QFT(2)
sim = simulatorUnitarySymPy(2)
sim.prepareBackend([gate])
sim.apply(gate, [0, 1])
display(sim.u)
Applying the InverseQFT
after the QFT
gate with the same number of qubits leads to the identity.
gate2 = InverseQFT(2)
sim.apply(gate2, [0, 1])
display(sim.u)
2.3.3. QubitReversal#
This operation is reversing the order of qubits. It is a special case of a permutation of qubits, which might be performed also with PermuteQubits
. This operation is reversing the order of qubits. It corresponds to a permutation of the
states of the computational basis.
from geqo.algorithms.algorithms import QubitReversal
from geqo.simulators.sympy import simulatorUnitarySymPy
gate = QubitReversal(3) # Create a qubit reversal operation on three qubits.
sim = simulatorUnitarySymPy(3) # The gate is defined on three qubits.
sim.apply(gate, [0, 1, 2])
display(sim.u)
2.3.4. Toffoli#
The Toffoli gate is a PauliX operation on a qubit and it has two control qubits. In total, it operates on three qubits.
The Toffoli gate is internally composed of several other gates, including rotation gates. Therefore, the method prepareBackend
has to be called before applying the gate.
To avoid problems with the same names for gates, the Toffoli gate supports name space prefixes. This means that all internally used gates obtain the provided prefix for its names.
from geqo.gates.multi_qubit_gates import Toffoli
from geqo.simulators.sympy import simulatorUnitarySymPy
gate = Toffoli("A.") # Create a Toffoli gate. The name space prefix is "A.".
seq = gate.getEquivalentSequence()
print(
seq
) # Show the Sequence, which is the internal decomposition. All gates with names obtain the name space prefix.
Sequence([], [0, 1, 2], [(Hadamard(), [2]), (CNOT(), [1, 2]), (Phase("A.-S.Pi/4"), [2]), (CNOT(), [0, 2]), (Phase("A.S.Pi/4"), [2]), (CNOT(), [1, 2]), (Phase("A.-S.Pi/4"), [2]), (CNOT(), [0, 2]), (Phase("A.S.Pi/4"), [1]), (Phase("A.S.Pi/4"), [2]), (CNOT(), [0, 1]), (Hadamard(), [2]), (Phase("A.S.Pi/4"), [0]), (Phase("A.-S.Pi/4"), [1]), (CNOT(), [0, 1])])
sim = simulatorUnitarySymPy(3)
sim.prepareBackend(
[gate]
) # This method sets the values for the internally used gates with the appropriate name space prefix.
sim.apply(gate, [0, 1, 2]) # The Toffoli gate operates on three qubits.
sim.u.simplify() # Simplify the expressions in the result matrix.
display(sim.u)