ó
    Š*£h%û  ã                   óò   • S r SSKJrJrJrJrJr  SSKJr  SSK	J
r
  SSKJr  SSKJr  SSKJrJrJr  SS	KJr  SS
KJr  \
S:w  a  SS/r " S S\5      rS rS rS rS rS rS rS r S r!S r"S r#S r$S r%g)z

Module for the SDM class.

é    )ÚaddÚnegÚposÚsubÚmul)Údefaultdict)ÚGROUND_TYPES)Údoctest_depends_on)Ú_strongly_connected_componentsé   )ÚDMBadInputErrorÚDMDomainErrorÚDMShapeError)ÚQQ)ÚDDMÚflintz
SDM.to_dfmzSDM.to_dfm_or_ddmc                   ó�  ^ • \ rS rSrSrSrSrSrU 4S jrS r	S r
S rS	 rS
 rS r\S 5       rS r\S 5       r\S 5       rS rS r\S 5       rS r\S 5       rS r\S 5       rS r\S 5       rS rS rS rS r \!" S/S9S 5       r"\!" S/S9S  5       r#\S! 5       r$\S" 5       r%\S# 5       r&\SNS$ j5       r'S% r(S& r)S' r*S( r+S) r,S* r-S+ r.S, r/S- r0S. r1S/ r2S0 r3S1 r4S2 r5S3 r6S4 r7S5 r8S6 r9S7 r:S8 r;S9 r<S: r=S; r>S< r?S= r@SNS> jrAS? rBS@ rCSA rDSB rESC rFSD rGSE rHSF rISG rJSH rK\L" SISJ5      4SK jrM\L" SISJ5      4SL jrNSMrOU =rP$ )OÚSDMé   ac  Sparse matrix based on polys domain elements

This is a dict subclass and is a wrapper for a dict of dicts that supports
basic matrix arithmetic +, -, *, **.


In order to create a new :py:class:`~.SDM`, a dict
of dicts mapping non-zero elements to their
corresponding row and column in the matrix is needed.

We also need to specify the shape and :py:class:`~.Domain`
of our :py:class:`~.SDM` object.

We declare a 2x2 :py:class:`~.SDM` matrix belonging
to QQ domain as shown below.
The 2x2 Matrix in the example is

.. math::
       A = \left[\begin{array}{ccc}
            0 & \frac{1}{2} \\
            0 & 0 \end{array} \right]


>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> elemsdict = {0:{1:QQ(1, 2)}}
>>> A = SDM(elemsdict, (2, 2), QQ)
>>> A
{0: {1: 1/2}}

We can manipulate :py:class:`~.SDM` the same way
as a Matrix class

>>> from sympy import ZZ
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> B  = SDM({0:{0: ZZ(3)}, 1:{1:ZZ(4)}}, (2, 2), ZZ)
>>> A + B
{0: {0: 3, 1: 2}, 1: {0: 1, 1: 4}}

Multiplication

>>> A*B
{0: {1: 8}, 1: {0: 3}}
>>> A*ZZ(2)
{0: {1: 4}, 1: {0: 2}}

