ó
¡¼™\c           @  sd  d  Z  d d l m Z m Z d d l m Z m Z m Z m Z 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 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 d d g Z" d e f d „  ƒ  YZ# e# Z$ d e f d „  ƒ  YZ% d e% f d „  ƒ  YZ& d e% f d „  ƒ  YZ' d S(   st  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.
iÿÿÿÿ(   t   print_functiont   division(   t   Exprt   Matrixt   expt   It   pit   Integert   Symbol(   t   range(   t   sqrt(   t   qapply(   t   QuantumErrort   QExpr(   t   eye(   t   matrix_tensor_product(   t   Gatet   HadamardGatet   SwapGatet   OneQubitGatet   CGatet	   PhaseGatet   TGatet   ZGatet   QFTt   IQFTt   RkGatet   Rkc           B  sk   e  Z d  Z d Z d Z d „  Z e d „  ƒ Z e d „  ƒ Z	 e d „  ƒ Z
 e d „  ƒ Z d d	 „ Z RS(
   s    This is the R_k gate of the QTF.u   Rku   Rc         G  s²   t  | ƒ d k r% t d | ƒ ‚ n  | d } | d } | d k rO t | ƒ S| d k re t | ƒ S| d k r{ t | ƒ S|  j | ƒ } t j |  | Œ } |  j | ƒ | _	 | S(   Ni   s)   Rk gates only take two arguments, got: %ri    i   i   (
   t   lenR   R   R   R   t
   _eval_argsR   t   __new__t   _eval_hilbert_spacet   hilbert_space(   t   clst   argst   targett   kt   inst(    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR   .   s    




c         C  s   t  j | ƒ S(   N(   R   R   (   R!   R"   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR   C   s    c         C  s   |  j  d S(   Ni   (   t   label(   t   self(    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR$   I   s    c         C  s   |  j  d  S(   Ni   (   R&   (   R'   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyt   targetsM   s    c         C  s   d |  j  t |  j ƒ f S(   Ns   $%s_%s$(   t   gate_name_latext   strR$   (   R'   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyt   gate_name_plotQ   s    t   sympyc         C  sa   | d k rM t  d d g d t t d ƒ t t t d ƒ |  j ƒ g g ƒ St d | ƒ ‚ d  S(   NR,   i   i    i   s#   Invalid format for the R_k gate: %r(   R   R   R   R   R   R$   t   NotImplementedError(   R'   t   format(    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyt   get_target_matrixU   s    A(   t   __name__t
   __module__t   __doc__t	   gate_nameR)   R   t   classmethodR   t   propertyR$   R(   R+   R/   (    (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR   )   s   	t   Fourierc           B  sk   e  Z d  Z e d „  ƒ Z d „  Z d „  Z e d „  ƒ Z e d „  ƒ Z	 e d „  ƒ Z
 e d „  ƒ Z RS(   s@   Superclass of Quantum Fourier and Inverse Quantum Fourier Gates.c         C  sU   t  | ƒ d k r% t d | ƒ ‚ n  | d | d k rH t d ƒ ‚ n  t j | ƒ S(   Ni   s*   QFT/IQFT only takes two arguments, got: %ri    i   s!   Start must be smaller than finish(   R   R   R   R   (   R'   R"   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR   b   s    c         K  s   |  j  d  |  S(   N(   t   _represent_ZGatet   None(   R'   t   options(    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyt   _represent_default_basisl   s    c   
      K  s'  | j  d d ƒ } | d k r- t d ƒ ‚ n  | |  j k  rO t d | ƒ ‚ n  |  j } |  j } g  t | ƒ D]; } g  t | ƒ D]" } | | | | t | ƒ ^ q ^ qn } t | ƒ }	 |  j d d k rñ t	 t
 d |  j d ƒ |	 ƒ }	 n  |  j | k  r#t	 |	 t
 d | |  j ƒ ƒ }	 n  |	 S(   s:   
            Represents the (I)QFT In the Z Basis
        t   nqubitsi    s.   The number of qubits must be given as nqubits.s2   The number of qubits %r is too small for the gate.i   (   t   getR   t
   min_qubitst   sizet   omegaR	   R
   R   R&   R   R   (
   R'   t   basisR9   R;   R>   R?   t   jt   it   arrayFTt   matrixFT(    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR7   o   s$    		K# c         C  s   t  |  j d |  j d ƒ S(   Ni    i   (   R	   R&   (   R'   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR(   Œ   s    c         C  s   |  j  d S(   Ni   (   R&   (   R'   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR=      s    c         C  s   d |  j  d |  j  d S(   s"   Size is the size of the QFT matrixi   i   i    (   R&   (   R'   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR>   ”   s    c         C  s
   t  d ƒ S(   NR?   (   R   (   R'   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR?   ™   s    (   R0   R1   R2   R4   R   R:   R7   R5   R(   R=   R>   R?   (    (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR6   _   s   
		c           B  sD   e  Z d  Z d Z d Z d „  Z d „  Z d „  Z e d „  ƒ Z	 RS(   s&   The forward quantum Fourier transform.u   QFTc         C  sÕ   |  j  d } |  j  d } d } xp t t | | ƒ ƒ D]Y } t | ƒ | } x@ t | | ƒ D]. } t | | d t | | d ƒ ƒ | } q] Wq6 Wx; t | | d ƒ D]% } t | | | | d ƒ | } q¨ W| S(   s%   Decomposes QFT into elementary gates.i    i   i   (   R&   t   reversedR	   R   R   R   R   (   R'   t   startt   finisht   circuitt   levelRB   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyt	   decompose¤   s    0#c         K  s   t  |  j ƒ  | ƒ S(   N(   R   RJ   (   R'   t   qubitsR9   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyt   _apply_operator_Qubit±   s    c         C  s   t  |  j Œ  S(   N(   R   R"   (   R'   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyt   _eval_inverse´   s    c         C  s   t  d t t |  j ƒ S(   Ni   (   R   R   R   R>   (   R'   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR?   ·   s    (
   R0   R1   R2   R3   R)   RJ   RL   RM   R5   R?   (    (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR   ž   s   			c           B  s;   e  Z d  Z d Z d Z d „  Z d „  Z e d „  ƒ Z RS(   s&   The inverse quantum Fourier transform.u   IQFTu
   {QFT^{-1}}c         C  sÖ   |  j  d } |  j  d } d } x; t | | d ƒ D]% } t | | | | d ƒ | } q5 Wxq t | | ƒ D]` } xG t t | | ƒ ƒ D]/ } t | | d t | | d ƒ ƒ | } q‹ Wt | ƒ | } qn W| S(   s&   Decomposes IQFT into elementary gates.i    i   i   (   R"   R	   R   RE   R   R   R   (   R'   RF   RG   RH   RB   RI   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyRJ   Â   s    #-c         C  s   t  |  j Œ  S(   N(   R   R"   (   R'   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyRM   Ï   s    c         C  s   t  d t t |  j ƒ S(   Niþÿÿÿ(   R   R   R   R>   (   R'   (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR?   Ò   s    (	   R0   R1   R2   R3   R)   RJ   RM   R5   R?   (    (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyR   ¼   s   		N((   R2   t
   __future__R    R   R,   R   R   R   R   R   R   R   t   sympy.core.compatibilityR	   t   sympy.functionsR
   t   sympy.physics.quantum.qapplyR   t   sympy.physics.quantum.qexprR   R   t   sympy.matricesR   t#   sympy.physics.quantum.tensorproductR   t   sympy.physics.quantum.gateR   R   R   R   R   R   R   R   t   __all__R   R   R6   R   R   (    (    (    s8   lib/python2.7/site-packages/sympy/physics/quantum/qft.pyt   <module>   s$   4:	3?