
    Цily                         S SK Jr  S SKJr  S SKJr  S SKJrJr  SSK	J
r
JrJrJrJrJrJr  \S:w  a  S/r\" S5      rS	/r\" S/S
9 " S S	5      5       rS SKJr  S SKJr  g)    )GROUND_TYPES)import_module)doctest_depends_onZZQQ   )DMBadInputErrorDMDomainErrorDMNonSquareMatrixErrorDMNonInvertibleMatrixErrorDMRankErrorDMShapeErrorDMValueErrorflint*DFMground_typesc                      \ rS 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 5       r\S 5       rS rS rS r\	S 5       rS rS rS rS rS 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! r%S" r&S# r'S$ r(S% r)S& r*S' r+S( r,S) r-S* r.S+ r/S, r0S- r1S. r2S/ r3\	S0 5       r4\	S1 5       r5\	S2 5       r6\	S3 5       r7S4 r8S5 r9S6 r:S7 r;S8 r<S9 r=S: r>S; r?S< r@S= rAS> rB\C" S?S@9SA 5       rD\C" S?S@9SB 5       rE\C" S?S@9SC 5       rFSD rG\C" S?S@9SE 5       rHSF rISNSH jrJSI rKSOSJ jrL\C" S?S@9SPSK j5       rM\C" S?S@9SPSL j5       rNSMrOgG)Qr   E   a  
Dense FLINT matrix. This class is a wrapper for matrices from python-flint.

>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.matrices.dfm import DFM
>>> dfm = DFM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> dfm
[[1, 2], [3, 4]]
>>> dfm.rep
[1, 2]
[3, 4]
>>> type(dfm.rep)  # doctest: +SKIP
<class 'flint._flint.fmpz_mat'>

Usually, the DFM class is not instantiated directly, but is created as the
internal representation of :class:`~.DomainMatrix`. When
`SYMPY_GROUND_TYPES` is set to `flint` and `python-flint` is installed, the
:class:`DFM` class is used automatically as the internal representation of
:class:`~.DomainMatrix` in dense format if the domain is supported by
python-flint.

>>> from sympy.polys.matrices.domainmatrix import DM
>>> dM = DM([[1, 2], [3, 4]], ZZ)
>>> dM.rep
[[1, 2], [3, 4]]

A :class:`~.DomainMatrix` can be converted to :class:`DFM` by calling the
:meth:`to_dfm` method:

>>> dM.to_dfm()
[[1, 2], [3, 4]]

denseTFc                     U R                  U5      nSU;  a
   U" U5      nOU" U6 nU R	                  XRU5      $ ! [        [        4 a    [        SU 35      ef = f)Construct from a nested list.r   z"Input should be a list of list of )_get_flint_func
ValueError	TypeErrorr
   _new)clsrowslistshapedomain	flint_matreps         X/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/sympy/polys/matrices/_dfm.py__new__DFM.__new__m   sq    ''/	E>U) U#CxxF++ 	* U%(J6(&STTUs	   9 Ac                     U R                  XU5        [        R                  U 5      nXl        U=Ul        u  Ul        Ul        X4l        U$ )z)Internal constructor from a flint matrix.)_checkobjectr&   r$   r!   rowscolsr"   )r   r$   r!   r"   objs        r%   r   DFM._new{   sD     	