ÚsparseFc                 ó  >^^• [         TU ]  U5        U=U l        =u  U l        U l        u  mmX0l        [        U4S jU  5       5      (       d  [        S5      e[        U4S jU R                  5        5       5      (       d  [        S5      eg )Nc              3   óN   >#   • U  H  nS Us=:*  =(       a    T:  Os  v •  M     g7f©r   N© )Ú.0ÚrÚms     €ÚU/home/mande/repo/quber/.venv/lib/python3.13/site-packages/sympy/polys/matrices/sdm.pyÚ	<genexpr>ÚSDM.__init__.<locals>.<genexpr>S   s   øé € Ð,¢t !�1˜—:“:˜A—:‘:¢tùs   ƒ"%zRow out of rangec              3   ó`   >#   • U  H#  o  H  nS Us=:*  =(       a    T:  Os  v •  M     M%     g7fr   r   )r   ÚrowÚcÚns      €r   r   r    U   s%   øé € ÐDª #Ã¸1�1˜—:“:˜A—:‘:Á‘:ªùs   ƒ+.zColumn out of range)	ÚsuperÚ__init__ÚshapeÚrowsÚcolsÚdomainÚallr   Úvalues)ÚselfÚ	elemsdictr'   r*   r   r$   Ú	__class__s       @@€r   r&   ÚSDM.__init__N   sy   ú€ Ü‰Ñ˜Ô#Ø38Ð8ˆŒ
Ð8Ñ)�T”Y ¤	©D¨A¨qØŒäÔ,¡tÓ,×,Ñ,Ü!Ð"4Ó5Ð5ÜÔD¨¯©¬ÓD×DÑDÜ!Ð"7Ó8Ð8ð Eó    c                 ó  •  X   U   $ ! [          as    U R                  u  p4U* Us=::  a  U:  aK  O  OHU* Us=::  a  U:  a:  O  O7 XU-     X$-     s $ ! [          a    U R                  R                  s s $ f = f[	        S5      ef = f©Nzindex out of range)ÚKeyErrorr'   r*   ÚzeroÚ
IndexError)r-   ÚiÚjr   r$   s        r   ÚgetitemÚSDM.getitemX   s‹   € ð
	7Ø‘7˜1‘:ÐøÜó 	7Ø—:‘:‰DˆAØˆr�Q�{˜Ž{ ˜r Q�{¨ž{ð,Ø A¡™; q¡uÑ-Ò-øÜó ,ØŸ;™;×+Ñ+Ô+ð,úô !Ð!5Ó6Ð6ð	7ús-   ‚	 ‰:BÁAÁBÁ A7Á2BÁ6A7Á7Bc                 ó6  • U R                   u  pEU* Us=::  a  U:  a  O  OU* Us=::  a  U:  d  O  [        S5      eX-  X%-  p!U(       a	   X0U   U'   g U R                  US 5      nUb   Xb	 U(       d  X	 g g g ! [         a    X#0X'    g f = f! [         a     g f = fr3   )r'   r6   r4   Úget)r-   r7   r8   Úvaluer   r$   Úrowis          r   ÚsetitemÚSDM.setiteme   s³   € Ø�z‰z‰ˆØ��a•˜!–   a¥¨!¥ÜÐ1Ó2Ð2Ø‰u�a‘eˆ1Þð%Ø"�Q‘˜’
ð —8‘8˜A˜tÓ$ˆDØÑð$Ø˜ö  Ø ™Gð  ð  øô	 ó %Ø˜*�“ð%ûô  ó Ùðús$   Á
A6 Á(B Á6BÂBÂ
BÂBc                 ó¶  • U R                   u  p4[        U5      U   n[        U5      U   n0 nU R                  5        Hc  u  p‰X…;   d  M  U	R                  5        V
Vs0 s H  u  p«X¦;   d  M  UR                  U
5      U_M      n	n
nU	(       d  MP  X—UR                  U5      '   Me     U R	                  U[        U5      [        U5      4U R                  5      $ s  snn
f ©N)r'   ÚrangeÚitemsÚindexÚnewÚlenr*   )r-   Úslice1Úslice2r   r$   ÚriÚciÚsdmr7   r"   r8   Úes               r   Úextract_sliceÚSDM.extract_slicez   s´   € Ø�z‰z‰ˆÜ�1‹X�fÑˆÜ�1‹X�fÑˆàˆØ—j‘j–l‰FˆAØ�wØ25·)±)´+ÔI²+©$¨!ÀÁ“~�r—x‘x “{ A’~±+�ÑIß�3Ø'*˜Ÿ™ ›Ó$ñ	 #ð �x‰x˜œc "›g¤s¨2£wÐ/°·±Ó=Ð=ùó	 Js   ÁCÁ+Cc                 óÖ  • U (       a  U(       a  U(       d0  U R                  [        U5      [        U5      4U R                  5      $ U R                  u  p4U* [	        U5      s=::  a  [        U5      s=::  a  U:  d  O  [        S5      eU* [	        U5      s=::  a  [        U5      s=::  a  U:  d  O  [        S5      e[        [        5      n[        [        5      n[        U5       H  u  pxXXU-     R                  U5        M     [        U5       H  u  pšXjU-     R                  U	5        M     [        U5      n[        U5      nU n0 nX½R                  5       -   H\  nXØ   n0 nXÏR                  5       -   H  n
Xú   nXj    H  n	UUU	'   M
     M     U(       d  M?  XX    H  nUR                  5       Xç'   M     M^     U R                  U[        U5      [        U5      4U R                  5      $ )NzRow index out of rangezColumn index out of range)ÚzerosrG   r*   r'   ÚminÚmaxr6   r   ÚlistÚ	enumerateÚappendÚsetÚkeysÚcopyrF   )r-   r(   r)   r   r$   ÚrowmapÚcolmapÚi2Úi1Új2Új1ÚrowsetÚcolsetÚsdm1Úsdm2Úrow1Úrow2Úrow1_j1s                     r   ÚextractÚSDM.extractˆ   s–  € Þž¦$Ø—:‘:œs 4›y¬#¨d«)Ð4°d·k±kÓBÐBà�z‰z‰ˆØ�”c˜$“iÕ0¤3 t£9Õ0¨qÕ0ÜÐ5Ó6Ð6Ø�”c˜$“iÕ0¤3 t£9Õ0¨qÕ0ÜÐ8Ó9Ð9ô œTÓ"ˆÜœTÓ"ˆÜ –o‰FˆBØ˜‘6‰N×!Ñ! "Ö%ñ &ä –o‰FˆBØ˜‘6‰N×!Ñ! "Ö%ñ &ô �V“ˆÜ�V“ˆàˆØˆØŸ9™9›;Ô&ˆBØ‘8ˆDØˆDØŸy™y›{Ô*�Ø™(�Ø œ*�BØ&�D˜“Hó %ñ +÷ ˆtØ œ*�BØ#Ÿy™y›{�D“Hó %ñ 'ð �x‰x˜œs 4›y¬#¨d«)Ð4°d·k±kÓBÐBr1   c                 óÞ   • / nU R                  5        HD  u  p#SR                  S UR                  5        5       5      nUR                  U< SU< S35        MF     SSR                  U5      -  $ )Nú, c              3   ó8   #   • U  H  u  pU< S U< 3v •  M     g7f)z: Nr   )r   r8   Úelems      r   r   ÚSDM.__str__.<locals>.<genexpr>±   s   é € Ð QÂ[¹'¸!«Q²Õ!5Â[ùs   ‚z: {Ú}z{%s})rD   ÚjoinrV   )r-   Úrowsstrr7   r"   Úelemsstrs        r   Ú__str__ÚSDM.__str__®   sZ   € ØˆØ—j‘j–l‰FˆAØ—y‘yÑ QÀSÇYÁYÄ[Ó QÓQˆHØ�N‰N««HÐ5Ö6ñ #ð ˜Ÿ	™	 'Ó*Ñ*Ð*r1   c                 ó¢   • [        U 5      R                  n[        R                  U 5      nU< SU< SU R                  < SU R
                  < S3$ )NÚ(rj   Ú))ÚtypeÚ__name__ÚdictÚ__repr__r'   r*   )r-   Úclsr(   s      r   rz   ÚSDM.__repr__µ   s6   € Ü�4‹j×!Ñ!ˆÜ�}‰}˜TÓ"ˆÛ#&«¨d¯j¬j¸$¿+¼+ÐFÐFr1   c                 ó   • U " XU5      $ )a†  

Parameters
==========

sdm: A dict of dicts for non-zero elements in SDM
shape: tuple representing dimension of SDM
domain: Represents :py:class:`~.Domain` of SDM

Returns
=======

An :py:class:`~.SDM` object

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> elemsdict = {0:{1: QQ(2)}}
>>> A = SDM.new(elemsdict, (2, 2), QQ)
>>> A
{0: {1: 2}}

r   )r{   rL   r'   r*   s       r   rF   ÚSDM.newº   s   € ñ6 �3˜vÓ&Ð&r1   c                 ó¾   • U R                  5        VVs0 s H  u  pXR                  5       _M     nnnU R                  X0R                  U R                  5      $ s  snnf )zü
Returns the copy of a :py:class:`~.SDM` object

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> elemsdict = {0:{1:QQ(2)}, 1:{}}
>>> A = SDM(elemsdict, (2, 2), QQ)
>>> B = A.copy()
>>> B
{0: {1: 2}, 1: {}}

)rD   rY   rF   r'   r*   )ÚAr7   ÚAiÚAcs       r   rY   ÚSDM.copy×   sF   € ð  )*¯©¬	Ô2ª	™u˜qˆa—‘“Šl©	ˆÑ2Ø�u‰u�RŸ™ !§(¡(Ó+Ð+ùó 3s   ”Ac                 ó  ^^	^
• Uu  nm
[        T5      U:X  a  [        U
4S jT 5       5      (       d  [        S5      eUU
4S jm	U	4S j[        U5       5       nU VVs0 s H  u  pgU(       d  M  Xg_M     nnnU " X‚U5      $ s  snnf )aJ  
Create :py:class:`~.SDM` object from a list of lists.

Parameters
==========

ddm:
    list of lists containing domain elements
shape:
    Dimensions of :py:class:`~.SDM` matrix
domain:
    Represents :py:class:`~.Domain` of :py:class:`~.SDM` object

Returns
=======

:py:class:`~.SDM` containing elements of ddm

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> ddm = [[QQ(1, 2), QQ(0)], [QQ(0), QQ(3, 4)]]
>>> A = SDM.from_list(ddm, (2, 2), QQ)
>>> A
{0: {0: 1/2}, 1: {1: 3/4}}

See Also
========

to_list
from_list_flat
from_dok
from_ddm
c              3   ó@   >#   • U  H  n[        U5      T:H  v •  M     g 7frB   )rG   )r   r"   r$   s     €r   r   Ú SDM.from_list.<locals>.<genexpr>  s   øé € Ð%Cºs¸¤c¨#£h°!¦mºsùs   ƒzInconsistent row-list/shapec                 ór   >• [        T5       Vs0 s H  nTU    U   (       d  M  UTU    U   _M     sn$ s  snf rB   )rC   )r7   r8   Úddmr$   s     €€r   Ú<lambda>ÚSDM.from_list.<locals>.<lambda>  s3   ø€ ´°q´ÓG²¨A¸SÀ¹VÀA½Y›K˜A˜c !™f Q™išK±ÒGùÒGs   �4¤4c              3   ó6   >#   • U  H  oT" U5      4v •  M     g 7frB   r   )r   r7   Úgetrows     €r   r   r†     s   øé € Ð2ª A‘V˜A“Y•ªùs   ƒ)rG   r+   r   rC   )r{   rˆ   r'   r*   r   Úirowsr7   r"   rL   rŒ   r$   s    `       @@r   Ú	from_listÚSDM.from_listê   sw   ú€ ðN ‰ˆˆ1Ü�C“˜A“¤#Ô%C¹sÓ%C×"CÑ"CÜ!Ð"?Ó@Ð@ÝGˆÜ2¬¨q¬Ó2ˆÙ$)Ô1¢E™&˜!¬S‹vˆqŠv¡EˆÑ1Ù�3˜vÓ&Ð&ùó 2s   ÁBÁ/Bc                 óN   • U R                  XR                  UR                  5      $ )a™  
Create :py:class:`~.SDM` from a :py:class:`~.DDM`.

Examples
========

>>> from sympy.polys.matrices.ddm import DDM
>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> ddm = DDM( [[QQ(1, 2), 0], [0, QQ(3, 4)]], (2, 2), QQ)
>>> A = SDM.from_ddm(ddm)
>>> A
{0: {0: 1/2}, 1: {1: 3/4}}
>>> SDM.from_ddm(ddm).to_ddm() == ddm
True

See Also
========

to_ddm
from_list
from_list_flat
from_dok
)rŽ   r'   r*   )r{   rˆ   s     r   Úfrom_ddmÚSDM.from_ddm  s   € ð4 �}‰}˜S§)¡)¨S¯Z©ZÓ8Ð8r1   c                 ó  • U R                   u  pU R                  R                  n[        U5       Vs/ s H  oC/U-  PM
     nnU R	                  5        H%  u  pgUR	                  5        H  u  p‰X•U   U'   M     M'     U$ s  snf )zü
Convert a :py:class:`~.SDM` object to a list of lists.

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> elemsdict = {0:{1:QQ(2)}, 1:{}}
>>> A = SDM(elemsdict, (2, 2), QQ)
>>> A.to_list()
[[0, 2], [0, 0]]


)r'   r*   r5   rC   rD   )
ÚMr   r$   r5   Ú_rˆ   r7   r"   r8   rM   s
             r   Úto_listÚSDM.to_list5  ss   € ð  �w‰w‰ˆØ�x‰x�}‰}ˆÜ#(¨¤8Ó,¢8˜aˆv˜Œz¡8ˆÐ,Ø—g‘g–i‰FˆAØŸ	™	ž‘�Ø�A‘�q“	ó $ñ  ð ˆ
ùò	 -s   ²A>c                 óÔ   • U R                   u  pU R                  R                  nU/X-  -  nU R                  5        H'  u  pVUR                  5        H  u  pxX„XR-  U-   '   M     M)     U$ )aY  
Convert :py:class:`~.SDM` to a flat list.

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0:{1:QQ(2)}, 1:{0: QQ(3)}}, (2, 2), QQ)
>>> A.to_list_flat()
[0, 2, 3, 0]
>>> A == A.from_list_flat(A.to_list_flat(), A.shape, A.domain)
True

See Also
========

from_list_flat
to_list
to_dok
to_ddm
)r'   r*   r5   rD   )	r”   r   r$   r5   Úflatr7   r"   r8   rM   s	            r   Úto_list_flatÚSDM.to_list_flatM  sb   € ð. �w‰w‰ˆØ�x‰x�}‰}ˆØˆv˜™ÑˆØ—g‘g–i‰FˆAØŸ	™	ž‘�Ø !�Q‘S˜1‘W“ó $ñ  ð ˆr1   c                 óÔ   • Uu  pE[        U5      XE-  :w  a  [        S5      e[        [        5      n[	        U5       H"  u  pxU(       d  M  [        Xu5      u  pšX†U	   U
'   M$     U " XbU5      $ )aj  
Create :py:class:`~.SDM` from a flat list of elements.

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM.from_list_flat([QQ(0), QQ(2), QQ(0), QQ(0)], (2, 2), QQ)
>>> A
{0: {1: 2}}
>>> A == A.from_list_flat(A.to_list_flat(), A.shape, A.domain)
True

See Also
========

to_list_flat
from_list
from_dok
from_ddm
zInconsistent flat-list shape)rG   r   r   ry   rU   Údivmod)r{   Úelementsr'   r*   r   r$   rL   ÚinjÚelementr7   r8   s              r   Úfrom_list_flatÚSDM.from_list_flatl  sj   € ð0 ‰ˆÜˆx‹=˜A™EÓ!Ü!Ð"@ÓAÐAÜœ$ÓˆÜ% hÖ/‰LˆCßˆwÜ˜c“~‘�Ø#�A‘�q“	ñ 0ñ �3˜vÓ&Ð&r1   c                 óŠ   • U R                  5       n[        U5      n[        UR                  5       5      nX R                  4nX44$ )a¹  
Convert :class:`SDM` to a flat list of nonzero elements and data.

Explanation
===========

This is used to operate on a list of the elements of a matrix and then
reconstruct a modified matrix with elements in the same positions using
:meth:`from_flat_nz`. Zero elements are omitted from the list.

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0:{1:QQ(2)}, 1:{0: QQ(3)}}, (2, 2), QQ)
>>> elements, data = A.to_flat_nz()
>>> elements
[2, 3]
>>> A == A.from_flat_nz(elements, data, A.domain)
True

See Also
========

from_flat_nz
to_list_flat
sympy.polys.matrices.ddm.DDM.to_flat_nz
sympy.polys.matrices.domainmatrix.DomainMatrix.to_flat_nz
)Úto_dokÚtuplerT   r,   r'   )r”   ÚdokÚindicesrž   Údatas        r   Ú
to_flat_nzÚSDM.to_flat_nzŽ  s<   € ð> �h‰h‹jˆÜ˜“*ˆÜ˜Ÿ
™
›Ó%ˆØŸ™Ð!ˆØˆ~Ðr1   c                 óV   • Uu  pE[        [        XA5      5      nU R                  XeU5      $ )zý
Reconstruct a :class:`~.SDM` after calling :meth:`to_flat_nz`.

See :meth:`to_flat_nz` for explanation.

See Also
========

to_flat_nz
from_list_flat
sympy.polys.matrices.ddm.DDM.from_flat_nz
sympy.polys.matrices.domainmatrix.DomainMatrix.from_flat_nz
)ry   ÚzipÚfrom_dok)r{   rž   r¨   r*   r§   r'   r¦   s          r   Úfrom_flat_nzÚSDM.from_flat_nz³  s+   € ð ‰ˆÜ”3�wÓ)Ó*ˆØ�|‰|˜C¨Ó/Ð/r1   c                 ót   • U R                  5        VVs0 s H  u  pXR                  5       _M     snn$ s  snnf )a@  
Convert to dictionary of dictionaries (dod) format.

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0: {1: QQ(2)}, 1: {0: QQ(3)}}, (2, 2), QQ)
>>> A.to_dod()
{0: {1: 2}, 1: {0: 3}}

See Also
========

from_dod
sympy.polys.matrices.domainmatrix.DomainMatrix.to_dod
)rD   rY   )r”   r7   r"   s      r   Úto_dodÚ
SDM.to_dodÆ  s,   € ð& -.¯G©G¬IÔ6ªI¡& !�—8‘8“:’©IÒ6Ð6ùÓ6s   ”4c                 ó¶   • [        [        5      nUR                  5        H.  u  pVUR                  5        H  u  pxU(       d  M  X„U   U'   M     M0     U " XBU5      $ )a™  
Create :py:class:`~.SDM` from dictionary of dictionaries (dod) format.

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> dod = {0: {1: QQ(2)}, 1: {0: QQ(3)}}
>>> A = SDM.from_dod(dod, (2, 2), QQ)
>>> A
{0: {1: 2}, 1: {0: 3}}
>>> A == SDM.from_dod(A.to_dod(), A.shape, A.domain)
True

See Also
========

to_dod
sympy.polys.matrices.domainmatrix.DomainMatrix.to_dod
©r   ry   rD   )	r{   Údodr'   r*   rL   r7   r"   r8   rM   s	            r   Úfrom_dodÚSDM.from_dodÛ  sQ   € ô. œ$ÓˆØ—i‘i–k‰FˆAØŸ	™	ž‘�ß�1Ø !˜‘F˜1“Ió $ñ "ñ �3˜vÓ&Ð&r1   c           	      óœ   • U R                  5        VVVVs0 s H#  u  pUR                  5         H	  u  p4X4U_M     M%     snnnn$ s  snnnnf )a  
Convert to dictionary of keys (dok) format.

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0: {1: QQ(2)}, 1: {0: QQ(3)}}, (2, 2), QQ)
>>> A.to_dok()
{(0, 1): 2, (1, 0): 3}

See Also
========

from_dok
to_list
to_list_flat
to_ddm
©rD   ©r”   r7   r"   r8   rM   s        r   r¤   Ú
SDM.to_dokù  s:   € ð* )*¯©¬	ÖJª	™f˜a¸c¿i¹i¿k±d°a��˜’	¹k‘©	ÔJÐJùÕJs   –*A
c                 óŠ   • [        [        5      nUR                  5        H  u  u  pVnU(       d  M  XtU   U'   M     U " XBU5      $ )a}  
Create :py:class:`~.SDM` from dictionary of keys (dok) format.

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> dok = {(0, 1): QQ(2), (1, 0): QQ(3)}
>>> A = SDM.from_dok(dok, (2, 2), QQ)
>>> A
{0: {1: 2}, 1: {0: 3}}
>>> A == SDM.from_dok(A.to_dok(), A.shape, A.domain)
True

See Also
========

to_dok
from_list
from_list_flat
from_ddm
r´   )r{   r¦   r'   r*   rL   r7   r8   rM   s           r   r­   ÚSDM.from_dok  sC   € ô2 œ$ÓˆØŸ™ž‰I‰FˆQ�AßˆqØ�A‘�q“	ñ %ñ �3˜vÓ&Ð&r1   c              #   ón   #   • U R                  5        H  nUR                  5        Sh  v•N   M     g N	7f)zô
Iterate over the nonzero values of a :py:class:`~.SDM` matrix.

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0: {1: QQ(2)}, 1: {0: QQ(3)}}, (2, 2), QQ)
>>> list(A.iter_values())
[2, 3]

N)r,   )r”   r"   s     r   Úiter_valuesÚSDM.iter_values/  s)   é € ð —8‘8–:ˆCØ—z‘z“|×#Ò#ò Ù#ùs   ‚'5©3ª
5c              #   ó~   #   • U R                  5        H%  u  pUR                  5        H  u  p4X4U4v •  M     M'     g7f)aN  
Iterate over indices and values of the nonzero elements.

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0: {1: QQ(2)}, 1: {0: QQ(3)}}, (2, 2), QQ)
>>> list(A.iter_items())
[((0, 1), 2), ((1, 0), 3)]

