# qml.tape.QubitParamShiftTape¶

class QubitParamShiftTape(name=None, do_queue=True)[source]

Bases: pennylane.tape.jacobian_tape.JacobianTape

Quantum tape for qubit parameter-shift analytic differentiation method.

This class extends the jacobian method of the quantum tape to support analytic gradients of qubit operations using the parameter-shift rule. This gradient method returns exact gradients, and can be computed directly on quantum hardware. Simply pass method=analytic when computing the Jacobian:

>>> tape.jacobian(dev, method="analytic")


For more details on the quantum tape, please see JacobianTape.

For a variational evolution $$U(\mathbf{p}) \vert 0\rangle$$ with $$N$$ parameters $$\mathbf{p}$$,

consider the expectation value of an observable $$O$$:

$f(\mathbf{p}) = \langle \hat{O} \rangle(\mathbf{p}) = \langle 0 \vert U(\mathbf{p})^\dagger \hat{O} U(\mathbf{p}) \vert 0\rangle.$

The gradient of this expectation value can be calculated using $$2N$$ expectation values using the parameter-shift rule:

$\frac{\partial f}{\partial \mathbf{p}} = \frac{1}{2\sin s} \left[ f(\mathbf{p} + s) - f(\mathbf{p} -s) \right].$

We can extend this to the variance, $$g(\mathbf{p})=\langle \hat{O}^2 \rangle (\mathbf{p}) - [\langle \hat{O} \rangle(\mathbf{p})]^2$$, by noting that:

$\frac{\partial g}{\partial \mathbf{p}}= \frac{\partial}{\partial \mathbf{p}} \langle \hat{O}^2 \rangle (\mathbf{p}) - 2 f(\mathbf{p}) \frac{\partial f}{\partial \mathbf{p}}.$

This results in $$4N + 1$$ evaluations.

In the case where $$O$$ is involutory ($$\hat{O}^2 = I$$), the first term in the above expression vanishes, and we are simply left with

$\frac{\partial g}{\partial \mathbf{p}} = - 2 f(\mathbf{p}) \frac{\partial f}{\partial \mathbf{p}},$

allowing us to compute the gradient using $$2N + 1$$ evaluations.

 data Alias to get_parameters() and set_parameters() for backwards compatibilities with operations. diagonalizing_gates Returns the gates that diagonalize the measured wires such that they are in the eigenbasis of the circuit observables. graph Returns a directed acyclic graph representation of the recorded quantum circuit: hash returns an integer hash uniquely representing the quantum tape interface automatic differentiation interface used by the quantum tape (if any) measurements Returns the measurements on the quantum tape. num_params Returns the number of trainable parameters on the quantum tape. observables Returns the observables on the quantum tape. operations Returns the operations on the quantum tape. output_dim The (inferred) output dimension of the quantum tape. queue Returns a list of objects in the annotated queue specs Resource information about a quantum circuit. trainable_params Store or return a set containing the indices of parameters that support differentiability.
data

Alias to get_parameters() and set_parameters() for backwards compatibilities with operations.

diagonalizing_gates

Returns the gates that diagonalize the measured wires such that they are in the eigenbasis of the circuit observables.

Returns

the operations that diagonalize the observables

Return type

List[Operation]

graph

Returns a directed acyclic graph representation of the recorded quantum circuit:

>>> tape.graph
<pennylane.circuit_graph.CircuitGraph object at 0x7fcc0433a690>


Note that the circuit graph is only constructed once, on first call to this property, and cached for future use.

Returns

the circuit graph object

Return type

CircuitGraph

hash

returns an integer hash uniquely representing the quantum tape

Type

int

interface

automatic differentiation interface used by the quantum tape (if any)

Type

str, None

measurements

Returns the measurements on the quantum tape.

Returns

list of recorded measurement processess

Return type

list[MeasurementProcess]

Example

with JacobianTape() as tape:
qml.RX(0.432, wires=0)
qml.RY(0.543, wires=0)
qml.CNOT(wires=[0, 'a'])
qml.RX(0.133, wires='a')
qml.expval(qml.PauliZ(wires=[0]))

