ó
¡¼™\c           @  s´  d  Z  d d l 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 m Z m Z d d l m Z d d l m Z d	 d
 d d d d d g Z e	 d ƒ Z e	 d d i d g d 6d e f ƒZ e sè e r
d	 e f d „  ƒ  YZ d „  Z n@ e j Z e j j Z e j j Z d	 e f d „  ƒ  YZ d „  Z i  d „ Z d d „ Z  d e f d „  ƒ  YZ! d e f d „  ƒ  YZ" d e f d „  ƒ  YZ# d! d  „ Z% d! S("   sÉ  Matplotlib based plotting of quantum circuits.

Todo:

* Optimize printing of large circuits.
* Get this to work with single gates.
* Do a better job checking the form of circuits to make sure it is a Mul of
  Gates.
* Get multi-target gates plotting.
* Get initial and final states to plot.
* Get measurements to plot. Might need to rethink measurement as a gate
  issue.
* Get scale and figsize to be handled in a better way.
* Write some tests/examples!
iÿÿÿÿ(   t   print_functiont   division(   t   Mul(   t   range(   t   import_module(   t   Gatet   OneQubitGatet   CGatet   CGateS(   t	   BasicMeta(   t   ManagedPropertiest   CircuitPlott   circuit_plott   labellert   Mzt   Mxt   CreateOneQubitGatet   CreateCGatet   numpyt
   matplotlibt   __import__kwargst   pyplott   fromlistt   catchc           B  s   e  Z d  „  Z RS(   c          O  s   t  d ƒ ‚ d  S(   Ns"   numpy or matplotlib not available.(   t   ImportError(   t   argst   kwargs(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyt   __init__,   s    (   t   __name__t
   __module__R   (    (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR   +   s   c          O  s   t  d ƒ ‚ d  S(   Ns"   numpy or matplotlib not available.(   R   (   R   R   (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR   /   s    c           B  sÔ   e  Z d  Z d Z d Z d Z d Z d Z d Z g  Z	 i  Z
 d Z d „  Z d „  Z d „  Z d	 „  Z d
 „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   s$   A class for managing a circuit plot.g      ð?g      4@gš™™™™™©?g333333Ã?g      à?c         K  sj   | |  _  t |  j  j ƒ |  _ | |  _ |  j | ƒ |  j ƒ  |  j ƒ  |  j ƒ  |  j	 ƒ  |  j
 ƒ  d  S(   N(   t   circuitt   lenR   t   ngatest   nqubitst   updatet   _create_gridt   _create_figuret   _plot_wirest   _plot_gatest   _finish(   t   selft   cR!   R   (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR   F   s    		



c         C  s   |  j  j | ƒ d S(   s'   Load the kwargs into the instance dict.N(   t   __dict__R"   (   R(   R   (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR"   Q   s    c         C  sc   |  j  } t j d |  j | | d t ƒ} t j d |  j | | d t ƒ} | |  _ | |  _ d S(   s   Create the grid of wires.g        t   dtypeN(   t   scalet   npt   arangeR!   t   floatR    t
   _wire_gridt
   _gate_grid(   R(   R,   t	   wire_gridt	   gate_grid(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR#   U   s
    	""	c         C  sÖ   t  j d |  j |  j |  j |  j f d d d d ƒ |  _ |  j j d d d d t ƒ} | j ƒ  d |  j } | j	 |  j
 d | |  j
 d	 | ƒ | j |  j d | |  j d	 | ƒ | j d
 ƒ | |  _ d S(   s"   Create the main matplotlib figure.t   figsizet	   facecolort   wt	   edgecolori   t   frameong      à?i    iÿÿÿÿt   equalN(   R   t   figureR    R,   R!   t   _figuret   add_subplott   Truet   set_axis_offt   set_xlimR1   t   set_ylimR0   t
   set_aspectt   _axes(   R(   t   axt   offset(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR$   ]   s    	 		
&&c         C  s/  |  j  d } |  j  d } | |  j | |  j f } xê t |  j ƒ D]Ù } |  j | |  j | f } t | | d d d |  j ƒ} |  j j | ƒ |  j	 rD d } |  j
 j |  j	 | ƒ rÃ d } n  |  j j | d |  j | | d t |  j	 | |  j
 ƒ d |  j d d d d	 d
 d	 ƒqD qD W|  j ƒ  d S(   s&   Plot the wires of the circuit diagram.i    iÿÿÿÿt   colort   kt   lwg      Ð?t   sizet   hat   centert   vaN(   R1   R,   R   R!   R0   t   Line2Dt	   linewidthRB   t   add_linet   labelst   initst   gett   textt   label_buffert   render_labelt   fontsizet   _plot_measured_wires(   R(   t   xstartt   xstopt   xdatat   it   ydatat   linet   init_label_buffer(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR%   o   s(    		 			c      	   C  sœ  |  j  ƒ  } |  j d } d } x| | D]t } |  j | | | |  j f } |  j | | |  j | | f } t | | d d d |  j ƒ} |  j j | ƒ q& Wx÷ t |  j	 ƒ  ƒ D]ã \ } }	 t
 |	 t ƒ sÛ t
 |	 t ƒ r± |	 j |	 j }
 x¦ |
 D]› } | | k rò |  j | |  j | | k rò t |
 ƒ t |
 ƒ f } |  j | | |  j | | f } t | | d d d |  j ƒ} |  j j | ƒ qò qò Wq± q± Wd  S(   Niÿÿÿÿg{®Gáz¤?RE   RF   RG   (   t   _measurementsR1   R,   R0   RL   RM   RB   RN   t	   enumeratet   _gatest
   isinstanceR   R   t   controlst   targetst   mint   max(   R(   t
   ismeasuredRX   t   dyt   imRY   R[   R\   RZ   t   gt   wirest   wire(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyRV   †   s0    "	"	c         C  s€   g  } t  |  j t ƒ rW xa t |  j j ƒ D]% } t  | t ƒ r+ | j | ƒ q+ q+ Wn% t  |  j t ƒ r| | j |  j ƒ n  | S(   s/   Create a list of all gates in the circuit plot.(   Ra   R   R   t   reversedR   R   t   append(   R(   t   gatesRi   (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR`   £   s    c         C  s7   x0 t  |  j ƒ  ƒ D] \ } } | j |  | ƒ q Wd S(   s0   Iterate through the gates and plot each of them.N(   R_   R`   t	   plot_gate(   R(   RZ   t   gate(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR&   ®   s    c         C  sŒ   i  } x t  |  j ƒ  ƒ D]k \ } } t | d t ƒ r xJ | j D]< } | | k rs | | | k r} | | | <q} qA | | | <qA Wq q W| S(   s“   Return a dict {i:j} where i is the index of the wire that has
            been measured, and j is the gate where the wire is measured.
            t   measurement(   R_   R`   t   getattrt   FalseRc   (   R(   Rf   RZ   Ri   t   target(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR^   ³   s    c         C  s+   x$ |  j  j ƒ  D] } | j t ƒ q Wd  S(   N(   R;   t   findobjt   set_clip_onRs   (   R(   t   o(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR'   Â   s    c         C  ss   |  j  | } |  j | } |  j j | | | d d d d d d d t d d d d	 d
 t d |  j ƒ d |  j ƒd S(   s#   Draw a box for a single qubit gate.RE   RF   RI   RJ   RK   t   bboxt   ect   fcR6   t   fillRG   RH   N(   R1   R0   RB   RR   t   dictR=   RM   RU   (   R(   t   tt   gate_idxt   wire_idxt   xt   y(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyt   one_qubit_boxÇ   s    	$c         C  s“   |  j  | } |  j | d } t |  j  ƒ t |  j ƒ |  j j | | | d d d d d d d t d d d	 d
 d t d |  j ƒ d |  j ƒ} d S(   s?   Draw a box for a two qubit gate. Doesn't work yet.
            g      à?RE   RF   RI   RJ   RK   Rx   Ry   Rz   R6   R{   RG   RH   N(	   R1   R0   t   printRB   RR   R|   R=   RM   RU   (   R(   R}   R~   R   R€   R   t   obj(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyt   two_qubit_boxÔ   s    	$c         C  sf   |  j  | |  j  | f } |  j | |  j | f } t | | d d d |  j ƒ} |  j j | ƒ d S(   s   Draw a vertical control line.RE   RF   RG   N(   R1   R0   RL   RM   RB   RN   (   R(   R~   t   min_wiret   max_wireRY   R[   R\   (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyt   control_lineä   s    	c         C  sn   |  j  | } |  j | } |  j } t | | f | |  j d d d d d t d |  j ƒ} |  j j | ƒ d S(   s   Draw a control point.Ry   RF   Rz   R{   RG   N(	   R1   R0   t   control_radiust   CircleR,   R=   RM   RB   t	   add_patch(   R(   R~   R   R€   R   t   radiusR)   (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyt   control_pointï   s    		c         C  s©   |  j  | } |  j | } |  j } t | | f | d d d d d t d |  j ƒ} |  j j | ƒ t | | f | | | | f d d d |  j ƒ} |  j j	 | ƒ d S(	   s7   Draw a NOT gates as the circle with plus in the middle.Ry   RF   Rz   R6   R{   RG   RE   N(
   R1   R0   t
   not_radiusRŠ   Rs   RM   RB   R‹   RL   RN   (   R(   R~   R   R€   R   RŒ   R)   t   l(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyt	   not_pointþ   s     		c         C  s»   |  j  | } |  j | } |  j } t | | | | f | | | | f d d d |  j ƒ} t | | | | f | | | | f d d d |  j ƒ} |  j j | ƒ |  j j | ƒ d S(   s   Draw a swap point as a cross.RE   RF   RG   N(   R1   R0   t
   swap_deltaRL   RM   RB   RN   (   R(   R~   R   R€   R   t   dt   l1t   l2(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyt
   swap_point  s    	(   R   R   t   __doc__R,   RU   RM   R‰   RŽ   R‘   RO   RP   RS   R   R"   R#   R$   R%   RV   R`   R&   R^   R'   R‚   R…   Rˆ   R   R   R•   (    (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR   9   s4   															c         K  s   t  |  | |  S(   sd  Draw the circuit diagram for the circuit with nqubits.

        Parameters
        ==========

        c : circuit
            The circuit to plot. Should be a product of Gate instances.
        nqubits : int
            The number of qubits to include in the circuit. Must be at least
            as big as the largest `min_qubits`` of the gates.
        (   R   (   R)   R!   R   (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR   '  s    c         C  s+   | j  |  ƒ } | r# d |  | f Sd |  S(   s  Slightly more flexible way to render labels.

    >>> from sympy.physics.quantum.circuitplot import render_label
    >>> render_label('q0')
    '$\\left|q0\\right\\rangle$'
    >>> render_label('q0', {'q0':'0'})
    '$\\left|q0\\right\\rangle=\\left|0\\right\\rangle$'
    s-   $\left|%s\right\rangle=\left|%s\right\rangle$s   $\left|%s\right\rangle$(   RQ   (   t   labelRP   t   init(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyRT   5  s    	t   qc         C  s/   g  t  |  ƒ D] } d | |  | d f ^ q S(   s‚  Autogenerate labels for wires of quantum circuits.

    Parameters
    ==========
    n : int
      number of qubits in the circuit
    symbol : string
      A character string to precede all gate labels. E.g. 'q_0', 'q_1', etc.

    >>> from sympy.physics.quantum.circuitplot import labeller
    >>> labeller(2)
    ['q_1', 'q_0']
    >>> labeller(3,'j')
    ['j_2', 'j_1', 'j_0']
    s   %s_%di   (   R   (   t   nt   symbolRZ   (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR   C  s    c           B  s    e  Z d  Z e Z d Z d Z RS(   sŠ   Mock-up of a z measurement gate.

    This is in circuitplot rather than gate.py because it's not a real
    gate, it just draws one.
    R   u   M_z(   R   R   R–   R=   Rq   t	   gate_namet   gate_name_latex(    (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR   U  s   c           B  s    e  Z d  Z e Z d Z d Z RS(   s‹   Mock-up of an x measurement gate.

    This is in circuitplot rather than gate.py because it's not a real
    gate, it just draws one.
    R   u   M_x(   R   R   R–   R=   Rq   Rœ   R   (    (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR   _  s   c           B  s   e  Z d d  „ Z RS(   c         C  s:   | s | } n  t  j |  | d t f i | d 6| d 6ƒ S(   NR   Rœ   R   (   R	   t   __new__R   (   t   mclt   namet	   latexname(    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyRž   j  s    	N(   R   R   t   NoneRž   (    (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR   i  s   c           s1   | s |  } n  t  |  | ƒ ‰  ‡  f d †  } | S(   s5   Use a lexical closure to make a controlled gate.
    c           s   t  t |  ƒ ˆ  | ƒ ƒ S(   N(   R   t   tuple(   t   ctrlsRt   (   t   onequbitgate(    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyt   ControlledGatev  s    (   R   (   R    R¡   R¦   (    (   R¥   s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyR   p  s
    	N(&   R–   t
   __future__R    R   t   sympyR   t   sympy.core.compatibilityR   t   sympy.externalR   t   sympy.physics.quantum.gateR   R   R   R   t   sympy.core.coreR	   t   sympy.core.assumptionsR
   t   __all__R-   t   RuntimeErrorR   t   objectR   R   R   t   linesRL   t   patchesRŠ   RT   R   R   R   R   R¢   R   (    (    (    s@   lib/python2.7/site-packages/sympy/physics/quantum/circuitplot.pyt   <module>   s@   "		î	

