
    MZd                        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&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)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        ;/usr/lib/python3/dist-packages/sympy/physics/quantum/qft.pyr%   zRkGate.__new__/   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_argsD   s     %%r.   c                      | j                   d   S Nr!   labelselfs    r-   r+   zRkGate.kJ       zz!}r.   c                      | j                   d d S r2   r3   r5   s    r-   targetszRkGate.targetsN   s    zz"1~r.   c                 N    d| j                   dt        | j                        dS )N$_)gate_name_latexstrr+   r5   s    r-   gate_name_plotzRkGate.gate_name_plotR   s    !113tvv;??r.   c           
          |dk(  rJt        ddgdt        t        d      t        z  t        z  t        d      | 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+   NotImplementedError)r6   formats     r-   get_target_matrixzRkGate.get_target_matrixV   s[    WAq6As71:b=?GAJ<N+O'P#QRSS!1F:< 	<r.   N)rA   )__name__
__module____qualname____doc__	gate_namer=   r%   classmethodr$   propertyr+   r9   r?   rD    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$   )r6   r)   s     r-   r$   zFourier._eval_argsc   sO    t9><tC  7d1gBCCt$$r.   c                 &     | j                   di |S )Nr0   )_represent_ZGate)r6   optionss     r-   _represent_default_basisz Fourier._represent_default_basism   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
   r4   r   r   )
r6   basisrR   rU   rX   rY   jiarrayFTmatrixFTs
             r-   rQ   zFourier._represent_ZGatep   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!   )rZ   r4   r5   s    r-   r9   zFourier.targets   s    TZZ]DJJqM22r.   c                      | j                   d   S r2   r3   r5   s    r-   rW   zFourier.min_qubits   r7   r.   c                 F    d| j                   d   | j                   d   z
  z  S )z"Size is the size of the QFT matrixr    r!   r   r3   r5   s    r-   rX   zFourier.size   s$     4::a=4::a=011r.   c                     t        d      S )NrY   r   r5   s    r-   rY   zFourier.omega   s    gr.   N)rE   rF   rG   rH   rJ   r$   rS   rQ   rK   r9   rW   rX   rY   rL   r.   r-   rN   rN   `   sq    J% %6: 3 3   2 2  r.   rN   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    )r4   reversedrZ   r   r   r   r   )r6   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 r0   )r   rk   )r6   qubitsrR   s      r-   _apply_operator_QubitzQFT._apply_operator_Qubit   s    dnn&v-..r.   c                 &    t        | j                   S r0   )r   r)   r5   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   rX   r5   s    r-   rY   z	QFT.omega   s    1R46$))#$$r.   N)rE   rF   rG   rH   rI   r=   rk   rn   rp   rK   rY   rL   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)   rZ   r   rf   r   r   r   )r6   rg   rh   ri   r]   rj   s         r-   rk   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 r0   )r   r)   r5   s    r-   rp   zIQFT._eval_inverse   s    DIIr.   c                 N    t        dt        z  t        z  | j                  z        S )Nrr   r5   s    r-   rY   z
IQFT.omega   s    2b57499$%%r.   N)
rE   rF   rG   rH   rI   r=   rk   rp   rK   rY   rL   r.   r-   r   r      s-    0I"O & &r.   r   N)'rH   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   rN   r   r   rL   r.   r-   <module>r      s|    ! / / $ 6 '   / ;  E  0<\ 0<f <d <~%' %<&7 &r.   