>>> tape.measurements
[expval(PauliZ(wires=[0]))]

num_params

Returns the number of trainable parameters on the quantum tape.

observables

Returns the observables on the quantum tape.

Returns

list of recorded quantum operations

Return type

list[Observable]

Example

with JacobianTape() as tape:
qml.RX(0.432, wires=0)
qml.RY(0.543, wires=0)
qml.CNOT(wires=[0, 'a'])
qml.RX(0.133, wires='a')
qml.expval(qml.PauliZ(wires=[0]))

>>> tape.observables
[expval(PauliZ(wires=[0]))]

operations

Returns the operations on the quantum tape.

Returns

recorded quantum operations

Return type

list[Operation]

Example

with JacobianTape() as tape:
qml.RX(0.432, wires=0)
qml.RY(0.543, wires=0)
qml.CNOT(wires=[0, 'a'])
qml.RX(0.133, wires='a')
qml.expval(qml.PauliZ(wires=[0]))

>>> tape.operations
[RX(0.432, wires=[0]), RY(0.543, wires=[0]), CNOT(wires=[0, 'a']), RX(0.133, wires=['a'])]

output_dim

The (inferred) output dimension of the quantum tape.

queue

Returns a list of objects in the annotated queue

specs

Resource information about a quantum circuit.

Returns

dictionaries that contain tape specifications

Return type

dict[str, Union[defaultdict,int]]

Example

with qml.tape.QubitParamShiftTape() as tape:
qml.RZ(0.26, wires=1)
qml.CNOT(wires=[1, 0])
qml.Rot(1.8, -2.7, 0.2, wires=0)
qml.CNOT(wires=[0, 1])
qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))


Asking for the specs produces a dictionary as shown below:

>>> tape.specs['gate_sizes']
defaultdict(int, {1: 4, 2: 2})
>>> tape.specs['gate_types']
defaultdict(int, {'Hadamard': 2, 'RZ': 1, 'CNOT': 2, 'Rot': 1})


As defaultdict objects, any key not present in the dictionary returns 0.

>>> tape.specs['gate_types']['RX']
0


In parameter-shift tapes, the number of device executions necessary for a gradient is calulated as well:

>>> tape.specs['num_parameter_shift_executions]
9

trainable_params

Store or return a set containing the indices of parameters that support differentiability. The indices provided match the order of appearence in the quantum circuit.

Setting this property can help reduce the number of quantum evaluations needed to compute the Jacobian; parameters not marked as trainable will be automatically excluded from the Jacobian computation.

The number of trainable parameters determines the number of parameters passed to set_parameters(), execute(), and jacobian(), and changes the default output size of methods jacobian() and get_parameters().

Note

Since the jacobian() method is not called for devices that support native backpropagation (such as default.qubit.tf and default.qubit.autograd), this property contains no relevant information when using backpropagation to compute gradients.

Example

with JacobianTape() as tape:
qml.RX(0.432, wires=0)
qml.RY(0.543, wires=0)
qml.CNOT(wires=[0, 'a'])
qml.RX(0.133, wires='a')
qml.expval(qml.PauliZ(wires=[0]))

>>> tape.trainable_params
{0, 1, 2}
>>> tape.trainable_params = {0} # set only the first parameter as free
>>> tape.get_parameters()
[0.432]

Parameters

param_indices (set[int]) – parameter indices

 Returns the currently active queuing context. Create a tape that is the adjoint of this one. analytic_pd(idx, params, **options) Generate the quantum tapes and classical post-processing function required to compute the gradient of the tape with respect to a single trainable tape parameter using an analytic method. append(obj, **kwargs) Append an object to this QueuingContext instance. copy([copy_operations, tape_cls]) Returns a shallow copy of the quantum tape. device_pd(device[, params]) Evaluate the gradient of the tape with respect to all trainable tape parameters by querying the provided device. draw([charset, wire_order, show_all_wires]) Draw the quantum tape as a circuit diagram. execute(device[, params]) Execute the tape on a quantum device. execute_device(params, device) Execute the tape on a quantum device. expand([depth, stop_at, expand_measurements]) Expand all operations in the processed queue to a specific depth. get_info(obj) Retrieves information of an object in the queue instance. Returns the trainable operation, and the corresponding operation argument index, for a specified trainable parameter index. get_parameters([trainable_only]) Return the parameters incident on the tape operations. hessian(device[, params]) Compute the Hessian of the parametrized quantum circuit recorded by the quantum tape. hessian_pd(i, j, params, **options) Generate the quantum tapes and classical post-processing function required to compute the Hessian of the tape with respect to two trainable tape parameter using an analytic method. Inverts the processed operations. jacobian(device[, params]) Compute the Jacobian of the parametrized quantum circuit recorded by the quantum tape. numeric_pd(idx[, params]) Generate the tapes and postprocessing methods required to compute the gradient of a parameter using the finite-difference method. parameter_shift(idx, params, **options) Generate the tapes and postprocessing methods required to compute the gradient of a parameter using the parameter-shift method. parameter_shift_hessian(i, j, params, **options) Generate the tapes and postprocessing methods required to compute the second derivative with respect to tape parameter $$i$$ and $$j$$ using the second-order parameter-shift method. parameter_shift_var(idx, params, **options) Generate the tapes and postprocessing methods required to compute the gradient of a parameter and its variance using the parameter-shift method. Whether a queuing context is active and recording operations remove(obj) Remove an object from this QueuingContext instance. set_parameters(params[, trainable_only]) Set the parameters incident on the tape operations. Context manager to temporarily stop recording operations onto the tape. to_openqasm([wires, rotations, measure_all]) Serialize the circuit as an OpenQASM 2.0 program. A context manager that unwraps a tape with tensor-like parameters to NumPy arrays. update_info(obj, **kwargs) Updates information of an object in the queue instance.
classmethod active_context()

Returns the currently active queuing context.

adjoint()

Create a tape that is the adjoint of this one.

Adjointed tapes are the conjugated and transposed version of the original tapes. Adjointed ops are equivalent to the inverted operation for unitary gates.

Returns

Return type

QuantumTape

analytic_pd(idx, params, **options)

Generate the quantum tapes and classical post-processing function required to compute the gradient of the tape with respect to a single trainable tape parameter using an analytic method.

Parameters
• idx (int) – trainable parameter index to differentiate with respect to

• params (list[Any]) – the quantum tape operation parameters

Returns

A tuple containing the list of generated tapes, in addition to a post-processing function to be applied to the evaluated tapes.

Return type

tuple[list[QuantumTape], function]

append(obj, **kwargs)

Append an object to this QueuingContext instance.

Parameters

obj – The object to be appended

copy(copy_operations=False, tape_cls=None)

Returns a shallow copy of the quantum tape.

Parameters
• copy_operations (bool) – If True, the tape operations are also shallow copied. Otherwise, if False, the copied tape operations will simply be references to the original tape operations; changing the parameters of one tape will likewise change the parameters of all copies.

• tape_cls (QuantumTape) – Cast the copied tape to a specific quantum tape subclass. If not provided, the same subclass is used as the original tape.

Returns

a shallow copy of the tape

Return type

QuantumTape

device_pd(device, params=None, **options)

Evaluate the gradient of the tape with respect to all trainable tape parameters by querying the provided device.

Parameters
• device (Device, QubitDevice) – a PennyLane device that can execute quantum operations and return measurement statistics

• params (list[Any]) – The quantum tape operation parameters. If not provided, the current tape parameter values are used (via get_parameters()).

draw(charset='unicode', wire_order=None, show_all_wires=False)

Draw the quantum tape as a circuit diagram.

Consider the following circuit as an example:

with QuantumTape() as tape:
qml.CRX(2.3, wires=[0, 1])
qml.Rot(1.2, 3.2, 0.7, wires=[1])
qml.CRX(-2.3, wires=[0, 1])
qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))


We can draw the tape after construction:

>>> print(tape.draw())
0: ──H──╭C────────────────────────────╭C─────────╭┤ ⟨Z ⊗ Z⟩
1: ─────╰RX(2.3)──Rot(1.2, 3.2, 0.7)──╰RX(-2.3)──╰┤ ⟨Z ⊗ Z⟩
>>> print(tape.draw(charset="ascii"))
0: --H--+C----------------------------+C---------+| <Z @ Z>
1: -----+RX(2.3)--Rot(1.2, 3.2, 0.7)--+RX(-2.3)--+| <Z @ Z>

Parameters
• charset (str, optional) – The charset that should be used. Currently, “unicode” and “ascii” are supported.

• wire_order (Sequence[Any]) – the order (from top to bottom) to print the wires of the circuit

• show_all_wires (bool) – If True, all wires, including empty wires, are printed.

Raises

ValueError – if the given charset is not supported

Returns

the circuit representation of the tape

Return type

str

execute(device, params=None)

Execute the tape on a quantum device.

Parameters
• device (Device) – a PennyLane device that can execute quantum operations and return measurement statistics

• params (list[Any]) – The quantum tape operation parameters. If not provided, the current tape parameters are used (via get_parameters()).

Example

with JacobianTape() as tape:
qml.RX(0.432, wires=0)
qml.RY(0.543, wires=0)
qml.CNOT(wires=[0, 'a'])
qml.RX(0.133, wires='a')
qml.probs(wires=[0, 'a'])


If parameters are not provided, the existing tape parameters are used:

>>> dev = qml.device("default.qubit", wires=[0, 'a'])
>>> tape.execute(dev)
array([[8.84828969e-01, 3.92449987e-03, 4.91235209e-04, 1.10755296e-01]])


Parameters can be optionally passed during execution:

>>> tape.execute(dev, params=[1.0, 0.0, 1.0])
array([[0.5931328 , 0.17701835, 0.05283049, 0.17701835]])


Parameters provided for execution are temporary, and do not affect the tapes’ parameters in-place:

>>> tape.get_parameters()
[0.432, 0.543, 0.133]

execute_device(params, device)

Execute the tape on a quantum device.

This is a low-level method, intended to be called by an interface, and does not support autodifferentiation.

For more details on differentiable tape execution, see execute().

Parameters
• device (Device) – a PennyLane device that can execute quantum operations and return measurement statistics

• params (list[Any]) – The quantum tape operation parameters. If not provided, the current tape parameter values are used (via get_parameters()).

expand(depth=1, stop_at=None, expand_measurements=False)

Expand all operations in the processed queue to a specific depth.

Parameters
• depth (int) – the depth the tape should be expanded

• stop_at (Callable) – A function which accepts a queue object, and returns True if 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.

Example

Consider the following nested tape:

with JacobianTape() as tape:
qml.BasisState(np.array([1, 1]), wires=[0, 'a'])

with JacobianTape() as tape2:
qml.Rot(0.543, 0.1, 0.4, wires=0)

qml.CNOT(wires=[0, 'a'])
qml.RY(0.2, wires='a')
qml.probs(wires=0), qml.probs(wires='a')


The nested structure is preserved:

>>> tape.operations
[BasisState(array([1, 1]), wires=[0, 'a']),
<JacobianTape: wires=[0], params=3>,
CNOT(wires=[0, 'a']),
RY(0.2, wires=['a'])]


Calling .expand will return a tape with all nested tapes expanded, resulting in a single tape of quantum operations:

>>> new_tape = tape.expand(depth=2)
>>> new_tape.operations
[PauliX(wires=[0]),
PauliX(wires=['a']),
RZ(0.543, wires=[0]),
RY(0.1, wires=[0]),
RZ(0.4, wires=[0]),
CNOT(wires=[0, 'a']),
RY(0.2, wires=['a'])]

get_info(obj)

Retrieves information of an object in the queue instance.

get_operation(idx)

Returns the trainable operation, and the corresponding operation argument index, for a specified trainable parameter index.

Parameters

idx (int) – the trainable parameter index

Returns

tuple containing the corresponding operation, and an integer representing the argument index, for the provided trainable parameter.

Return type

tuple[Operation, int]

get_parameters(trainable_only=True, **kwargs)

Return the parameters incident on the tape operations.

