§
    OŠtj  ã                   ó>  — d Z ddlmZ ddlmZmZmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZ ddlmZ ddlmZmZmZmZmZmZmZm Z  ddl!m"Z" g d¢Z# G d„ de¦  «        Z$e$Z% G d„ de¦  «        Z& G d„ de&¦  «        Z' G d„ de&¦  «        Z(dS )at  An implementation of qubits and gates acting on them.

Todo:

* Update docstrings.
* Update tests.
* Implement apply using decompose.
* Implement represent using decompose or something smarter. For this to
  work we first have to implement represent for SWAP.
* Decide if we want upper index to be inclusive in the constructor.
* Fix the printing of Rk gates in plotting.
é    )ÚExpr)ÚIÚIntegerÚpi©ÚSymbol)Úexp)ÚMatrix©Úsqrt)Úqapply)ÚQuantumErrorÚQExpr)Úeye)Úmatrix_tensor_product)ÚGateÚHadamardGateÚSwapGateÚOneQubitGateÚCGateÚ	PhaseGateÚTGateÚZGate)Úsign)ÚQFTÚIQFTÚRkGateÚRkc                   ó€   — e Zd ZdZdZdZd„ Zed„ ¦   «         Ze	d„ ¦   «         Z
e	d„ ¦   «         Ze	d„ ¦   «         Zdd
„ZdS )r   z This is the R_k gate of the QTF.r   ÚRc                 óp  — t          |¦  «        dk    rt          d|z  ¦  «        ‚|d         }|d         }|dk    rt          |¦  «        S |dk    rt          |¦  «        S |dk    rt	          |¦  «        S |                      |¦  «        }t          j        | g|¢R Ž }|                      |¦  «        |_	        |S )Né   z)Rk gates only take two arguments, got: %rr   é   é   )
Úlenr   r   r   r   Ú
_eval_argsr   Ú__new__Ú_eval_hilbert_spaceÚhilbert_space)ÚclsÚargsÚtargetÚkÚinsts        úW/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/sympy/physics/quantum/qft.pyr'   zRkGate.__new__1   sÃ   € Ýˆt‰9Œ9˜Š>ˆ>ÝØ;¸dÑBñô ð ð �a”ˆØ�ŒGˆØ�Š6ˆ6Ý˜‘=”=Ð Ø�!ŠVˆVÝ˜VÑ$Ô$Ð$Ø�!ŠVˆVÝ˜‘=”=Ð Ø�~Š~˜dÑ#Ô#ˆÝŒ|˜CÐ' $Ð'Ð'Ð'ˆØ ×4Ò4°TÑ:Ô:ˆÔØˆó    c                 ó*   — t          j        |¦  «        S ©N)r   r&   )r*   r+   s     r/   r&   zRkGate._eval_argsF   s   € õ Ô Ñ%Ô%Ð%r0   c                 ó   — | j         d         S ©Nr#   ©Úlabel©Úselfs    r/   r-   zRkGate.kL   ó   € àŒz˜!Œ}Ðr0   c                 ó    — | j         d d…         S r4   r5   r7   s    r/   ÚtargetszRkGate.targetsP   s   € àŒz˜"˜1˜"Œ~Ðr0   c                 óB   — d| j         ›dt          | j        ¦  «        ›d�S )Nú$Ú_)Úgate_name_latexÚstrr-   r7   s    r/   Úgate_name_plotzRkGate.gate_name_plotT   s$   € € à!Ô1Ð1Ð1µ3°t´v±;´;°;°;Ð?Ð?r0   Úsympyc                 ó$  — |dk    ryt          ddgdt          t          | j        ¦  «        t	          d¦  «        z  t
          z  t          z  t	          d¦  «        t          | j        ¦  «        z  z  ¦  «        gg¦  «        S t          d|z  ¦  «        ‚)NrB   r#   r   r"   z#Invalid format for the R_k gate: %r)	r
   r	   r   r-   r   r   r   ÚabsÚNotImplementedError)r8   Úformats     r/   Úget_target_matrixzRkGate.get_target_matrixX   s†   € Ø�WÒÐÝ˜A˜q˜6 A¥s­4°´©<¬<½À¹
