qml.tape.expand_tape¶
- expand_tape(tape, depth=1, stop_at=None, expand_measurements=False)[source]¶
Expand all objects in a tape to a specific depth.
- Parameters:
tape (QuantumTape) – The tape to expand
depth (int) – the depth the tape should be expanded
stop_at (Callable) – A function which accepts a queue object, and returns
Trueif this object should not be expanded. If not provided, all objects that support expansion will be expanded.expand_measurements (bool) – If
True, measurements will be expanded to basis rotations and computational basis measurements.
- Returns:
The expanded version of
tape.- Return type:
See also
decompose()for a transform that performs the same job and fits into the current transform architecture.Warning
This method cannot be used with a tape with non-commuting measurements, even if
expand_measurements=False.>>> from pennylane.tape import expand_tape >>> mps = [qml.expval(qml.X(0)), qml.expval(qml.Y(0))] >>> tape = qml.tape.QuantumScript([], mps) >>> expand_tape(tape) Traceback (most recent call last): ... pennylane.exceptions.QuantumFunctionError: Only observables that are qubit-wise commuting Pauli words can be returned on the same wire, some of the following measurements do not commute: [expval(X(0)), expval(Y(0))]
Since commutation is determined by pauli word arithmetic, non-pauli words cannot share wires with other measurements, even if they commute:
>>> measurements = [qml.expval(qml.Projector([0], 0)), qml.probs(wires=0)] >>> tape = qml.tape.QuantumScript([], measurements) >>> expand_tape(tape) Traceback (most recent call last): ... pennylane.exceptions.QuantumFunctionError: Only observables that are qubit-wise commuting Pauli words can be returned on the same wire, some of the following measurements do not commute: [expval(Projector(array([0]), wires=[0])), probs(wires=[0])]
For this reason, we recommend the use of
decompose()instead.Usage Details
>>> from pennylane.tape import expand_tape >>> ops = [qml.Permute((2,1,0), wires=(0,1,2)), qml.X(0)] >>> measurements = [qml.expval(qml.X(0))] >>> tape = qml.tape.QuantumScript(ops, measurements) >>> expanded_tape = expand_tape(tape) >>> print(expanded_tape.draw()) 0: ─╭SWAP──RX─╭GlobalPhase─┤ <X> 2: ─╰SWAP─────╰GlobalPhase─┤
Specifying a depth greater than one decomposes operations multiple times.
>>> expanded_tape2 = expand_tape(tape, depth=2) >>> print(expanded_tape2.draw()) 0: ─╭●─╭X─╭●──RX─┤ <X> 2: ─╰X─╰●─╰X─────┤
The
stop_atcallable allows the specification of terminal operations that should no longer be decomposed. In this example, theXoperator is not decomposed becausestop_at(qml.X(0)) == True.>>> def stop_at(obj): ... return isinstance(obj, qml.X) >>> expanded_tape = expand_tape(tape, stop_at=stop_at) >>> print(expanded_tape.draw()) 0: ─╭SWAP──X─┤ <X> 2: ─╰SWAP────┤
Warning
If an operator does not have a decomposition, it will not be decomposed, even if
stop_at(obj) == False. If you want to decompose to reach a certain gateset, you will need an extra validation pass to ensure you have reached the gateset.>>> def stop_at(obj): ... return getattr(obj, "name", "") in {"RX", "RY"} >>> tape = qml.tape.QuantumScript([qml.RZ(0.1, 0)]) >>> expand_tape(tape, stop_at=stop_at).circuit [RZ(0.1, wires=[0])]
If more than one observable exists on a wire, the diagonalizing gates will be applied and the observable will be substituted for an analogous combination of
qml.Zoperators. This will happen even ifexpand_measurements=False.>>> mps = [qml.expval(qml.X(0)), qml.expval(qml.X(0) @ qml.X(1))] >>> tape = qml.tape.QuantumScript([], mps) >>> expanded_tape = expand_tape(tape) >>> print(expanded_tape.draw()) 0: ──RY─┤ <Z> ╭<Z@Z> 1: ──RY─┤ ╰<Z@Z>
Setting
expand_measurements=Trueapplies any diagonalizing gates and converts the measurement into a wires+eigvals representation.Warning
Many components of PennyLane do not support the wires + eigvals representation. Setting
expand_measurements=Trueshould be used with extreme caution.>>> tape = qml.tape.QuantumScript([], [qml.expval(qml.X(0))]) >>> expand_tape(tape, expand_measurements=True).circuit [H(0), expval(eigvals=[ 1. -1.], wires=[0])]