class_docstr: Symbolic operator representing the product of operators.
  
  Args:
      *factors (tuple[~.operation.Operator]): a tuple of operators which will be multiplied
          together.
  
  Keyword Args:
      id (str or None): id for the product operator. Default is None.
  
  .. seealso:: :func:`~.ops.op_math.prod`
  
  **Example**
  
  >>> prop_op = Prod(qml.PauliX(wires=0), qml.PauliZ(wires=0))
  >>> prop_op
  PauliX(wires=[0]) @ PauliZ(wires=[0])
  >>> qml.matrix(prop_op)
  array([[ 0,  -1],
         [ 1,   0]])
  >>> prop_op.terms()
  ([1.0], [PauliX(wires=[0]) @ PauliZ(wires=[0])])
  
  .. note::
      When a Prod operator is applied in a circuit, its factors are applied in the reverse order.
      (i.e ``Prod(op1, op2)`` corresponds to :math:`\hat{op}_{1}\cdot\hat{op}_{2}` which indicates
      first applying :math:`\hat{op}_{2}` then :math:`\hat{op}_{1}` in the circuit). We can see this
      in the decomposition of the operator.
  
  >>> op = Prod(qml.PauliX(wires=0), qml.PauliZ(wires=1))
  >>> op.decomposition()
  [PauliZ(wires=[1]), PauliX(wires=[0])]
  
  .. details::
      :title: Usage Details
  
      The Prod operator represents both matrix composition and tensor products
      between operators.
  
      >>> prod_op = Prod(qml.RZ(1.23, wires=0), qml.PauliX(wires=0), qml.PauliZ(wires=1))
      >>> prod_op.matrix()
      array([[ 0.        +0.j        ,  0.        +0.j        ,
               0.81677345-0.57695852j,  0.        +0.j        ],
             [ 0.        +0.j        ,  0.        +0.j        ,
               0.        +0.j        , -0.81677345+0.57695852j],
             [ 0.81677345+0.57695852j,  0.        +0.j        ,
               0.        +0.j        ,  0.        +0.j        ],
             [ 0.        +0.j        , -0.81677345-0.57695852j,
               0.        +0.j        ,  0.        +0.j        ]])
  
      The Prod operation can be used inside a `qnode` as an operation which,
      if parameterized, can be differentiated.
  
      .. code-block:: python
  
          dev = qml.device("default.qubit", wires=3)
  
          @qml.qnode(dev)
          def circuit(theta):
              qml.prod(qml.PauliZ(0), qml.RX(theta, 1))
              return qml.expval(qml.PauliZ(1))
  
      >>> par = np.array(1.23, requires_grad=True)
      >>> circuit(par)
      tensor(0.33423773, requires_grad=True)
      >>> qml.grad(circuit)(par)
      tensor(-0.9424888, requires_grad=True)
  
      The Prod operation can also be measured as an observable.
      If the circuit is parameterized, then we can also differentiate through the
      product observable.
  
      .. code-block:: python
  
          prod_op = Prod(qml.PauliZ(wires=0), qml.Hadamard(wires=1))
          dev = qml.device("default.qubit", wires=2)
  
          @qml.qnode(dev)
          def circuit(weights):
              qml.RX(weights[0], wires=0)
              return qml.expval(prod_op)
  
      >>> weights = np.array([0.1], requires_grad=True)
      >>> qml.grad(circuit)(weights)
      array([-0.07059289])
