
    g.                    \   d 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 g dZ ed          Z edd	d
gief          Zer!erej        Zej        j        Zej        j        Z G d d          Zd Zi fdZddZ G d de	          Z G d de	          Z G d de          ZddZdS )a  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!
    )annotations)Mul)import_module)GateOneQubitGateCGateCGateS)CircuitPlotcircuit_plotlabellerMzMxCreateOneQubitGateCreateCGatenumpy
matplotlibfromlistpyplot)import_kwargscatchc                      e Zd ZU dZdZdZdZdZdZdZ	g Z
ded<   i Zded	<   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dS )r
   z$A class for managing a circuit plot.g      ?g      4@g?g333333?z	list[str]labelszdict[str, str]inits      ?c                   t           rt          st          d          || _        t	          | j        j                  | _        || _        |                     |           | 	                                 | 
                                 |                                  |                                  |                                  d S )Nz"numpy or matplotlib not available.)npr   ImportErrorcircuitlenargsngatesnqubitsupdate_create_grid_create_figure_plot_wires_plot_gates_finish)selfcr"   kwargss       ]/var/www/html/ai-engine/env/lib/python3.11/site-packages/sympy/physics/quantum/circuitplot.py__init__zCircuitPlot.__init__<   s     	D 	DBCCC$,+,,F    c                :    | j                             |           dS )z'Load the kwargs into the instance dict.N)__dict__r#   )r)   r+   s     r,   r#   zCircuitPlot.updateI   s    V$$$$$r.   c                    | j         }t                              d| j        |z  |t                    }t                              d| j        |z  |t                    }|| _        || _        dS )zCreate the grid of wires.g        )dtypeN)scaler   aranger"   floatr!   
_wire_grid
_gate_grid)r)   r3   	wire_grid	gate_grids       r,   r$   zCircuitPlot._create_gridM   s[    
IIc4<#5uEIJJ	IIc4;u#4e5III	##r.   c                   t                               | j        | j        z  | j        | j        z  fdd          | _        | j                            dddd          }|                                 d| j        z  }|                    | j	        d         |z
  | j	        d         |z              |
                    | j        d         |z
  | j        d         |z              |                    d	           || _        d
S )z"Create the main matplotlib figure.w)figsize	facecolor	edgecolor   T)frameonr   r   equalN)r   figurer!   r3   r"   _figureadd_subplotset_axis_offset_xlimr7   set_ylimr6   
set_aspect_axes)r)   axoffsets      r,   r%   zCircuitPlot._create_figureU   s    }}[+T\$*-DE % 
 

 \%%q! & 
 
 	TZ
DOA&/1Dv1MNNN
DOA&/1Dv1MNNN
g


r.   c           
     f   | j         d         }| j         d         }|| j        z
  || j        z   f}t          | j                  D ]}| j        |         | j        |         f}t          ||d| j                  }| j                            |           | j	        rd}| j
                            | j	        |                   rd}| j                            |d         | j        z
  |z
  |d         t          | j	        |         | j
                  | j        ddd           |                                  dS )	z&Plot the wires of the circuit diagram.r   rA   kcolorlwg      ?center)sizerP   havaN)r7   r3   ranger"   r6   Line2D	linewidthrJ   add_liner   r   gettextlabel_bufferrender_labelfontsize_plot_measured_wires)r)   xstartxstopxdataiydatalineinit_label_buffers           r,   r&   zCircuitPlot._plot_wiresg   s?   ##$*$edj&89t|$$ 	7 	7A_Q');<Eu>  D
 J%%%{ 7$%!:>>$+a.11Kt3D
!HT../@@q Q
;;X	   7 7 7
 	!!#####r.   c                   |                                  }| j        d         }d}|D ]q}| j        ||                  || j        z   f}| j        |         |z   | j        |         |z   f}t	          ||d| j                  }| j                            |           rt          | 	                                          D ]\  }}	t          |	t          t          f          r|	j        |	j        z   }
|
D ]}||v r| j        |         | j        ||                  k    rpt          |
          t!          |
          f}| j        |         |z
  | j        |         |z
  f}t	          ||d| j                  }| j                            |           d S )NrA   g{Gz?rN   rO   )_measurementsr7   r3   r6   rW   rX   rJ   rY   	enumerate_gates
