class_docstr: Performs the Grover Diffusion Operator.
  
  .. math::
  
      G = 2 |s \rangle \langle s | - I
      = H^{\bigotimes n} \left( 2 |0\rangle \langle 0| - I \right) H^{\bigotimes n}
  
  where :math:`n` is the number of wires, and :math:`|s\rangle` is the uniform superposition:
  
  .. math::
  
      |s\rangle = H^{\bigotimes n} |0\rangle =  \frac{1}{\sqrt{2^n}} \sum_{i=0}^{2^n-1} | i \rangle.
  
  For this template, the operator is implemented with a layer of Hadamards, a layer of :math:`X`,
  followed by a multi-controlled :math:`Z` gate, then another layer of :math:`X` and Hadamards.
  This is expressed in a compact form by the circuit below:
  
  .. figure:: ../../_static/templates/subroutines/grover.svg
      :align: center
      :width: 60%
      :target: javascript:void(0);
  
  The open circles on the controlled gate indicate control on 0 instead of 1.
  The ``Z`` gates on the last wire result from leveraging the circuit identity :math:`HXH = Z`,
  where the last ``H`` gate converts the multi-controlled :math:`Z` gate into a
  multi-controlled :math:`X` gate.
  
  Args:
      wires (Union[Wires, Sequence[int], or int]): the wires to apply to
      work_wires (Union[Wires, Sequence[int], or int]): optional auxiliary wires to assist
          in the decomposition of :class:`~.MultiControlledX`.
  
  **Example**
  
  The Grover Diffusion Operator amplifies the magnitude of the basis state with
  a negative phase.  For example, if the solution to the search problem is the :math:`|111\rangle`
  state, we require an oracle that flips its phase; this could be implemented using a `CCZ` gate:
  
  .. code-block:: python
  
      n_wires = 3
      wires = list(range(n_wires))
  
      def oracle():
          qml.Hadamard(wires[-1])
          qml.Toffoli(wires=wires)
          qml.Hadamard(wires[-1])
  
  We can then implement the entire Grover Search Algorithm for ``num_iterations`` iterations by alternating calls to the oracle and the diffusion operator:
  
  .. code-block:: python
  
      dev = qml.device('default.qubit', wires=wires)
  
      @qml.qnode(dev)
      def GroverSearch(num_iterations=1):
          for wire in wires:
              qml.Hadamard(wire)
  
          for _ in range(num_iterations):
              oracle()
              qml.templates.GroverOperator(wires=wires)
          return qml.probs(wires)
  
  >>> GroverSearch(num_iterations=1)
  tensor([0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125, 0.03125,
          0.78125], requires_grad=True)
  >>> GroverSearch(num_iterations=2)
  tensor([0.0078125, 0.0078125, 0.0078125, 0.0078125, 0.0078125, 0.0078125,
      0.0078125, 0.9453125], requires_grad=True)
  
  We can see that the marked :math:`|111\rangle` state has the greatest probability amplitude.
  
  Optimally, the oracle-operator pairing should be repeated :math:`\lceil \frac{\pi}{4}\sqrt{2^{n}} \rceil` times.
