qml.transforms.commute_controlled¶
- commute_controlled(tape, direction='right')[source]¶
Quantum transform to move commuting gates past control and target qubits of controlled operations.
- Parameters
tape (QNode or QuantumTape or Callable) – A quantum circuit.
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 circuit as described in
qml.transform
.- Return type
qnode (QNode) or quantum function (Callable) or tuple[List[QuantumTape], function]
Example
>>> dev = qml.device('default.qubit', wires=3)
You can apply the transform directly on
QNode
:@partial(commute_controlled, direction="right") @qml.qnode(device=dev) def circuit(theta): qml.CZ(wires=[0, 2]) qml.X(2) qml.S(wires=0) qml.CNOT(wires=[0, 1]) qml.Y(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.Z(0))
>>> circuit(0.5) 0.9999999999999999
Usage Details
You can also apply it on quantum function.
def qfunc(theta): qml.CZ(wires=[0, 2]) qml.X(2) qml.S(wires=0) qml.CNOT(wires=[0, 1]) qml.Y(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.Z(0))
>>> 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(qfunc, direction="right") >>> 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─────────────────────┤