class_docstr: An operation representing the QDrift approximation for the complex matrix exponential
  of a given Hamiltonian.
  
  The QDrift subroutine provides a method to approximate the matrix exponential of a Hamiltonian
  expressed as a linear combination of terms which in general do not commute. For the Hamiltonian
  :math:`H = \Sigma_j h_j H_{j}`, the product formula is constructed by random sampling from the
  terms of the Hamiltonian with the probability :math:`p_j = h_j / \sum_{j} hj` as:
  
  .. math::
  
      \prod_{j}^{n} e^{i \lambda H_j \tau / n},
  
  where :math:`\tau` is time, :math:`\lambda = \sum_j |h_j|` and :math:`n` is the total number of
  terms to be sampled and added to the product. Note, the terms :math:`H_{j}` are assumed to be
  normalized such that the "impact" of each term is fully encoded in the magnitude of :math:`h_{j}`.
  
  The number of samples :math:`n` required for a given error threshold can be approximated by:
  
  .. math::
  
      n \ \approx \ \frac{2\lambda^{2}t^{2}}{\epsilon}
  
  For more details see `Phys. Rev. Lett. 123, 070503 (2019) <https://arxiv.org/abs/1811.08017>`_.
  
  Args:
      hamiltonian (Union[.Hamiltonian, .Sum]): The Hamiltonian written as a sum of operations
      time (float): The time of evolution, namely the parameter :math:`t` in :math:`e^{iHt}`
      n (int): An integer representing the number of exponentiated terms
      seed (int): The seed for the random number generator
  
  Raises:
      TypeError: The ``hamiltonian`` is not of type :class:`~.Hamiltonian`, or :class:`~.Sum`
      QuantumFunctionError: If the coefficients of ``hamiltonian`` are trainable and are used
          in a differentiable workflow.
  
  **Example**
  
  .. code-block:: python3
  
      coeffs = [0.25, 0.75]
      ops = [qml.PauliX(0), qml.PauliZ(0)]
      H = qml.dot(coeffs, ops)
  
      dev = qml.device("default.qubit", wires=2)
      @qml.qnode(dev)
      def my_circ():
          # Prepare some state
          qml.Hadamard(0)
  
          # Evolve according to H
          qml.QDrift(H, time=1.2, n=10, seed=10)
  
          # Measure some quantity
          return qml.probs()
  
  >>> my_circ()
  array([0.65379493, 0.        , 0.34620507, 0.        ])
  
  
  .. details::
      :title: Usage Details
  
      We currently **Do NOT** support computing gradients with respect to the
      coefficients of the input Hamiltonian. We can however compute the gradient
      with respect to the evolution time:
  
      .. code-block:: python3
  
          dev = qml.device("default.qubit", wires=2)
  
          @qml.qnode(dev)
          def my_circ(time):
              # Prepare H:
              H = qml.dot([0.2, -0.1], [qml.PauliY(0), qml.PauliZ(1)])
  
              # Prepare some state
              qml.Hadamard(0)
  
              # Evolve according to H
              qml.QDrift(H, time, n=10, seed=10)
  
              # Measure some quantity
              return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
  
  
      >>> time = np.array(1.23)
      >>> print(qml.grad(my_circ)(time))
      0.27980654844422853
  
      The error in the approximation of time evolution with the QDrift protocol is
      directly related to the number of samples used in the product. We provide a
      method to upper-bound the error:
  
      >>> H = qml.dot([0.25, 0.75], [qml.PauliX(0), qml.PauliZ(0)])
      >>> print(qml.QDrift.error(H, time=1.2, n=10))
      0.3661197552925645
docstr: A method for determining the upper-bound for the error in the approximation of
  the true matrix exponential.
  
  The error is bounded according to the following expression:
  
  .. math::
  
      \epsilon \ \leq \ \frac{2\lambda^{2}t^{2}}{n}  e^{\frac{2 \lambda t}{n}},
  
  where :math:`t` is time, :math:`\lambda = \sum_j |h_j|` and :math:`n` is the total number of
  terms to be added to the product. For more details see `Phys. Rev. Lett. 123, 070503 (2019) <https://arxiv.org/abs/1811.08017>`_.
  
  Args:
      hamiltonian (Union[.Hamiltonian, .Sum]): The Hamiltonian written as a sum of operations
      time (float): The time of evolution, namely the parameter :math:`t` in :math:`e^{-iHt}`
      n (int): An integer representing the number of exponentiated terms. default is 1
  
  Raises:
      TypeError: The given operator must be a PennyLane .Hamiltonian or .Sum
  
  Returns:
      float: upper bound on the precision achievable using the QDrift protocol