3v&nnS!)..	&CHch

    c                 N    U R                  XR                  U R                  5      $ )z>Create a new DFM with the same shape and domain but a new rep.)r   r!   r"   )selfr$   s     r%   _new_repDFM._new_rep   s    yyjj$++66r/   c                 j   UR                  5       UR                  5       4nXB:w  a  [        S5      eU[        :X  a*  [	        U[
        R                  5      (       d  [        S5      eU[        :X  a*  [	        U[
        R                  5      (       d  [        S5      eU[        [        4;  a  [        S5      eg )Nz(Shape of rep does not match shape of DFMzRep is not a flint.fmpz_matzRep is not a flint.fmpq_mat#Only ZZ and QQ are supported by DFM)nrowsncolsr
   r   
isinstancer   fmpz_matRuntimeErrorr   fmpq_matNotImplementedError)r   r$   r!   r"   repshapes        r%   r)   
DFM._check   s    IIK-!"LMMR<
3 ? ?<==r\*S%.."A"A<==B8#%&KLL $r/   c                      U[         [        4;   $ )z4Return True if the given domain is supported by DFM.r   r   r"   s     r%   _supports_domainDFM._supports_domain   s     "b!!r/   c                     U[         :X  a  [        R                  $ U[        :X  a  [        R                  $ [        S5      e)z3Return the flint matrix class for the given domain.r5   )r   r   r9   r   r;   r<   r@   s     r%   r   DFM._get_flint_func   s2     R<>>!r\>>!%&KLLr/   c                 8    U R                  U R                  5      $ )z5Callable to create a flint matrix of the same domain.)r   r"   r1   s    r%   _func	DFM._func   s     ##DKK00r/   c                 4    [        U R                  5       5      $ )zReturn ``str(self)``.)strto_ddmrF   s    r%   __str__DFM.__str__   s    4;;=!!r/   c                 @    S[        U R                  5       5      SS  3$ )zReturn ``repr(self)``.r      N)reprrK   rF   s    r%   __repr__DFM.__repr__   s"    T$++-(,-..r/   c                     [        U[        5      (       d  [        $ U R                  UR                  :H  =(       a    U R                  UR                  :H  $ )zReturn ``self == other``.)r8   r   NotImplementedr"   r$   r1   others     r%   __eq__
DFM.__eq__   s<    %%%!! {{ell*Dtxx599/DDr/   c                     U " XU5      $ )r    )r   r    r!   r"   s       r%   	from_listDFM.from_list   s     8F++r/   c                 6    U R                   R                  5       $ )zConvert to a nested list.)r$   tolistrF   s    r%   to_listDFM.to_list   s    xx  r/   c                 V    U R                  U R                  U R                  5      5      $ )zReturn a copy of self.)r2   rG   r$   rF   s    r%   copyDFM.copy   s    }}TZZ122r/   c                 v    [         R                  " U R                  5       U R                  U R                  5      $ )zConvert to a DDM.)DDMr[   r_   r!   r"   rF   s    r%   rK   
DFM.to_ddm   #    }}T\\^TZZEEr/   c                 v    [         R                  " U R                  5       U R                  U R                  5      $ )zConvert to a SDM.)SDMr[   r_   r!   r"   rF   s    r%   to_sdm
DFM.to_sdm   rg   r/   c                     U $ )zReturn self.rZ   rF   s    r%   to_dfm
DFM.to_dfm   s    r/   c                     U $ )a  
Convert to a :class:`DFM`.

This :class:`DFM` method exists to parallel the :class:`~.DDM` and
:class:`~.SDM` methods. For :class:`DFM` it will always return self.

See Also
========

to_ddm
to_sdm
sympy.polys.matrices.domainmatrix.DomainMatrix.to_dfm_or_ddm
rZ   rF   s    r%   to_dfm_or_ddmDFM.to_dfm_or_ddm   s	     r/   c                 l    U R                  UR                  5       UR                  UR                  5      $ )zConvert from a DDM.)r[   r_   r!   r"   )r   ddms     r%   from_ddmDFM.from_ddm   s%     }}S[[]CIIszzBBr/   c                     U R                  U5      n U" / UQUP76 nU " XRU5      $ ! [         a    [        SU 35      e[         a    [        SU 35      ef = f)z Inverse of :meth:`to_list_flat`.z'Incorrect number of elements for shape zInput should be a list of )r   r   r
   r   )r   elementsr!   r"   funcr$   s         r%   from_list_flatDFM.from_list_flat   s}     ""6*	I((x(C
 3v&&	  	U!$KE7"STT 	I!$>vh"GHH	Is	   
& 0Ac                 6    U R                   R                  5       $ )zConvert to a flat list.)r$   entriesrF   s    r%   to_list_flatDFM.to_list_flat   s    xx!!r/   c                 >    U R                  5       R                  5       $ )z$Convert to a flat list of non-zeros.)rK   
to_flat_nzrF   s    r%   r   DFM.to_flat_nz   s    {{}''))r/   c                 L    [         R                  " XU5      R                  5       $ )zInverse of :meth:`to_flat_nz`.)re   from_flat_nzrm   )r   rw   datar"   s       r%   r   DFM.from_flat_nz   s      7>>@@r/   c                 >    U R                  5       R                  5       $ )zConvert to a DOD.)rK   to_dodrF   s    r%   r   
DFM.to_dod      {{}##%%r/   c                 L    [         R                  " XU5      R                  5       $ )zInverse of :meth:`to_dod`.)re   from_dodrm   )r   dodr!   r"   s       r%   r   DFM.from_dod       ||C/6688r/   c                 >    U R                  5       R                  5       $ )zConvert to a DOK.)rK   to_dokrF   s    r%   r   
DFM.to_dok
  r   r/   c                 L    [         R                  " XU5      R                  5       $ )zInverse of :math:`to_dod`.)re   from_dokrm   )r   dokr!   r"   s       r%   r   DFM.from_dok  r   r/   c              #      #    U R                   u  pU R                  n[        U5       H,  n[        U5       H  nX4U4   nU(       d  M  X4U4   v   M     M.     g7f)z0Iterater over the non-zero values of the matrix.Nr!   r$   ranger1   mnr$   ijrepijs          r%   iter_valuesDFM.iter_values  sP     zzhhqA1XqD	5d)O  s   AAAc              #      #    U R                   u  pU R                  n[        U5       H+  n[        U5       H  nX4U4   nU(       d  M  XE4U4v   M     M-     g7f)zBIterate over indices and values of nonzero elements of the matrix.Nr   r   s          r%   
iter_itemsDFM.iter_items  sQ     zzhhqA1XqD	565/)  s   AAAc                    XR                   :X  a  U R                  5       $ U[        :X  aN  U R                   [        :X  a:  U R	                  [
        R                  U R                  5      U R                  U5      $ U[        :X  aA  U R                   [        :X  a-  U R                  5       R                  U5      R                  5       $ [        S5      e)zConvert to a new domain.r5   )r"   rb   r   r   r   r   r;   r$   r!   rK   
convert_torm   r<   )r1   r"   s     r%   r   DFM.convert_to'  s    [[ 99;r\dkkR/99U^^DHH5tzz6JJr\dkkR/;;=++F3::<< &&KLLr/   c           	          U R                   u  p4US:  a  X-  nUS:  a  X$-  n U R                  X4   $ ! [         a    [        SU SU SU R                    35      ef = f)zGet the ``(i, j)``-th entry.r   Invalid indices (, ) for Matrix of shape r!   r$   r   
IndexError)r1   r   r   r   r   s        r%   getitemDFM.getitem5  sv     zzq5FAq5FA	]88AD>! 	]02aS8Ntzzl[\\	]	   4 )Ac           	          U R                   u  pEUS:  a  X-  nUS:  a  X%-  n X0R                  X4'   g! [         a    [        SU SU SU R                    35      ef = f)zSet the ``(i, j)``-th entry.r   r   r   r   Nr   )r1   r   r   valuer   r   s         r%   setitemDFM.setitemC  ss     zzq5FAq5FA	]"HHQTN 	]02aS8Ntzzl[\\	]r   c           
          U R                   nU VVs/ s H  oB Vs/ s H  oSXE4   PM
     snPM     nnn[        U5      [        U5      4nU R                  XgU R                  5      $ s  snf s  snnf )z%Extract a submatrix with no checking.)r$   lenr[   r"   )r1   	i_indices	j_indicesMr   r   lolr!   s           r%   _extractDFM._extractQ  sc     HH5>?Y+A!$+Y?YY0~~c$++66 ,?s   	A+A&A+&A+c                    U R                   u  p4/ n/ nU HK  nUS:  a  Xs-   nOUnSUs=::  a  U:  d  O  [        SU SU R                    35      eUR                  U5        MM     U HK  n	U	S:  a  X-   n
OU	n
SU
s=::  a  U:  d  O  [        SU	 SU R                    35      eUR                  U
5        MM     U R                  XV5      $ )zExtract a submatrix.r   zInvalid row index z for Matrix of shape zInvalid column index )r!   r   appendr   )r1   r    colslistr   r   new_rowsnew_colsr   i_posr   j_poss              r%   extractDFM.extractY  s    
 zzA1u>> #5aS8Mdjj\!Z[[OOE"  A1u>> #8;PQUQ[Q[P\!]^^OOE"  }}X00r/   c                 x    U R                   u  p4[        U5      U   n[        U5      U   nU R                  XV5      $ )zSlice a DFM.)r!   r   r   )r1   rowslicecolslicer   r   r   r   s          r%   extract_sliceDFM.extract_slicew  s:     zz!HX&	!HX&	}}Y22r/   c                 :    U R                  U R                  * 5      $ zNegate a DFM matrix.r2   r$   rF   s    r%   negDFM.neg  s    }}dhhY''r/   c                 R    U R                  U R                  UR                  -   5      $ )zAdd two DFM matrices.r   rU   s     r%   addDFM.add      }}TXX		122r/   c                 R    U R                  U R                  UR                  -
  5      $ )zSubtract two DFM matrices.r   rU   s     r%   subDFM.sub  r   r/   c                 >    U R                  U R                  U-  5      $ )z1Multiply a DFM matrix from the right by a scalar.r   rU   s     r%   mulDFM.mul  s    }}TXX-..r/   c                 <    U R                  XR                  -  5      $ )z0Multiply a DFM matrix from the left by a scalar.r   rU   s     r%   rmulDFM.rmul  s    }}UXX-..r/   c                 x    U R                  5       R                  UR                  5       5      R                  5       $ )z/Elementwise multiplication of two DFM matrices.)rK   mul_elementwiserm   rU   s     r%   r   DFM.mul_elementwise  s*     {{},,U\\^<CCEEr/   c                     U R                   UR                  4nU R                  U R                  UR                  -  X R                  5      $ )zMultiply two DFM matrices.)r+   r,   r   r$   r"   )r1   rV   r!   s      r%   matmul
