Description
Most qibo
gate classes have a custom decompose
method that returns the equivalent gate decomposed in a "standard" gate set. This gate set is usually CNOT
+ single-qubit gates. For instance, the RBS
gate admits the following decomposition:
In [6]: from qibo import Circuit, gates
...:
...: nqubits = 3
...:
...: gate = gates.RBS(1, 2, 0.1)
...:
...: circuit = Circuit(nqubits)
...: circuit.add(gate.decompose())
...: circuit.draw()
0: ────────────
1: ─H─o─RY─o─H─
2: ───X─RY─X───
The gates in the decomposition above correctly act on qubits
In [7]: from qibo import Circuit, gates
...:
...: nqubits = 3
...:
...: gate = gates.RBS(1, 2, 0.1).controlled_by(0)
...:
...: circuit = Circuit(nqubits)
...: circuit.add(gate)
...: circuit.draw()
...: print()
...:
...: circuit = Circuit(nqubits)
...: circuit.add(gate.decompose())
...: circuit.draw()
0: ─o───
1: ─RBS─
2: ─RBS─
0: ─H─o─RY─o─H─
1: ───X─RY─X───
2: ────────────
As one can see the in the example above, not only the gates act on different qubits than the original gate but the decomposition completely lost the information that the gate was a controlled gate.
What an acceptable solution looks like for the example above:
0: ─o─o─o──o──o─o─
1: ─H─o─RY─|──o─H─
2: ───X────RY─X───
For all gates, controlling every gate in the decomposition by the correct qubits is an acceptable solution. However, a lot of the gate decompositions only subset of the gates in the decomposition actually need to be controlled because the rest of the circuit amounts to an identity. For instance, in the example above the following is what an ideal solution looks like:
0: ─────o──o──────
1: ─H─o─RY─|──o─H─
2: ───X────RY─X───