¼
Ñ+BÅ2Ñ+EÅaÑ+GÍÐQRÉÌÕUXÐY]ÔY_ÑU`ÔU`ÑI`Ñ+aÑ'bÔ'bÐ#cÐdÑeÔeÐeÝ!Ø1°FÑ:ñ<ô <ð 	<r0   N)rB   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	gate_namer?   r'   Úclassmethodr&   Úpropertyr-   r;   rA   rG   © r0   r/   r   r   ,   s¶   € € € € € Ø*Ð*Ø€IØ€Oðð ð ð* ð&ð &ñ „[ð&ð
 ðð ñ „Xðð ðð ñ „Xðð ð@ð @ñ „Xð@ð<ð <ð <ð <ð <ð <r0   r   c                   óŒ   — e Zd ZdZed„ ¦   «         Zd„ Zd„ Zed„ ¦   «         Z	ed„ ¦   «         Z
ed„ ¦   «         Zed„ ¦   «         Zd	S )
ÚFourierz@Superclass of Quantum Fourier and Inverse Quantum Fourier Gates.c                 ó¶   — t          |¦  «        dk    rt          d|z  ¦  «        ‚|d         |d         k    rt          d¦  «        ‚t          j        |¦  «        S )Nr"   z*QFT/IQFT only takes two arguments, got: %rr   r#   z!Start must be smaller than finish)r%   r   r   r&   )r8   r+   s     r/   r&   zFourier._eval_argse   s_   € åˆt‰9Œ9˜Š>ˆ>ÝØ<¸tÑCñô ð ð �Œ7�d˜1”gÒÐÝÐBÑCÔCÐCÝŒ˜tÑ$Ô$Ð$r0   c                 ó   —  | j         di |¤ŽS )Nr2   )Ú_represent_ZGate)r8   Úoptionss     r/   Ú_represent_default_basisz Fourier._represent_default_basiso   s   € Ø$ˆtÔ$Ð5Ð5¨WÐ5Ð5Ð5r0   c                 óê  ‡‡— |                      dd¦  «        }|dk    rt          d¦  «        ‚|| j        k     rt          d|z  ¦  «        ‚| j        Š| j        Šˆˆfd„t          ‰¦  «        D ¦   «         }t          |¦  «        }| j        d         dk    r+t          t          d| j        d         z  ¦  «        |¦  «        }| j        |k     r(t          |t          d|| j        z
  z  ¦  «        ¦  «        }|S )z:
            Represents the (I)QFT In the Z Basis
        Únqubitsr   z.The number of qubits must be given as nqubits.z2The number of qubits %r is too small for the gate.c                 óL   •‡— g | ]Šˆˆˆfd „t          ‰¦  «        D ¦   «         ‘Œ S )c                 óF   •— g | ]}‰|‰z  ‰z  z  t          ‰¦  «        z  ‘ŒS rO   r   )Ú.0ÚiÚjÚomegaÚsizes     €€€r/   ú
<listcomp>z7Fourier._represent_ZGate.<locals>.<listcomp>.<listcomp>‚   sG   ø€ ð 9ð 9ð 9Ø'(ð Øˆa‰C�$‰JñÝ˜T™
œ
ñ#ð 9ð 9ð 9r0   )Úrange)r[   r]   r^   r_   s    @€€r/   r`   z,Fourier._represent_ZGate.<locals>.<listcomp>‚   sa   øø€ ð Oð Oð OØ=>ð9ð 9ð 9ð 9ð 9ð 9Ý,1°$©K¬Kð9ñ 9ô 9ð Oð Oð Or0   r"   )
Úgetr   Ú
min_qubitsr_   r^   ra   r
   r6   r   r   )r8   ÚbasisrU   rX   ÚarrayFTÚmatrixFTr^   r_   s         @@r/   rT   zFourier._represent_ZGater   s(  øø€ ð —+’+˜i¨Ñ+Ô+ˆØ�aŠ<ˆ<ÝØ@ñBô Bð Bà�T”_Ò$Ð$ÝØDÀwÑNñô ð ð ŒyˆØ”
ˆðOð Oð Oð Oð OÝBGÈÁ+Ä+ðOñ Oô Oˆå˜'‘?”?ˆð Œ:�aŒ=˜AÒÐÝ,­S°°D´J¸q´MÑ1AÑ-BÔ-BÀHÑMÔMˆHØŒ?˜WÒ$Ð$Ý,Ø�#˜a '¨D¬OÑ";Ñ<Ñ=Ô=ñ?ô ?ˆHð ˆr0   c                 óN   — t          | j        d         | j        d         ¦  «        S )Nr   r#   )ra   r6   r7   s    r/   r;   zFourier.targets�   s   € å�T”Z ”] D¤J¨q¤MÑ2Ô2Ð2r0   c                 ó   — | j         d         S r4   r5   r7   s    r/   rc   zFourier.min_qubits“   r9   r0   c                 ó>   — d| j         d         | j         d         z
  z  S )z"Size is the size of the QFT matrixr"   r#   r   r5   r7   s    r/   r_   zFourier.size—   s    € ð �4”:˜a”= 4¤:¨a¤=Ñ0Ñ1Ð1r0   c                 ó    — t          d¦  «        S )Nr^   r   r7   s    r/   r^   zFourier.omegaœ   s   € å�g‰ŒÐr0   N)rH   rI   rJ   rK   rM   r&   rV   rT   rN   r;   rc   r_   r^   rO   r0   r/   rQ   rQ   b   s½   € € € € € ØJÐJàð%ð %ñ „[ð%ð6ð 6ð 6ðð ð ð: ð3ð 3ñ „Xð3ð ðð ñ „Xðð ð2ð 2ñ „Xð2ð ðð ñ „Xðð ð r0   rQ   c                   óB   — e Zd ZdZd Zd Zd„ Zd„ Zd„ Ze	d„ ¦   «         Z
