Ë
    täi.  ã                  ó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       úp/Volumes/fast/ai/experiments/MLX_z-image/.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   € à—
‘
ˆÜ—I‘I˜c 4§<¡<°Ñ#5°uÄE�IÓJˆ	Ü—I‘I˜c 4§;¡;¨uÑ#4°eÄ5�IÓ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�!Øð &ó 
ˆð 	�‰ÔØ�T—Z‘Z‘ˆØ
�‰�D—O‘O AÑ&¨Ñ/°·±ÀÑ1DÀvÑ1MÔNØ
�‰�D—O‘O AÑ&¨Ñ/°·±ÀÑ1DÀvÑ1MÔ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%  € à—‘ Ñ#ˆØ—‘ Ñ#ˆØ˜$Ÿ*™*Ñ$ e¨d¯j©jÑ&8Ð9ˆÜ�t—|‘|Ö$ˆAØ—_‘_ QÑ'¨¯©¸Ñ);Ð<ˆEÜØ�uØØ—>‘>ôˆDð
 �J‰J×Ñ Ô%Ø�{‹{Ø$%Ð!Ø—:‘:—>‘> $§+¡+¨a¡.Ô1ÀtÐ3DØ—
‘
—‘Ø˜!‘H˜T×.Ñ.Ñ.Ð/@Ñ@ÀÀqÁÜ  §¡¨Q¡°·
±
Ó;ØŸ™Ø ¨Xð	  õ 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{®Gáz¤?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~   sq  € Ø×'Ñ'Ó)ˆ
Ø—‘ Ñ#ˆØˆãˆBØ—_‘_ Z°¡^Ñ4°U¸4¿:¹:Ñ5EÐFˆEØ—_‘_ RÑ(¨Ñ+¨D¯O©O¸BÑ,?ÀÑ,BÐCˆEÜØ�uØØ—>‘>ôˆDð
 �J‰J×Ñ Õ%ð ô ˜TŸ[™[›]Ö+‰CˆAˆaÜ˜!œe¤V˜_Õ-ØŸ
™
 Q§Y¡YÑ.�Û!�DØ˜zÒ)ØŸ?™?¨1Ñ-°·±À
È4Ñ@PÑ0QÓQÜ # E£
¬C°«JÐ 6˜Ø $§¡°Ñ 2°2Ñ 5°t·±ÀqÑ7IÈ"Ñ7LÐ L˜Ü%Ø! 5Ø"%Ø#Ÿ~™~ô ˜ð
 Ÿ
™
×+Ñ+¨DÕ1ñ "ñ ,r.   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›   so   € àˆÜ�d—l‘l¤CÔ(Ü˜dŸl™l×/Ñ/Ö0�Ü˜a¤Õ&Ø—L‘L •Oð 1ð
 ˆô ˜Ÿ™¤dÔ+Ø�L‰L˜Ÿ™Ô&Øˆ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)   € ä  §¡£Ö/‰GˆAˆtØ�N‰N˜4 Õ#ñ 0r.   c                óº   — i }t        | j                  «       «      D ]<  \  }}t        |dd«      sŒ|j                  D ]  }||v r||   |kD  sŒ|||<   Œ|||<   Œ Œ> |S )z�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.
        ÚmeasurementF)ri   rj   Úgetattrrm   )r)   rp   rc   rs   Útargets        r,   rh   zCircuitPlot._measurements«   sm   € ð ˆ
Ü˜TŸ[™[›]Ö+‰CˆAˆaÜ�q˜ uÕ-ØŸiœi�FØ Ñ+Ø% fÑ-°Ó1Ø12˜J vÒ.à-.˜
 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Ø�M‰M˜%Õ ñ (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   € à�O‰O˜HÑ%ˆØ�O‰O˜HÑ%ˆØ�
‰
�‰Øˆq�!ØØØØ 3°¸D¿N¹NÑ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   € ô
 	ˆd�o‰oÔÜˆd�o‰oÕ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   € à—‘ Ñ*¨D¯O©O¸HÑ,EÐFˆØ—‘ Ñ*¨D¯O©O¸HÑ,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   € à�O‰O˜HÑ%ˆØ�O‰O˜HÑ%ˆØ×$Ñ$ˆÜØ�ˆ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�   € à�O‰O˜HÑ%ˆØ�O‰O˜HÑ%ˆØ—‘ˆÜØ�ˆFØØØØØ�~‰~ô
ˆð 	�
‰
×Ñ˜QÔÜØ�ˆF�Q˜‘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³   € à�O‰O˜HÑ%ˆØ�O‰O˜HÑ%ˆØ�O‰OˆÜØ�‰U�A˜‘EˆNØ�‰U�A˜‘EˆNØØ�~‰~ô	
ˆô Ø�‰U�A˜‘EˆNØ�‰U�A˜‘EˆNØØ�~‰~ô	
ˆð 	�
‰
×Ñ˜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Ø€FˆIÓØ€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+   € ð �9‰9�UÓ€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   <  s1   € ô" /4°A¬hÓ7©h¨ˆG�v˜a ™c !™e�nÓ$¨hÑ7Ð7ùÒ7s   Ž%c                  ó   — e Zd ZdZdZd ZdZy)r   zŠ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.
    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   z‹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.
    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Ü�D˜6‘M¤L ?Ø°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   ø€ Ü”U˜5“\¡,¨vÓ"6Ó7Ð7r.   )r   )rÁ   rÂ   rÊ   rÉ   s      @r,   r   r   j  s$   ø€ ñ Øˆ	Ü% d¨IÓ6€Lô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Ó€ÙØ ¨h¨ZÐ 8Øˆ/ô€
ñ ‰*Ø×Ñ€FØ×Ñ×$Ñ$€FØ×Ñ×&Ñ&€F÷
o ñ o òb-ð !ó .ó8ô&ˆô ôˆô ô?˜ô ?ôr.   