isinstancer   r	   controlstargetsminmax)r)   
ismeasuredra   dyimrb   rd   re   rc   gwireswires               r,   r_   z CircuitPlot._plot_measured_wires~   s   ''))
# 	& 	&B_Z^4U4:5EFE_R(+DOB,?,BCEu>  D
 J%%%%T[[]]++ 	2 	2CAa!eV_-- 2
QY.! 
2 
2Dz))?1-
4@P0QQQ #E

CJJ 6 $ 22 5tq7I"7L L%!5"%#~     
 
++D111	2 	2r.   c                4   g }t          | j        t                    rGt          | j        j                  D ],}t          |t
                    r|                    |           -n4t          | j        t
                    r|                    | j                   |S )z/Create a list of all gates in the circuit plot.)rk   r   r   reversedr    r   append)r)   gatesrs   s      r,   rj   zCircuitPlot._gates   s    dlC(( 	'dl/00 $ $a&& $LLOOO$ d++ 	'LL&&&r.   c                    t          |                                           D ]\  }}|                    | |           dS )z0Iterate through the gates and plot each of them.N)ri   rj   	plot_gate)r)   rc   gates      r,   r'   zCircuitPlot._plot_gates   sF     // 	$ 	$GAtNN4####	$ 	$r.   c                    i }t          |                                           D ];\  }}t          |dd          r%|j        D ]}||v r||         |k    r|||<   |||<   <|S )zReturn 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.
        measurementF)ri   rj   getattrrm   )r)   rp   rc   rs   targets        r,   rh   zCircuitPlot._measurements   s     
T[[]]++ 	/ 	/CAaqu-- /i / /F++%f-1112Jv.-.
6**r.   c                h    | j                                         D ]}|                    d           d S )NF)rD   findobjset_clip_on)r)   os     r,   r(   zCircuitPlot._finish   s>    %%'' 	! 	!AMM%    	! 	!r.   c                    | j         |         }| j        |         }| j                            |||dddddd| j        d| j                   dS )z#Draw a box for a single qubit gate.rN   rR   r;   TecfcfillrQ   )rP   rT   rU   bboxrS   N)r7   r6   rJ   r[   rX   r^   )r)   tgate_idxwire_idxxys         r,   one_qubit_boxzCircuitPlot.one_qubit_box   sg    OH%OH%
q!3DNKK 	 	
 	
 	
 	
 	
r.   c                V    t          | j                   t          | j                   dS )z<Draw a box for a two qubit gate. Does not work yet.
        N)printr7   r6   )r)   r   r   r   s       r,   two_qubit_boxzCircuitPlot.two_qubit_box   s*    
 	dodor.   c                    | j         |         | j         |         f}| j        |         | j        |         f}t          ||d| j                  }| j                            |           dS )zDraw a vertical control line.rN   rO   N)r7   r6   rW   rX   rJ   rY   )r)   r   min_wiremax_wirerb   rd   re   s          r,   control_linezCircuitPlot.control_line   sq    *DOH,EF*DOH,EF5~
 
 

 	
D!!!!!r.   c                    | j         |         }| j        |         }| j        }t          ||f|| j        z  ddd| j                  }| j                            |           dS )zDraw a control point.rN   Tr   N)r7   r6   control_radiusCircler3   rX   rJ   	add_patch)r)   r   r   r   r   radiusr*   s          r,   control_pointzCircuitPlot.control_point   ss    OH%OH%$F4:~
 
 
 	