DFM.matmul  s6    EJJ'yyEII-ukkBBr/   c                 "    U R                  5       $ r   )r   rF   s    r%   __neg__DFM.__neg__  s    xxzr/   c                 N    U R                  U5      nU R                  U" U6 X5      $ )zReturn a zero DFM matrix.)r   r   )r   r!   r"   rx   s       r%   zeros	DFM.zeros  s)     ""6*xxee44r/   c                 J    [         R                  " X5      R                  5       $ )zReturn a one DFM matrix.)re   onesrm   )r   r!   r"   s      r%   r   DFM.ones  s     xx&--//r/   c                 J    [         R                  " X5      R                  5       $ )z%Return the identity matrix of size n.)re   eyerm   )r   r   r"   s      r%   r   DFM.eye  s     wwq!((**r/   c                 J    [         R                  " X5      R                  5       $ )zReturn a diagonal matrix.)re   diagrm   )r   rw   r"   s      r%   r   DFM.diag  s     xx)0022r/   c                 \    U R                  5       R                  X5      R                  5       $ )z/Apply a function to each entry of a DFM matrix.)rK   	applyfuncrm   )r1   rx   r"   s      r%   r   DFM.applyfunc  s"    {{}&&t4;;==r/   c                     U R                  U R                  R                  5       U R                  U R                  4U R
                  5      $ )zTranspose a DFM matrix.)r   r$   	transposer,   r+   r"   rF   s    r%   r   DFM.transpose  s3    yy++-		499/Et{{SSr/   c                     U R                  5       R                  " U Vs/ s H  o"R                  5       PM     sn6 R                  5       $ s  snf )zHorizontally stack matrices.)rK   hstackrm   r1   othersos      r%   r   
