qml.transforms.commute_controlled¶
-
commute_controlled
(tape, direction='right')[source]¶ Quantum function transform to move commuting gates past control and target qubits of controlled operations.
- Parameters
qfunc (function) – A quantum function.
direction (str) – The direction in which to move single-qubit gates. Options are “right” (default), or “left”. Single-qubit gates will be pushed through controlled operations as far as possible in the specified direction.
- Returns
the transformed quantum function
- Return type
function
Example
Consider the following quantum function.
def qfunc(theta): qml.CZ(wires=[0, 2]) qml.PauliX(wires=2) qml.S(wires=0) qml.CNOT(wires=[0, 1]) qml.PauliY(wires=1) qml.CRY(theta, wires=[0, 1]) qml.PhaseShift(theta/2, wires=0) qml.Toffoli(wires=[0, 1, 2]) qml.T(wires=0) qml.RZ(theta/2, wires=1) return qml.expval(qml.PauliZ(0))
>>> dev = qml.device('default.qubit', wires=3) >>> qnode = qml.QNode(qfunc, dev) >>> print(qml.draw(qnode)(0.5)) 0: ─╭●──S─╭●────╭●─────────Rϕ(0.25)─╭●──T────────┤ <Z> 1: ─│─────╰X──Y─╰RY(0.50)───────────├●──RZ(0.25)─┤ 2: ─╰Z──X───────────────────────────╰X───────────┤
Diagonal gates on either side of control qubits do not affect the outcome of controlled gates; thus we can push all the single-qubit gates on the first qubit together on the right (and fuse them if desired). Similarly, X gates commute with the target of
CNOT
andToffoli
(andPauliY
withCRY
). We can use the transform to push single-qubit gates as far as possible through the controlled operations:>>> optimized_qfunc = commute_controlled(direction="right")(qfunc) >>> optimized_qnode = qml.QNode(optimized_qfunc, dev) >>> print(qml.draw(optimized_qnode)(0.5)) 0: ─╭●─╭●─╭●───────────╭●──S─────────Rϕ(0.25)──T─┤ <Z> 1: ─│──╰X─╰RY(0.50)──Y─├●──RZ(0.25)──────────────┤ 2: ─╰Z─────────────────╰X──X─────────────────────┤