
    z	iH*                    t    S r SSKJr  SSKrSSKJrJrJr  SSK	J
r
  SSKJr   " S S	\5      r " S
 S\5      rg)zMDefine a Quantum Fourier Transform circuit (QFT) and a native gate (QFTGate).    )annotationsN)QuantumRegisterCircuitInstructionGate)deprecate_func   )BlueprintCircuitc                    ^  \ rS rSrSr\" SSSS9      S             SU 4S jjj5       r\SU 4S jj5       r\R                  SS	 j5       r\SS
 j5       r
\
R                  SS j5       r
\SS j5       r\R                  SS j5       r\SS j5       r\R                  SS j5       rSS jrSSS jjrSS S jjrS!U 4S jjrSrU =r$ )"QFT   a  Quantum Fourier Transform Circuit.

The Quantum Fourier Transform (QFT) on :math:`n` qubits is the operation

.. math::

    |j\rangle \mapsto \frac{1}{2^{n/2}} \sum_{k=0}^{2^n - 1} e^{2\pi ijk / 2^n} |k\rangle

The circuit that implements this transformation can be implemented using Hadamard gates
on each qubit, a series of controlled-U1 (or Z, depending on the phase) gates and a
layer of Swap gates. The layer of Swap gates can in principle be dropped if the QFT appears
at the end of the circuit, since then the re-ordering can be done classically. They
can be turned off using the ``do_swaps`` attribute.

For 4 qubits, the circuit that implements this transformation is:

.. plot::
   :alt: Diagram illustrating the previously described circuit.

   from qiskit.circuit.library import QFT
   from qiskit.visualization.library import _generate_circuit_library_visualization
   circuit = QFT(4)
   _generate_circuit_library_visualization(circuit)

The inverse QFT can be obtained by calling the ``inverse`` method on this class.
The respective circuit diagram is:

.. plot::
   :alt: Diagram illustrating the previously described circuit.

   from qiskit.circuit.library import QFT
   from qiskit.visualization.library import _generate_circuit_library_visualization
   circuit = QFT(4).inverse()
   _generate_circuit_library_visualization(circuit)

One method to reduce circuit depth is to implement the QFT approximately by ignoring
controlled-phase rotations where the angle is beneath a threshold. This is discussed
in more detail in https://arxiv.org/abs/quant-ph/9601018 or
https://arxiv.org/abs/quant-ph/0403071.

Here, this can be adjusted using the ``approximation_degree`` attribute: the smallest
``approximation_degree`` rotation angles are dropped from the QFT. For instance, a QFT
on 5 qubits with approximation degree 2 yields (the barriers are dropped in this example):

.. plot::
   :alt: Diagram illustrating the previously described circuit.

   from qiskit.circuit.library import QFT
   from qiskit.visualization.library import _generate_circuit_library_visualization
   circuit = QFT(5, approximation_degree=2)
   _generate_circuit_library_visualization(circuit)

z2.1)zxUse qiskit.circuit.library.QFTGate or qiskit.synthesis.qft.synth_qft_full instead, for access to all previous arguments.zin Qiskit 3.0)sinceadditional_msgremoval_timelinec                x   > Uc  U(       a  SOSn[         TU ]  US9  X l        X0l        XPl        X@l        Xl        g)a  
Args:
    num_qubits: The number of qubits on which the QFT acts.
    approximation_degree: The degree of approximation (0 for no approximation).
    do_swaps: Whether to include the final swaps in the QFT.
    inverse: If True, the inverse Fourier transform is constructed.
    insert_barriers: If True, barriers are inserted as visualization improvement.
    name: The name of the circuit.
NIQFTr   name)super__init___approximation_degree	_do_swaps_insert_barriers_inverse
num_qubits)selfr   approximation_degreedo_swapsinverseinsert_barriersr   	__class__s          a/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/circuit/library/basis_change/qft.pyr   QFT.__init__N   s>    4 <$6%Dd#%9"! /$    c                   > [         TU ]  $ )z\The number of qubits in the QFT circuit.

Returns:
    The number of qubits in the circuit.
)r   r   )r   r    s    r!   r   QFT.num_qubitsr   s     w!!r#   c                    XR                   :w  a3  U R                  5         / U l        Ub  US:  a  [        USS9/U l        gggg)zSet the number of qubits.

Note that this changes the registers of the circuit.

Args:
    num_qubits: The new number of qubits.
Nr   qr   )r   _invalidateqregsr   )r   r   s     r!   r   r%   }   sK     (DJ%*q.-jsCD
 +9%	 )r#   c                    U R                   $ )z[The approximation degree of the QFT.

Returns:
    The currently set approximation degree.
)r   r   s    r!   r   QFT.approximation_degree   s     )))r#   c                r    US:  a  [        S5      eXR                  :w  a  U R                  5         Xl        gg)zSet the approximation degree of the QFT.

Args:
    approximation_degree: The new approximation degree.

Raises:
    ValueError: If the approximation degree is smaller than 0.
r   z.Approximation degree cannot be smaller than 0.N)
ValueErrorr   r(   )r   r   s     r!   r   r,      s;      !#MNN#=#==)=& >r#   c                    U R                   $ )z{Whether barriers are inserted for better visualization or not.

Returns:
    True, if barriers are inserted, False if not.
)r   r+   s    r!   r   QFT.insert_barriers   s     $$$r#   c                P    XR                   :w  a  U R                  5         Xl         gg)zSpecify whether barriers are inserted for better visualization or not.

