§
    ¹³ÙgQ*  ã                  ó‚   — d Z ddlmZ ddlZddlmZmZmZ ddl	m
Z
 ddlmZ  G d„ d	e¦  «        Z G d
„ de¦  «        ZdS )zMDefine a Quantum Fourier Transform circuit (QFT) and a native gate (QFTGate).é    )ÚannotationsN)ÚQuantumRegisterÚCircuitInstructionÚGate)Údeprecate_funcé   )ÚBlueprintCircuitc                  ón  ‡ — e Zd ZdZ eddd¬¦  «        	 	 	 	 	 	 d%d&ˆ fd„¦   «         Zed'ˆ fd„¦   «         Zej        d(d„¦   «         Zed'd„¦   «         Z	e	j        d)d„¦   «         Z	ed*d„¦   «         Z
e
j        d+d„¦   «         Z
ed*d„¦   «         Zej        d,d„¦   «         Zd*d„Zd-d.d!„Zd/d0d#„Zd1ˆ fd$„Zˆ xZS )2ÚQFTa!	  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1.3)zxUse qiskit.circuit.library.QFTGate or qiskit.synthesis.qft.synth_qft_full instead, for access to all previous arguments.T)ÚsinceÚadditional_msgÚpendingNr   FÚ
num_qubitsú
int | NoneÚapproximation_degreeÚintÚdo_swapsÚboolÚinverseÚinsert_barriersÚnameú
str | NoneÚreturnÚNonec                ó¢   •— |€|rdnd}t          ¦   «                              |¬¦  «         || _        || _        || _        || _        || _        dS )aæ  Construct a new QFT circuit.

        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   ©r   )ÚsuperÚ__init__Ú_approximation_degreeÚ	_do_swapsÚ_insert_barriersÚ_inverser   )Úselfr   r   r   r   r   r   Ú	__class__s          €ú]/granary/edev/quantum/lib/python3.11/site-packages/qiskit/circuit/library/basis_change/qft.pyr   zQFT.__init__N   s\   ø€ ð6 ˆ<Ø$Ð/�6�6¨%ˆDå‰Œ×Ò˜dÐÑ#Ô#Ð#Ø%9ˆÔ"Ø!ˆŒØ /ˆÔØˆŒØ$ˆŒˆˆó    c                ó*   •— t          ¦   «         j        S )ztThe number of qubits in the QFT circuit.

        Returns:
            The number of qubits in the circuit.
        )r   r   )r$   r%   s    €r&   r   zQFT.num_qubitss   s   ø€ õ ‰wŒwÔ!Ð!r'   c                óœ   — || j         k    r<|                      ¦   «          g | _        |�!|dk    rt          |d¬¦  «        g| _        dS dS dS dS )z¡Set 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   zQFT.num_qubits~   sg   € ð ˜œÒ(Ð(Ø×ÒÑÔÐàˆDŒJØÐ%¨*°qª.¨.Ý-¨j¸sÐCÑCÔCÐD�”
�
�
ð )Ð(ð &Ð%¨.¨.r'   c                ó   — | j         S )zsThe approximation degree of the QFT.

        Returns:
            The currently set approximation degree.
        )r    ©r$   s    r&   r   zQFT.approximation_degreeŽ   s   € ð Ô)Ð)r'   c                ó€   — |dk     rt          d¦  «        ‚|| j        k    r|                      ¦   «          || _        dS dS )zØSet 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   zQFT.approximation_degree—   sT   € ð   !Ò#Ð#ÝÐMÑNÔNÐNà 4Ô#=Ò=Ð=Ø×ÒÑÔÐØ)=ˆDÔ&Ð&Ð&ð >Ð=r'   c                ó   — | j         S )z“Whether barriers are inserted for better visualization or not.

        Returns:
            True, if barriers are inserted, False if not.
        )r"   r.   s    r&   r   zQFT.insert_barriers¨   s   € ð Ô$Ð$r'   c                óV   — || j         k    r|                      ¦   «          || _         dS dS )z©Specify 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   zQFT.insert_barriers±   s:   € ð ˜dÔ3Ò3Ð3Ø×ÒÑÔÐØ$3ˆDÔ!Ð!Ð!ð 4Ð3r'   c                ó   — | j         S )z‘Whether 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   zQFT.do_swaps¼   s   € ð Œ~Ðr'   c                óV   — || j         k    r|                      ¦   «          || _         dS dS )z¢Specify 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   zQFT.do_swapsÅ   s6   € ð �t”~Ò%Ð%Ø×ÒÑÔÐØ%ˆDŒNˆNˆNð &Ð%r'   c                ó   — | j         S )z¤Whether the inverse Fourier transform is implemented.

        Returns:
            True, if the inverse Fourier transform is implemented, False otherwise.
        )r#   r.   s    r&   Ú
