-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Say I build a circuit using the power
and control
modifier on gates.
from qiskit.circuit.library import *
from qiskit import *
from qiskit.quantum_info import random_unitary
from qiskit.extensions import UnitaryGate
from numpy import pi
θ = pi/8
U = random_unitary(2)
circuit = QuantumCircuit(3)
circuit.append(PhaseGate(θ).power(3), [0])
circuit.append(PhaseGate(θ).control(2), [0, 1, 2])
circuit.append(UnitaryGate(U).control(), [0, 2])
It is good that the circuit drawers support these modifiers natively:
┌─────┐
q_0: ┤ p^3 ├─■────────────■─────
└─────┘ │ │
q_1: ────────■────────────┼─────
│P(π/8) ┌────┴────┐
q_2: ────────■───────┤ Unitary ├
└─────────┘
The following issues exist:
-
I can't directly control the
quantum_info.random_unitary
U, have to build a UnitaryGate out of it first. i.e. quantum_info objects are not first class citizens in circuits. -
PhaseGate(θ).control(2)
yields aMCPhaseGate
under the hood (that's why the circuit drawer knows to draw it like that). I'm not sure we need thisMCPhaseGate
class, sincePhaseGate(θ).control(2)
already has well-defined semantics. The synthesis routine should know that this is a diagonal gate and thus decompose it appropriately. The drawer should also know that controlled phase gates can be drawn symmetrically. -
The decomposition gets greedily computed and stored in the gate itself when you modify a gate via power or control or inverse (https://github.com/Qiskit/qiskit-terra/blob/bdedeae59a5341b6ea4f399fe4a4f03c051e2e13/qiskit/circuit/library/standard_gates/p.py#L109). Instead we can keep them as powered- or controlled- or inverted- gates and make the rest of Qiskit work with that (e.g. quantum_info should be able to simulate this circuit at this high level without caring about the decomposition).
-
Similarly all gate optimization routines should work the same way even if the base gates happen to be controlled. For example optimize_1q_decomposition should work when we have ctrl-U and ctrl-V back-to-back (I did this in an old PR but never merged).