DFM.hstack  8    {{}##&%A&Qhhj&%ABIIKK%A   A
c                     U R                  5       R                  " U Vs/ s H  o"R                  5       PM     sn6 R                  5       $ s  snf )zVertically stack matrices.)rK   vstackrm   r   s      r%   r   
DFM.vstack  r   r   c                     U R                   nU R                  u  p#[        [        X#5      5       Vs/ s H  oAXD4   PM
     sn$ s  snf )z$Return the diagonal of a DFM matrix.)r$   r!   r   min)r1   r   r   r   r   s        r%   diagonalDFM.diagonal  s=    HHzz!&s1y!12!1A!$!1222s   Ac                     U R                   n[        U R                  5       H#  n[        U5       H  nXU4   (       d  M      g   M%     g)z2Return ``True`` if the matrix is upper triangular.FT)r$   r   r+   r1   r   r   r   s       r%   is_upperDFM.is_upper  s?    HHtyy!A1XT77   " r/   c                     U R                   n[        U R                  5       H1  n[        US-   U R                  5       H  nXU4   (       d  M      g   M3     g)z2Return ``True`` if the matrix is lower triangular.r	   FTr$   r   r+   r,   r  s       r%   is_lowerDFM.is_lower  sJ    HHtyy!A1q5$)),T77  - " r/   c                 P    U R                  5       =(       a    U R                  5       $ )z*Return ``True`` if the matrix is diagonal.)r  r  rF   s    r%   is_diagonalDFM.is_diagonal  s    }}24==?2r/   c                     U R                   n[        U R                  5       H-  n[        U R                  5       H  nXU4   (       d  M      g   M/     g)z1Return ``True`` if the matrix is the zero matrix.FTr  r  s       r%   is_zero_matrixDFM.is_zero_matrix  sD    HHtyy!A499%T77  & " r/   c                 >    U R                  5       R                  5       $ )z5Return the number of non-zero elements in the matrix.)rK   nnzrF   s    r%   r  DFM.nnz      {{}  ""r/   c                 >    U R                  5       R                  5       $ )z7Return the strongly connected components of the matrix.)rK   sccrF   s    r%   r  DFM.scc  r  r/   r   r   c                 6    U R                   R                  5       $ )a  
Compute the determinant of the matrix using FLINT.

Examples
========

>>> from sympy import Matrix
>>> M = Matrix([[1, 2], [3, 4]])
>>> dfm = M.to_DM().to_dfm()
>>> dfm
[[1, 2], [3, 4]]
>>> dfm.det()
-2

Notes
=====

Calls the ``.det()`` method of the underlying FLINT matrix.

For :ref:`ZZ` or :ref:`QQ` this calls ``fmpz_mat_det`` or
``fmpq_mat_det`` respectively.

At the time of writing the implementation of ``fmpz_mat_det`` uses one
of several algorithms depending on the size of the matrix and bit size
of the entries. The algorithms used are:

- Cofactor for very small (up to 4x4) matrices.
- Bareiss for small (up to 25x25) matrices.
- Modular algorithms for larger matrices (up to 60x60) or for larger
  matrices with large bit sizes.
- Modular "accelerated" for larger matrices (60x60 upwards) if the bit
  size is smaller than the dimensions of the matrix.

The implementation of ``fmpq_mat_det`` clears denominators from each
row (not the whole matrix) and then calls ``fmpz_mat_det`` and divides
by the product of the denominators.

See Also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.det
    Higher level interface to compute the determinant of a matrix.
)r$   detrF   s    r%   r  DFM.det  s    b xx||~r/   c                 ^    U R                   R                  5       R                  5       SSS2   $ )a;  
Compute the characteristic polynomial of the matrix using FLINT.

