qml.workflow.jacobian_products.TransformJacobianProducts

class TransformJacobianProducts(inner_execute, gradient_transform, gradient_kwargs=None, cache_full_jacobian=False)[source]

Bases: pennylane.workflow.jacobian_products.JacobianProductCalculator

Compute VJPs, JVPs and Jacobians via a gradient transform TransformDispatcher.

Parameters
  • inner_execute (Callable[[Tuple[QuantumTape]], ResultBatch]) – a function that executes the batch of circuits and returns their results.

  • gradient_transform (TransformDispatcher) – the gradient transform to use.

  • gradient_kwargs (dict) – Any keyword arguments for the gradient transform.

Keyword Arguments

cache_full_jacobian=False (bool) – Whether or not to compute the full jacobian and cache it, instead of treating each call as independent. This keyword argument is used to patch problematic autograd behaviour when caching is turned off. In this case, caching will be based on the identity of the batch, rather than the potentially expensive hash that is used by the cache.

>>> inner_execute = qml.device('default.qubit').execute
>>> gradient_transform = qml.gradients.param_shift
>>> kwargs = {"broadcast": True}
>>> jpc = TransformJacobianProducts(inner_execute, gradient_transform, kwargs)

compute_jacobian(tapes)

Compute the full Jacobian for a batch of tapes.

compute_vjp(tapes, dy)

Compute the vjp for a given batch of tapes.

execute_and_compute_jacobian(tapes)

Compute the results and the full Jacobian for a batch of tapes.

execute_and_compute_jvp(tapes, tangents)

Calculate both the results for a batch of tapes and the jvp.

compute_jacobian(tapes)[source]

Compute the full Jacobian for a batch of tapes.

This method is required to compute Jacobians in the tensorflow interface

Parameters

tapes (tuple[QuantumScript]) – the batch of tapes to take the derivatives of

Examples:

For an instance of JacobianProductCalculator jpc, we have:

>>> tape0 = qml.tape.QuantumScript([qml.RX(0.1, wires=0)], [qml.expval(qml.Z(0))])
>>> tape1 = qml.tape.QuantumScript([qml.RY(0.2, wires=0)], [qml.expval(qml.Z(0)), qml.expval(qml.X(0))])
>>> batch = (tape0, tape1)
>>> jpc.compute_jacobian(batch)
(array(-0.09983342), (array(-0.19866933), array(0.98006658)))

While this method could support non-scalar parameters in theory, no implementation currently supports jacobians with non-scalar parameters.

compute_vjp(tapes, dy)[source]

Compute the vjp for a given batch of tapes.

This method is used by autograd, torch, and tensorflow to compute VJPs.

Parameters
  • tapes (tuple[QuantumScript]) – the batch of tapes to take the derivatives of

  • dy (tuple[tuple[TensorLike]]) – the derivatives of the results of an execution. The i``th entry (cotangent) corresponds to the ``i th tape, and the j th entry of the i th cotangent corresponds to the j th return value of the i th tape.

Returns

the vector jacobian product.

Return type

TensorLike

Examples:

For an instance of JacobianProductCalculator jpc, we have:

>>> tape0 = qml.tape.QuantumScript([qml.RX(0.1, wires=0)], [qml.expval(qml.Z(0))])
>>> tape1 = qml.tape.QuantumScript([qml.RY(0.2, wires=0)], [qml.expval(qml.Z(0)), qml.expval(qml.X(0))])
>>> batch = (tape0, tape1)
>>> dy0 = (0.5, )
>>> dy1 = (2.0, 3.0)
>>> dys = (dy0, dy1)
>>> vjps = jpc.compute_vjp(batch, dys)
>>> vjps
(array([-0.04991671]), array([2.54286107]))
>>> expected_vjp0 = 0.5 * -np.sin(0.1)
>>> qml.math.allclose(vjps[0], expected_vjp0)
True
>>> expected_vjp1 = 2.0 * -np.sin(0.2) + 3.0 * np.cos(0.2)
>>> qml.math.allclose(vjps[1], expected_vjp1)
True

While this method could support non-scalar parameters in theory, no implementation currently supports jacobians with non-scalar parameters.

execute_and_compute_jacobian(tapes)[source]

Compute the results and the full Jacobian for a batch of tapes.

This method is required to compute Jacobians in the jax-jit interface

Parameters

tapes (tuple[QuantumScript]) – the batch of tapes to take the derivatives of

Examples:

For an instance of JacobianProductCalculator jpc, we have:

>>> tape0 = qml.tape.QuantumScript([qml.RX(0.1, wires=0)], [qml.expval(qml.Z(0))])
>>> tape1 = qml.tape.QuantumScript([qml.RY(0.2, wires=0)], [qml.expval(qml.Z(0)), qml.expval(qml.X(0))])
>>> batch = (tape0, tape1)
>>> results, jacs = jpc.execute_and_compute_jacobian(batch)
>>> results
(0.9950041652780258, (0.9800665778412417, 0.19866933079506116))
>>> jacs
(array(-0.09983342), (array(-0.19866933), array(0.98006658)))

While this method could support non-scalar parameters in theory, no implementation currently supports jacobians with non-scalar parameters.

execute_and_compute_jvp(tapes, tangents)[source]

Calculate both the results for a batch of tapes and the jvp.

This method is required to compute JVPs in the JAX interface.

Parameters
  • tapes (Sequence[QuantumScript | QuantumTape]) – The batch of tapes to take the derivatives of

  • tangents (Sequence[Sequence[TensorLike]]) – the tangents for the parameters of the tape. The i th tangent corresponds to the i th tape, and the j th entry into a tangent entry corresponds to the j th trainable parameter of the tape.

Returns

the results of the execution and the jacobian vector product

Return type

ResultBatch, TensorLike

Examples:

For an instance of JacobianProductCalculator jpc, we have:

>>> tape0 = qml.tape.QuantumScript([qml.RX(0.1, wires=0)], [qml.expval(qml.Z(0))])
>>> tape1 = qml.tape.QuantumScript([qml.RY(0.2, wires=0)], [qml.expval(qml.Z(0))])
>>> batch = (tape0, tape1)
>>> tangents0 = (1.5, )
>>> tangents1 = (2.0, )
>>> tangents = (tangents0, tangents1)
>>> results, jvps = jpc.execute_and_compute_jvp(batch, tangents)
>>> expected_results = (np.cos(0.1), np.cos(0.2))
>>> qml.math.allclose(results, expected_results)
True
>>> jvps
(array(-0.14975012), array(-0.39733866))
>>> expected_jvps = 1.5 * -np.sin(0.1), 2.0 * -np.sin(0.2)
>>> qml.math.allclose(jvps, expected_jvps)
True

While this method could support non-scalar parameters in theory, no implementation currently supports jacobians with non-scalar parameters.