qml.transforms.cancel_inverses¶
- cancel_inverses(tape)[source]¶
Quantum function transform to remove any operations that are applied next to their (self-)inverses or adjoint.
- Parameters
tape (QNode or QuantumTape or Callable) – A quantum circuit.
- Returns
The transformed circuit as described in
qml.transform
.- Return type
qnode (QNode) or quantum function (Callable) or tuple[List[QuantumTape], function]
Example
You can apply the cancel inverses transform directly on
QNode
.>>> dev = qml.device('default.qubit', wires=3)
@cancel_inverses @qml.qnode(device=dev) def circuit(x, y, z): qml.Hadamard(wires=0) qml.Hadamard(wires=1) qml.Hadamard(wires=0) qml.RX(x, wires=2) qml.RY(y, wires=1) qml.X(1) qml.RZ(z, wires=0) qml.RX(y, wires=2) qml.CNOT(wires=[0, 2]) qml.X(1) return qml.expval(qml.Z(0))
>>> circuit(0.1, 0.2, 0.3) 0.999999999999999
Usage Details
You can also apply it on quantum functions:
def qfunc(x, y, z): qml.Hadamard(wires=0) qml.Hadamard(wires=1) qml.Hadamard(wires=0) qml.RX(x, wires=2) qml.RY(y, wires=1) qml.X(1) qml.RZ(z, wires=0) qml.RX(y, wires=2) qml.CNOT(wires=[0, 2]) qml.X(1) return qml.expval(qml.Z(0))
The circuit before optimization:
>>> qnode = qml.QNode(qfunc, dev) >>> print(qml.draw(qnode)(1, 2, 3)) 0: ──H─────────H─────────RZ(3.00)─╭●────┤ <Z> 1: ──H─────────RY(2.00)──X────────│───X─┤ 2: ──RX(1.00)──RX(2.00)───────────╰X────┤
We can see that there are two adjacent Hadamards on the first qubit that should cancel each other out. Similarly, there are two Pauli-X gates on the second qubit that should cancel. We can obtain a simplified circuit by running the
cancel_inverses
transform:>>> optimized_qfunc = cancel_inverses(qfunc) >>> optimized_qnode = qml.QNode(optimized_qfunc, dev) >>> print(qml.draw(optimized_qnode)(1, 2, 3)) 0: ──RZ(3.00)───────────╭●─┤ <Z> 1: ──H─────────RY(2.00)─│──┤ 2: ──RX(1.00)──RX(2.00)─╰X─┤