qml.transforms.merge_rotations

merge_rotations = <function merge_rotations>[source]

Quantum function transform to combine rotation gates of the same type that act sequentially.

If the combination of two rotation produces an angle that is close to 0, neither gate will be applied.

Parameters
  • qfunc (function) – A quantum function.

  • atol (float) – After fusion of gates, if the fused angle \(\theta\) is such that \(|\theta|\leq \text{atol}\), no rotation gate will be applied.

  • include_gates (None or list[str]) – A list of specific operations to merge. If set to None (default), all operations with the is_composable_rotation attribute set to True will be merged. Otherwise, only the operations whose names match those in the list will undergo merging.

Returns

the transformed quantum function

Return type

function

Example

Consider the following quantum function.

def qfunc(x, y, z):
    qml.RX(x, wires=0)
    qml.RX(y, wires=0)
    qml.CNOT(wires=[1, 2])
    qml.RY(y, wires=1)
    qml.Hadamard(wires=2)
    qml.CRZ(z, wires=[2, 0])
    qml.RY(-y, wires=1)
    return qml.expval(qml.PauliZ(0))

The circuit before optimization:

>>> dev = qml.device('default.qubit', wires=3)
>>> qnode = qml.QNode(qfunc, dev)
>>> print(qml.draw(qnode)(1, 2, 3))
 0: ───RX(1)──RX(2)──────────╭RZ(3)──┤ ⟨Z⟩
 1: ──╭C──────RY(2)──RY(-2)──│───────┤
 2: ──╰X──────H──────────────╰C──────┤

By inspection, we can combine the two RX rotations on the first qubit. On the second qubit, we have a cumulative angle of 0, and the gates will cancel.

>>> optimized_qfunc = merge_rotations()(qfunc)
>>> optimized_qnode = qml.QNode(optimized_qfunc, dev)
>>> print(qml.draw(optimized_qnode)(1, 2, 3))
 0: ───RX(3)─────╭RZ(3)──┤ ⟨Z⟩
 1: ──╭C─────────│───────┤
 2: ──╰X──────H──╰C──────┤

It is also possible to explicitly specify which rotations merge_rotations should be merged using the include_gates argument. For example, if in the above circuit we wanted only to merge the “RX” gates, we could do so as follows:

>>> optimized_qfunc = merge_rotations(include_gates=["RX"])(qfunc)
>>> optimized_qnode = qml.QNode(optimized_qfunc, dev)
>>> print(qml.draw(optimized_qnode)(1, 2, 3))
 0: ───RX(3)─────────────────╭RZ(3)──┤ ⟨Z⟩
 1: ──╭C──────RY(2)──RY(-2)──│───────┤
 2: ──╰X──────H──────────────╰C──────┤