class_docstr: AQFT(order, wires)
  Apply an approximate quantum Fourier transform (AQFT).
  
  The `AQFT <https://arxiv.org/abs/1803.04933>`_ method helps to reduce the number of ``ControlledPhaseShift`` operations required
  for QFT by only using a maximum of ``order`` number of ``ControlledPhaseShift`` gates per qubit.
  
  .. seealso:: :class:`~.QFT`
  
  Args:
      order (int): the order of approximation
      wires (int or Iterable[Number, str]]): the wire(s) the operation acts on
  
  **Example**
  
  The approximate quantum Fourier transform is applied by specifying the corresponding wires and
  the order of approximation:
  
  .. code-block::
  
      wires = 3
      dev = qml.device('default.qubit', wires=wires)
  
      @qml.qnode(dev)
      def circuit_aqft():
          qml.PauliX(0)
          qml.Hadamard(1)
          qml.AQFT(order=1,wires=range(wires))
          return qml.state()
  
  
  .. code-block:: pycon
  
      >>> circuit_aqft()
      [ 0.5 +0.j   -0.25-0.25j  0.  +0.j   -0.25+0.25j  0.5 +0.j   -0.25-0.25j   0.  +0.j   -0.25+0.25j]
  
  
  .. details::
      :title: Usage Details
  
      **Order**
  
      The order of approximation must be a whole number less than :math:`n-1`
      where :math:`n` is the number of wires the operation is being applied on.
      This creates four cases for different ``order`` values:
  
      * ``order`` :math:`< 0`
          This will raise a ``ValueError``
  
      * ``order`` :math:`= 0`
          This will warn the user that only a Hadamard transform is being applied.
  
          .. code-block::
  
              @qml.qnode(dev)
              def circ():
                  qml.AQFT(order=0, wires=range(6))
                  return qml.probs()
  
          The resulting circuit is:
  
          >>> print(qml.draw(circ, expansion_strategy='device')())
          UserWarning: order=0, applying Hadamard transform warnings.warn("order=0, applying Hadamard transform")
          0: ──H─╭SWAP─────────────┤ ╭Probs
          1: ──H─│─────╭SWAP───────┤ ├Probs
          2: ──H─│─────│─────╭SWAP─┤ ├Probs
          3: ──H─│─────│─────╰SWAP─┤ ├Probs
          4: ──H─│─────╰SWAP───────┤ ├Probs
          5: ──H─╰SWAP─────────────┤ ╰Probs
  
      * :math:`0 <` ``order`` :math:`< n-1`
          This is the intended AQFT use case.
  
          .. code-block::
  
              @qml.qnode(dev)
              def circ():
                  qml.AQFT(order=2, wires=range(4))
                  return qml.probs()
  
          The resulting circuit is:
  
          >>> print(qml.draw(circ, expansion_strategy='device')())
          0: ──H─╭Rϕ(1.57)─╭Rϕ(0.79)────────────────────────────────────────╭SWAP───────┤ ╭Probs
          1: ────╰●────────│──────────H─╭Rϕ(1.57)─╭Rϕ(0.79)─────────────────│─────╭SWAP─┤ ├Probs
          2: ──────────────╰●───────────╰●────────│──────────H─╭Rϕ(1.57)────│─────╰SWAP─┤ ├Probs
          3: ─────────────────────────────────────╰●───────────╰●─────────H─╰SWAP───────┤ ╰Probs
  
      * ``order`` :math:`\geq n-1`
          Using the QFT class is recommended in this case. The AQFT operation here is
          equivalent to QFT.
docstr: Representation of the operator as a product of other operators (static method).
  
  .. math:: O = O_1 O_2 \dots O_n.
  
  .. seealso:: :meth:`~.AQFT.decomposition`.
  
  Args:
      wires (Iterable, Wires): wires that the operator acts on
      order (int): order of approximation
  
  Returns:
      list[Operator]: decomposition of the operator
  
  **Example:**
  
  >>> qml.AQFT.compute_decomposition((0, 1, 2), 3, order=1)
  [Hadamard(wires=[0]), ControlledPhaseShift(1.5707963267948966, wires=[1, 0]), Hadamard(wires=[1]), ControlledPhaseShift(1.5707963267948966, wires=[2, 1]), Hadamard(wires=[2]), SWAP(wires=[0, 2])]
code: def compute_decomposition(
      wires, order
  ):  # pylint: disable=arguments-differ
      r"""Representation of the operator as a product of other operators (static method).
  
      .. math:: O = O_1 O_2 \dots O_n.
  
      .. seealso:: :meth:`~.AQFT.decomposition`.
  
      Args:
          wires (Iterable, Wires): wires that the operator acts on
          order (int): order of approximation
  
      Returns:
          list[Operator]: decomposition of the operator
  
      **Example:**
  
      >>> qml.AQFT.compute_decomposition((0, 1, 2), 3, order=1)
      [Hadamard(wires=[0]), ControlledPhaseShift(1.5707963267948966, wires=[1, 0]), Hadamard(wires=[1]), ControlledPhaseShift(1.5707963267948966, wires=[2, 1]), Hadamard(wires=[2]), SWAP(wires=[0, 2])]
  
      """
      n_wires = len(wires)
      shifts = [2 * np.pi * 2**-i for i in range(2, n_wires + 1)]
  
      decomp_ops = []
      for i, wire in enumerate(wires):
          decomp_ops.append(qml.Hadamard(wire))
          counter = 0
  
          for shift, control_wire in zip(
              shifts[: len(shifts) - i], wires[i + 1 :]
          ):
              if counter >= order:
                  break
  
              op = qml.ControlledPhaseShift(
                  shift, wires=[control_wire, wire]
              )
              decomp_ops.append(op)
              counter = counter + 1
  
      first_half_wires = wires[: n_wires // 2]
      last_half_wires = wires[-(n_wires // 2) :]
  
      for wire1, wire2 in zip(
          first_half_wires, reversed(last_half_wires)
      ):
          swap = qml.SWAP(wires=[wire1, wire2])
          decomp_ops.append(swap)
  
      return decomp_ops
  
file_path: pennylane/pennylane/templates/subroutines/aqft.py
imports: import warnings
  import numpy
  import pennylane
  from pennylane.operation import Operation
label_desc: Use image node_id 3 for calling the AQFT obj's underlying member method code with example usage: obj.compute_decomposition(wires, order) and returns: decomp_ops