class_docstr: Provides methods for calculating the JVP/VJP between the Jacobians of tapes and tangents/cotangents.
class_docstr_tok: ["Provides","methods","for","calculating","the","JVP\/VJP","between","the","Jacobians","of","tapes","and","tangents\/cotangents","."]
docstr: Compute the vjp for a given batch of tapes.
  
  This method is used by autograd, torch, and tensorflow to compute VJPs.
  
  Args:
      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:
      TensorLike: the vector jacobian product.
  
  **Examples:**
  
  For an instance of :class:`~.JacobianProductCalculator` ``jpc``, we have:
  
  >>> tape0 = qml.tape.QuantumScript([qml.RX(0.1, wires=0)], [qml.expval(qml.PauliZ(0))])
  >>> tape1 = qml.tape.QuantumScript([qml.RY(0.2, wires=0)], [qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliX(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.
docstr_tok: ["Compute","the","vjp","for","a","given","batch","of","tapes",".","This","method","is","used","by","autograd",",","torch",",","and","tensorflow","to","compute","VJPs",".","Args",":","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",":","TensorLike",":","the","vector","jacobian","product",".","*","*","Examples",":","*","*","For","an","instance","of",":","class",":","`","~.JacobianProductCalculator","`","``","jpc","``",",","we","have",":",">",">",">","tape0","=","qml.tape.QuantumScript","(","[","qml.RX","(","0.1",",","wires=0",")","]",",","[","qml.expval","(","qml.PauliZ","(","0",")",")","]",")",">",">",">","tape1","=","qml.tape.QuantumScript","(","[","qml.RY","(","0.2",",","wires=0",")","]",",","[","qml.expval","(","qml.PauliZ","(","0",")",")",",","qml.expval","(","qml.PauliX","(","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","."]
code: def compute_vjp(
      self, tapes: Batch, dy: Tuple[Tuple[TensorLike]]
  ) -> Tuple:
      """Compute the vjp for a given batch of tapes.
  
      This method is used by autograd, torch, and tensorflow to compute VJPs.
  
      Args:
          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:
          TensorLike: the vector jacobian product.
  
      **Examples:**
  
      For an instance of :class:`~.JacobianProductCalculator` ``jpc``, we have:
  
      >>> tape0 = qml.tape.QuantumScript([qml.RX(0.1, wires=0)], [qml.expval(qml.PauliZ(0))])
      >>> tape1 = qml.tape.QuantumScript([qml.RY(0.2, wires=0)], [qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliX(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.
  
      """
  
imports: import abc
  from functools import partial
  import inspect
  import logging
  from typing import Tuple, Callable, Optional, Union
  from cachetools import LRUCache
  import numpy
  import pennylane
  from pennylane.tape import QuantumScript
  from pennylane.typing import ResultBatch, TensorLike
label_desc: Use image node_id 2 for calling the JacobianProductCalculator obj's underlying member method code with example usage: obj.compute_vjp(tapes, dy) without return types