dS )r   z&The forward quantum Fourier transform.c           
      óˆ  — | j         d         }| j         d         }d}t          t          ||¦  «        ¦  «        D ]S}t          |¦  «        |z  }t          ||z
  ¦  «        D ],}t	          ||z
  dz
  t          ||dz   ¦  «        ¦  «        |z  }Œ-ŒTt          ||z
  dz  ¦  «        D ]}t          ||z   ||z
  dz
  ¦  «        |z  }Œ|S )z%Decomposes QFT into elementary gates.r   r#   r"   )r6   Úreversedra   r   r   r   r   )r8   ÚstartÚfinishÚcircuitÚlevelr\   s         r/   Ú	decomposezQFT.decompose§   sê   € à”
˜1”ˆØ”˜A”ˆØˆÝ�e E¨6Ñ2Ô2Ñ3Ô3ð 	Mð 	MˆEÝ" 5Ñ)Ô)¨'Ñ1ˆGÝ˜5 5™=Ñ)Ô)ð Mð M�Ý ¨¡	¨A¡­v°e¸QÀ¹UÑ/CÔ/CÑDÔDÀWÑL��ðMå˜ ™¨Ñ*Ñ+Ô+ð 	Bð 	BˆAÝ˜q 5™y¨&°1©*°q©.Ñ9Ô9¸'ÑAˆGˆGØˆr0   c                 óJ   — t          |                      ¦   «         |z  ¦  «        S r2   )r   rr   )r8   ÚqubitsrU   s      r/   Ú_apply_operator_QubitzQFT._apply_operator_Qubit´   s   € Ý�d—n’nÑ&Ô& vÑ-Ñ.Ô.Ð.r0   c                 ó   — t          | j        Ž S r2   )r   r+   r7   s    r/   Ú_eval_inversezQFT._eval_inverse·   s   € Ý�T”YÐÐr0   c                 óP   — t          dt          z  t          z  | j        z  ¦  «        S )Nr"   ©r	   r   r   r_   r7   s    r/   r^   z	QFT.omegaº   s   € å�1•R‘4�‘6˜$œ)Ñ#Ñ$Ô$Ð$r0   N)rH   rI   rJ   rK   rL   r?   rr   ru   rw   rN   r^   rO   r0   r/   r   r   ¡   sl   € € € € € Ø0Ð0à€IØ€Oðð ð ð/ð /ð /ð ð  ð  ð ð%ð %ñ „Xð%ð %ð %r0   r   c                   ó<   — e Zd ZdZd ZdZd„ Zd„ Zed„ ¦   «         Z	dS )r   z&The inverse quantum Fourier transform.z
{QFT^{-1}}c           
      óŠ  — | j         d         }| j         d         }d}t          ||z
  dz  ¦  «        D ]}t          ||z   ||z
  dz
  ¦  «        |z  }Œt          ||¦  «        D ]a}t          t          ||z
  ¦  «        ¦  «        D ]-}t	          ||z
  dz
  t          || dz
  ¦  «        ¦  «        |z  }Œ.t          |¦  «        |z  }Œb|S )z&Decomposes IQFT into elementary gates.r   r#   r"   )r+   ra   r   rm   r   r   r   )r8   rn   ro   rp   r\   rq   s         r/   rr   zIQFT.decomposeÅ   sæ   € à”	˜!”ˆØ”˜1”ˆØˆÝ˜ ™¨Ñ*Ñ+Ô+ð 	Bð 	BˆAÝ˜q 5™y¨&°1©*°q©.Ñ9Ô9¸'ÑAˆGˆGÝ˜5 &Ñ)Ô)ð 	2ð 	2ˆEÝ�e E¨E¡MÑ2Ô2Ñ3Ô3ð Nð N�Ý ¨¡	¨A¡­v°e¸a¸RÀ!¹VÑ/DÔ/DÑEÔEÀgÑM��Ý" 5Ñ)Ô)¨'Ñ1ˆGˆGØˆr0   c                 ó   — t          | j        Ž S r2   )r   r+   r7   s    r/   rw   zIQFT._eval_inverseÒ   s   € Ý�D”IˆÐr0   c                 óP   — t          dt          z  t          z  | j        z  ¦  «        S )Néþÿÿÿry   r7   s    r/   r^   z