class_docstr_tok: ["Symbolic","operator","representing","the","product","of","operators",".","Args",":","*","factors","(","tuple","[","~.operation.Operator","]",")",":","a","tuple","of","operators","which","will","be","multiplied","together",".","Keyword","Args",":","id","(","str","or","None",")",":","id","for","the","product","operator",".","Default","is","None",".","..","seealso",":",":",":","func",":","`","~.ops.op_math.prod","`","*","*","Example","*","*",">",">",">","prop_op","=","Prod","(","qml.PauliX","(","wires=0",")",",","qml.PauliZ","(","wires=0",")",")",">",">",">","prop_op","PauliX","(","wires=","[","0","]",")","@","PauliZ","(","wires=","[","0","]",")",">",">",">","qml.matrix","(","prop_op",")","array","(","[","[","0",",","-1","]",",","[","1",",","0","]","]",")",">",">",">","prop_op.terms","(",")","(","[","1.0","]",",","[","PauliX","(","wires=","[","0","]",")","@","PauliZ","(","wires=","[","0","]",")","]",")","..","note",":",":","When","a","Prod","operator","is","applied","in","a","circuit",",","its","factors","are","applied","in","the","reverse","order",".","(","i.e","``","Prod","(","op1",",","op2",")","``","corresponds","to",":","math",":","`","\\hat","{","op","}","_","{","1","}","\\cdot\\hat","{","op","}","_","{","2","}","`","which","indicates","first","applying",":","math",":","`","\\hat","{","op","}","_","{","2","}","`","then",":","math",":","`","\\hat","{","op","}","_","{","1","}","`","in","the","circuit",")",".","We","can","see","this","in","the","decomposition","of","the","operator",".",">",">",">","op","=","Prod","(","qml.PauliX","(","wires=0",")",",","qml.PauliZ","(","wires=1",")",")",">",">",">","op.decomposition","(",")","[","PauliZ","(","wires=","[","1","]",")",",","PauliX","(","wires=","[","0","]",")","]","..","details",":",":",":","title",":","Usage","Details","The","Prod","operator","represents","both","matrix","composition","and","tensor","products","between","operators",".",">",">",">","prod_op","=","Prod","(","qml.RZ","(","1.23",",","wires=0",")",",","qml.PauliX","(","wires=0",")",",","qml.PauliZ","(","wires=1",")",")",">",">",">","prod_op.matrix","(",")","array","(","[","[","0",".","+0.j",",","0",".","+0.j",",","0.81677345-0.57695852j",",","0",".","+0.j","]",",","[","0",".","+0.j",",","0",".","+0.j",",","0",".","+0.j",",","-0.81677345+0.57695852j","]",",","[","0.81677345+0.57695852j",",","0",".","+0.j",",","0",".","+0.j",",","0",".","+0.j","]",",","[","0",".","+0.j",",","-0.81677345-0.57695852j",",","0",".","+0.j",",","0",".","+0.j","]","]",")","The","Prod","operation","can","be","used","inside","a","`","qnode","`","as","an","operation","which",",","if","parameterized",",","can","be","differentiated",".","..","code-block",":",":","python","dev","=","qml.device","(","``","default.qubit","''",",","wires=3",")","@","qml.qnode","(","dev",")","def","circuit","(","theta",")",":","qml.prod","(","qml.PauliZ","(","0",")",",","qml.RX","(","theta",",","1",")",")","return","qml.expval","(","qml.PauliZ","(","1",")",")",">",">",">","par","=","np.array","(","1.23",",","requires_grad=True",")",">",">",">","circuit","(","par",")","tensor","(","0.33423773",",","requires_grad=True",")",">",">",">","qml.grad","(","circuit",")","(","par",")","tensor","(","-0.9424888",",","requires_grad=True",")","The","Prod","operation","can","also","be","measured","as","an","observable",".","If","the","circuit","is","parameterized",",","then","we","can","also","differentiate","through","the","product","observable",".","..","code-block",":",":","python","prod_op","=","Prod","(","qml.PauliZ","(","wires=0",")",",","qml.Hadamard","(","wires=1",")",")","dev","=","qml.device","(","``","default.qubit","''",",","wires=2",")","@","qml.qnode","(","dev",")","def","circuit","(","weights",")",":","qml.RX","(","weights","[","0","]",",","wires=0",")","return","qml.expval","(","prod_op",")",">",">",">","weights","=","np.array","(","[","0.1","]",",","requires_grad=True",")",">",">",">","qml.grad","(","circuit",")","(","weights",")","array","(","[","-0.07059289","]",")"]
code: def has_decomposition(self):
      return True
  
imports: import itertools
  from copy import copy
  from functools import reduce, wraps
  from itertools import combinations
  from typing import List, Tuple, Union
  from scipy.sparse import kron
  import pennylane
  from pennylane import math
  from pennylane.operation import Operator
  from pennylane.ops.op_math.pow import Pow
  from pennylane.ops.op_math.sprod import SProd
  from pennylane.ops.op_math.sum import Sum
  from pennylane.ops.qubit import Hamiltonian
  from pennylane.ops.qubit.non_parametric_ops import PauliX, PauliY, PauliZ
  from pennylane.queuing import QueuingManager
  from pennylane.typing import TensorLike
  from pennylane.wires import Wires
  from .composite import CompositeOp
label_desc: Use image node_id 4 for calling the Prod obj's underlying member method code with example usage: obj.has_decomposition() and returns: True