o
    jg                     @   s  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 deZ$e$Z%G dd deZ&G dd de&Z'G d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                   @   sZ   e Zd ZdZdZdZdd Zedd Ze	dd	 Z
e	d
d Ze	dd ZdddZdS )r   z This is the R_k gate of the QTF.r   Rc                 G   s   t |dkrtd| |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inst r,   Q/var/www/html/zoom/venv/lib/python3.10/site-packages/sympy/physics/quantum/qft.pyr$   1   s    
zRkGate.__new__c                 C   s
   t |S N)r   r#   )r'   r(   r,   r,   r-   r#   F   s   
zRkGate._eval_argsc                 C   
   | j d S Nr    labelselfr,   r,   r-   r*   L      
zRkGate.kc                 C   s   | j d d S r0   r1   r3   r,   r,   r-   targetsP   s   zRkGate.targetsc                 C   s   d| j t| jf S )Nz$%s_%s$)gate_name_latexstrr*   r3   r,   r,   r-   gate_name_plotT   s   zRkGate.gate_name_plotsympyc                 C   sT   |dkr$t ddgdtt| jtd t t tdt| j  ggS td| )Nr:   r    r   r   z#Invalid format for the R_k gate: %r)	r	   r   r   r*   r   r   r   absNotImplementedError)r4   formatr,   r,   r-   get_target_matrixX   s
   @zRkGate.get_target_matrixN)r:   )__name__
__module____qualname____doc__	gate_namer7   r$   classmethodr#   propertyr*   r6   r9   r>   r,   r,   r,   r-   r   ,   s    



r   c                   @   s\   e Zd ZdZedd Zdd Zdd Zedd	 Z	ed
d Z
edd Zedd ZdS )Fourierz@Superclass of Quantum Fourier and Inverse Quantum Fourier Gates.c                 C   s:   t |dkrtd| |d |d krtdt|S )Nr   z*QFT/IQFT only takes two arguments, got: %rr   r    z!Start must be smaller than finish)r"   r   r   r#   )r4   r(   r,   r,   r-   r#   e   s   
zFourier._eval_argsc                 K   s   | j di |S )Nr.   )_represent_ZGate)r4   optionsr,   r,   r-   _represent_default_basiso      z Fourier._represent_default_basisc                    s   | dd}|dkrtd|| jk rtd| | j| j  fddtD }t|}| jd dkrBtt	d| jd  |}| j|k rSt|t	d|| j  }|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                    s&   g | ]  fd dt D qS )c                    s$   g | ]}|    t  qS r,   r
   ).0i)jomegasizer,   r-   
<listcomp>   s    
z7Fourier._represent_ZGate.<locals>.<listcomp>.<listcomp>)range)rL   rO   rP   )rN   r-   rQ      s
    
z,Fourier._represent_ZGate.<locals>.<listcomp>r   )
getr   
min_qubitsrP   rO   rR   r	   r2   r   r   )r4   basisrH   rK   arrayFTmatrixFTr,   rS   r-   rG   r   s,   

zFourier._represent_ZGatec                 C   s   t | jd | jd S )Nr   r    )rR   r2   r3   r,   r,   r-   r6         zFourier.targetsc                 C   r/   r0   r1   r3   r,   r,   r-   rU      r5   zFourier.min_qubitsc                 C   s   d| j d | j d   S )z"Size is the size of the QFT matrixr   r    r   r1   r3   r,   r,   r-   rP      s   zFourier.sizec                 C   s   t dS )NrO   r   r3   r,   r,   r-   rO      s   zFourier.omegaN)r?   r@   rA   rB   rD   r#   rI   rG   rE   r6   rU   rP   rO   r,   r,   r,   r-   rF   b   s    
	


rF   c                   @   s<   e Zd ZdZd Zd Zdd Zdd Zdd Ze	dd	 Z
d
S )r   z&The forward quantum Fourier transform.c                 C   s   | j d }| j d }d}tt||D ]!}t|| }t|| D ]}t|| d t||d | }q!qt|| d D ]}t|| || d | }q=|S )z%Decomposes QFT into elementary gates.r   r    r   )r2   reversedrR   r   r   r   r   )r4   startfinishcircuitlevelrM   r,   r,   r-   	decompose   s   

"zQFT.decomposec                 K   s   t |  | S r.   )r   r_   )r4   qubitsrH   r,   r,   r-   _apply_operator_Qubit   rJ   zQFT._apply_operator_Qubitc                 C   
   t | j S r.   )r   r(   r3   r,   r,   r-   _eval_inverse      
zQFT._eval_inversec                 C      t dt t | j S )Nr   r   r   r   rP   r3   r,   r,   r-   rO      rY   z	QFT.omegaN)r?   r@   rA   rB   rC   r7   r_   ra   rc   rE   rO   r,   r,   r,   r-   r      s    r   c                   @   s4   e Zd ZdZd ZdZdd Zdd Zedd Z	d	S )
r   z&The inverse quantum Fourier transform.z
{QFT^{-1}}c                 C   s   | j d }| j d }d}t|| d D ]}t|| || d | }qt||D ]$}tt|| D ]}t|| d t|| d | }q3t|| }q)|S )z&Decomposes IQFT into elementary gates.r   r    r   )r(   rR   r   rZ   r   r   r   )r4   r[   r\   r]   rM   r^   r,   r,   r-   r_      s   

$zIQFT.decomposec                 C   rb   r.   )r   r(   r3   r,   r,   r-   rc      rd   zIQFT._eval_inversec                 C   re   )Nrf   r3   r,   r,   r-   rO      rY   z
IQFT.omegaN)
r?   r@   rA   rB   rC   r7   r_   rc   rE   rO   r,   r,   r,   r-   r      s    r   N))rB   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   rF   r   r   r,   r,   r,   r-   <module>   s&    (3?