
    Ed                     2   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  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)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        9lib/python3.11/site-packages/sympy/physics/quantum/qft.pyr&   zRkGate.__new__/   s    t99> 	;dB   aG6 	!== !V 	!V$$$!V 	!== ~~d##|C'$''' 44T::    c                 *    t          j        |          S N)r   r%   )r)   r*   s     r.   r%   zRkGate._eval_argsD   s     %%%r/   c                     | j         d         S Nr"   labelselfs    r.   r,   zRkGate.kJ       z!}r/   c                      | j         d d         S r3   r4   r6   s    r.   targetszRkGate.targetsN   s    z"1"~r/   c                 B    d| j         dt          | j                  dS )N$_)gate_name_latexstrr,   r6   s    r.   gate_name_plotzRkGate.gate_name_plotR   s$     !1113tv;;;;??r/   sympyc           
          |dk    rWt          ddgdt          t          d          t          z  t          z  t          d          | j        z  z            gg          S t          d|z            )NrA   r"   r   r!   z#Invalid format for the R_k gate: %r)r
   r	   r   r   r   r,   NotImplementedError)r7   formats     r.   get_target_matrixzRkGate.get_target_matrixV   sn    W 	TAq6As71::b=?GAJJ<N+O'P'P#QRSSS!1F:< < 	<r/   N)rA   )__name__
__module____qualname____doc__	gate_namer>   r&   classmethodr%   propertyr,   r:   r@   rE    r/   r.   r   r   *   s        **IO  * & & [&
   X   X @ @ X@< < < < < <r/   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%   )r7   r*   s     r.   r%   zFourier._eval_argsc   se    t99> 	<tC   7d1g 	DBCCCt$$$r/   c                      | j         di |S )Nr1   )_represent_ZGate)r7   optionss     r.   _represent_default_basisz Fourier._represent_default_basism   s    $t$55W555r/   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 rM   r   ).0ijomegasizes     r.   
<listcomp>z7Fourier._represent_ZGate.<locals>.<listcomp>.<listcomp>   sG     9 9 9'( aC$JT

# 9 9 9r/   )range)rY   r[   r\   r]   s    @r.   r^   z,Fourier._represent_ZGate.<locals>.<listcomp>   sa     O O O=>9 9 9 9 9 9,1$KK9 9 9 O O Or/   r!   )
getr   
min_qubitsr]   r\   r_   r
   r5   r   r   )r7   basisrS   rV   arrayFTmatrixFTr\   r]   s         @@r.   rR   zFourier._represent_ZGatep   s3    ++i++a< 	B@B B BT_$ 	DwN   y
O O O O OBG++O O O'?? :a=A 	N,SDJqM1A-B-BHMMH?W$ 	?,#a'DO";<==? ?H r/   c                 N    t          | j        d         | j        d                   S )Nr   r"   )r_   r5   r6   s    r.   r:   zFourier.targets   s    TZ]DJqM222r/   c                     | j         d         S r3   r4   r6   s    r.   ra   zFourier.min_qubits   r8   r/   c                 >    d| j         d         | j         d         z
  z  S )z"Size is the size of the QFT matrixr!   r"   r   r4   r6   s    r.   r]   zFourier.size   s      4:a=4:a=011r/   c                      t          d          S )Nr\   r   r6   s    r.   r\   zFourier.omega   s    gr/   N)rF   rG   rH   rI   rK   r%   rT   rR   rL   r:   ra   r]   r\   rM   r/   r.   rO   rO   `   s        JJ% % [%6 6 6  : 3 3 X3   X 2 2 X2   X  r/   rO   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!   )r5   reversedr_   r   r   r   r   )r7   startfinishcircuitlevelrZ   s         r.   	decomposezQFT.decompose   s    
1AeE62233 	M 	ME"5))'1G55=)) M M	AveQU/C/CDDWLM*++ 	B 	BAq5y&1*q.99'AGGr/   c                 J    t          |                                 |z            S r1   )r   rp   )r7   qubitsrS   s      r.   _apply_operator_QubitzQFT._apply_operator_Qubit   s    dnn&&v-...r/   c                     t          | j         S r1   )r   r*   r6   s    r.   _eval_inversezQFT._eval_inverse   s    TYr/   c                 P    t          dt          z  t          z  | j        z            S )Nr!   r	   r   r   r]   r6   s    r.   r\   z	QFT.omega   s    1R46$)#$$$r/   N)rF   rG   rH   rI   rJ   r>   rp   rs   ru   rL   r\   rM   r/   r.   r   r      sl        00IO  / / /      % % X% % %r/   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*   r_   r   rk   r   r   r   )r7   rl   rm   rn   rZ   ro   s         r.   rp   zIQFT.decompose   s    	!1*++ 	B 	BAq5y&1*q.99'AGG5&)) 	2 	2EeEEM2233 N N	AveaR!V/D/DEEgM"5))'1GGr/   c                     t          | j         S r1   )r   r*   r6   s    r.   ru   zIQFT._eval_inverse   s    DIr/   c                 P    t          dt          z  t          z  | j        z            S )Nrw   r6   s    r.   r\   z
IQFT.omega   s    2b5749$%%%r/   N)
rF   rG   rH   rI   rJ   r>   rp   ru   rL   r\   rM   r/   r.   r   r      s]        00I"O     & & X& & &r/   r   N)'rI   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   __all__r   r   rO   r   r   rM   r/   r.   <module>r      s    !           / / / / / / / / / / $ $ $ $ $ $ 6 6 6 6 6 6 ' ' ' ' ' '             / / / / / / ; ; ; ; ; ; ; ;       E E E E E E                     0< 0< 0< 0< 0<\ 0< 0< 0<f < < < < <d < < <~% % % % %' % % %<& & & & &7 & & & & &r/   