qml.transforms.create_expand_fn

create_expand_fn(depth, stop_at=None, device=None, docstring=None)[source]

Create a function for expanding a tape to a given depth, and with a specific stopping criterion. This is a wrapper around expand().

Parameters
  • depth (int) – Depth for the expansion

  • stop_at (callable) – Stopping criterion. This must be a function with signature stop_at(obj), where obj is a queueable PennyLane object such as Operation or MeasurementProcess. It must return a boolean, indicating if the expansion should stop at this object.

  • device (Device) – Ensure that the expanded tape only uses native gates of the given device.

  • docstring (str) – docstring for the generated expansion function

Returns

Tape expansion function. The returned function accepts a QuantumTape, and returns an expanded QuantumTape.

Return type

callable

Example

Let us construct an expansion function that expands a tape in order to decompose trainable multi-parameter gates. We allow for up to five expansion steps, which can be controlled with the argument depth. The stopping criterion is easy to write as

>>> stop_at = ~(qml.operation.has_multipar & qml.operation.is_trainable)

Then the expansion function can be obtained via

>>> expand_fn = qml.transforms.create_expand_fn(depth=5, stop_at=stop_at)

We can test the newly generated function on an example tape:

with qml.tape.JacobianTape() as tape:
    qml.RX(0.2, wires=0)
    qml.RX(qml.numpy.array(-2.4, requires_grad=True), wires=1)
    qml.Rot(1.7, 0.92, -1.1, wires=0)
    qml.Rot(*qml.numpy.array([-3.1, 0.73, 1.36], requires_grad=True), wires=1)
>>> new_tape = expand_fn(tape)
>>> print(tape.draw())
 0: ──RX(0.2)───Rot(1.7, 0.92, -1.1)───┤
 1: ──RX(-2.4)──Rot(-3.1, 0.73, 1.36)──┤
>>> print(new_tape.draw())
 0: ──RX(0.2)───Rot(1.7, 0.92, -1.1)──────────────────────┤
 1: ──RX(-2.4)──RZ(-3.1)──────────────RY(0.73)──RZ(1.36)──┤