is_inversezQFT.is_inverseÐ   s   € ð Œ}Ðr'   Ú	annotatedú'QFT'c                ód  — | j         dv r| j        rdnd}n
| j         dz   }|                      |¬¦  «        }| j        d         j                             ¦   «         }||_         |j                             ¦   «          |                     t          ||j	        g ¦  «        ¦  «         | j         |_        |S )am  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$   r7   r   ÚinvertedÚiqfts        r&   r   zQFT.inverseØ   s®   € ð Œ9˜Ð'Ð'Ø œMÐ5�5�5¨vˆDˆDà”9˜uÑ$ˆDà—9’9 $�9Ñ'Ô'ˆð Œy˜Œ|Ô%×-Ò-Ñ/Ô/ˆØˆŒ	àŒ×ÒÑÔÐØ×ÒÕ+¨D°(´/À2ÑFÔFÑGÔGÐGà $¤Ð-ˆÔØˆr'   Úraise_on_failurec                ó>   — d}| j         €d}|rt          d¦  «        ‚|S )z,Check if the current configuration is valid.TNFz&The number of qubits has not been set.)r   ÚAttributeError)r$   rC   Úvalids      r&   Ú_check_configurationzQFT._check_configurationö   s1   € àˆØŒ?Ð"ØˆEØð OÝ$Ð%MÑNÔNÐNØˆr'   c                óp  •— | j         rdS t          ¦   «                              ¦   «          | j        }|dk    rdS ddlm}  ||| j        | j        | j        | j	        | j
        ¬¦  «        }| j        r|                     ¦   «         n|                     ¦   «         }|                      || j        d¬¦  «         dS )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.qftrJ   r!   r"   r    r#   r   r   Úto_instructionÚto_gateÚcomposer@   )r$   r   rJ   ÚcircuitÚwrappedr%   s        €r&   rM   z
QFT._buildÿ   sË   ø€ àŒ>ð 	ØˆFå‰Œ�ŠÑÔÐà”_ˆ
à˜Š?ˆ?ØˆFà7Ð7Ð7Ð7Ð7Ð7à �.ØØ”^Ø Ô1Ø!%Ô!;Ø”MØ”ð
ñ 
ô 
ˆð /3Ô.BÐY�'×(Ò(Ñ*Ô*Ð*ÈÏÊÑHYÔHYˆØ�Š�W T¤[¸$ˆÑ?Ô?Ð?Ð?Ð?r'   )Nr   TFFN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   )r   r   r   r   )r   r   r   r   )r   r   )r   r   r   r   )r   r   r   r   )F)r7   r   r   r8   )T)rC   r   r   r   )r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Úpropertyr   Úsetterr   r   r   r6   r   rG   rM   Ú__classcell__©r%   s   @r&   r   r      s  ø€ € € € € ð4ð 4ðl €^Øð
ð ðñ ô ð "&Ø$%ØØØ %Øð%ð %ð %ð %ð %ð %ñô ð%ð: ð"ð "ð "ð "ð "ñ „Xð"ð ÔðEð Eð Eñ ÔðEð ð*ð *ð *ñ „Xð*ð Ô ð>ð >ð >ñ !Ô ð>ð  ð%ð %ð %ñ „Xð%ð Ôð4ð 4ð 4ñ Ôð4ð ðð ð ñ „Xðð „_ð&ð &ð &ñ „_ð&ðð ð ð ðð ð ð ð ð<ð ð ð ð ð@ð @ð @ð @ð @ð @ð @ð @ð @ð @r'   r   c                  ó6   ‡ — e Zd ZdZdˆ fd„Zedfd„Zd„ Zˆ xZS )	ÚQFTGatezáQuantum 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

    r   r   c                óP   •— t          ¦   «                              d|g ¬¦  «         dS )z[
        Args:
            num_qubits: The number of qubits on which the QFT acts.
        Úqft)r   r   ÚparamsN)r   r   )r$   r   r%   s     €r&   r   zQFTGate.__init__%  s*   ø€ õ 	‰Œ×Ò˜e°
À2ÐÑFÔFÐFÐFÐFr'   Nc                óø   — |du rt          d¦  «        ‚| j        }t          j        d|z  ¦  «        }t          j        ||¦  «        }t          j        dt          j        z  |z  d|z  z  |¬¦  «        d|dz  z  z  S )z%Return a numpy array for the QFTGate.Fz9unable to avoid copy while creating an array as requestedr   y               @g      à?)Údtype)r0   r   ÚnpÚarangeÚouterÚexpÚpi)r$   rb   r;   ÚnÚnumsre   s         r&   Ú	__array__zQFTGate.__array__/  sz   € à�5ˆ=ˆ=ÝÐXÑYÔYÐYØŒOˆÝŒy˜˜A™‰ŒˆÝ”˜˜tÑ$Ô$ˆÝŒv�b�2œ5‘j 5Ñ(¨C°©FÑ3¸5ÐAÑAÔAÀSÈQÐQRÉUÁ^ÑTÐTr'   c                ó>   — ddl m}  || j        ¬¦  «        | _        dS )zGProvide a specific decomposition of the QFTGate into a quantum circuit.r   rI   )r   N)rN   rJ   r   Ú
definition)r$   rJ   s     r&   Ú_definezQFTGate._define8  s.   € à7Ð7Ð7Ð7Ð7Ð7à(˜.°D´OÐDÑDÔDˆŒˆˆr'   )r   r   )	rT   rU   rV   rW   r   Úcomplexrj   rm   rZ   r[   s   @r&   r]   r]     s‚   ø€ € € € € ðð ðGð Gð Gð Gð Gð Gð &¨Dð Uð Uð Uð UðEð Eð Eð Eð Eð Eð Er'   r]   )rW   Ú
__future__r   Únumpyrc   Úqiskit.circuit.quantumcircuitr   r   r   Úqiskit.utils.deprecationr   Úblueprintcircuitr	   r   r]   © r'   r&   ú<module>ru      sè   ðð TÐ Sà "Ð "Ð "Ð "Ð "Ð "Ø Ð Ð Ð à SÐ SÐ SÐ SÐ SÐ SÐ SÐ SÐ SÐ SØ 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø /Ð /Ð /Ð /Ð /Ð /ð@@ð @@ð @@ð @@ð @@Ð
ñ @@ô @@ð @@ðF"Eð "Eð "Eð "Eð "Eˆdñ "Eô "Eð "Eð "Eð "Er'   