
    sg.                    h   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r8e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y)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y)r
   z$A class for managing a circuit plot.g      ?g      4@g?g333333?z	list[str]labelszdict[str, str]inits      ?c                X   t         rt        st        d      || _        t	        | j                  j
                        | _        || _        | j                  |       | j                          | j                          | j                          | j                          | j                          y )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       T/var/www/html/venv/lib/python3.12/site-packages/sympy/physics/quantum/circuitplot.py__init__zCircuitPlot.__init__<   s|    BCC$,,++,F    c                :    | j                   j                  |       y)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        j                  d| j                  |z  |t              }t        j                  d| j
                  |z  |t              }|| _        || _        y)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   sW    

IIc4<<#5uEIJ	IIc4;;u#4e5II	##r.   c                   t         j                  | j                  | j                  z  | j                  | j                  z  fdd      | _        | j
                  j                  dddd      }|j                          d| j                  z  }|j                  | j                  d   |z
  | j                  d   |z          |j                  | j                  d   |z
  | j                  d   |z          |j                  d	       || _        y
)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! & 
 	TZZ
DOOA&/1Dv1MN
DOOA&/1Dv1MN
g
r.   c           
        | j                   d   }| j                   d   }|| j                  z
  || j                  z   f}t        | j                        D ]  }| j                  |   | j                  |   f}t        ||d| j                        }| j                  j                  |       | j                  sbd}| j                  j                  | j                  |         rd}| j                  j                  |d   | j                  z
  |z
  |d   t        | j                  |   | j                        | j                  ddd        | j!                          y)	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*   ##$**$edjj&89t||$ 	7A__Q');<Eu>>D
 JJ%{{$%!::>>$++a.1t3D

!HT.../@@q Q

;X	   7	7  	!!#r.   c                "   | j                         }| j                  d   }d}|D ]{  }| j                  ||      || j                  z   f}| j                  |   |z   | j                  |   |z   f}t	        ||d| j
                        }| j                  j                  |       } t        | j                               D ]  \  }}	t        |	t        t        f      s|	j                  |	j                  z   }
|
D ]  }||v s| j                  |   | j                  ||      kD  s+t        |
      t!        |
      f}| j                  |   |z
  | j                  |   |z
  f}t	        ||d| j
                        }| j                  j                  |         y )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(+DOOB,?,BCEu>>D
 JJ%	& T[[]+ 	2CAa!eV_-

QYY.! 
2Dz)??1-
4@P0QQ #E
CJ 6 $ 22 5tq7I"7L L%!5"%#~~ 
 

++D1
2	2r.   c                8   g }t        | j                  t              rHt        | j                  j                        D ]$  }t        |t
              s|j                  |       & |S t        | j                  t
              r|j                  | 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   st    dllC(dll//0 $a&LLO$
  d+LL&r.   c                j    t        | j                               D ]  \  }}|j                  | |        y)z0Iterate through the gates and plot each of them.N)ri   rj   	plot_gate)r)   rc   gates      r,   r'   zCircuitPlot._plot_gates   s.     / 	$GAtNN4#	$r.   c                    i }t        | j                               D ]<  \  }}t        |dd      s|j                  D ]  }||v r||   |kD  s|||<   |||<    > |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   sw     
T[[]+ 	/CAaqu-ii /F+%f-112Jv.-.
6*/	/ r.   c                d    | j                   j                         D ]  }|j                  d        y )NF)rD   findobjset_clip_on)r)   os     r,   r(   zCircuitPlot._finish   s*    %%' 	!AMM% 	!r.   c                    | j                   |   }| j                  |   }| j                  j                  |||dddddd| j                  d| j
                         y)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   sZ    OOH%OOH%

q!3DNNK 	 	
r.   c                X    t        | j                         t        | j                         y)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    
 	doodoor.   c                    | j                   |   | j                   |   f}| j                  |   | j                  |   f}t        ||d| j                        }| j                  j                  |       y)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   sg    *DOOH,EF*DOOH,EF5~~

 	

D!r.   c                    | j                   |   }| j                  |   }| j                  }t        ||f|| j                  z  ddd| j
                        }| j                  j                  |       y)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   sj    OOH%OOH%$$F4::~~
 	

Qr.   c                D   | j                   |   }| j                  |   }| j                  }t        ||f|ddd| j                        }| j
                  j                  |       t        ||f||z
  ||z   fd| j                        }| j
                  j                  |       y)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    OOH%OOH%F~~
 	

QFQZV,~~

 	

Ar.   c                h   | j                   |   }| j                  |   }| j                  }t        ||z
  ||z   f||z
  ||z   fd| j                        }t        ||z
  ||z   f||z   ||z
  fd| j                        }| j
                  j                  |       | j
                  j                  |       y)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    OOH%OOH%OO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
   /   s    .EHINJJFIE>L%$$$.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                D    |j                  |       }|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]   .  s+     99UDCH$OO%--r.   c                T    t        |       D cg c]  }d|| |z
  dz
  fz   c}S c c}w )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']
    z%s_%dr?   )rV   )nsymbolrc   s      r,   r   r   <  s-    " /4Ah7Gvac!en$777s   %c                      e Zd ZdZdZd ZdZy)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Or.   r   c                      e Zd ZdZdZd ZdZy)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y)r   Nc                :    |s|}t        |dz   t        f||d      S )Nr   )r   r   )typer   )mclname	latexnames      r,   __new__zCreateOneQubitGate.__new__d  s)    ID6ML?9=? 	?r.   N)r   r   r   r   r   r.   r,   r   r   c  s    ?r.   r   Nc                2    |s| }t        | |      fd}|S )z5Use a lexical closure to make a controlled gate.
    c                :    t        t        |        |            S r   )r   tuple)ctrlsr   onequbitgates     r,   ControlledGatez#CreateCGate.<locals>.ControlledGatep  s    U5\,v"677r.   )r   )r   r   r   r   s      @r,   r   r   j  s$     	%dI6L8r.   )qr   )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 7hZ 8/
 *F$$F&&F
o  o b- ! .8&  ? ?r.   