The returned parameters are provided in order of appearance on the tape.

Parameters

trainable_only (bool) – if True, returns only trainable parameters

Example

with JacobianTape() as tape:
qml.RX(0.432, wires=0)
qml.RY(0.543, wires=0)
qml.CNOT(wires=[0, 'a'])
qml.RX(0.133, wires='a')
qml.expval(qml.PauliZ(wires=[0]))


By default, all parameters are trainable and will be returned:

>>> tape.get_parameters()
[0.432, 0.543, 0.133]


Setting the trainable parameter indices will result in only the specified parameters being returned:

>>> tape.trainable_params = {1} # set the second parameter as free
>>> tape.get_parameters()
[0.543]


The trainable_only argument can be set to False to instead return all parameters:

>>> tape.get_parameters(trainable_only=False)
[0.432, 0.543, 0.133]

hessian(device, params=None, **options)

Compute the Hessian of the parametrized quantum circuit recorded by the quantum tape.

The quantum tape can be interpreted as a simple $$\mathbb{R}^m \to \mathbb{R}^n$$ function, mapping $$m$$ (trainable) gate parameters to $$n$$ measurement statistics, such as expectation values or probabilities.

By default, the Hessian will be computed with respect to all parameters on the quantum tape. This can be modified by setting the trainable_params attribute of the tape.

The Hessian can be currently computed using only the 'analytic' method.

Parameters
• device (Device, QubitDevice) – a PennyLane device that can execute quantum operations and return measurement statistics

• params (list[Any]) – The quantum tape operation parameters. If not provided, the current tape parameter values are used (via get_parameters()).

Keyword Arguments
• method="analytic" (str) – The differentiation method. Currently only supports "analytic".

• s1=pi/2 (float) – the size of the shift for index i in the parameter-shift Hessian computations

• s2=pi/2 (float) – the size of the shift for index j in the parameter-shift Hessian computations

Returns

2-dimensional array of shape (tape.num_params, tape.num_params)

Return type

array[float]

Example

n_wires = 5
weights = [2.73943676, 0.16289932, 3.4536312, 2.73521126, 2.6412488]

with QubitParamShiftTape() as tape:
for i in range(n_wires):
qml.RX(weights[i], wires=i)

qml.CNOT(wires=[0, 1])
qml.CNOT(wires=[2, 1])
qml.CNOT(wires=[3, 1])
qml.CNOT(wires=[4, 3])

qml.expval(qml.PauliZ(1))


If parameters are not provided, the existing tape parameters are used:

>>> dev = qml.device("default.qubit", wires=n_wires)
>>> tape.hessian(dev)
array([[ 0.79380556,  0.05549219,  0.10891309, -0.1452963,   0.],
[ 0.05549219,  0.79380556, -0.04208544,  0.05614438,  0.],
[ 0.10891309, -0.04208544,  0.79380556,  0.11019314,  0.],
[-0.1452963,   0.05614438,  0.11019314,  0.79380556,  0.],
[ 0.,          0.,          0.,          0.,          0.]])


Parameters can be optionally passed during execution:

>>> tape.hessian(dev, params=[1.0, 1.0, 2.0, 0, 0])
array([[ 0.12148432, -0.29466251,  0.41341091,  0.,          0.],
[-0.29466251,  0.12148432,  0.41341091,  0.,          0.],
[ 0.41341091,  0.41341091,  0.12148432,  0.,          0.],
[ 0.,          0.,          0.,          0.12148432,  0.],
[ 0.,          0.,          0.,          0.,          0.]])


Parameters provided for execution are temporary, and do not affect the tapes’ parameters in-place:

>>> tape.get_parameters()
[2.73943676, 0.16289932, 3.4536312, 2.73521126, 2.6412488]


If a tape has no trainable parameters, the Hessian will be empty:

>>> tape.trainable_params = {}
>>> tape.hessian(dev)
array([], shape=(0, 0), dtype=float64)

hessian_pd(i, j, params, **options)

Generate the quantum tapes and classical post-processing function required to compute the Hessian of the tape with respect to two trainable tape parameter using an analytic method.