Qr.   c                ,   | j         |         }| j        |         }| j        }t          ||f|ddd| j                  }| j                            |           t          ||f||z
  ||z   fd| j                  }| j                            |           dS )z7Draw a NOT gates as the circle with plus in the middle.rN   r;   Fr   rO   N)	r7   r6   
not_radiusr   rX   rJ   r   rW   rY   )r)   r   r   r   r   r   r*   ls           r,   	not_pointzCircuitPlot.not_point   s    OH%OH%F~
 
 
 	
QFQZV,~
 
 

 	
Ar.   c                P   | j         |         }| j        |         }| j        }t          ||z
  ||z   f||z
  ||z   fd| j                  }t          ||z
  ||z   f||z   ||z
  fd| j                  }| j                            |           | j                            |           dS )zDraw a swap point as a cross.rN   rO   N)r7   r6   
swap_deltarW   rX   rJ   rY   )r)   r   r   r   r   dl1l2s           r,   
swap_pointzCircuitPlot.swap_point  s    OH%OH%OUAENUAEN~	
 
 
 UAENUAEN~	
 
 
 	
B
Br.   N)__name__
__module____qualname____doc__r3   r^   rX   r   r   r   r   __annotations__r   r\   r-   r#   r$   r%   r&   r_   rj   r'   rh   r(   r   r   r   r   r   r    r.   r,   r
   r
   /   sQ        ..EHINJJFEL  % % %$ $ $  $$ $ $.2 2 2:	 	 	$ $ $
  ! ! !

 
 
  "	" 	" 	"       *         r.   r
   c                    t          | |fi |S )aE  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      r,   r   r      s     q',,V,,,r.   c                L    |                     |           }|r	d| d|dS d| z  S )a  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$'
    z$\left|z\right\rangle=\left|z\right\rangle$z$\left|%s\right\rangle$)rZ   )labelr   inits      r,   r]   r]   .  sB     99UD P PCH55$$$OO%--r.   qc                >      fdt                     D             S )a  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']
    c                *    g | ]}d |z
  dz
  fz  S )z%s_%dr?   r   ).0rc   nsymbols     r,   
<listcomp>zlabeller.<locals>.<listcomp>M  s*    777Gvac!en$777r.   )rV   )r   r   s   ``r,   r   r   <  s)    " 87777eAhh7777r.   c                      e Zd ZdZdZd ZdZdS )r   zMock-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.
    TM_zNr   r   r   r   r~   	gate_namegate_name_latexr   r.   r,   r   r   O  )         
 KIOOOr.   r   c                      e Zd ZdZdZd ZdZdS )r   zMock-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.
    TM_xNr   r   r.   r,   r   r   Y  r   r.   r   c                      e Zd ZddZdS )r   Nc                D    |s|}t          |dz   t          f||d          S )Nr   )r   r   )typer   )mclname	latexnames      r,   __new__zCreateOneQubitGate.__new__d  s6     	ID6ML?9==? ? 	?r.   N)r   r   r   r   r   r.   r,   r   r   c  s(        ? ? ? ? ? ?r.   r   Nc                :    |s| }t          | |          fd}|S )z5Use a lexical closure to make a controlled gate.
    c                P    t          t          |            |                    S r   )r   tuple)ctrlsr   onequbitgates     r,   ControlledGatez#CreateCGate.<locals>.ControlledGatep  s#    U5\\,,v"6"6777r.   )r   )r   r   r   r   s      @r,   r   r   j  s@      	%dI66L8 8 8 8 8r.   )r   r   )r   
__future__r   sympy.core.mulr   sympy.externalr   sympy.physics.quantum.gater   r   r   r	   __all__r   RuntimeErrorr   r   linesrW   patchesr   r
   r   r]   r   r   r   r   r   r   r   r.   r,   <module>r      s     # " " " " "       ( ( ( ( ( ( H H H H H H H H H H H H   ]7]hZ 8/  
  '* 'F$F&F
o  o  o  o  o  o  o  o b- - - ! . . . .8 8 8 8&              ? ? ? ? ? ? ? ?     r.   