class_docstr: An operation representing the Suzuki-Trotter product approximation for the complex matrix
  exponential of a given Hamiltonian.
  
  The Suzuki-Trotter product formula provides a method to approximate the matrix exponential of
  Hamiltonian expressed as a linear combination of terms which in general do not commute. Consider
  the Hamiltonian :math:`H = \Sigma^{N}_{j=0} O_{j}`, the product formula is constructed using
  symmetrized products of the terms in the Hamiltonian. The symmetrized products of order
  :math:`m \in [1, 2, 4, ..., 2k]` with :math:`k \in \mathbb{N}` are given by:
  
  .. math::
  
      \begin{align}
          S_{1}(t) &= \Pi_{j=0}^{N} \ e^{i t O_{j}} \\
          S_{2}(t) &= \Pi_{j=0}^{N} \ e^{i \frac{t}{2} O_{j}} \cdot \Pi_{j=N}^{0} \ e^{i \frac{t}{2} O_{j}} \\
          &\vdots \\
          S_{m}(t) &= S_{m-2}(p_{m}t)^{2} \cdot S_{m-2}((1-4p_{m})t) \cdot S_{m-2}(p_{m}t)^{2},
      \end{align}
  
  where the coefficient is :math:`p_{m} = 1 / (4 - \sqrt[m - 1]{4})`. The :math:`m`th order,
  :math:`n`-step Suzuki-Trotter approximation is then defined as:
  
  .. math:: e^{iHt} \approx \left [S_{m}(t / n)  \right ]^{n}.
  
  For more details see `J. Math. Phys. 32, 400 (1991) <https://pubs.aip.org/aip/jmp/article-abstract/32/2/400/229229>`_.
  
  Args:
      hamiltonian (Union[.Hamiltonian, .Sum]): The Hamiltonian written as a linear combination
          of operators with known matrix exponentials.
      time (float): The time of evolution, namely the parameter :math:`t` in :math:`e^{iHt}`
      n (int): An integer representing the number of Trotter steps to perform
      order (int): An integer (:math:`m`) representing the order of the approximation (must be 1 or even)
      check_hermitian (bool): A flag to enable the validation check to ensure this is a valid unitary operator
  
  Raises:
      TypeError: The ``hamiltonian`` is not of type :class:`~.Hamiltonian`, or :class:`~.Sum`.
      ValueError: The ``hamiltonian`` must have atleast two terms.
      ValueError: One or more of the terms in ``hamiltonian`` are not Hermitian.
      ValueError: The ``order`` is not one or a positive even integer.
  
  **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.TrotterProduct(H, time=2.4, order=2)
  
          # Measure some quantity
          return qml.state()
  
  >>> my_circ()
  array([-0.13259524+0.59790098j,  0.        +0.j        , -0.13259524-0.77932754j,  0.        +0.j        ])
  
  .. details::
      :title: Usage Details
  
      This operation is similar to the :class:`~.ApproxTimeEvolution`. One can recover the behaviour
      of :class:`~.ApproxTimeEvolution` by taking the adjoint:
  
      >>> qml.adjoint(qml.TrotterProduct(hamiltonian, time, order=1, n=n))
  
      We can also compute the gradient with respect to the coefficients of the Hamiltonian and the
      evolution time:
  
      .. code-block:: python3
  
          @qml.qnode(dev)
          def my_circ(c1, c2, time):
              # Prepare H:
              H = qml.dot([c1, c2], [qml.PauliX(0), qml.PauliZ(0)])
  
              # Prepare some state
              qml.Hadamard(0)
  
              # Evolve according to H
              qml.TrotterProduct(H, time, order=2)
  
              # Measure some quantity
              return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
  
      >>> args = np.array([1.23, 4.5, 0.1])
      >>> qml.grad(my_circ)(*tuple(args))
      (tensor(0.00961064, requires_grad=True), tensor(-0.12338274, requires_grad=True), tensor(-5.43401259, requires_grad=True))
docstr: Initialize the TrotterProduct class
docstr_tok: ["Initialize","the","TrotterProduct","class"]
code: def __init__(  # pylint: disable=too-many-arguments
      self,
      hamiltonian,
      time,
      n=1,
      order=1,
      check_hermitian=True,
      id=None,
  ):
      r"""Initialize the TrotterProduct class"""
  
      if order <= 0 or order != 1 and order % 2 != 0:
          raise ValueError(
              f"The order of a TrotterProduct must be 1 or a positive even integer, got {order}."
          )
  
      if isinstance(hamiltonian, qml.Hamiltonian):
          coeffs, ops = hamiltonian.terms()
          if len(coeffs) < 2:
              raise ValueError(
                  "There should be atleast 2 terms in the Hamiltonian. Otherwise use `qml.exp`"
              )
  
          hamiltonian = qml.dot(coeffs, ops)
  
      if not isinstance(hamiltonian, Sum):
          raise TypeError(
              f"The given operator must be a PennyLane ~.Hamiltonian or ~.Sum got {hamiltonian}"
          )
  
      if check_hermitian:
          for op in hamiltonian.operands:
              if not op.is_hermitian:
                  raise ValueError(
                      "One or more of the terms in the Hamiltonian may not be Hermitian"
                  )
  
      self._hyperparameters = {
          "n": n,
          "order": order,
          "base": hamiltonian,
          "check_hermitian": check_hermitian,
      }
      super().__init__(time, wires=hamiltonian.wires, id=id)
  
file_path: pennylane/pennylane/templates/subroutines/trotter.py
imports: import pennylane
  from pennylane.operation import Operation
  from pennylane.ops import Sum
label_desc: Use image node_id 1 to create a new TrotterProduct object from inherited base classes: Operation with example: obj = TrotterProduct(hamiltonian, time, n, order, check_hermitian, id)