Parameters
• i (int) – trainable parameter index to differentiate with respect to

• j (int) – trainable parameter index to differentiate with respect to

• params (list[Any]) – the quantum tape operation parameters

Returns

A tuple containing the list of generated tapes, in addition to a post-processing function to be applied to the evaluated tapes.

Return type

tuple[list[QuantumTape], function]

inv()

Inverts the processed operations.

Inversion is performed in-place.

Note

This method only inverts the quantum operations/unitary recorded by the quantum tape; state preparations and measurements are left unchanged.

Example

with JacobianTape() as tape:
qml.BasisState(np.array([1, 1]), wires=[0, 'a'])
qml.RX(0.432, wires=0)
qml.Rot(0.543, 0.1, 0.4, wires=0).inv()
qml.CNOT(wires=[0, 'a'])
qml.probs(wires=0), qml.probs(wires='a')


This tape has the following properties:

>>> tape.operations
[BasisState(array([1, 1]), wires=[0, 'a']),
RX(0.432, wires=[0]),
Rot.inv(0.543, 0.1, 0.4, wires=[0]),
CNOT(wires=[0, 'a'])]
>>> tape.get_parameters()
[array([1, 1]), 0.432, 0.543, 0.1, 0.4]


Here, let’s set some trainable parameters:

>>> tape.trainable_params = {1, 2}
>>> tape.get_parameters()
[0.432, 0.543]


Inverting the tape:

>>> tape.inv()
>>> tape.operations
[BasisState(array([1, 1]), wires=[0, 'a']),
CNOT.inv(wires=[0, 'a']),
Rot(0.543, 0.1, 0.4, wires=[0]),
RX.inv(0.432, wires=[0])]


Tape inversion also modifies the order of tape parameters:

>>> tape.get_parameters(trainable_only=False)
[array([1, 1]), 0.543, 0.1, 0.4, 0.432]
>>> tape.get_parameters(trainable_only=True)
[0.543, 0.432]
>>> tape.trainable_params
{1, 4}

jacobian(device, params=None, **options)[source]

Compute the Jacobian of the parametrized quantum circuit recorded by the quantum tape.

The quantum tape can be interpreted as a simple $$\mathbb{R}^m \to \mathbb{R}^n$$ function, mapping $$m$$ (trainable) gate parameters to $$n$$ measurement statistics, such as expectation values or probabilities.

By default, the Jacobian will be computed with respect to all parameters on the quantum tape. This can be modified by setting the trainable_params attribute of the tape.

The Jacobian can be computed using several methods:

• Finite differences ('numeric'). The first-order method evaluates the circuit at $$n+1$$ points of the parameter space, the second-order method at $$2n$$ points, where n = tape.num_params.

• Analytic method ('analytic'). Analytic, if implemented by the inheriting quantum tape.

• Best known method for each parameter ('best'): uses the analytic method if possible, otherwise finite difference.

• Device method ('device'): Delegates the computation of the Jacobian to the device executing the circuit. Only supported by devices that provide their own method for computing derivatives; support can be checked by querying the device capabilities: dev.capabilities()['provides_jacobian'] must return True. Examples of supported devices include the experimental "default.tensor.tf" device.

Note

The finite difference method is sensitive to statistical noise in the circuit output, since it compares the output at two points infinitesimally close to each other. Hence the 'F' method works best with exact expectation values when using simulator devices.

Parameters
• device (Device, QubitDevice) – a PennyLane device that can execute quantum operations and return measurement statistics

• params (list[Any]) – The quantum tape operation parameters. If not provided, the current tape parameter values are used (via get_parameters()).

Keyword Arguments
• method="best" (str) – The differentiation method. Must be one of "numeric", "analytic", "best", or "device".

• h=1e-7 (float) – finite difference method step size

• order=1 (int) – The order of the finite difference method to use. 1 corresponds to forward finite differences, 2 to centered finite differences.

• shift=pi/2 (float) – the size of the shift for two-term parameter-shift gradient computations

• argnum=None (int, list(int), None) – Which argument(s) to compute the Jacobian with respect to. When there are fewer parameters specified than the total number of trainable parameters, the jacobian is being estimated.