Args:
    insert_barriers: If True, barriers are inserted, if False not.
N)r   r(   )r   r   s     r!   r   r0      s'     333$3! 4r#   c                    U R                   $ )zyWhether the final swaps of the QFT are applied or not.

Returns:
    True, if the final swaps are applied, False if not.
)r   r+   s    r!   r   QFT.do_swaps   s     ~~r#   c                P    XR                   :w  a  U R                  5         Xl         gg)zSpecify whether to do the final swaps of the QFT circuit or not.

Args:
    do_swaps: If True, the final swaps are applied, if False not.
N)r   r(   )r   r   s     r!   r   r3      s$     ~~%%N &r#   c                    U R                   $ )zWhether the inverse Fourier transform is implemented.

Returns:
    True, if the inverse Fourier transform is implemented, False otherwise.
)r   r+   s    r!   
is_inverseQFT.is_inverse   s     }}r#   c                   U R                   S;   a  U R                  (       a  SOSnOU R                   S-   nU R                  US9nU R                  S   R                  R                  5       nX$l         UR                  R                  5         UR                  [        XCR                  / 5      5        U R                  (       + Ul        U$ )a-  Invert this circuit.

Args:
    annotated: indicates whether the inverse gate can be implemented
        as an annotated gate. The value of this argument is ignored as the
        inverse of a QFT is an IQFT which is just another instance of
        :class:`.QFT`.

Returns:
    The inverted circuit.
)r   r   r   r   _dgr   r   )
r   r   copydata	operationr   clear_appendr   qubits)r   	annotatedr   invertediqfts        r!   r   QFT.inverse   s     99' MM5vD99u$D99$9' yy|%%--/	+D//2FG $-r#   c                L    SnU R                   c  SnU(       a  [        S5      eU$ )z,Check if the current configuration is valid.TFz&The number of qubits has not been set.)r   AttributeError)r   raise_on_failurevalids      r!   _check_configurationQFT._check_configuration   s*    ??"E$%MNNr#   c           	       > U R                   (       a  g[        TU ]	  5         U R                  nUS:X  a  gSSKJn  U" UU R                  U R                  U R                  U R                  U R                  S9nU R                  (       a  UR                  5       OUR                  5       nU R                  X@R                  SS9  g)z(If not already built, build the circuit.Nr   synth_qft_full)r   r   r   r   r   T)r?   inplace)	_is_builtr   _buildr   qiskit.synthesis.qftrL   r   r   r   r   r   r   to_instructionto_gatecomposer?   )r   r   rL   circuitwrappedr    s        r!   rO   
QFT._build   s    >>__
?7 ^^ 11!%!;!;MM
 /3.B.B'((*HYW[[$?r#   )r   r   r   r   r   r)   )Nr   TFFN)r   z
int | Noner   intr   boolr   rX   r   rX   r   z
str | NonereturnNone)rY   rW   )r   rW   rY   rZ   )r   rW   rY   rZ   )rY   rX   )r   rX   rY   rZ   )r   rX   rY   rZ   )F)r@   rX   rY   z'QFT')T)rF   rX   rY   rX   )rY   rZ   )__name__
__module____qualname____firstlineno____doc__r   r   propertyr   setterr   r   r   r6   r   rH   rO   __static_attributes____classcell__r    s   @r!   r   r      sZ   4l 
 ) "&$% %%% "% 	%
 % % % 
%%8 " " E E * *   > !>  % % 4 4   __& &<@ @r#   r   c                  H   ^  \ rS rSrSr  SU 4S jjr\S4S jrS rSr	U =r
$ )	QFTGatei  zQuantum Fourier Transform Gate.

The Quantum Fourier Transform (QFT) on :math:`n` qubits is the operation

.. math::

    |j\rangle \mapsto \frac{1}{2^{n/2}} \sum_{k=0}^{2^n - 1} e^{2\pi ijk / 2^n} |k\rangle

c                $   > [         TU ]  SU/ S9  g)zC
Args:
    num_qubits: The number of qubits on which the QFT acts.
qft)r   r   paramsN)r   r   )r   r   r    s     r!   r   QFTGate.__init__$  s     	e
2Fr#   Nc                   USL a  [        S5      eU R                  n[        R                  " SU-  5      n[        R                  " XD5      n[        R
                  " S[        R                  -  U-  SU-  -  US9SUS-  -  -  $ )z%Return a numpy array for the QFTGate.Fz9unable to avoid copy while creating an array as requestedr   y               @g      ?)dtype)r.   r   nparangeouterexppi)r   rl   r:   nnumsro   s         r!   	__array__QFTGate.__array__.  sr    5=XYYOOyyA$vvb255j5(CF35ASQQRU^TTr#   c                :    SSK Jn  U" U R                  S9U l        g)zGProvide a specific decomposition of the QFTGate into a quantum circuit.r   rK   )r   N)rP   rL   r   
definition)r   rL   s     r!   _defineQFTGate._define7  s    7(DOODr#   )rw   )r   rW   )r[   r\   r]   r^   r_   r   complexrt   rx   rb   rc   rd   s   @r!   rf   rf     s0    GG &D UE Er#   rf   )r_   
__future__r   numpyrm   qiskit.circuit.quantumcircuitr   r   r   qiskit.utils.deprecationr   blueprintcircuitr	   r   rf    r#   r!   <module>r      s=    T "  S S 3 /@
 @D"Ed "Er#   