See Also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.iter_items
Nr¹   rº   s        r   Ú
iter_itemsÚSDM.iter_items@  s6   é € ð$ —g‘g–i‰FˆAØŸ	™	ž‘�Ø�f˜a�i”ó $ò  ùs   ‚;=c                 ó`   • [        U R                  5       U R                  U R                  5      $ )zê
Convert a :py:class:`~.SDM` object to a :py:class:`~.DDM` object

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0:{1:QQ(2)}, 1:{}}, (2, 2), QQ)
>>> A.to_ddm()
[[0, 2], [0, 0]]

)r   r–   r'   r*   ©r”   s    r   Úto_ddmÚ
SDM.to_ddmV  s!   € ô �1—9‘9“; §¡¨¯©Ó2Ð2r1   c                 ó   • U $ )z5
Convert to :py:class:`~.SDM` format (returns self).
r   rÅ   s    r   Úto_sdmÚ
SDM.to_sdmf  s	   € ð ˆr1   r   )Úground_typesc                 ó>   • U R                  5       R                  5       $ )aH  
Convert a :py:class:`~.SDM` object to a :py:class:`~.DFM` object

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0:{1:QQ(2)}, 1:{}}, (2, 2), QQ)
>>> A.to_dfm()
[[0, 2], [0, 0]]

See Also
========

to_ddm
to_dfm_or_ddm
sympy.polys.matrices.domainmatrix.DomainMatrix.to_dfm
)rÆ   Úto_dfmrÅ   s    r   rÍ   Ú
SDM.to_dfml  s   € ð* �x‰x‹z× Ñ Ó"Ð"r1   c                 ó>   • U R                  5       R                  5       $ )a³  
Convert to :py:class:`~.DFM` if possible, else :py:class:`~.DDM`.

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0:{1:QQ(2)}, 1:{}}, (2, 2), QQ)
>>> A.to_dfm_or_ddm()
[[0, 2], [0, 0]]
>>> type(A.to_dfm_or_ddm())  # depends on the ground types
<class 'sympy.polys.matrices._dfm.DFM'>

See Also
========

to_ddm
to_dfm
sympy.polys.matrices.domainmatrix.DomainMatrix.to_dfm_or_ddm
)rÆ   Úto_dfm_or_ddmrÅ   s    r   rÐ   ÚSDM.to_dfm_or_ddmƒ  s   € ð. �x‰x‹z×'Ñ'Ó)Ð)r1   c                 ó   • U " 0 X5      $ )aQ  

Returns a :py:class:`~.SDM` of size shape,
belonging to the specified domain

In the example below we declare a matrix A where,

.. math::
    A := \left[\begin{array}{ccc}
    0 & 0 & 0 \\
    0 & 0 & 0 \end{array} \right]

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM.zeros((2, 3), QQ)
>>> A
{}

r   )r{   r'   r*   s      r   rQ   Ú	SDM.zerosœ  s   € ñ* �2�uÓ%Ð%r1   c                 óÔ   • UR                   nUu  pE[        [        [        U5      U/U-  5      5      n[        U5       Vs0 s H  owUR	                  5       _M     nnU " X�U5      $ s  snf rB   )Úonery   r¬   rC   rY   )	r{   r'   r*   rÕ   r   r$   r"   r7   rL   s	            r   ÚonesÚSDM.ones³  s_   € à�j‰jˆØ‰ˆÜ”3”u˜Q“x #  q¡Ó)Ó*ˆÜ&+¨A¤hÓ/¢h �#—(‘(“*Š}¡hˆÐ/Ù�3˜vÓ&Ð&ùò 0s   Á A%c                 ó¼   • [        U[        5      (       a  XpCOUu  p4UR                  n[        [	        X45      5       Vs0 s H  ofXe0_M     nnU " XsU4U5      $ s  snf )zÿ

Returns a identity :py:class:`~.SDM` matrix of dimensions
size x size, belonging to the specified domain

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> I = SDM.eye((2, 2), QQ)
>>> I
{0: {0: 1}, 1: {1: 1}}

)Ú
isinstanceÚintrÕ   rC   rR   )r{   r'   r*   r(   r)   rÕ   r7   rL   s           r   ÚeyeÚSDM.eye»  s_   € ô" �eœS×!Ñ!Ø‘$à‰JˆDØ�j‰jˆÜ$)¬#¨d«/Ô$:Ó;Ò$:˜q�1�(Š{Ñ$:ˆÐ;Ù�3˜t˜ fÓ-Ð-ùò <s   ¿Ac                 ó¦   • Uc  [        U5      [        U5      4n[        U5       VVs0 s H  u  pEU(       d  M  XDU0_M     nnnU " XcU5      $ s  snnf rB   )rG   rU   )r{   Údiagonalr*   r'   r7   ÚvrL   s          r   ÚdiagÚSDM.diagÔ  sR   € à‰=Ü˜“]¤C¨£MÐ2ˆEÜ%.¨xÔ%8Ô>Ò%8™T˜Q¼A‹yˆq�a�&ŠyÑ%8ˆÑ>Ù�3˜vÓ&Ð&ùó ?s
   ¨A¹Ac                 óp   • [        U 5      nU R                  XR                  SSS2   U R                  5      $ )zÜ

Returns the transpose of a :py:class:`~.SDM` matrix

Examples
========

>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import QQ
>>> A = SDM({0:{1:QQ(2)}, 1:{}}, (2, 2), QQ)
>>> A.transpose()
{1: {0: 2}}

Néÿÿÿÿ)Úsdm_transposerF   r'   r*   )r”   ÚMTs     r   Ú	transposeÚSDM.transposeÛ  s/   € ô ˜1ÓˆØ�u‰u�RŸ™¡ 2 ™¨¯©Ó1Ð1r1   c                 óÜ   • [        U[        5      (       d  [        $ U R                  UR                  :w  a'  [	        SU R                  < SUR                  < 35      eU R                  U5      $ )NúMatrix size mismatch: z + )rÙ   r   ÚNotImplementedr'   r   r   ©r€   ÚBs     r   Ú__add__ÚSDM.__add__í  óJ   € Ü˜!œS×!Ñ!Ü!Ð!Ø�W‰W˜Ÿ™ÓÝÀ!Ç'Ä'È1Ï7Ë7ÐSÓTÐTØ�u‰u�Q‹xˆr1   c                 óÜ   • [        U[        5      (       d  [        $ U R                  UR                  :w  a'  [	        SU R                  < SUR                  < 35      eU R                  U5      $ )Nré   z - )rÙ   r   rê   r'   r   r   rë   s     r   Ú__sub__ÚSDM.__sub__ô  rï   r1   c                 ó"   • U R                  5       $ rB   )r   ©r€   s    r   Ú__neg__ÚSDM.__neg__û  s   € Ø�u‰u‹wˆr1   c                 óš   • [        U[        5      (       a  U R                  U5      $ XR                  ;   a  U R	                  U5      $ [
        $ )zA * B)rÙ   r   Úmatmulr*   r   rê   rë   s     r   Ú__mul__ÚSDM.__mul__þ  s9   € ä�aœ×ÑØ—8‘8˜A“;ÐØ—(‘(‹]Ø—5‘5˜“8ˆOä!Ð!r1   c                 óN   • XR                   ;   a  U R                  U5      $ [        $ rB   )r*   Úrmulrê   )ÚaÚbs     r   Ú__rmul__ÚSDM.__rmul__  s   € Ø—‘‹=Ø—6‘6˜!“9Ðä!Ð!r1   c                 óú   • U R                   UR                   :w  a  [        eU R                  u  p#UR                  u  pEX4:w  a  [        e[	        XU R                   X%5      nU R                  XbU4U R                   5      $ )aà  
Performs matrix multiplication of two SDM matrices

Parameters
==========

A, B: SDM to multiply

Returns
=======

SDM
    SDM after multiplication

Raises
======

DomainError
    If domain of A does not match
    with that of B

Examples
========

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> B = SDM({0:{0:ZZ(2), 1:ZZ(3)}, 1:{0:ZZ(4)}}, (2, 2), ZZ)
>>> A.matmul(B)
{0: {0: 8}, 1: {0: 2, 1: 3}}

)r*   r   r'   r   Ú
sdm_matmulrF   )r€   rì   r   r$   Ún2ÚoÚCs          r   rø   Ú
SDM.matmul  sg   € ðB �8‰8�q—x‘xÓÜÐØ�w‰w‰ˆØ—‘‰ˆØ‹7ÜÐÜ�q˜QŸX™X qÓ,ˆØ�u‰u�Q˜A˜ §¡Ó)Ð)r1   c                 óp   ^• [        U U4S j5      nU R                  X R                  U R                  5      $ )zæ
Multiplies each element of A with a scalar b

Examples
========

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> A.mul(ZZ(3))
{0: {1: 6}, 1: {0: 3}}

c                 ó   >• U T-  $ rB   r   ©Úaijrþ   s    €r   r‰   ÚSDM.mul.<locals>.<lambda>E  s	   ø€ ¨¨Aªr1   ©Ú	unop_dictrF   r'   r*   ©r€   rþ   ÚCsdms    ` r   r   ÚSDM.mul7  s+   ø€ ô ˜Ô-Ó.ˆØ�u‰u�TŸ7™7 A§H¡HÓ-Ð-r1   c                 óp   ^• [        U U4S j5      nU R                  X R                  U R                  5      $ )Nc                 ó   >• TU -  $ rB   r   r	  s    €r   r‰   ÚSDM.rmul.<locals>.<lambda>I  s	   ø€ ¨¨#ªr1   r  r  s    ` r   rü   ÚSDM.rmulH  s)   ø€ Ü˜Ô-Ó.ˆØ�u‰u�TŸ7™7 A§H¡HÓ-Ð-r1   c                 ó*  ^• U R                   UR                   :w  a  [        eU R                  UR                  :w  a  [        eU R                   R                  mU4S jn[        X[        X"5      nU R                  X0R                  U R                   5      $ )Nc                 ó   >• T$ rB   r   )rM   r5   s    €r   r‰   Ú%SDM.mul_elementwise.<locals>.<lambda>R  s   ø€ ™$r1   )r*   r   r'   r   r5   Ú
binop_dictr   rF   )r€   rì   Úfzeror  r5   s       @r   Úmul_elementwiseÚSDM.mul_elementwiseL  sh   ø€ Ø�8‰8�q—x‘xÓÜÐØ�7‰7�a—g‘gÓÜÐØ�x‰x�}‰}ˆÜˆÜ˜!¤ UÓ2ˆØ�u‰u�TŸ7™7 A§H¡HÓ-Ð-r1   c                 ó‚   • [        X[        [        [        5      nU R                  X R                  U R
                  5      $ )a  

Adds two :py:class:`~.SDM` matrices

Examples
========

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> B = SDM({0:{0: ZZ(3)}, 1:{1:ZZ(4)}}, (2, 2), ZZ)
>>> A.add(B)
{0: {0: 3, 1: 2}, 1: {0: 1, 1: 4}}

)r  r   r   rF   r'   r*   ©r€   rì   r  s      r   r   ÚSDM.addV  ó-   € ô  ˜!¤¤S¬#Ó.ˆØ�u‰u�TŸ7™7 A§H¡HÓ-Ð-r1   c                 ó‚   • [        X[        [        [        5      nU R	                  X R
                  U R                  5      $ )a#  

Subtracts two :py:class:`~.SDM` matrices

Examples
========

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> B  = SDM({0:{0: ZZ(3)}, 1:{1:ZZ(4)}}, (2, 2), ZZ)
>>> A.sub(B)
{0: {0: -3, 1: 2}, 1: {0: 1, 1: -4}}

)r  r   r   r   rF   r'   r*   r  s      r   r   ÚSDM.subi  r  r1   c                 ón   • [        U [        5      nU R                  XR                  U R                  5      $ )zê