docstr_tok: ["A","method","for","determining","the","upper-bound","for","the","error","in","the","approximation","of","the","true","matrix","exponential",".","The","error","is","bounded","according","to","the","following","expression",":","..","math",":",":","\\epsilon","\\","\\leq","\\","\\frac","{","2\\lambda^","{","2","}","t^","{","2","}","}","{","n","}","e^","{","\\frac","{","2","\\lambda","t","}","{","n","}","}",",","where",":","math",":","`","t","`","is","time",",",":","math",":","`","\\lambda","=","\\sum_j","|h_j|","`","and",":","math",":","`","n","`","is","the","total","number","of","terms","to","be","added","to","the","product",".","For","more","details","see","`","Phys",".","Rev",".","Lett",".","123",",","070503","(","2019",")","<","https",":","\/\/arxiv.org\/abs\/1811.08017",">","`","_",".","Args",":","hamiltonian","(","Union","[",".Hamiltonian",",",".Sum","]",")",":","The","Hamiltonian","written","as","a","sum","of","operations","time","(","float",")",":","The","time","of","evolution",",","namely","the","parameter",":","math",":","`","t","`","in",":","math",":","`","e^","{","-iHt","}","`","n","(","int",")",":","An","integer","representing","the","number","of","exponentiated","terms",".","default","is","1","Raises",":","TypeError",":","The","given","operator","must","be","a","PennyLane",".Hamiltonian","or",".Sum","Returns",":","float",":","upper","bound","on","the","precision","achievable","using","the","QDrift","protocol"]
code: def error(hamiltonian, time, n=1):
      r"""A method for determining the upper-bound for the error in the approximation of
      the true matrix exponential.
  
      The error is bounded according to the following expression:
  
      .. math::
  
          \epsilon \ \leq \ \frac{2\lambda^{2}t^{2}}{n}  e^{\frac{2 \lambda t}{n}},
  
      where :math:`t` is time, :math:`\lambda = \sum_j |h_j|` and :math:`n` is the total number of
      terms to be added to the product. For more details see `Phys. Rev. Lett. 123, 070503 (2019) <https://arxiv.org/abs/1811.08017>`_.
  
      Args:
          hamiltonian (Union[.Hamiltonian, .Sum]): The Hamiltonian written as a sum of operations
          time (float): The time of evolution, namely the parameter :math:`t` in :math:`e^{-iHt}`
          n (int): An integer representing the number of exponentiated terms. default is 1
  
      Raises:
          TypeError: The given operator must be a PennyLane .Hamiltonian or .Sum
  
      Returns:
          float: upper bound on the precision achievable using the QDrift protocol
      """
      if isinstance(hamiltonian, Hamiltonian):
          lmbda = qml.math.sum(qml.math.abs(hamiltonian.coeffs))
  
      elif isinstance(hamiltonian, Sum):
          lmbda = qml.math.sum(
              qml.math.abs(op.scalar) if isinstance(op, SProd) else 1.0
              for op in hamiltonian
          )
  
      else:
          raise TypeError(
              f"The given operator must be a PennyLane ~.Hamiltonian or ~.Sum got {hamiltonian}"
          )
  
      return (2 * lmbda**2 * time**2 / n) * qml.math.exp(
          2 * lmbda * time / n
      )
  
file_path: pennylane/pennylane/templates/subroutines/qdrift.py
imports: import pennylane
  from pennylane.operation import Operation
  from pennylane.math import requires_grad, unwrap
  from pennylane.ops import Sum, SProd, Hamiltonian
label_desc: Use image node_id 4 for calling the QDrift obj's underlying member method code with example usage: obj.error(hamiltonian, time, n) and returns: unknown