Examples
========

>>> from sympy import Matrix
>>> M = Matrix([[1, 2], [3, 4]])
>>> dfm = M.to_DM().to_dfm()  # need ground types = 'flint'
>>> dfm
[[1, 2], [3, 4]]
>>> dfm.charpoly()
[1, -5, -2]

Notes
=====

Calls the ``.charpoly()`` method of the underlying FLINT matrix.

For :ref:`ZZ` or :ref:`QQ` this calls ``fmpz_mat_charpoly`` or
``fmpq_mat_charpoly`` respectively.

At the time of writing the implementation of ``fmpq_mat_charpoly``
clears a denominator from the whole matrix and then calls
``fmpz_mat_charpoly``. The coefficients of the characteristic
polynomial are then multiplied by powers of the denominator.

The ``fmpz_mat_charpoly`` method uses a modular algorithm with CRT
reconstruction. The modular algorithm uses ``nmod_mat_charpoly`` which
uses Berkowitz for small matrices and non-prime moduli or otherwise
the Danilevsky method.

See Also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.charpoly
    Higher level interface to compute the characteristic polynomial of
    a matrix.
N)r$   charpolycoeffsrF   s    r%   r   DFM.charpoly0  s*    T xx  "))+DbD11r/   c                 <   U R                   nU R                  u  p#X#:w  a  [        S5      eU[        :X  a  [	        SU-  5      eU[
        :X  a*   U R                  U R                  R                  5       5      $ [        SU-  5      e! [         a    [        S5      ef = f)a  
Compute the inverse of a matrix using FLINT.

Examples
========

>>> from sympy import Matrix, QQ
>>> M = Matrix([[1, 2], [3, 4]])
>>> dfm = M.to_DM().to_dfm().convert_to(QQ)
>>> dfm
[[1, 2], [3, 4]]
>>> dfm.inv()
[[-2, 1], [3/2, -1/2]]
>>> dfm.matmul(dfm.inv())
[[1, 0], [0, 1]]

Notes
=====

Calls the ``.inv()`` method of the underlying FLINT matrix.

For now this will raise an error if the domain is :ref:`ZZ` but will
use the FLINT method for :ref:`QQ`.

The FLINT methods for :ref:`ZZ` and :ref:`QQ` are ``fmpz_mat_inv`` and
``fmpq_mat_inv`` respectively. The ``fmpz_mat_inv`` method computes an
inverse with denominator. This is implemented by calling
``fmpz_mat_solve`` (see notes in :meth:`lu_solve` about the algorithm).

The ``fmpq_mat_inv`` method clears denominators from each row and then
multiplies those into the rhs identity matrix before calling
``fmpz_mat_solve``.

See Also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.inv
    Higher level method for computing the inverse of a matrix.
z!cannot invert a non-square matrixzfield expected, got %szmatrix is not invertiblez#DFM.inv() is not implemented for %s)r"   r!   r   r   r   r   r2   r$   invZeroDivisionErrorr   r<   )r1   Kr   r   s       r%   r$  DFM.inv\  s    n KKzz6()LMM7 81 <=="WM}}TXX\\^44 &&Ka&OPP % M01KLLMs   (B Bc                     U R                  5       R                  5       u  pnUR                  5       UR                  5       U4$ )z*Return the LU decomposition of the matrix.)rK   lurm   )r1   LUswapss       r%   r)  DFM.lu  s3    kkm&&(exxz188:u,,r/   c           
         U R                   UR                   :X  d'  [        SU R                   < SUR                   < 35      eU R                   R                  (       d  [        SU R                   -  5      eU R                  u  p#UR                  u  pEX$:w  a  [	        SU< SU< SU< SU< 35      eX54nX#:w  a;  U R                  5       R                  UR                  5       5      R                  5       $  U R                  R                  UR                  5      nU R                  XvU R                   5      $ ! [         a    [        S5      ef = f)a  
Solve a matrix equation using FLINT.

Examples
========

>>> from sympy import Matrix, QQ
>>> M = Matrix([[1, 2], [3, 4]])
>>> dfm = M.to_DM().to_dfm().convert_to(QQ)
>>> dfm
[[1, 2], [3, 4]]
>>> rhs = Matrix([1, 2]).to_DM().to_dfm().convert_to(QQ)
>>> dfm.lu_solve(rhs)
[[0], [1/2]]

Notes
=====

Calls the ``.solve()`` method of the underlying FLINT matrix.

For now this will raise an error if the domain is :ref:`ZZ` but will
use the FLINT method for :ref:`QQ`.

The FLINT methods for :ref:`ZZ` and :ref:`QQ` are ``fmpz_mat_solve``
and ``fmpq_mat_solve`` respectively. The ``fmpq_mat_solve`` method
uses one of two algorithms:

- For small matrices (<25 rows) it clears denominators between the
  matrix and rhs and uses ``fmpz_mat_solve``.
- For larger matrices it uses ``fmpq_mat_solve_dixon`` which is a
  modular approach with CRT reconstruction over :ref:`QQ`.

The ``fmpz_mat_solve`` method uses one of four algorithms:

- For very small (<= 3x3) matrices it uses a Cramer's rule.
- For small (<= 15x15) matrices it uses a fraction-free LU solve.
- Otherwise it uses either Dixon or another multimodular approach.

See Also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.lu_solve
    Higher level interface to solve a matrix equation.
zDomains must match: z != zField expected, got %szMatrix size mismatch: z * z vs z Matrix det == 0; not invertible.)r"   r   is_Fieldr!   r   rK   lu_solverm   r$   solver%  r   r   )r1   rhsr   r   r   k	sol_shapesols           r%   r0  DFM.lu_solve  s	   \ {{cjj($++szz Z[[
 {{## 84;; FGGzzyy6QPQSTVWXYYF	 6;;=))#**,7>>@@	Q((..)C yy55 ! 	Q,-OPP	Qs   5%D6 6Ec                 f    U R                  5       R                  5       u  pUR                  5       U4$ )/Return a basis for the nullspace of the matrix.)rK   	nullspacerm   )r1   rs   	nonpivotss      r%   r9  DFM.nullspace   s+    & 002zz|Y&&r/   Nc                 d    U R                  5       R                  US9u  p#UR                  5       U4$ )r8  )pivots)rj   nullspace_from_rrefrm   )r1   r=  sdmr:  s       r%   r>  DFM.nullspace_from_rref  s0     ::&:Izz|Y&&r/   c                 Z    U R                  5       R                  5       R                  5       $ )z+Return a particular solution to the system.)rK   
particularrm   rF   s    r%   rB  DFM.particular  s     {{}'')0022r/   c                     S nU" U5      nU" U5      nSUs=:  a  S:  d  O  [        S5      eU R                  u  pxU R                  R                  5       U:w  a  [	        S5      eU R                  R                  XX4US9$ )zACall the fmpz_mat.lll() method but check rank to avoid segfaults.c                     [         R                  " U 5      (       a+  [        U R                  5      [        U R                  5      -  $ [        U 5      $ N)r   of_typefloat	numeratordenominator)xs    r%   to_floatDFM._lll.<locals>.to_float*  s5    zz!}}Q[[)E!--,@@@Qxr/   g      ?r	   z delta must be between 0.25 and 1z-Matrix must have full row rank for Flint LLL.)	transformdeltaetar$   gram)r   r!   r$   rankr   lll)	r1   rN  rO  rP  r$   rQ  rL  r   r   s	            r%   _lllDFM._lll   s{    	  smeaABB zz88==?aMNN xx||i#UY|ZZr/   c                     U R                   [        :w  a  [        SU R                   -  5      eU R                  U R                  :  a  [        S5      eU R                  US9nU R                  U5      $ )a  Compute LLL-reduced basis using FLINT.

See :meth:`lll_transform` for more information.

Examples
========

>>> from sympy import Matrix
>>> M = Matrix([[1, 2, 3], [4, 5, 6]])
>>> M.to_DM().to_dfm().lll()
[[2, 1, 0], [-1, 1, 3]]

See Also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.lll
    Higher level interface to compute LLL-reduced basis.
lll_transform
    Compute LLL-reduced basis and transform matrix.
ZZ expected, got %s,Matrix must not have more rows than columns.)rO  )r"   r   r   r+   r,   r   rT  r2   )r1   rO  r$   s      r%   rS  DFM.lll>  s`    , ;;" 5 CDDYY"MNNiiei$}}S!!r/   c                 T   U R                   [        :w  a  [        SU R                   -  5      eU R                  U R                  :  a  [        S5      eU R                  SUS9u  p#U R                  U5      nU R                  X0R                  U R                  4U R                   5      nXE4$ )a  Compute LLL-reduced basis and transform using FLINT.

Examples
========

>>> from sympy import Matrix
>>> M = Matrix([[1, 2, 3], [4, 5, 6]]).to_DM().to_dfm()
>>> M_lll, T = M.lll_transform()
>>> M_lll
[[2, 1, 0], [-1, 1, 3]]
>>> T
[[-2, 1], [3, -1]]
>>> T.matmul(M) == M_lll
True

See Also
========

sympy.polys.matrices.domainmatrix.DomainMatrix.lll
    Higher level interface to compute LLL-reduced basis.
lll
    Compute LLL-reduced basis without transform matrix.
rW  rX  T)rN  rO  )	r"   r   r   r+   r,   r   rT  r2   r   )r1   rO  r$   TbasisT_dfms         r%   lll_transformDFM.lll_transform\  s    2 ;;" 5 CDDYY"MNNT7c"		!ii3T[[A|r/   rZ   rF  )FgGz?gRQ?zbasisapprox)g      ?)P__name__
__module____qualname____firstlineno____doc__fmtis_DFMis_DDMr&   classmethodr   r2   r)   rA   r   propertyrG   rL   rQ   rW   r[   r_   rb   rK   rj   rm   rp   rt   ry   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r   r  r   r$  r)  r0  r9  r>  rB  rT  rS  r^  __static_attributes__rZ   r/   r%   r   r   E   s    D CFF,  7 	M 	M " " M M 1 1"/E , ,!3FF  C C 	' 	'"* A A& 9 9& 9 9$*M]]71<3(33//F
C 5 5 0 0
 + +
 3 3>TLL33## W-0 .0d W-)2 .)2V W-FQ .FQP-  W-H6 .H6T','3[< W-" .": W-  . r/   )re   )ri   N)sympy.external.gmpyr   sympy.external.importtoolsr   sympy.utilities.decoratorr   sympy.polys.domainsr   r   
exceptionsr
   r   r   r   r   r   r   __doctest_skip__r   __all__r   sympy.polys.matrices.ddmre   ri   rZ   r/   r%   <module>ru     sv   T - 4 8 &   7u 	g ' '+w w ,wv ) (r/   