Returns

2-dimensional array of shape (tape.output_dim, tape.num_params)

Return type

array[float]

Example

with JacobianTape() as tape:
qml.RX(0.432, wires=0)
qml.RY(0.543, wires=0)
qml.CNOT(wires=[0, 'a'])
qml.RX(0.133, wires='a')
qml.probs(wires=[0, 'a'])


If parameters are not provided, the existing tape parameters are used:

>>> dev = qml.device("default.qubit", wires=[0, 'a'])
>>> tape.jacobian(dev)
array([[-0.178441  , -0.23358253, -0.05892804],
[-0.00079144, -0.00103601,  0.05892804],
[ 0.00079144,  0.00103601,  0.00737611],
[ 0.178441  ,  0.23358253, -0.00737611]])


Parameters can be optionally passed during execution:

>>> tape.jacobian(dev, params=[1.0, 0.0, 1.0])
array([[-3.24029934e-01, -9.99200722e-09, -3.24029934e-01],
[-9.67055711e-02, -2.77555756e-09,  3.24029935e-01],
[ 9.67055709e-02,  3.05311332e-09,  9.67055709e-02],
[ 3.24029935e-01,  1.08246745e-08, -9.67055711e-02]])


Parameters provided for execution are temporary, and do not affect the tapes’ parameters in-place:

>>> tape.get_parameters()
[0.432, 0.543, 0.133]


Explicitly setting the trainable parameters can significantly reduce computational resources, as non-trainable parameters are ignored during the computation:

>>> tape.trainable_params = {0} # set only the first parameter as trainable
>>> tape.jacobian(dev)
array([[-0.178441  ],
[-0.00079144],
[ 0.00079144],
[ 0.178441  ]])


If a tape has no trainable parameters, the Jacobian will be empty:

>>> tape.trainable_params = {}
>>> tape.jacobian(dev)
array([], shape=(4, 0), dtype=float64)

numeric_pd(idx, params=None, **options)

Generate the tapes and postprocessing methods required to compute the gradient of a parameter using the finite-difference method.

Parameters
• idx (int) – trainable parameter index to differentiate with respect to

• params (list[Any]) – The quantum tape operation parameters. If not provided, the current tape parameter values are used (via get_parameters()).

Keyword Arguments
• h=1e-7 (float) – finite difference method step size

• order=1 (int) – The order of the finite difference method to use. 1 corresponds to forward finite differences, 2 to centered finite differences.

Returns

A tuple containing the list of generated tapes, in addition to a post-processing function to be applied to the evaluated tapes.

Return type

tuple[list[QuantumTape], function]

parameter_shift(idx, params, **options)[source]

Generate the tapes and postprocessing methods required to compute the gradient of a parameter using the parameter-shift method.

Parameters
• idx (int) – trainable parameter index to differentiate with respect to

• params (list[Any]) – the quantum tape operation parameters

Keyword Arguments

shift=pi/2 (float) – the size of the shift for two-term parameter-shift gradient computations

Returns

A tuple containing the list of generated tapes, in addition to a post-processing function to be applied to the evaluated tapes.

Return type

tuple[list[QuantumTape], function]

parameter_shift_hessian(i, j, params, **options)[source]

Generate the tapes and postprocessing methods required to compute the second derivative with respect to tape parameter $$i$$ and $$j$$ using the second-order parameter-shift method.

Parameters
• i (int) – trainable parameter index to differentiate with respect to

• j (int) – trainable parameter index to differentiate with respect to

• params (list[Any]) – the quantum tape operation parameters

Keyword Arguments
• s1=pi/2 (float) – the size of the shift for index i in the parameter-shift Hessian computations

• s2=pi/2 (float) – the size of the shift for index j in the parameter-shift Hessian computations

Returns

A tuple containing the list of generated tapes, in addition to a post-processing function to be applied to the evaluated tapes.

Return type

tuple[list[QuantumTape], function]

parameter_shift_var(idx, params, **options)[source]

Generate the tapes and postprocessing methods required to compute the gradient of a parameter and its variance using the parameter-shift method.