Returns the negative of a :py:class:`~.SDM` matrix

Examples
========

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> A.neg()
{0: {1: -2}, 1: {0: -1}}

)r  r   rF   r'   r*   )r€   r  s     r   r   ÚSDM.neg|  s)   € ô ˜œCÓ ˆØ�u‰u�TŸ7™7 A§H¡HÓ-Ð-r1   c                 ó¤   ^^• U R                   mTT:X  a  U R                  5       $ [        U UU4S j5      nU R                  X R                  T5      $ )a  
Converts the :py:class:`~.Domain` of a :py:class:`~.SDM` matrix to K

Examples
========

>>> from sympy import ZZ, QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> A.convert_to(QQ)
{0: {1: 2}, 1: {0: 1}}

c                 ó(   >• TR                  U T5      $ rB   )Úconvert_from)rM   ÚKÚKolds    €€r   r‰   Ú SDM.convert_to.<locals>.<lambda>Ÿ  s   ø€  A§N¡N°1°dÔ$;r1   )r*   rY   r  rF   r'   )r€   r'  ÚAkr(  s    ` @r   Ú
convert_toÚSDM.convert_toŽ  sB   ù€ ð �x‰xˆØ�‹9Ø—6‘6“8ˆOÜ�qÕ;Ó<ˆØ�u‰u�RŸ™ !Ó$Ð$r1   c                 óP   • [        [        [        U R                  5       5      5      $ )a!  Number of non-zero elements in the :py:class:`~.SDM` matrix.

Examples
========

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ)
>>> A.nnz()
2

See Also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.nnz
)ÚsumÚmaprG   r,   rô   s    r   ÚnnzÚSDM.nnz¢  s   € ô" ”3”s˜AŸH™H›JÓ'Ó(Ð(r1   c           
      ó¸   • U R                   u  pX:X  d   e[        U5      nU Vs0 s H  oD[        U R                  U/ 5      5      _M      nn[	        X55      $ s  snf )a#  Strongly connected components of a square matrix *A*.

Examples
========

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0: ZZ(2)}, 1:{1:ZZ(1)}}, (2, 2), ZZ)
>>> A.scc()
[[0], [1]]

See also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.scc
)r'   rC   rT   r<   r   )r€   r(   r)   ÚVrß   ÚEmaps         r   ÚsccÚSDM.sccµ  sX   € ð" —W‘W‰
ˆØ‹|Ðˆ|Ü�$‹KˆÙ/0Ó1ªq¨!”4˜Ÿ™˜a ›Ó%Ò%©qˆÐ1Ü-¨aÓ6Ð6ùò 2s   ¥%Ac                 ón   • [        U 5      u  pnU R                  XR                  U R                  5      U4$ )a  

Returns reduced-row echelon form and list of pivots for the :py:class:`~.SDM`

Examples
========

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(2), 1:QQ(4)}}, (2, 2), QQ)
>>> A.rref()
({0: {0: 1, 1: 2}}, [0])

)Ú	sdm_irrefrF   r'   r*   )r€   rì   Úpivotsr•   s       r   ÚrrefÚSDM.rrefÌ  s/   € ô ! “|‰ˆ�1Ø�u‰u�QŸ™ §¡Ó*¨FÐ2Ð2r1   c                 óŠ   • U R                   n[        X5      u  p#nU R                  X R                  U R                   5      nXSU4$ )a  

Returns reduced-row echelon form (RREF) with denominator and pivots.

Examples
========

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(2), 1:QQ(4)}}, (2, 2), QQ)
>>> A.rref_den()
({0: {0: 1, 1: 2}}, 1, [0])

)r*   Úsdm_rref_denrF   r'   )r€   r'  Ú
A_rref_sdmÚdenomr9  ÚA_rrefs         r   Úrref_denÚSDM.rref_denÞ  s?   € ð �H‰HˆÜ$0°Ó$6Ñ!ˆ
˜6Ø—‘�z§7¡7¨A¯H©HÓ5ˆØ˜fÐ$Ð$r1   c                 óZ   • U R                  5       R                  5       R                  5       $ )zö

Returns inverse of a matrix A

Examples
========

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ)
>>> A.inv()
{0: {0: -2, 1: 1}, 1: {0: 3/2, 1: -1/2}}

)rÐ   ÚinvrÉ   rô   s    r   rD  ÚSDM.invò  s#   € ð �‰Ó ×$Ñ$Ó&×-Ñ-Ó/Ð/r1   c                 ó>   • U R                  5       R                  5       $ )zÊ
Returns determinant of A

Examples
========

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ)
>>> A.det()
-2

)rÐ   Údetrô   s    r   rG  ÚSDM.det  s   € ð* �‰Ó ×$Ñ$Ó&Ð&r1   c                 óŠ   • U R                  5       R                  5       u  pnU R                  U5      U R                  U5      U4$ )a  

Returns LU decomposition for a matrix A

Examples
========

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ)
>>> A.lu()
({0: {0: 1}, 1: {0: 3, 1: 1}}, {0: {0: 1, 1: 2}, 1: {1: -2}}, [])

)rÆ   Úlur‘   )r€   ÚLÚUÚswapss       r   rJ  ÚSDM.lu  s6   € ð —h‘h“j—m‘m“o‰ˆˆeØ�z‰z˜!‹}˜aŸj™j¨›m¨UÐ2Ð2r1   c                 óˆ   • U R                  5       R                  5       u  pUR                  5       nUR                  5       nX44$ )zŒ
QR decomposition for SDM (Sparse Domain Matrix).

Returns:
    - Q: Orthogonal matrix as a SDM.
    - R: Upper triangular matrix as a SDM.
)rÆ   ÚqrrÉ   )r-   Úddm_qÚddm_rÚQÚRs        r   rP  ÚSDM.qr,  s7   € ð —{‘{“}×'Ñ'Ó)‰ˆØ�L‰L‹NˆØ�L‰L‹NˆØˆtˆr1   c                 óz   • U R                  U R                  5       R                  UR                  5       5      5      $ )a  

Uses LU decomposition to solve Ax = b,

Examples
========

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ)
>>> b = SDM({0:{0:QQ(1)}, 1:{0:QQ(2)}}, (2, 1), QQ)
>>> A.lu_solve(b)
{1: {0: 1/2}}

)r‘   rÆ   Úlu_solve)r€   rþ   s     r   rW  ÚSDM.lu_solve9  s*   € ð  �z‰z˜!Ÿ(™(›*×-Ñ-¨a¯h©h«jÓ9Ó:Ð:r1   c                 óÌ   • U R                  5       R                  5       u  pp4UR                  5       nUR                  5       nUR                  5       nUR                  5       nXVXx4$ )zx
Fraction free LU decomposition of SDM.

Uses DDM implementation.

See Also
========

sympy.polys.matrices.ddm.DDM.fflu
)rÐ   ÚfflurÉ   )	r-   Úddm_pÚddm_lÚddm_dÚddm_uÚPrK  ÚDrL  s	            r   rZ  ÚSDM.ffluK  sV   € ð &*×%7Ñ%7Ó%9×%>Ñ%>Ó%@Ñ"ˆ�eØ�L‰L‹NˆØ�L‰L‹NˆØ�L‰L‹NˆØ�L‰L‹NˆØ�QˆzÐr1   c                 ó  • U R                   S   nU R                  R                  n[        U 5      u  p4n[	        X2XU5      u  pg[        [        U5      5      n[        U5      U4nU R                  XhU R                  5      U4$ )a(  
Nullspace of a :py:class:`~.SDM` matrix A.

The domain of the matrix must be a field.

It is better to use the :meth:`~.DomainMatrix.nullspace` method rather
than this method which is otherwise no longer used.

Examples
========

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0: QQ(2), 1: QQ(4)}}, (2, 2), QQ)
>>> A.nullspace()
({0: {0: -2, 1: 1}}, [1])


See Also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.nullspace
    The preferred way to get the nullspace of a matrix.

r   )	r'   r*   rÕ   r8  Úsdm_nullspace_from_rrefry   rU   rG   rF   )	r€   ÚncolsrÕ   rì   r9  Únzcolsr'  Ú	nonpivotsr'   s	            r   Ú	nullspaceÚSDM.nullspace]  sq   € ð4 —‘˜‘
ˆØ�h‰h�l‰lˆÜ% a›LÑˆ�6Ü.¨q°uÀfÓM‰ˆÜ”˜1“ÓˆÜ�Q“˜�ˆØ�u‰u�Q˜qŸx™xÓ(¨)Ð3Ð3r1   c                 óP  • U R                   u  p#U R                  nUc'  [        [        [        U R                  5       5      5      nU(       d'  U R                  X34U5      [        [        U5      5      4$ [        U5      U:X  a  U R                  SU4U5      / 4$ U S   US      nUR                  U5      (       a   e[        U5      n[        [        5      nU R                  5        H2  u  p‰U	R                  5        H  u  p«Xz   R                  X‹45        M     M4     / n/ n[        U5       HD  n
X¦;   a  M
  UR                  U
5        X¥0nXz    H  u  pûU* XáU   '   M     UR                  U5        MF     [!        [#        U5      5      nU R%                  U[        U5      U4U5      nUU4$ )aŒ  
Returns nullspace for a :py:class:`~.SDM` matrix ``A`` in RREF.

The domain of the matrix can be any domain.

The matrix must already be in reduced row echelon form (RREF).

Examples
========

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0: QQ(2), 1: QQ(4)}}, (2, 2), QQ)
>>> A_rref, pivots = A.rref()
>>> A_null, nonpivots = A_rref.nullspace_from_rref(pivots)
>>> A_null
{0: {0: -2, 1: 1}}
>>> pivots
[0]
>>> nonpivots
[1]

See Also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.nullspace
    The higher-level function that would usually be called instead of
    calling this one directly.

sympy.polys.matrices.domainmatrix.DomainMatrix.nullspace_from_rref
    The higher-level direct equivalent of this function.

sympy.polys.matrices.ddm.DDM.nullspace_from_rref
    The equivalent function for dense :py:class:`~.DDM` matrices.

r   )r'   r*   Úsortedr/  rR   r,   rÛ   rT   rC   rG   rQ   Úis_zerorW   r   rD   rV   ry   rU   rF   )r€   r9  r   r$   r'  Ú	pivot_valÚ
pivots_setÚnonzero_colsr7   r�   r8   ÚAijÚbasisrf  ÚvecÚiprL   ÚA_nulls                     r   Únullspace_from_rrefÚSDM.nullspace_from_rref  s‡  € ðJ �w‰w‰ˆØ�H‰Hˆà‰>ÜœC¤ Q§X¡X£ZÓ0Ó1ˆFæØ—5‘5˜!˜ Ó#¤T¬%°«(£^Ð3Ð3Ü�‹[˜AÓØ—7‘7˜A˜q˜6 1Ó% rÐ)Ð)ð �a‘D˜ ™‘Oˆ	Ø—9‘9˜Y×'Ñ'Ð'Ð'ä˜“[ˆ
ô
 #¤4Ó(ˆØ—W‘W–Y‰EˆAØŸ(™(ž*‘�Ø‘×&Ñ&¨ xÖ0ó %ñ ð ˆØˆ	Ü�q–ˆAØ‹ÙØ×Ñ˜QÔà�.ˆCØ'œ?‘�Ø#& $�˜2‘J“ñ +ð �L‰L˜Öñ ô ”9˜UÓ#Ó$ˆØ—‘�sœS ›Z¨˜O¨QÓ/ˆà˜	Ð"Ð"r1   c                 ó²   • U R                   S   n[        U 5      u  p#n[        X!U5      nU(       a  SU0O0 nU R                  USUS-
  4U R                  5      $ )Nr   r   )r'   r8  Úsdm_particular_from_rrefrF   r*   )r€   rd  rì   r9  re  r_  Úreps          r   Ú
particularÚSDM.particularÖ  sU   € Ø—‘˜‘
ˆÜ% a›LÑˆ�6Ü$ Q¨vÓ6ˆÞˆq�‰e˜bˆØ�u‰u�S˜1˜e A™g˜,¨¯©Ó1Ð1r1   c                 ó²  • [        U R                  5       5      nU R                  u  p4U R                  nU H�  nUR                  u  pxXs:X  d   eUR                  U:X  d   eUR	                  5        H?  u  pšUR                  U	S5      nUc  0 =X)'   nU
R	                  5        H  u  pÍXÛXÄ-   '   M     MA     XH-  nMƒ     U R                  X#U4U R                  5      $ )a'  Horizontally stacks :py:class:`~.SDM` matrices.

Examples
========

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM

>>> A = SDM({0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}, (2, 2), ZZ)
>>> B = SDM({0: {0: ZZ(5), 1: ZZ(6)}, 1: {0: ZZ(7), 1: ZZ(8)}}, (2, 2), ZZ)
>>> A.hstack(B)
{0: {0: 1, 1: 2, 2: 5, 3: 6}, 1: {0: 3, 1: 4, 2: 7, 3: 8}}

>>> C = SDM({0: {0: ZZ(9), 1: ZZ(10)}, 1: {0: ZZ(11), 1: ZZ(12)}}, (2, 2), ZZ)
>>> A.hstack(B, C)
{0: {0: 1, 1: 2, 2: 5, 3: 6, 4: 9, 5: 10}, 1: {0: 3, 1: 4, 2: 7, 3: 8, 4: 11, 5: 12}}
N)ry   rY   r'   r*   rD   r<   rF   )r€   rì   ÚAnewr(   r)   r*   ÚBkÚBkrowsÚBkcolsr7   ÚBkir�   r8   ÚBkijs                 r   ÚhstackÚ
SDM.hstackÝ  sÊ   € ô$ �A—F‘F“H‹~ˆØ—W‘W‰
ˆØ—‘ˆãˆBØŸX™X‰NˆFØ“>Ð!�>Ø—9‘9 Ó&Ð&Ð&àŸ(™(ž*‘�Ø—X‘X˜a Ó&�Ø‘:Ø#%Ð%�D‘G˜bØ"Ÿy™yž{‘G�AØ#'�q‘x“Ló  +ñ	 %ð ‰NŠDñ ð �u‰u�T $˜<¨¯©Ó2Ð2r1   c                 óJ  • [        U R                  5       5      nU R                  u  p4U R                  nU HM  nUR                  u  pxX„:X  d   eUR                  U:X  d   eUR	                  5        H  u  pšX¢X“-   '   M     X7-  nMO     U R                  X#U4U R                  5      $ )aC  Vertically stacks :py:class:`~.SDM` matrices.

Examples
========

>>> from sympy import ZZ
>>> from sympy.polys.matrices.sdm import SDM

>>> A = SDM({0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}, (2, 2), ZZ)
>>> B = SDM({0: {0: ZZ(5), 1: ZZ(6)}, 1: {0: ZZ(7), 1: ZZ(8)}}, (2, 2), ZZ)
>>> A.vstack(B)
{0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}, 2: {0: 5, 1: 6}, 3: {0: 7, 1: 8}}

>>> C = SDM({0: {0: ZZ(9), 1: ZZ(10)}, 1: {0: ZZ(11), 1: ZZ(12)}}, (2, 2), ZZ)
>>> A.vstack(B, C)
{0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}, 2: {0: 5, 1: 6}, 3: {0: 7, 1: 8}, 4: {0: 9, 1: 10}, 5: {0: 11, 1: 12}}
)ry   rY   r'   r*   rD   rF   )r€   rì   r|  r(   r)   r*   r}  r~  r  r7   r€  s              r   ÚvstackÚ
SDM.vstack  s•   € ô$ �A—F‘F“H‹~ˆØ—W‘W‰
ˆØ—‘ˆãˆBØŸX™X‰NˆFØ“>Ð!�>Ø—9‘9 Ó&Ð&Ð&àŸ(™(ž*‘�Ø!$�Q‘X“ñ %à‰NŠDñ ð �u‰u�T $˜<¨¯©Ó2Ð2r1   c                 óø   • U R                  5        VVVVs0 s H0  u  p4X4R                  5        VVs0 s H  u  pVXQ" U5      _M     snn_M2     nnnnnU R                  XpR                  U5      $ s  snnf s  snnnnf rB   )rD   rF   r'   )r-   Úfuncr*   r7   r"   r8   rM   rL   s           r   Ú	applyfuncÚSDM.applyfunc#  s]   € ØEIÇZÁZÄ\ÖRÂ\¹6¸1ˆq¯)©)¬+Ô6ª+¡$ !�1�d˜1“g’:©+Ò6Ò6Á\ˆÓRØ�x‰x˜ŸZ™Z¨Ó0Ð0ùó 7ùÕRs   –A4
±A.ÁA4
Á.A4
c                 ó²   • U R                   nU R                  u  p#[        XU5      nUR                  /US-   -  nUR	                  5        H	  u  pgXuU'   M     U$ )ar  
Returns the coefficients of the characteristic polynomial
of the :py:class:`~.SDM` matrix. These elements will be domain elements.
The domain of the elements will be same as domain of the :py:class:`~.SDM`.

Examples
========

>>> from sympy import QQ, Symbol
>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy.polys import Poly
>>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ)
>>> A.charpoly()
[1, -5, -2]

We can create a polynomial using the
coefficients using :py:class:`~.Poly`

>>> x = Symbol('x')
>>> p = Poly(A.charpoly(), x, domain=A.domain)
>>> p
Poly(x**2 - 5*x - 2, x, domain='QQ')

r   )r*   r'   Úsdm_berkr5   rD   )r€   r'  r$   r•   ÚpdictÚplistr7   Úpis           r   ÚcharpolyÚSDM.charpoly'  sV   € ð2 �H‰HˆØ�w‰w‰ˆÜ˜˜qÓ!ˆØ—‘�˜A ™EÑ"ˆØ—[‘[–]‰EˆAØ�!‹Hñ #àˆr1   c                 ó   • U (       + $ )z0
Says whether this matrix has all zero entries.
r   ©r-   s    r   Úis_zero_matrixÚSDM.is_zero_matrixH  s   € ð Œxˆr1   c                 óB   • [        S U R                  5        5       5      $ )zf
Says whether this matrix is upper-triangular. True can be returned
even if the matrix is not square.
c              3   óB   #   • U  H  u  pU  H	  o1U:*  v •  M     M     g 7frB   r   ©r   r7   r"   r8   s       r   r   ÚSDM.is_upper.<locals>.<genexpr>S  ó   é € ÐBª™f˜a¼c¸˜–6¹c‘6ªùó   ‚©r+   rD   r“  s    r   Úis_upperÚSDM.is_upperN  ó   € ô
 ÑB¨¯
©
¬ÓBÓBÐBr1   c                 óB   • [        S U R                  5        5       5      $ )zf
Says whether this matrix is lower-triangular. True can be returned
even if the matrix is not square.
c              3   óB   #   • U  H  u  pU  H	  o1U:¬  v •  M     M     g 7frB   r   r˜  s       r   r   ÚSDM.is_lower.<locals>.<genexpr>Z  rš  r›  rœ  r“  s    r   Úis_lowerÚSDM.is_lowerU  rŸ  r1   c                 óB   • [        S U R                  5        5       5      $ )z^
Says whether this matrix is diagonal. True can be returned
even if the matrix is not square.
c              3   óB   #   • U  H  u  pU  H	  o1U:H  v •  M     M     g 7frB   r   r˜  s       r   r   Ú"SDM.is_diagonal.<locals>.<genexpr>a  rš  r›  rœ  r“  s    r   Úis_diagonalÚSDM.is_diagonal\  rŸ  r1   c                 óÌ   • U R                   u  pU R                  R                  nU R                  5        VVs/ s H  u  pEXB:  d  M  UR	                  XC5      PM     snn$ s  snnf )z/
Returns the diagonal of the matrix as a list.
)r'   r*   r5   rD   r<   )r-   r   r$   r5   r7   r"   s         r   rÞ   ÚSDM.diagonalc  sN   € ð �z‰z‰ˆØ�{‰{×ÑˆØ/3¯z©z¬|ÔEª|¡V Q¸q¹uÓ �—‘˜Ö ©|ÒEÐEùÓEs   ¸A ÁA é   é   c                 óX   • U R                  5       R                  US9R                  5       $ )zA
Returns the LLL-reduced basis for the :py:class:`~.SDM` matrix.
©Údelta)rÐ   ÚlllrÉ   )r€   r°  s     r   r±  ÚSDM.lllk  s(   € ð �‰Ó ×$Ñ$¨5Ð$Ð1×8Ñ8Ó:Ð:r1   c                 ó€   • U R                  5       R                  US9u  p#UR                  5       UR                  5       4$ )z:
Returns the LLL-reduced basis and transformation matrix.
r¯  )rÐ   Úlll_transformrÉ   )r€   r°  ÚreducedÚ	transforms       r   r´  ÚSDM.lll_transformq  s<   € ð Ÿ_™_Ó.×<Ñ<À5Ð<ÐIÑˆØ�~‰~Ó ×!1Ñ!1Ó!3Ð3Ð3r1   )r)   r*   r(   r'   rB   )Qrx   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚfmtÚis_DFMÚis_DDMr&   r9   r?   rN   rg   rr   rz   ÚclassmethodrF   rY   rŽ   r‘   r–   rš   r¡   r©   r®   r±   r¶   r¤   r­   r¿   rÂ   rÆ   rÉ   r
   rÍ   rÐ   rQ   rÖ   rÛ   rà   ræ   rí   rñ   rõ   rù   rÿ   rø   r   rü   r  r   r   r   r+  r0  r5  r:  rA  rD  rG  rJ  rP  rW  rZ  rg  rt  ry  r‚  r…  r‰  r�  r”  r�  r£  r¨  rÞ   r   r±  r´  Ú__static_attributes__Ú__classcell__)r/   s   @r   r   r      sl  ø† ñ.ð` €CØ€FØ€Fõ9ò7ò$ò*>ò$CòL+òGð
 ñ'ó ð'ò8,ð& ñ,'ó ð,'ð\ ñ9ó ð9ò6ò0ð> ñ'ó ð'òB#ðJ ñ0ó ð0ò$7ð* ñ'ó ð'ò:Kð. ñ'ó ð'ò<$ò" ò,3ò ñ  g YÑ/ñ#ó 0ð#ñ,  g YÑ/ñ*ó 0ð*ð0 ñ&ó ð&ð, ñ'ó ð'ð ñ.ó ð.ð0 ó'ó ð'ò2ò$òòò"ò"ò(*òT.ò".ò.ò.ò&.ò&.ò$%ò()ò&7ò.3ò$%ò(0ò"'ò.3ò$ò;ò$ò$ 4ôDU#òn2ò#3òJ3òB1òòBòCòCòCòFñ ˜˜1“Xô ;ñ  " ! Q›x÷ 4ò 4r1   r   c                 ó¦  • [        U 5      [        U5      pe0 nXV-   H—  nX   X   p©0 n[        U	5      [        U
5      pÜXÍ-   H  nU" Xž   X®   5      nU(       d  M  XûU'   M     XÍ-
   H  nU" Xž   5      nU(       d  M  XûU'   M     XÜ-
   H  nU" X®   5      nU(       d  M  XûU'   M     U(       d  M“  X·U'   M™     XV-
   HE  nX   n	0 nU	R                  5        H  u  nnU" U5      nU(       d  M  XûU'   M     U(       d  MA  X·U'   MG     Xe-
   HE  nX   n
0 nU
R                  5        H  u  nnU" U5      nU(       d  M  XûU'   M     U(       d  MA  X·U'   MG     U$ rB   )rW   rD   )r€   rì   ÚfabÚfaÚfbÚAnzÚBnzr  r7   r�   ÚBiÚCiÚAnziÚBnzir8   ÚCijro  ÚBijs                     r   r  r  y  sj  € Ü�1‹v”s˜1“vˆØ
€AàŒYˆØ‘�q‘tˆBØˆÜ˜“Wœc "›gˆdØ”ˆAÙ�b‘e˜R™UÓ#ˆCßˆsØ�1“ñ ð ”ˆAÙ�R‘U“)ˆCßˆsØ�1“ñ ð ”ˆAÙ�R‘U“)ˆCßˆsØ�1“ñ ÷ ˆ2Øˆa‹Dñ# ð& ŒYˆØ‰TˆØˆØ—h‘h–j‰FˆAˆsÙ�S“'ˆCßˆsØ�1“ñ !÷ ˆ2Øˆa‹Dñ ð ŒYˆØ‰TˆØˆØ—h‘h–j‰FˆAˆsÙ�S“'ˆCßˆsØ�1“ñ !÷ ˆ2Øˆa‹Dñ ð €Hr1   c                 ó¶   • 0 nU R                  5        HB  u  p40 nUR                  5        H  u  pgU" U5      nU(       d  M  X…U'   M     U(       d  M>  XRU'   MD     U$ rB   r¹   )	r€   Úfrì   r7   r�   rÈ  r8   ro  rÍ  s	            r   r  r  §  sZ   € Ø
€AØ—‘–‰ˆØˆØ—h‘h–j‰FˆAÙ�C“&ˆCßˆsØ�1“ñ !÷ ˆ2Øˆa‹Dñ ð €Hr1   c                 óª   • 0 nU R                  5        H&  u  p#UR                  5        H  u  pE XQU   U'   M     M(     U$ ! [         a	    X%0X'    M)  f = frB   )rD   r4   )r”   rå   r7   ÚMir8   ÚMijs         r   rä   rä   ´  s\   € Ø	€BØ—‘–‰ˆØ—h‘h–j‰FˆAð!Ø�1‘�a“ó !ñ ð €Iøô ó !Ø˜�”ð!ús   ®?¿AÁAc                 ó|   ^ ^• UR                  U U4S jT R                  5       TR                  5       -   5       5      $ )Nc              3   ó:   >#   • U  H  nTU   TU   -  v •  M     g 7frB   r   )r   r8   r€   rì   s     €€r   r   Úsdm_dotvec.<locals>.<genexpr>À  s   øé € Ð:Ò&9 ��1‘˜˜!™–Ò&9ùs   ƒ)r.  rX   )r€   rì   r'  s   `` r   Ú
sdm_dotvecrÖ  ¿  s)   ù€ Ø�5‰5Õ: a§f¡f£h°·±³Ò&9Ó:Ó:Ð:r1   c                 ón   • 0 nU R                  5        H  u  pE[        XQU5      nU(       d  M  XcU'   M      U$ rB   )rD   rÖ  )r€   rì   r'  r  r7   r�   rÉ  s          r   Úsdm_matvecmulrØ  Ã  s8   € Ø
€AØ—‘–‰ˆÜ˜˜qÓ!ˆßˆ2Øˆa‹Dñ ð €Hr1   c                 ó°  • UR                   (       a  [        XX#U5      $ 0 n[        U5      nU R                  5        H–  u  px0 n	[        U5      n
X¦-   Ho  nX‹   nX   R                  5        HR  u  pÞU	R	                  US 5      nUb'  XüU-  -   nU(       a  XùU'   M.  U	R                  U5        MA  XÎ-  nU(       d  MN  XùU'   MT     Mq     U	(       d  M’  X•U'   M˜     U$ rB   )Úis_EXRAWÚsdm_matmul_exrawrW   rD   r<   Úpop)r€   rì   r'  r   r  r  ÚB_knzr7   r�   rÉ  ÚAi_knzÚkÚAikr8   ÚBkjrÌ  s                   r   r  r  Ì  sË   € ð" 	‡z‡zÜ  a¨AÓ.Ð.à
€AÜ�‹F€EØ—‘–‰ˆØˆÜ�R“ˆØ”ˆAØ‘%ˆCØ™$Ÿ*™*ž,‘�Ø—f‘f˜Q “o�Ø‘?Ø c¡	™/�CÞØ #˜1›àŸ™˜qž	à™)�Cß�sØ #˜1›ó 'ñ  ÷ ˆ2Øˆa‹Dñ% ð& €Hr1   c           
      óx  • UR                   n0 n[        U5      nU R                  5        GH*  u  p‰[        [        5      n
[        U	5      nX·-   Hz  nXœ   nX]-  U:X  a2  X   R                  5        H  u  pïX®   R                  Xß-  5        M     MA  [        U5       H*  nX®   R                  XÑU   R                  Xå5      -  5        M,     M|     X·-
   H7  nXYU   -  nUU:w  d  M  [        U5       H  nX®   R                  U5        M     M9     0 nU
R                  5        H%  u  nnUR                  U5      nU(       d  M   UUU'   M'     U(       d  GM&  UXh'   GM-     UR                  5        HÍ  u  nnUR                  5        H³  u  pïX_-  U:w  d  M  [        U5       H•  nU R                  U0 5      R                  XÅ5      nXÕ:X  d  M+  UR                  U0 5      nUR                  Xå5      Xß-  -   nUU:w  a  UUU'   UXh'   Md  UR                  US 5        U(       a  UXh'   Mƒ  UR                  US 5        M—     Mµ     MÏ     U$ rB   )
r5   rW   rD   r   rT   rV   rC   r<   r.  rÜ  )r€   rì   r'  r   r  r5   r  rÝ  r7   r�   ÚCi_listrÞ  rß  rà  r8   rá  ÚzAikrÉ  ÚCij_listrÌ  r}  s                        r   rÛ  rÛ  ø  sü  € ð �6‰6€DØ
€AÜ�‹F€EØ—‘—‰ˆÜœdÓ#ˆÜ�R“ˆð ”ˆAØ‘%ˆCØ‰z˜TÓ!à™dŸj™jžl‘F�AØ‘J×%Ñ% c¡iÖ0ó +ô ˜qž�AØ‘J×%Ñ% c¨a©D¯H©H°QÓ,=Ñ&=Ö>ó "ñ  ð ”ˆAØ˜Q™%‘<ˆDØ�t�|Ü˜qž�AØ‘J×%Ñ% dÖ+ó "ñ  ð ˆØ"Ÿ=™=ž?‰KˆAˆxØ—%‘%˜“/ˆCßˆsØ��1“ñ +÷ ‰2ØˆAŒDñ; ð@ —‘–‰ˆˆ2Ø—h‘h–j‰FˆAØ‰z˜TÕ!Ü˜qž�AØŸ%™%  2›,×*Ñ*¨1Ó3�Cà•{ØŸU™U 1 b›\˜Ø Ÿf™f Q›o°±	Ñ9˜Ø $›;Ø$'˜B˜q™EØ#%˜A›DàŸF™F 1 dœOÞ!Ø') £à !§¡ a¨¦ó "ó !ñ ð& €Hr1   c                 óü  • [        S U R                  5        5       [        S9n0 n[        5       n[        5       n[	        [        5      nU(       Gax  UR                  5       nUR                  5        VVs0 s H  u  pxXs;  d  M  Xx_M     nnnU[        U5      -   H�  nX'   n	Xg   n[        U5      n
[        U	5      nXº-
   H  nU* Xœ   -  Xl'   M     UR                  U5        U
R                  U5        Xº-   H-  nXl   X‰U   -  -
  nU(       a  XÖU'   M  UR                  U5        M/     M�     U(       d  Më  [        U5      nXg   nXbU'   [        U5      n
US-  nU H  nXo==   U-  ss'   M     UR                  US5       Hè  nX,   nUU   n[        U5      nU
U-
   H!  nU* Xo   -  UU'   X_   R                  U5        M#     UR                  U5        UR                  U5        U
U-   HI  nUU   UXo   -  -
  nU(       a  UUU'   M  UR                  U5        X÷:w  d  M6  X_   R                  U5        MK     [        U5      S:X  d  MÆ  UR                  U5        UR                  U5        Mê     [        U5      S:X  a  UR                  U5        O4UR                  U5        U H  nX÷:w  d  M
  X_   R                  U5        M     U(       a  GMx  [        X4-  5      n[        U5       VVs0 s H	  u  nnUU_M     nnnUR                  5        VVVs0 s H  u  nnUU Vs1 s H  nUU   iM
     sn_M     nnnnU Vs/ s H  nUU   PM
     nn[        [        U5      5      nUUU4$ s  snnf s  snnf s  snf s  snnnf s  snf )a1  RREF and pivots of a sparse matrix *A*.

Compute the reduced row echelon form (RREF) of the matrix *A* and return a
list of the pivot columns. This routine does not work in place and leaves
the original matrix *A* unmodified.

The domain of the matrix must be a field.

Examples
========

This routine works with a dict of dicts sparse representation of a matrix:

>>> from sympy import QQ
>>> from sympy.polys.matrices.sdm import sdm_irref
>>> A = {0: {0: QQ(1), 1: QQ(2)}, 1: {0: QQ(3), 1: QQ(4)}}
>>> Arref, pivots, _ = sdm_irref(A)
>>> Arref
{0: {0: 1}, 1: {1: 1}}
>>> pivots
[0, 1]

The analogous calculation with :py:class:`~.MutableDenseMatrix` would be

>>> from sympy import Matrix
>>> M = Matrix([[1, 2], [3, 4]])
>>> Mrref, pivots = M.rref()
>>> Mrref
Matrix([
[1, 0],
[0, 1]])
>>> pivots
(0, 1)

Notes
=====

The cost of this algorithm is determined purely by the nonzero elements of
the matrix. No part of the cost of any step in this algorithm depends on
the number of rows or columns in the matrix. No step depends even on the
number of nonzero rows apart from the primary loop over those rows. The
implementation is much faster than ddm_rref for sparse matrices. In fact
at the time of writing it is also (slightly) faster than the dense
implementation even if the input is a fully dense matrix so it seems to be
faster in all cases.

The elements of the matrix should support exact division with ``/``. For
example elements of any domain that is a field (e.g. ``QQ``) should be
fine. No attempt is made to handle inexact arithmetic.

See Also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.rref
    The higher-level function that would normally be used to call this
    routine.
sympy.polys.matrices.dense.ddm_irref
    The dense equivalent of this routine.
sdm_rref_den
    Fraction-free version of this routine.
c              3   ó@   #   • U  H  oR                  5       v •  M     g 7frB   )rY   )r   r�   s     r   r   Úsdm_irref.<locals>.<genexpr>“  s   é € Ð3ª
 "—G‘G—I�Iª
ùs   ‚©Úkeyrã   r   r   )rj  r,   rR   rW   r   rÜ  rD   Úremover   rG   rU   ry   )r€   ÚArowsÚpivot_row_mapÚreduced_pivotsÚnonreduced_pivotsÚnonzero_columnsr�   r8   ro  ÚAjÚAinzÚAjnzrß  rà  ÚAijinvÚlr*  ÚAkjÚAknzÚAklr9  r$   ÚpÚ	pivot2rowr#   Úsr7   r(   r:  s                                r   r8  r8  8  s[  € ôv Ñ3¨¯©¬
Ó3¼Ñ=€Eð €Mô “U€Nô ›Ðô "¤#Ó&€Oç
à�Y‰Y‹[ˆð $&§8¡8¤:ÔI¢:™˜°Ñ1H‹fˆaŠf¡:ˆÑIð #¤S¨£WÔ,ˆAØÑ!ˆBØ‘%ˆCÜ�r“7ˆDÜ�r“7ˆDØ”[�Ø˜ ¡™�“ñ !à�F‰F�1ŒIØ�K‰K˜ŒNØ”[�Ø‘e˜c q¡E™kÑ)�ÞØ�q“Eà—F‘F˜1–Ió !ñ -ö$ Ùô �‹GˆØ‰eˆØ�aÑÜ�2‹wˆð �b‘ˆÛˆAØ‹E�V‰O�Eñ ð !×$Ñ$ Q¨Ö+ˆAØÑ!ˆBØ�Q‘%ˆCÜ�r“7ˆDØ˜D”[�Ø˜ ¡™��1‘ØÑ"×&Ñ& qÖ)ñ !ð �F‰F�1ŒIØ�K‰K˜ŒNØ˜D”[�Ø˜‘e˜c B¡E™kÑ)�ÞØ�B�q“Eð —F‘F˜1”IØ•vØ'Ñ*×1Ñ1°!Ö4ñ !ô �2‹w˜!�|Ø×"Ñ" 1Ô%Ø!×(Ñ(¨Ö+ñ) ,ô, ˆr‹7�a‹<Ø×Ñ˜qÕ!à×!Ñ! !Ô$Û�Ø•6Ø#Ñ&×*Ñ*¨1Ö-ñ ÷M ‰%ôV �NÑ6Ó7€FÜ"+¨FÔ"3Ô4Ò"3™$˜!˜Q��A’Ñ"3€IÑ4Ø@O×@UÑ@UÔ@WÕXÒ@W¹¸¸1�q±Ó3²¨A˜9 Qœ<±Ñ3Ò3Ñ@W€OÒXÙ&,Ó-¢f ˆM˜!Ô¡f€DÐ-Ü”	˜$“Ó €DØ�˜Ð(Ð(ùóW JùóN 5ùÚ3ùÔXùÚ-s0   Á4M!ÂM!Ë$M'ÌM2ÌM-Ì(M2Ì7M9Í-M2c                 óˆ	  • U (       d  0 UR                   / 4$ [        U 5      S:X  a6  U R                  5       u  n[        U5      nX#   nSUR	                  5       0XC/4$ UR
                  (       a  UR                  nOUR                  n[        [        U R                  5       5      6 u  pg0 n0 n	UR                  5       n
U	R                  5       n/ nSnSn[        U[        S9nU GH  nUR                  5        VVs0 s H  u  p4X:;  d  M  X4_M     nnn0 nX²R                  5       -   Hz  nUR                  U5      nXÉU      nUR                  5        HK  u  nnUR                  U5      nUc
  UU-  UU'   M$  UUU-  -   nU(       a  UUU'   M:  UR                  U5        MM     M|     [        U5      n[        U5      nU=(       d    UR                   nUU-
   H  nUU   * UU'   M     UU-
   H  nUU   U-  UU'   M     UU-   H0  nUU   U-  UU   -
  nU(       a  UUU'   M  UR                  U5        M2     U(       d  GM[  [        U5      nUR                  U5      n[        U	R                  5       5       GH*  u  nnUU   nUU;  a2  UR                  5        H  u  nnUU-  nUb	  U" UU5      nUUU'   M     MD  UR                  U5      n[        U5      n[        U5      nUU-
   H#  nU* UU   -  UU'   Uc  M  U" UU   U5      UU'   M%     UU-
   H"  nUUU   -  UU'   Uc  M  U" UU   U5      UU'   M$     UU-   H?  nUUU   -  UUU   -  -
  nU(       a  Ub	  U" UU5      nUUU'   M.  UR                  U5        MA     U(       a  GM  U	R                  U5        UUU'   GM-     [        U5      nUR!                  U5        U(       a  UX“'   OUXƒ'   UR#                  U5      (       d
  Uc  UnOXÔ-  nUb  U" XÞ5      nUnGM     Uc  UR                   n0 UEU	En U R                  5        VVs0 s H	  u  nnUU_M     n!nn[%        U5       VVs/ s H  u  nnU!U   U4PM     n"nn[        [        U"5      6 u  n#n$[        U#5      n#[%        U$5       H  u  nnXÒU#U   '   M     ['        [%        U$5      5      n%U%UU#4$ s  snnf s  snnf s  snnf )a“  
Return the reduced row echelon form (RREF) of A with denominator.

The RREF is computed using fraction-free Gauss-Jordan elimination.

Explanation
===========

The algorithm used is the fraction-free version of Gauss-Jordan elimination
described as FFGJ in [1]_. Here it is modified to handle zero or missing
pivots and to avoid redundant arithmetic. This implementation is also
optimized for sparse matrices.

The domain $K$ must support exact division (``K.exquo``) but does not need
to be a field. This method is suitable for most exact rings and fields like
:ref:`ZZ`, :ref:`QQ` and :ref:`QQ(a)`. In the case of :ref:`QQ` or
:ref:`K(x)` it might be more efficient to clear denominators and use
:ref:`ZZ` or :ref:`K[x]` instead.

For inexact domains like :ref:`RR` and :ref:`CC` use ``ddm_irref`` instead.

Examples
========

>>> from sympy.polys.matrices.sdm import sdm_rref_den
>>> from sympy.polys.domains import ZZ
>>> A = {0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}
>>> A_rref, den, pivots = sdm_rref_den(A, ZZ)
>>> A_rref
{0: {0: -2}, 1: {1: -2}}
>>> den
-2
>>> pivots
[0, 1]

See Also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.rref_den
    Higher-level interface to ``sdm_rref_den`` that would usually be used
    instead of calling this function directly.
sympy.polys.matrices.sdm.sdm_rref_den
    The ``SDM`` method that uses this function.
sdm_irref
    Computes RREF using field division.
ddm_irref_den
    The dense version of this algorithm.

References
==========

.. [1] Fraction-free algorithms for linear and polynomial equations.
    George C. Nakos , Peter R. Turner , Robert M. Williams.
    https://dl.acm.org/doi/10.1145/271130.271133
r   r   Nré  )rÕ   rG   r,   rR   rY   Úis_ExactÚexquoÚquor¬   rj  rD   rX   rÜ  r<   rW   rT   rV   Úis_onerU   ry   )&r€   r'  r�   r8   ro  rþ  r•   Úrows_in_orderÚcol_to_row_reducedÚcol_to_row_unreducedrµ  Ú	unreducedÚA_rref_rowsr?  ÚdivisorÚA_rowsÚ	Ai_cancelrñ  rß  ÚAjkÚ
Aik_cancelÚAi_nzÚAi_cancel_nzÚdrà  Úpkr*  rõ  rø  rö  ÚAk_nzr7   Ú
col_to_rowÚ
row_to_colÚA_rref_rows_colr9  r@  r>  s&                                         r   r=  r=  ø  s  € öz Ø�A—E‘E˜2ˆÐÜ	ˆQ‹�1‹Ø�h‰h‹j‰ˆÜ�‹GˆØ‰eˆØ�B—G‘G“I�  SÐ)Ð)ð 	‡z‡zØ—‘‰à—‘ˆô œF 1§7¡7£9Ó-Ð.Ñ€AàÐØÐØ ×%Ñ%Ó'€GØ$×)Ñ)Ó+€Ið €KØ€EØ€Gô �M¤sÑ+€Fäˆð $&§8¡8¤:ÔB¢:™˜°Ñ1A‹fˆaŠf¡:ˆÑBð ˆ	àŸW™W›YÔ&ˆAð —&‘&˜“)ˆCà°!Ñ4Ñ5ˆBàŸ(™(ž*‘��3Ø&Ÿ]™]¨1Ó-�
ØÑ%Ø#&¨¡9�I˜a“Là!+¨c°C©iÑ!7�JÞ!Ø'1˜	 !›à!Ÿ™ aÖ(ó %ñ 'ô& �B“ˆÜ˜9“~ˆà�N�Q—U‘Uˆà Ô%ˆAØ˜q‘\�MˆBˆq‹Eñ &ð ˜Ô%ˆAØ�q‘E˜A‘IˆBˆq‹Eñ &ð  Ô%ˆAØ�Q‘%˜!‘)˜i¨™lÑ*ˆCÞØ��1“à—‘�q–	ñ &ö Úô �‹GˆØ�f‰f�Q‹iˆô Ð.×4Ñ4Ó6×7‰EˆB�à˜Q‘ˆBà˜‹{ð !Ÿh™hžj‘F�A�sØ ™)�CØÑ*Ù# C¨Ó1˜Ø�B�q“Eñ	 )ñ
 à—&‘&˜“)ˆCÜ˜“GˆEÜ˜“GˆEà˜U”]�Ø˜  1¡™��1‘ØÓ&Ù! " Q¡%¨Ó1�B�q“Eñ #ð ˜U”]�Ø˜b ™e™��1‘ØÓ&Ù! " Q¡%¨Ó1�B�q“Eñ #ð
 ˜U”]�Ø˜B˜q™E‘k C¨"¨Q©%¡KÑ/�ÞØÑ*Ù# C¨Ó1˜Ø�B�q“Eà—F‘F˜1–Iñ #÷ ‘2Ø$×(Ñ(¨Ô,Ø)*Ð" 2Ô&ñS 8ôV �ÓˆØ×Ñ˜2ÔÞØ&'Ð Ò#à$%ÐÑ!ð �x‰x˜�}‰}Ø‰}Ø‘à‘�àÑÙ˜%Ó)ˆEð ‹ñ} ð@ �}Ø—‘ˆð @Ð&Ð?Ð*>Ð?€JØ#-×#3Ñ#3Ô#5Ô6Ò#5™4˜1˜a�!�Q’$Ñ#5€JÑ6Ü8AÀ+Ô8NÔOÒ8N©u¨q°"˜
 1™ rÓ*Ñ8N€OÑOÜœ& Ó1Ð2�N€FˆFÜ�&‹\€Fô ˜6Ö"‰ˆˆ2Øˆ6�!‰9‹ñ #ô ”i Ó'Ó(€Jà�u˜fÐ$Ð$ùó[ CùóD 7ùÛOs   Ã8R2ÄR2Ð&R8ÑR>c                 óä   • [        [        [        U5      5      [        U5      -
  5      n/ nU H=  nXq0nUR                  US5       H  n	X	   U   * XƒU	   '   M     UR	                  U5        M?     Xe4$ )z%Get nullspace from A which is in RREFr   )rj  rW   rC   r<   rV   )
r€   rÕ   rd  r9  rn  rf  r'  r8   ÚKjr7   s
             r   rc  rc    ss   € ä”sœ5 ›<Ó(¬3¨v«;Ñ6Ó7€Ià
€AÛˆØˆWˆØ×!Ñ! ! RÖ(ˆAØ™T !™W˜HˆB�a‰y‹Mñ )à	�‰�Žñ	 ð ˆ<Ðr1   c                 ó‚   • 0 n[        U5       H-  u  pEX   R                  US-
  S5      nUc  M!  X`U   U   -  X5'   M/     U$ )z1Get a particular solution from A which is in RREFr   N)rU   r<   )r€   rd  r9  r_  r7   r8   ÚAins          r   rw  rw    sK   € à
€AÜ˜&Ö!‰ˆØ‰d�h‰h�u˜Q‘w Ó%ˆØ‹?Ø˜1™˜a™‘=ˆA‹Dñ "ð €Hr1   c           
      ó,  • UR                   nUR                  nUS:X  a  SU0$ US:X  a3  SU0nU R                  S0 5      R                  SU5      =n(       a  U* US'   UR                   0 0 [        [        5      4u  pxpšU R                  5        H]  u  p¼UR                  5        HD  u  pÞU(       a  U(       a  XêUS-
     US-
  '   M"  U(       a	  XéUS-
  '   M2  U(       a	  XèUS-
  '   MB  UnMF     M_     U	n[        X‰U5      nXG* U* /n[        SUS-   5       H6  n[        X¯U5      nU(       d    O"[        X�U5      nUR                  U* 5        M8     U(       a-  US   (       d#  UR                  5         U(       a  US   (       d  M#  [        X¡S-
  U5      nUSSS2   n0 n[        [        U5      [        [        U5      [        U5      -   US-   5      5       HB  n[	        [        UU[        U5      -
  S-   5      5      n[        UUU5      =n(       d  M=  UUU'   MD     U$ )að  
Berkowitz algorithm for computing the characteristic polynomial.

Explanation
===========

The Berkowitz algorithm is a division-free algorithm for computing the
characteristic polynomial of a matrix over any commutative ring using only
arithmetic in the coefficient ring. This implementation is for sparse
matrices represented in a dict-of-dicts format (like :class:`SDM`).

Examples
========

>>> from sympy import Matrix
>>> from sympy.polys.matrices.sdm import sdm_berk
>>> from sympy.polys.domains import ZZ
>>> M = {0: {0: ZZ(1), 1:ZZ(2)}, 1: {0:ZZ(3), 1:ZZ(4)}}
>>> sdm_berk(M, 2, ZZ)
{0: 1, 1: -5, 2: -2}
>>> Matrix([[1, 2], [3, 4]]).charpoly()
PurePoly(lambda**2 - 5*lambda - 2, lambda, domain='ZZ')

See Also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.charpoly
    The high-level interface to this function.
sympy.polys.matrices.dense.ddm_berk
    The dense version of this function.

References
==========

.. [1] https://en.wikipedia.org/wiki/Samuelson%E2%80%93Berkowitz_algorithm
r   r   r¬  rã   N)r5   rÕ   r<   r   ry   rD   rÖ  rC   rØ  rV   rÜ  rŒ  rR   rS   rG   rU   )r”   r$   r'  r5   rÕ   r�  ÚM00rý   rT  r  r€   r7   rÑ  r8   rÒ  ÚAnCÚRCÚTvalsÚRAnCÚqÚTqÚTiÚTqis                          r   rŒ  rŒ  #  só  € ðJ �6‰6€DØ
�%‰%€CàˆAƒvØ�3ˆxˆØ	
ˆa‹Ø�C�ˆØ—%‘%˜˜2“,×"Ñ" 1 dÓ+Ð+ˆ3Õ+Ø�tˆE�!‰Hð —‘˜˜R¤¬TÓ!2Ð2�J€Aˆ!Ø—‘–‰ˆØ—h‘h–j‰FˆAÞ–QØ!�!�A‘#‘�q˜‘s“ÞØ�!�A‘#“ÞØ�!�A‘#“à’ó !ñ ð. €CÜ	�A˜!Ó	€Bà�"�r�cˆN€EÜ�1�a˜‘cŽ]ˆÜ˜A AÓ&ˆÞÙÜ˜! !Ó$ˆØ�‰�d�UÖñ ö ˜˜bŸ	Ø�	‰	Œö ˜˜bŸ	™	ô 	��a‘C˜Ó€Að" ‘$�B�$‰K€Eà	€Bä”3�q“6œ3œs 1›v¤c¨%£jÑ0°!°A±#Ó6Ö7ˆÜ”)˜E 1¤S¨£Z¡<°¡>Ó2Ó3ˆÜ˜R  AÓ&Ð&ˆ3×&ØˆBˆq‹Eñ 8ð
 €Ir1   N)&r»  Úoperatorr   r   r   r   r   Úcollectionsr   Úsympy.external.gmpyr	   Úsympy.utilities.decoratorr
   Úsympy.utilities.iterablesr   Ú
exceptionsr   r   r   Úsympy.polys.domainsr   rˆ   r   Ú__doctest_skip__ry   r   r  r  rä   rÖ  rØ  r  rÛ  r8  r=  rc  rw  rŒ  r   r1   r   Ú<module>r)     s“   ðñ÷ -Õ ,Ý #å ,Ý 8Ý Dç DÑ Då "å ð �7ÓØ$Ð&9Ð:Ðô]4ˆ$ô ]4ò@++ò\
òò;òò)òX=ò@})ò@P%òfòórr1   