
    sg                     $   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(y)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                   f    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y
)r   z This is the R_k gate of the QTF.r   Rc                 ,   t        |      dk7  rt        d|z        |d   }|d   }|dk(  rt        |      S |dk(  rt        |      S |dk(  rt	        |      S | j                  |      }t        j                  | g| }| j                  |      |_	        |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        L/var/www/html/venv/lib/python3.12/site-packages/sympy/physics/quantum/qft.pyr&   zRkGate.__new__1   s    t9>;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_argsF   s     %%r/   c                      | j                   d   S Nr"   labelselfs    r.   r,   zRkGate.kL       zz!}r/   c                      | j                   d d S r3   r4   r6   s    r.   targetszRkGate.targetsP   s    zz"1~r/   c                 N    d| j                   dt        | j                        dS )N$_)gate_name_latexstrr,   r6   s    r.   gate_name_plotzRkGate.gate_name_plotT   s    !113tvv;??r/   c                     |dk(  rit        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        )Nsympyr"   r   r!   z#Invalid format for the R_k gate: %r)	r
   r	   r   r,   r   r   r   absNotImplementedError)r7   formats     r.   get_target_matrixzRkGate.get_target_matrixX   st    WAq6As4<
+B2+Ea+GQRUXY]Y_Y_U`I`+a'b#cdee!1F:< 	<r/   N)rB   )__name__
__module____qualname____doc__	gate_namer>   r&   classmethodr%   propertyr,   r:   r@   rF    r/   r.   r   r   ,   sk    *IO* & &
     @ @<r/   r   c                   l    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y	)
Fourierz@Superclass of Quantum Fourier and Inverse Quantum Fourier Gates.c                     t        |      dk7  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_argse   sO    t9><tC  7d1gBCCt$$r/   c                 &     | j                   di |S )Nr1   )_represent_ZGate)r7   optionss     r.   _represent_default_basisz Fourier._represent_default_basiso   s    $t$$5W55r/   c                 B   |j                  dd      }|dk(  rt        d      || j                  k  rt        d|z        | j                  }| j                  }t        |      D cg c]0  }t        |      D cg c]  }|||z  |z  z  t        |      z   c}2 }}}t        |      }	| j                  d   dk7  r%t        t        d| j                  d   z        |	      }	| j                  |k  r%t        |	t        d|| j                  z
  z              }	|	S c c}w c c}}w )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.r!   )getr   
min_qubitssizeomegaranger   r
   r5   r   r   )
r7   basisrT   rW   rZ   r[   jiarrayFTmatrixFTs
             r.   rS   zFourier._represent_ZGater   s3    ++i+a<@B BT__$DwN  yy

 CH+O=>E$K9'( aC$JT
# 9 O O'? ::a=A,SDJJqM1A-BHMH??W$,#a'DOO";<=?H 9 Os   &D8DDDc                 N    t        | j                  d   | j                  d         S )Nr   r"   )r\   r5   r6   s    r.   r:   zFourier.targets   s    TZZ]DJJqM22r/   c                      | j                   d   S r3   r4   r6   s    r.   rY   zFourier.min_qubits   r8   r/   c                 F    d| j                   d   | j                   d   z
  z  S )z"Size is the size of the QFT matrixr!   r"   r   r4   r6   s    r.   rZ   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)rG   rH   rI   rJ   rL   r%   rU   rS   rM   r:   rY   rZ   r[   rN   r/   r.   rP   rP   b   sq    J% %6: 3 3   2 2  r/   rP   c                   :    e Zd ZdZd Zd Zd Zd Zd Ze	d        Z
y)r   z&The forward quantum Fourier transform.c           
      \   | j                   d   }| j                   d   }d}t        t        ||            D ]E  }t        |      |z  }t        ||z
        D ]$  }t	        ||z
  dz
  t        ||dz               |z  }& G t        ||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levelr_   s         r.   	decomposezQFT.decompose   s    

1AeE623 	ME"5)'1G55=) M	AveQU/CDWLM	M *+ 	BAq5y&1*q.9'AG	Br/   c                 :    t        | j                         |z        S r1   )r   rm   )r7   qubitsrT   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    TYYr/   c                 N    t        dt        z  t        z  | j                  z        S )Nr!   r	   r   r   rZ   r6   s    r.   r[   z	QFT.omega   s    1R46$))#$$r/   N)rG   rH   rI   rJ   rK   r>   rm   rp   rr   rM   r[   rN   r/   r.   r   r      s2    0IO/  % %r/   r   c                   4    e Zd ZdZd ZdZd Zd Zed        Z	y)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 ]O  }t        t        ||z
              D ]%  }t	        ||z
  dz
  t        || dz
              |z  }' t        |      |z  }Q |S )z&Decomposes IQFT into elementary gates.r   r"   r!   )r*   r\   r   rh   r   r   r   )r7   ri   rj   rk   r_   rl   s         r.   rm   zIQFT.decompose   s    		!1*+ 	BAq5y&1*q.9'AG	B5&) 	2EeEEM23 N	AveaR!V/DEgMN"5)'1G	2 r/   c                 &    t        | j                   S r1   )r   r*   r6   s    r.   rr   zIQFT._eval_inverse   s    DIIr/   c                 N    t        dt        z  t        z  | j                  z        S )Nrt   r6   s    r.   r[   z
IQFT.omega   s    2b57499$%%r/   N)
rG   rH   rI   rJ   rK   r>   rm   rr   rM   r[   rN   r/   r.   r   r      s-    0I"O & &r/   r   N))rJ   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   rP   r   r   rN   r/   r.   <module>r      s    ! / / $ 6 '   / ;  E   60<\ 0<f <d <~%' %<&7 &r/   