Parameters
• idx (int) – trainable parameter index to differentiate with respect to

• params (list[Any]) – the quantum tape operation parameters

Keyword Arguments

shift=pi/2 (float) – the size of the shift for two-term parameter-shift gradient computations

Returns

A tuple containing the list of generated tapes, in addition to a post-processing function to be applied to the evaluated tapes.

Return type

tuple[list[QuantumTape], function]

classmethod recording()

Whether a queuing context is active and recording operations

remove(obj)

Remove an object from this QueuingContext instance.

Parameters

obj – the object to be removed

set_parameters(params, trainable_only=True)

Set the parameters incident on the tape operations.

Parameters
• params (list[float]) – A list of real numbers representing the parameters of the quantum operations. The parameters should be provided in order of appearance in the quantum tape.

• trainable_only (bool) – if True, set only trainable parameters

Example

with JacobianTape() as tape:
qml.RX(0.432, wires=0)
qml.RY(0.543, wires=0)
qml.CNOT(wires=[0, 'a'])
qml.RX(0.133, wires='a')
qml.expval(qml.PauliZ(wires=[0]))


By default, all parameters are trainable and can be modified:

>>> tape.set_parameters([0.1, 0.2, 0.3])
>>> tape.get_parameters()
[0.1, 0.2, 0.3]


Setting the trainable parameter indices will result in only the specified parameters being modifiable. Note that this only modifies the number of parameters that must be passed.

>>> tape.trainable_params = {0, 2} # set the first and third parameter as free
>>> tape.set_parameters([-0.1, 0.5])
>>> tape.get_parameters(trainable_only=False)
[-0.1, 0.2, 0.5]


The trainable_only argument can be set to False to instead set all parameters:

>>> tape.set_parameters([4, 1, 6], trainable_only=False)
>>> tape.get_parameters(trainable_only=False)
[4, 1, 6]

stop_recording()

Context manager to temporarily stop recording operations onto the tape. This is useful is scratch space is needed.

Example

>>> with qml.tape.QuantumTape() as tape:
...     qml.RX(0, wires=0)
...     with tape.stop_recording():
...         qml.RY(1.0, wires=1)
...     qml.RZ(2, wires=1)
>>> tape.operations
[RX(0, wires=[0]), RZ(2, wires=[1])]

to_openqasm(wires=None, rotations=True, measure_all=True)

Serialize the circuit as an OpenQASM 2.0 program.

Measurements are assumed to be performed on all qubits in the computational basis. An optional rotations argument can be provided so that output of the OpenQASM circuit is diagonal in the eigenbasis of the tape’s observables. The measurement outputs can be restricted to only those specified in the tape by setting measure_all=False.

Note

The serialized OpenQASM program assumes that gate definitions in qelib1.inc are available.

Parameters
• wires (Wires or None) – the wires to use when serializing the circuit

• rotations (bool) – in addition to serializing user-specified operations, also include the gates that diagonalize the measured wires such that they are in the eigenbasis of the circuit observables.

• measure_all (bool) – whether to perform a computational basis measurement on all qubits or just those specified in the tape

Returns

OpenQASM serialization of the circuit

Return type

str

unwrap()

A context manager that unwraps a tape with tensor-like parameters to NumPy arrays.

Parameters

tape (QuantumTape) – the quantum tape to unwrap

Returns

the unwrapped quantum tape

Return type

QuantumTape

Example

>>> with tf.GradientTape():
...     with qml.tape.QuantumTape() as tape:
...         qml.RX(tf.Variable(0.1), wires=0)
...         qml.RY(tf.constant(0.2), wires=0)
...         qml.RZ(tf.Variable(0.3), wires=0)
...     with tape.unwrap():
...         print("Trainable params:", tape.trainable_params)
...         print("Unwrapped params:", tape.get_parameters())
Trainable params: {0, 2}
Unwrapped params: [0.1, 0.3]
>>> print("Original parameters:", tape.get_parameters())
Original parameters: [<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.1>,
<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.3>]

update_info(obj, **kwargs)

Updates information of an object in the queue instance.