IQFT.omegaÕ   s   € å�2•b‘5�‘7˜4œ9Ñ$Ñ%Ô%Ð%r0   N)
rH   rI   rJ   rK   rL   r?   rr   rw   rN   r^   rO   r0   r/   r   r   ¿   s]   € € € € € Ø0Ð0à€IØ"€Oðð ð ðð ð ð ð&ð &ñ „Xð&ð &ð &r0   r   N))rK   Úsympy.core.exprr   Úsympy.core.numbersr   r   r   Úsympy.core.symbolr   Ú&sympy.functions.elementary.exponentialr	   Úsympy.matrices.denser
   Úsympy.functionsr   Úsympy.physics.quantum.qapplyr   Úsympy.physics.quantum.qexprr   r   Úsympy.matricesr   Ú#sympy.physics.quantum.tensorproductr   Úsympy.physics.quantum.gater   r   r   r   r   r   r   r   Ú$sympy.functions.elementary.complexesr   Ú__all__r   r   rQ   r   r   rO   r0   r/   ú<module>rŒ      s  ððð ð !Ð  Ð  Ð  Ð  Ð  Ø /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ø $Ð $Ð $Ð $Ð $Ð $Ø 6Ð 6Ð 6Ð 6Ð 6Ð 6Ø 'Ð 'Ð 'Ð 'Ð 'Ð 'Ø  Ð  Ð  Ð  Ð  Ð  à /Ð /Ð /Ð /Ð /Ð /Ø ;Ð ;Ð ;Ð ;Ð ;Ð ;Ð ;Ð ;Ø Ð Ð Ð Ð Ð Ø EÐ EÐ EÐ EÐ EÐ Eðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð 6Ð 5Ð 5Ð 5Ð 5Ð 5ðð ð €ð0<ð 0<ð 0<ð 0<ð 0<ˆ\ñ 0<ô 0<ð 0<ðf €ð<ð <ð <ð <ð <ˆdñ <ô <ð <ð~%ð %ð %ð %ð %ˆ'ñ %ô %ð %ð<&ð &ð &ð &ð &ˆ7ñ &ô &ð &ð &ð &r0   