class_docstr_tok: ["Performs","the","Grover","Diffusion","Operator",".","..","math",":",":","G","=","2","|s","\\rangle","\\langle","s","|","-","I","=","H^","{","\\bigotimes","n","}","\\left","(","2","|0\\rangle","\\langle","0|","-","I","\\right",")","H^","{","\\bigotimes","n","}","where",":","math",":","`","n","`","is","the","number","of","wires",",","and",":","math",":","`","|s\\rangle","`","is","the","uniform","superposition",":","..","math",":",":","|s\\rangle","=","H^","{","\\bigotimes","n","}","|0\\rangle","=","\\frac","{","1","}","{","\\sqrt","{","2^n","}","}","\\sum_","{","i=0","}","^","{","2^n-1","}","|","i","\\rangle",".","For","this","template",",","the","operator","is","implemented","with","a","layer","of","Hadamards",",","a","layer","of",":","math",":","`","X","`",",","followed","by","a","multi-controlled",":","math",":","`","Z","`","gate",",","then","another","layer","of",":","math",":","`","X","`","and","Hadamards",".","This","is","expressed","in","a","compact","form","by","the","circuit","below",":","..","figure",":",":","..","\/","..","\/_static\/templates\/subroutines\/grover.svg",":","align",":","center",":","width",":","60","%",":","target",":","javascript",":","void","(","0",")",";","The","open","circles","on","the","controlled","gate","indicate","control","on","0","instead","of","1",".","The","``","Z","``","gates","on","the","last","wire","result","from","leveraging","the","circuit","identity",":","math",":","`","HXH","=","Z","`",",","where","the","last","``","H","``","gate","converts","the","multi-controlled",":","math",":","`","Z","`","gate","into","a","multi-controlled",":","math",":","`","X","`","gate",".","Args",":","wires","(","Union","[","Wires",",","Sequence","[","int","]",",","or","int","]",")",":","the","wires","to","apply","to","work_wires","(","Union","[","Wires",",","Sequence","[","int","]",",","or","int","]",")",":","optional","auxiliary","wires","to","assist","in","the","decomposition","of",":","class",":","`","~.MultiControlledX","`",".","*","*","Example","*","*","The","Grover","Diffusion","Operator","amplifies","the","magnitude","of","the","basis","state","with","a","negative","phase",".","For","example",",","if","the","solution","to","the","search","problem","is","the",":","math",":","`","|111\\rangle","`","state",",","we","require","an","oracle","that","flips","its","phase",";","this","could","be","implemented","using","a","`","CCZ","`","gate",":","..","code-block",":",":","python","n_wires","=","3","wires","=","list","(","range","(","n_wires",")",")","def","oracle","(",")",":","qml.Hadamard","(","wires","[","-1","]",")","qml.Toffoli","(","wires=wires",")","qml.Hadamard","(","wires","[","-1","]",")","We","can","then","implement","the","entire","Grover","Search","Algorithm","for","``","num_iterations","``","iterations","by","alternating","calls","to","the","oracle","and","the","diffusion","operator",":","..","code-block",":",":","python","dev","=","qml.device","(","'default.qubit","'",",","wires=wires",")","@","qml.qnode","(","dev",")","def","GroverSearch","(","num_iterations=1",")",":","for","wire","in","wires",":","qml.Hadamard","(","wire",")","for","_","in","range","(","num_iterations",")",":","oracle","(",")","qml.templates.GroverOperator","(","wires=wires",")","return","qml.probs","(","wires",")",">",">",">","GroverSearch","(","num_iterations=1",")","tensor","(","[","0.03125",",","0.03125",",","0.03125",",","0.03125",",","0.03125",",","0.03125",",","0.03125",",","0.78125","]",",","requires_grad=True",")",">",">",">","GroverSearch","(","num_iterations=2",")","tensor","(","[","0.0078125",",","0.0078125",",","0.0078125",",","0.0078125",",","0.0078125",",","0.0078125",",","0.0078125",",","0.9453125","]",",","requires_grad=True",")","We","can","see","that","the","marked",":","math",":","`","|111\\rangle","`","state","has","the","greatest","probability","amplitude",".","Optimally",",","the","oracle-operator","pairing","should","be","repeated",":","math",":","`","\\lceil","\\frac","{","\\pi","}","{","4","}","\\sqrt","{","2^","{","n","}","}","\\rceil","`","times","."]
code: def _flatten(self):
      hyperparameters = (
          ("work_wires", self.hyperparameters["work_wires"]),
      )
      return tuple(), (self.wires, hyperparameters)
  
file_path: pennylane/pennylane/templates/subroutines/grover.py
imports: import numpy
  from pennylane.operation import AnyWires, Operation
  from pennylane.ops import Hadamard, PauliZ, MultiControlledX, GlobalPhase
  from pennylane.wires import Wires
label_desc: Use image node_id 2 for calling the GroverOperator obj's underlying member method code with example usage: obj._flatten() and returns: tuple,  self,  hyperparameters