§
    ¬³Ùgly  ã                   óä   — d dl mZ d dlmZ d dlmZ d dlmZmZ ddl	m
Z
mZmZmZmZmZmZ edk    rdgZ ed¦  «        Zd	gZ edg¬
¦  «         G d„ d	¦  «        ¦   «         Zd dlmZ d dlmZ dS )é    )ÚGROUND_TYPES)Úimport_module)Údoctest_depends_on©ÚZZÚQQé   )ÚDMBadInputErrorÚDMDomainErrorÚDMNonSquareMatrixErrorÚDMNonInvertibleMatrixErrorÚDMRankErrorÚDMShapeErrorÚDMValueErrorÚflintÚ*ÚDFM©Úground_typesc                   ó†  — e Zd ZdZdZdZdZd„ Zed„ ¦   «         Z	d„ Z
ed„ ¦   «         Zed	„ ¦   «         Zed
„ ¦   «         Zed„ ¦   «         Zd„ Zd„ Zd„ Zed„ ¦   «         Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zed„ ¦   «         Zed„ ¦   «         Zd„ Zd„ Zed„ ¦   «         Zd„ Zed„ ¦   «         Z d„ Z!ed„ ¦   «         Z"d„ Z#d „ Z$d!„ Z%d"„ Z&d#„ Z'd$„ Z(d%„ Z)d&„ Z*d'„ Z+d(„ Z,d)„ Z-d*„ Z.d+„ Z/d,„ Z0d-„ Z1d.„ Z2ed/„ ¦   «         Z3ed0„ ¦   «         Z4ed1„ ¦   «         Z5ed2„ ¦   «         Z6d3„ Z7d4„ Z8d5„ Z9d6„ Z:d7„ Z;d8„ Z<d9„ Z=d:„ Z>d;„ Z?d<„ Z@d=„ ZA eBd>¬?¦  «        d@„ ¦   «         ZC eBd>¬?¦  «        dA„ ¦   «         ZD eBd>¬?¦  «        dB„ ¦   «         ZEdC„ ZF eBd>¬?¦  «        dD„ ¦   «         ZGdE„ ZHdQdG„ZIdH„ ZJdRdM„ZK eBd>¬?¦  «        dSdO„¦   «         ZL eBd>¬?¦  «        dSdP„¦   «         ZMdFS )Tr   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                 óÔ   — |                       |¦  «        }d|vr4	  ||¦  «        }n,# t          t          f$ r t          d|› �¦  «        ‚w xY w ||Ž }|                      |||¦  «        S )ú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         úO/granary/edev/quantum/lib/python3.11/site-packages/sympy/polys/matrices/_dfm.pyÚ__new__zDFM.__new__m   s”   € à×'Ò'¨Ñ/Ô/ˆ	à�Eˆ>ˆ>ðUØ�i Ñ)Ô)��øÝ¥	Ð*ð Uð Uð UÝ%Ð&SÈ6Ð&SÐ&SÑTÔTÐTðUøøøð �)˜UÐ#ˆCà�xŠx˜˜U FÑ+Ô+Ð+s	   ›' §$Ac                 ó°   — |                       |||¦  «         t                               | ¦  «        }||_        |x|_        \  |_        |_        ||_        |S )z)Internal constructor from a flint matrix.)Ú_checkÚobjectr%   r#   r    ÚrowsÚcolsr!   )r   r#   r    r!   Úobjs        r$   r   zDFM._new{   sS   € ð 	�
Š
�3˜˜vÑ&Ô&Ð&Ý�nŠn˜SÑ!Ô!ˆØˆŒØ).Ð.ˆŒ	Ñ&�C”H˜cœhØˆŒ
Øˆ
ó    c                 óD   — |                       || j        | j        ¦  «        S )z>Create a new DFM with the same shape and domain but a new rep.)r   r    r!   )Úselfr#   s     r$   Ú_new_repzDFM._new_rep…   s   € à�yŠy˜˜dœj¨$¬+Ñ6Ô6Ð6r,   c                 óŽ  — |                      ¦   «         |                     ¦   «         f}||k    rt          d¦  «        ‚|t          k    r)t	          |t
          j        ¦  «        st          d¦  «        ‚|t          k    r)t	          |t
          j	        ¦  «        st          d¦  «        ‚|t          t          fvrt          d¦  «        ‚d S )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'   z
DFM._check‰   s¬   € à—I’I‘K”K §¢¡¤Ð-ˆØ�uÒÐÝ!Ð"LÑMÔMÐMØ•RŠ<ˆ<¥
¨3µ´Ñ ?Ô ?ˆ<ÝÐ<Ñ=Ô=Ð=Ø•rŠ\ˆ\¥*¨Sµ%´.Ñ"AÔ"Aˆ\ÝÐ<Ñ=Ô=Ð=Ø�B¥˜8Ð#Ð#Ý%Ð&KÑLÔLÐLð $Ð#r,   c                 ó"   — |t           t          fv S )z4Return True if the given domain is supported by DFM.r   ©r   r!   s     r$   Ú_supports_domainzDFM._supports_domain•   s   € ð �"�b˜Ð!Ð!r,   c                 ó|   — |t           k    rt          j        S |t          k    rt          j        S t          d¦  «        ‚)z3Return the flint matrix class for the given domain.r1   )r   r   r5   r   r7   r8   r;   s     r$   r   zDFM._get_flint_funcš   s5   € ð •RŠ<ˆ<Ý”>Ð!Ø•rŠ\ˆ\Ý”>Ð!å%Ð&KÑLÔLÐLr,   c                 ó6   — |                       | j        ¦  «        S )z5Callable to create a flint matrix of the same domain.)r   r!   ©r.   s    r$   Ú_funcz	DFM._func¤   s   € ð ×#Ò# D¤KÑ0Ô0Ð0r,   c                 óD   — t          |                      ¦   «         ¦  «        S )zReturn ``str(self)``.)ÚstrÚto_ddmr?   s    r$   Ú__str__zDFM.__str__©   s   € å�4—;’;‘=”=Ñ!Ô!Ð!r,   c                 óZ   — dt          |                      ¦   «         ¦  «        dd…         › �S )zReturn ``repr(self)``.r   é   N)ÚreprrC   r?   s    r$   Ú__repr__zDFM.__repr__­   s)   € à.•T˜$Ÿ+š+™-œ-Ñ(Ô(¨¨¨Ô,Ð.Ð.Ð.r,   c                 óz   — t          |t          ¦  «        st          S | j        |j        k    o| j        |j        k    S )zReturn ``self == other``.)r4   r   ÚNotImplementedr!   r#   ©r.   Úothers     r$   Ú__eq__z
DFM.__eq__±   s9   € å˜%¥Ñ%Ô%ð 	"Ý!Ð!ð Œ{˜eœlÒ*ÐD¨t¬x¸5¼9Ò/DÐDr,   c                 ó   —  | |||¦  «        S )r   © )r   r   r    r!   s       r$   Ú	from_listzDFM.from_listº   s   € ð ˆs�8˜U FÑ+Ô+Ð+r,   c                 ó4   — | j                              ¦   «         S )zConvert to a nested list.)r#   Útolistr?   s    r$   Úto_listzDFM.to_list¿   s   € àŒx�ŠÑ Ô Ð r,   c                 ó\   — |                       |                      | j        ¦  «        ¦  «        S )zReturn a copy of self.)r/   r@   r#   r?   s    r$   ÚcopyzDFM.copyÃ   s"   € à�}Š}˜TŸZšZ¨¬Ñ1Ô1Ñ2Ô2Ð2r,   c                 óf   — t          j        |                      ¦   «         | j        | j        ¦  «        S )zConvert to a DDM.)ÚDDMrP   rS   r    r!   r?   s    r$   rC   z
DFM.to_ddmÇ   ó"   € åŒ}˜TŸ\š\™^œ^¨T¬Z¸¼ÑEÔEÐEr,   c                 óf   — t          j        |                      ¦   «         | j        | j        ¦  «        S )zConvert to a SDM.)ÚSDMrP   rS   r    r!   r?   s    r$   Úto_sdmz
DFM.to_sdmË   rX   r,   c                 ó   — | S )zReturn self.rO   r?   s    r$   Úto_dfmz
DFM.to_dfmÏ   s   € àˆr,   c                 ó   — | S )aL  
        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
        rO   r?   s    r$   Úto_dfm_or_ddmzDFM.to_dfm_or_ddmÓ   s	   € ð ˆr,   c                 óh   — |                       |                     ¦   «         |j        |j        ¦  «        S )zConvert from a DDM.)rP   rS   r    r!   )r   Úddms     r$   Úfrom_ddmzDFM.from_ddmã   s&   € ð �}Š}˜SŸ[š[™]œ]¨C¬I°s´zÑBÔBÐBr,   c                 óÔ   — |                       |¦  «        }	  |g |¢|‘R Ž }n;# t          $ r t          d|› �¦  «        ‚t          $ r t          d|› �¦  «        ‚w xY w | |||¦  «        S )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_flatzDFM.from_list_flatè   s¯   € ð ×"Ò" 6Ñ*Ô*ˆð	IØ�$Ð(˜Ð(˜xÐ(Ð(Ð(ˆCˆCøÝð 	Uð 	Uð 	UÝ!Ð"SÈEÐ"SÐ"SÑTÔTÐTÝð 	Ið 	Ið 	IÝ!Ð"G¸vÐ"GÐ"GÑHÔHÐHð	Iøøøàˆs�3˜˜vÑ&Ô&Ð&s	   —
" ¢8Ac                 ó4   — | j                              ¦   «         S )zConvert to a flat list.)r#   Úentriesr?   s    r$   Úto_list_flatzDFM.to_list_flatô   s   € àŒx×ÒÑ!Ô!Ð!r,   c                 óN   — |                       ¦   «                              ¦   «         S )z$Convert to a flat list of non-zeros.)rC   Ú
to_flat_nzr?   s    r$   rk   zDFM.to_flat_nzø   s   € à�{Š{‰}Œ}×'Ò'Ñ)Ô)Ð)r,   c                 óR   — t          j        |||¦  «                             ¦   «         S )zInverse of :meth:`to_flat_nz`.)rW   Úfrom_flat_nzr]   )r   rd   Údatar!   s       r$   rm   zDFM.from_flat_nzü   s%   € õ Ô ¨$°Ñ7Ô7×>Ò>Ñ@Ô@Ð@r,   c                 óN   — |                       ¦   «                              ¦   «         S )zConvert to a DOD.)rC   Úto_dodr?   s    r$   rp   z
DFM.to_dod  ó   € à�{Š{‰}Œ}×#Ò#Ñ%Ô%Ð%r,   c                 óR   — t          j        |||¦  «                             ¦   «         S )zInverse of :meth:`to_dod`.)rW   Úfrom_dodr]   )r   Údodr    r!   s       r$   rs   zDFM.from_dod  ó$   € õ Œ|˜C ¨Ñ/Ô/×6Ò6Ñ8Ô8Ð8r,   c                 óN   — |                       ¦   «                              ¦   «         S )zConvert to a DOK.)rC   Úto_dokr?   s    r$   rw   z
DFM.to_dok
  rq   r,   c                 óR   — t          j        |||¦  «                             ¦   «         S )zInverse of :math:`to_dod`.)rW   Úfrom_dokr]   )r   Údokr    r!   s       r$   ry   zDFM.from_dok  ru   r,   c              #   ó¤   K  — | j         \  }}| j        }t          |¦  «        D ],}t          |¦  «        D ]}|||f         }|r|||f         V — ŒŒ-dS )z0Iterater over the non-zero values of the matrix.N©r    r#   Úrange©r.   ÚmÚnr#   ÚiÚjÚrepijs          r$   Úiter_valueszDFM.iter_values  sx   è è € àŒz‰ˆˆ1ØŒhˆÝ�q‘”ð 	$ð 	$ˆAÝ˜1‘X”Xð $ð $�Ø˜A˜q˜Dœ	�Øð $Ø˜a ˜dœ)�O�O�Oøð$ð	$ð 	$r,   c              #   óœ   K  — | j         \  }}| j        }t          |¦  «        D ](}t          |¦  «        D ]}|||f         }|r||f|fV — ŒŒ)dS )zBIterate over indices and values of nonzero elements of the matrix.Nr|   r~   s          r$   Ú
iter_itemszDFM.iter_items  s{   è è € àŒz‰ˆˆ1ØŒhˆÝ�q‘”ð 	*ð 	*ˆAÝ˜1‘X”Xð *ð *�Ø˜A˜q˜Dœ	�Øð *Ø˜q˜6 5˜/Ð)Ð)Ð)øð*ð	*ð 	*r,   c                 ó®  — || j         k    r|                      ¦   «         S |t          k    rI| j         t          k    r9|                      t
                               | j        ¦  «        | j        |¦  «        S |t          k    rI| j         t          k    r9|  	                    ¦   «          
                    |¦  «                             ¦   «         S t          d¦  «        ‚)zConvert to a new domain.r1   )r!   rU   r   r   r   r   r7   r#   r    rC   Ú
convert_tor]   r8   )r.   r!   s     r$   rˆ   zDFM.convert_to'  s¦   € à�T”[Ò Ð Ø—9’9‘;”;ÐØ•rŠ\ˆ\˜dœk­RÒ/Ð/Ø—9’9�UŸ^š^¨D¬HÑ5Ô5°t´zÀ6ÑJÔJÐJØ•rŠ\ˆ\˜dœk­RÒ/Ð/à—;’;‘=”=×+Ò+¨FÑ3Ô3×:Ò:Ñ<Ô<Ð<õ &Ð&KÑLÔLÐLr,   c           	      ó¸   — | j         \  }}|dk     r||z  }|dk     r||z  }	 | j        ||f         S # t          $ r t          d|› d|› d| j         › �¦  «        ‚w xY w)zGet the ``(i, j)``-th entry.r   úInvalid indices (ú, ú) for Matrix of shape ©r    r#   r   Ú
IndexError)r.   r�   r‚   r   r€   s        r$   ÚgetitemzDFM.getitem5  s‘   € ð Œz‰ˆˆ1ØˆqŠ5ˆ5Ø�‰FˆAØˆqŠ5ˆ5Ø�‰FˆAð	]Ø”8˜A˜q˜D”>Ð!øÝð 	]ð 	]ð 	]ÝÐ[°Ð[Ð[°aÐ[Ð[ÈtÌzÐ[Ð[Ñ\Ô\Ð\ð	]øøøs	   ¢1 ±(Ac           	      ó¶   — | j         \  }}|dk     r||z  }|dk     r||z  }	 || j        ||f<   dS # t          $ r t          d|› d|› d| j         › �¦  «        ‚w xY w)zSet the ``(i, j)``-th entry.r   rŠ   r‹   rŒ   Nr�   )r.   r�   r‚   Úvaluer   r€   s         r$   ÚsetitemzDFM.setitemC  s”   € ð Œz‰ˆˆ1ØˆqŠ5ˆ5Ø�‰FˆAØˆqŠ5ˆ5Ø�‰FˆAð	]Ø"ˆDŒH�Q˜�T‰NˆNˆNøÝð 	]ð 	]ð 	]ÝÐ[°Ð[Ð[°aÐ[Ð[ÈtÌzÐ[Ð[Ñ\Ô\Ð\ð	]øøøs	   ¢0 °(Ac                 ó¦   ‡‡— | j         Šˆˆfd„|D ¦   «         }t          |¦  «        t          ‰¦  «        f}|                      ||| j        ¦  «        S )z%Extract a submatrix with no checking.c                 ó0   •‡— g | ]Šˆˆfd „‰D ¦   «         ‘ŒS )c                 ó$   •— g | ]}‰‰|f         ‘ŒS rO   rO   )Ú.0r‚   ÚMr�   s     €€r$   ú
<listcomp>z+DFM._extract.<locals>.<listcomp>.<listcomp>U  s!   ø€ Ð+Ð+Ð+˜A��!�Q�$”Ð+Ð+Ð+r,   rO   )r–   r�   r—   Ú	j_indicess    @€€r$   r˜   z DFM._extract.<locals>.<listcomp>U  s2   øø€ Ð?Ð?Ð?°Ð+Ð+Ð+Ð+Ð+ Ð+Ñ+Ô+Ð?Ð?Ð?r,   )r#   ÚlenrP   r!   )r.   Ú	i_indicesr™   Úlolr    r—   s     `  @r$   Ú_extractzDFM._extractQ  sW   øø€ ð ŒHˆØ?Ð?Ð?Ð?Ð?°YÐ?Ñ?Ô?ˆÝ�Y‘”¥ Y¡¤Ð0ˆØ�~Š~˜c 5¨$¬+Ñ6Ô6Ð6r,   c                 óŽ  — | j         \  }}g }g }|D ]N}|dk     r||z   }n|}d|cxk    r|k     sn t          d|› d| j         › �¦  «        ‚|                     |¦  «         ŒO|D ]N}	|	dk     r|	|z   }
n|	}
d|
cxk    r|k     sn t          d|	› d| j         › �¦  «        ‚|                     |
¦  «         ŒO|                      ||¦  «        S )zExtract a submatrix.r   zInvalid row index z for Matrix of shape zInvalid column index )r    rŽ   Úappendr�   )r.   r   Úcolslistr   r€   Únew_rowsÚnew_colsr�   Úi_posr‚   Új_poss              r$   ÚextractzDFM.extractY  s  € ð
 Œz‰ˆˆ1àˆØˆàð 	#ð 	#ˆAØ�1ŠuˆuØ˜A™��à�Ø˜�>�>’>�> ’>�>�>�>Ý Ð!Z°aÐ!ZÐ!ZÈdÌjÐ!ZÐ!ZÑ[Ô[Ð[Ø�OŠO˜EÑ"Ô"Ð"Ð"àð 	#ð 	#ˆAØ�1ŠuˆuØ˜A™��à�Ø˜�>�>’>�> ’>�>�>�>Ý Ð!]¸Ð!]Ð!]ÐQUÔQ[Ð!]Ð!]Ñ^Ô^Ð^Ø�OŠO˜EÑ"Ô"Ð"Ð"à�}Š}˜X xÑ0Ô0Ð0r,   c                 ó–   — | j         \  }}t          |¦  «        |         }t          |¦  «        |         }|                      ||¦  «        S )zSlice a DFM.)r    r}   r�   )r.   ÚrowsliceÚcolslicer   r€   r›   r™   s          r$   Úextract_slicezDFM.extract_slicew  sC   € ð Œz‰ˆˆ1Ý˜!‘H”H˜XÔ&ˆ	Ý˜!‘H”H˜XÔ&ˆ	Ø�}Š}˜Y¨	Ñ2Ô2Ð2r,   c                 ó8   — |                       | j         ¦  «        S ©zNegate a DFM matrix.©r/   r#   r?   s    r$   ÚnegzDFM.neg  s   € à�}Š}˜dœh˜YÑ'Ô'Ð'r,   c                 óF   — |                       | j        |j        z   ¦  «        S )zAdd two DFM matrices.r¬   rK   s     r$   ÚaddzDFM.addƒ  ó   € à�}Š}˜TœX¨¬	Ñ1Ñ2Ô2Ð2r,   c                 óF   — |                       | j        |j        z
  ¦  «        S )zSubtract two DFM matrices.r¬   rK   s     r$   ÚsubzDFM.sub‡  r°   r,   c                 ó<   — |                       | j        |z  ¦  «        S )z1Multiply a DFM matrix from the right by a scalar.r¬   rK   s     r$   ÚmulzDFM.mul‹  s   € à�}Š}˜TœX¨Ñ-Ñ.Ô.Ð.r,   c                 ó<   — |                       || j        z  ¦  «        S )z0Multiply a DFM matrix from the left by a scalar.r¬   rK   s     r$   ÚrmulzDFM.rmul�  s   € à�}Š}˜U T¤XÑ-Ñ.Ô.Ð.r,   c                 ó˜   — |                       ¦   «                              |                      ¦   «         ¦  «                             ¦   «         S )z/Elementwise multiplication of two DFM matrices.)rC   Úmul_elementwiser]   rK   s     r$   r¸   zDFM.mul_elementwise“  s4   € ð �{Š{‰}Œ}×,Ò,¨U¯\ª\©^¬^Ñ<Ô<×CÒCÑEÔEÐEr,   c                 óp   — | j         |j        f}|                      | j        |j        z  || j        ¦  «        S )zMultiply two DFM matrices.)r)   r*   r   r#   r!   )r.   rL   r    s      r$   Úmatmulz
DFM.matmul˜  s1   € à”˜EœJÐ'ˆØ�yŠy˜œ E¤IÑ-¨u°d´kÑBÔBÐBr,   c                 ó*   — |                       ¦   «         S r«   )r­   r?   s    r$   Ú__neg__zDFM.__neg__¡  s   € à�xŠx‰zŒzÐr,   c                 ó`   — |                       |¦  «        }|                       ||Ž ||¦  «        S )zReturn a zero DFM matrix.)r   r   )r   r    r!   re   s       r$   Úzerosz	DFM.zeros¥  s3   € ð ×"Ò" 6Ñ*Ô*ˆØ�xŠx˜˜˜e˜ e¨VÑ4Ô4Ð4r,   c                 óP   — t          j        ||¦  «                             ¦   «         S )zReturn a one DFM matrix.)rW   Úonesr]   )r   r    r!   s      r$   rÀ   zDFM.ones¯  s"   € õ Œx˜˜vÑ&Ô&×-Ò-Ñ/Ô/Ð/r,   c                 óP   — t          j        ||¦  «                             ¦   «         S )z%Return the identity matrix of size n.)rW   Úeyer]   )r   r€   r!   s      r$   rÂ   zDFM.eyeµ  s"   € õ Œw�q˜&Ñ!Ô!×(Ò(Ñ*Ô*Ð*r,   c                 óP   — t          j        ||¦  «                             ¦   «         S )zReturn a diagonal matrix.)rW   Údiagr]   )r   rd   r!   s      r$   rÄ   zDFM.diag»  s"   € õ Œx˜ &Ñ)Ô)×0Ò0Ñ2Ô2Ð2r,   c                 óv   — |                       ¦   «                              ||¦  «                             ¦   «         S )z/Apply a function to each entry of a DFM matrix.)rC   Ú	applyfuncr]   )r.   re   r!   s      r$   rÆ   zDFM.applyfuncÀ  s,   € à�{Š{‰}Œ}×&Ò& t¨VÑ4Ô4×;Ò;Ñ=Ô=Ð=r,   c                 ó€   — |                       | j                             ¦   «         | j        | j        f| j        ¦  «        S )zTranspose a DFM matrix.)r   r#   Ú	transposer*   r)   r!   r?   s    r$   rÈ   zDFM.transposeÄ  s1   € à�yŠy˜œ×+Ò+Ñ-Ô-°´	¸4¼9Ð/EÀtÄ{ÑSÔSÐSr,   c                 ór   —  |                       ¦   «         j        d„ |D ¦   «         Ž                      ¦   «         S )zHorizontally stack matrices.c                 ó6   — g | ]}|                      ¦   «         ‘ŒS rO   ©rC   ©r–   Úos     r$   r˜   zDFM.hstack.<locals>.<listcomp>Ê  ó    € Ð%AÐ%AÐ%A°Q a§h¢h¡j¤jÐ%AÐ%AÐ%Ar,   )rC   Úhstackr]   ©r.   Úotherss     r$   rÏ   z
DFM.hstackÈ  ó5   € à#ˆt�{Š{‰}Œ}Ô#Ð%AÐ%A¸&Ð%AÑ%AÔ%AÐB×IÒIÑKÔKÐKr,   c                 ór   —  |                       ¦   «         j        d„ |D ¦   «         Ž                      ¦   «         S )zVertically stack matrices.c                 ó6   — g | ]}|                      ¦   «         ‘ŒS rO   rË   rÌ   s     r$   r˜   zDFM.vstack.<locals>.<listcomp>Î  rÎ   r,   )rC   Úvstackr]   rÐ   s     r$   rÕ   z
DFM.vstackÌ  rÒ   r,   c                 óx   ‡— | j         Š| j        \  }}ˆfd„t          t          ||¦  «        ¦  «        D ¦   «         S )z$Return the diagonal of a DFM matrix.c                 ó$   •— g | ]}‰||f         ‘ŒS rO   rO   )r–   r�   r—   s     €r$   r˜   z DFM.diagonal.<locals>.<listcomp>Ô  s!   ø€ Ð2Ð2Ð2˜A��!�Q�$”Ð2Ð2Ð2r,   )r#   r    r}   Úmin)r.   r   r€   r—   s      @r$   ÚdiagonalzDFM.diagonalÐ  s?   ø€ àŒHˆØŒz‰ˆˆ1Ø2Ð2Ð2Ð2¥¥s¨1¨a¡y¤yÑ!1Ô!1Ð2Ñ2Ô2Ð2r,   c                 ó‚   — | j         }t          | j        ¦  «        D ]"}t          |¦  «        D ]}|||f         r  dS ŒŒ#dS )z2Return ``True`` if the matrix is upper triangular.FT)r#   r}   r)   ©r.   r—   r�   r‚   s       r$   Úis_upperzDFM.is_upperÖ  sa   € àŒHˆÝ�t”yÑ!Ô!ð 	!ð 	!ˆAÝ˜1‘X”Xð !ð !�Ø�Q˜�T”7ð !Ø ˜5˜5˜5ð!ð!ð ˆtr,   c                 ó”   — | j         }t          | j        ¦  «        D ]+}t          |dz   | j        ¦  «        D ]}|||f         r  dS ŒŒ,dS )z2Return ``True`` if the matrix is lower triangular.r	   FT©r#   r}   r)   r*   rÛ   s       r$   Úis_lowerzDFM.is_lowerß  sk   € àŒHˆÝ�t”yÑ!Ô!ð 	!ð 	!ˆAÝ˜1˜q™5 $¤)Ñ,Ô,ð !ð !�Ø�Q˜�T”7ð !Ø ˜5˜5˜5ð!ð!ð ˆtr,   c                 óR   — |                       ¦   «         o|                      ¦   «         S )z*Return ``True`` if the matrix is diagonal.)rÜ   rß   r?   s    r$   Úis_diagonalzDFM.is_diagonalè  s   € à�}Š}‰ŒÐ2 4§=¢=¡?¤?Ð2r,   c                 óŒ   — | j         }t          | j        ¦  «        D ]'}t          | j        ¦  «        D ]}|||f         r  dS ŒŒ(dS )z1Return ``True`` if the matrix is the zero matrix.FTrÞ   rÛ   s       r$   Úis_zero_matrixzDFM.is_zero_matrixì  se   € àŒHˆÝ�t”yÑ!Ô!ð 	!ð 	!ˆAÝ˜4œ9Ñ%Ô%ð !ð !�Ø�Q˜�T”7ð !Ø ˜5˜5˜5ð!ð!ð ˆtr,   c                 óN   — |                       ¦   «                              ¦   «         S )z5Return the number of non-zero elements in the matrix.)rC   Únnzr?   s    r$   rå   zDFM.nnzõ  ó   € à�{Š{‰}Œ}× Ò Ñ"Ô"Ð"r,   c                 óN   — |                       ¦   «                              ¦   «         S )z7Return the strongly connected components of the matrix.)rC   Úsccr?   s    r$   rè   zDFM.sccù  ræ   r,   r   r   c                 ó4   — | j                              ¦   «         S )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#   Údetr?   s    r$   rê   zDFM.detý  s   € ðb Œx�|Š|‰~Œ~Ðr,   c                 ój   — | j                              ¦   «                              ¦   «         ddd…         S )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Úcoeffsr?   s    r$   rí   zDFM.charpoly0  s0   € ðT Œx× Ò Ñ"Ô"×)Ò)Ñ+Ô+¨D¨D¨b¨DÔ1Ð1r,   c                 óV  — | j         }| j        \  }}||k    rt          d¦  «        ‚|t          k    rt	          d|z  ¦  «        ‚|t
          k    rJ	 |                      | j                             ¦   «         ¦  «        S # t          $ r t          d¦  «        ‚w xY wt          d|z  ¦  «        ‚)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   r/   r#   ÚinvÚZeroDivisionErrorr   r8   )r.   ÚKr   r€   s       r$   rð   zDFM.inv\  s»   € ðn ŒKˆØŒz‰ˆˆ1à�Š6ˆ6Ý(Ð)LÑMÔMÐMà•Š7ˆ7ÝÐ 8¸1Ñ <Ñ=Ô=Ð=Ø•"ŠWˆWðMØ—}’} T¤X§\¢\¡^¤^Ñ4Ô4Ð4øÝ$ð Mð Mð MÝ0Ð1KÑLÔLÐLðMøøøõ
 &Ð&KÈaÑ&OÑPÔPÐPs   Á+A< Á<Bc                 ó¨   — |                       ¦   «                              ¦   «         \  }}}|                     ¦   «         |                     ¦   «         |fS )z*Return the LU decomposition of the matrix.)rC   Úlur]   )r.   ÚLÚUÚswapss       r$   rô   zDFM.lu¥  s>   € à—k’k‘m”m×&Ò&Ñ(Ô(‰ˆˆ1ˆeØ�xŠx‰zŒz˜1Ÿ8š8™:œ: uÐ,Ð,r,   c           
      ón  — | j         |j         k    st          d| j         ›d|j         ›�¦  «        ‚| j         j        st          d| j         z  ¦  «        ‚| j        \  }}|j        \  }}||k    rt	          d|›d|›d|›d|›�¦  «        ‚||f}||k    rK|                      ¦   «                              |                     ¦   «         ¦  «                             ¦   «         S 	 | j         	                    |j        ¦  «        }n# t          $ r t          d¦  «        ‚w xY w|                      ||| j         ¦  «        S )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   rC   Úlu_solver]   r#   Úsolverñ   r   r   )r.   Úrhsr   r€   r‚   ÚkÚ	sol_shapeÚsols           r$   rú   zDFM.lu_solveµ  sP  € ð\ Œ{˜cœjÒ(Ð(Ý�-À$Ä+À+À+ÈsÌzÈzÐ ZÑ[Ô[Ð[ð
 Œ{Ô#ð 	HÝÐ 8¸4¼;Ñ FÑGÔGÐGàŒz‰ˆˆ1ØŒy‰ˆˆ1Ø�Š6ˆ6Ý�,ÈQÈQÈQÐPQÐPQÐPQÐSTÐSTÐSTÐVWÐVWÐXÑYÔYÐYØ˜�Fˆ	ð �Š6ˆ6Ø—;’;‘=”=×)Ò)¨#¯*ª*©,¬,Ñ7Ô7×>Ò>Ñ@Ô@Ð@ð	QØ”(—.’. ¤Ñ)Ô)ˆCˆCøÝ ð 	Qð 	Qð 	QÝ,Ð-OÑPÔPÐPð	Qøøøð �yŠy˜˜i¨¬Ñ5Ô5Ð5s   ÃC> Ã>Dc                 ó€   — |                       ¦   «                              ¦   «         \  }}|                     ¦   «         |fS )ú/Return a basis for the nullspace of the matrix.)rC   Ú	nullspacer]   )r.   ra   Ú	nonpivotss      r$   r  zDFM.nullspace   s4   € ð& Ÿš™œ×0Ò0Ñ2Ô2‰ˆˆYØ�zŠz‰|Œ|˜YÐ&Ð&r,   Nc                 ó„   — |                       ¦   «                              |¬¦  «        \  }}|                     ¦   «         |fS )r  )Úpivots)r[   Únullspace_from_rrefr]   )r.   r  Úsdmr  s       r$   r  zDFM.nullspace_from_rref  s9   € ð Ÿš™œ×:Ò:À&Ð:ÑIÔI‰ˆˆYØ�zŠz‰|Œ|˜YÐ&Ð&r,   c                 ór   — |                       ¦   «                              ¦   «                              ¦   «         S )z+Return a particular solution to the system.)rC   Ú
particularr]   r?   s    r$   r	  zDFM.particular  s(   € à�{Š{‰}Œ}×'Ò'Ñ)Ô)×0Ò0Ñ2Ô2Ð2r,   ç®Gáz®ï?çR¸…ëQà?ÚzbasisÚapproxc                 ó  — d„ } ||¦  «        } ||¦  «        }d|cxk     rdk     sn t          d¦  «        ‚| j        \  }}| j                             ¦   «         |k    rt	          d¦  «        ‚| j                             |||||¬¦  «        S )zACall the fmpz_mat.lll() method but check rank to avoid segfaults.c                 óš   — t          j        | ¦  «        r)t          | j        ¦  «        t          | j        ¦  «        z  S t          | ¦  «        S ©N)r   Úof_typeÚfloatÚ	numeratorÚdenominator)Úxs    r$   Úto_floatzDFM._lll.<locals>.to_float*  s<   € ÝŒz˜!‰}Œ}ð  Ý˜Qœ[Ñ)Ô)­E°!´-Ñ,@Ô,@Ñ@Ð@å˜Q‘x”x�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)	r.   r  r  r  r#   r  r  r   r€   s	            r$   Ú_lllzDFM._lll   s­   € ð	 ð 	 ð 	 ð �˜‘”ˆØˆh�s‰mŒmˆà�eÐÐÒÐ˜aÒÐÐÐÝÐAÑBÔBÐBð Œz‰ˆˆ1ØŒ8�=Š=‰?Œ?˜aÒÐÝÐMÑNÔNÐNð Œx�|Š| i°uÀ#È3ÐUYˆ|ÑZÔZÐZr,   ç      è?c                 óä   — | j         t          k    rt          d| j         z  ¦  «        ‚| j        | j        k    rt          d¦  «        ‚|                      |¬¦  «        }|                      |¦  «        S )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.)r  )r!   r   r   r)   r*   r   r  r/   )r.   r  r#   s      r$   r  zDFM.lll>  sj   € ð, Œ;�"ÒÐÝÐ 5¸¼Ñ CÑDÔDÐDØŒY˜œÒ"Ð"ÝÐMÑNÔNÐNà�iŠi˜eˆiÑ$Ô$ˆØ�}Š}˜SÑ!Ô!Ð!r,   c                 óD  — | j         t          k    rt          d| j         z  ¦  «        ‚| j        | j        k    rt          d¦  «        ‚|                      d|¬¦  «        \  }}|                      |¦  «        }|                      || j        | j        f| j         ¦  «        }||fS )ad  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.
        r   r!  T)r  r  )	r!   r   r   r)   r*   r   r  r/   r   )r.   r  r#   ÚTÚbasisÚT_dfms         r$   Úlll_transformzDFM.lll_transform\  s™   € ð2 Œ;�"ÒÐÝÐ 5¸¼Ñ CÑDÔDÐDØŒY˜œÒ"Ð"ÝÐMÑNÔNÐNà—’ T°�Ñ7Ô7‰ˆˆQØ—’˜cÑ"Ô"ˆØ—	’	˜!˜dœi¨¬Ð3°T´[ÑAÔAˆØ�eˆ|Ðr,   r  )Fr
  r  r  r  )r  )NÚ__name__Ú
__module__Ú__qualname__Ú__doc__ÚfmtÚis_DFMÚis_DDMr%   Úclassmethodr   r/   r'   r<   r   Úpropertyr@   rD   rH   rM   rP   rS   rU   rC   r[   r]   r_   rb   rf   ri   rk   rm   rp   rs   rw   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&  rO   r,   r$   r   r   E   sÔ  € € € € € ð ð  ðD €CØ€FØ€Fð,ð ,ð ,ð ðð ñ „[ðð7ð 7ð 7ð ð	Mð 	Mñ „[ð	Mð ð"ð "ñ „[ð"ð ðMð Mñ „[ðMð ð1ð 1ñ „Xð1ð"ð "ð "ð/ð /ð /ðEð Eð Eð ð,ð ,ñ „[ð,ð!ð !ð !ð3ð 3ð 3ðFð Fð FðFð Fð Fðð ð ðð ð ð  ðCð Cñ „[ðCð ð	'ð 	'ñ „[ð	'ð"ð "ð "ð*ð *ð *ð ðAð Añ „[ðAð&ð &ð &ð ð9ð 9ñ „[ð9ð&ð &ð &ð ð9ð 9ñ „[ð9ð$ð $ð $ð*ð *ð *ðMð Mð Mð]ð ]ð ]ð]ð ]ð ]ð7ð 7ð 7ð1ð 1ð 1ð<3ð 3ð 3ð(ð (ð (ð3ð 3ð 3ð3ð 3ð 3ð/ð /ð /ð/ð /ð /ðFð Fð Fð
Cð Cð Cðð ð ð ð5ð 5ñ „[ð5ð ð0ð 0ñ „[ð0ð
 ð+ð +ñ „[ð+ð
 ð3ð 3ñ „[ð3ð>ð >ð >ðTð Tð TðLð Lð LðLð Lð Lð3ð 3ð 3ðð ð ðð ð ð3ð 3ð 3ðð ð ð#ð #ð #ð#ð #ð #ð Ð WÐ-Ñ-Ô-ð0ð 0ñ .Ô-ð0ðd Ð WÐ-Ñ-Ô-ð)2ð )2ñ .Ô-ð)2ðV Ð WÐ-Ñ-Ô-ðFQð FQñ .Ô-ðFQðP-ð -ð -ð  Ð WÐ-Ñ-Ô-ðH6ð H6ñ .Ô-ðH6ðT'ð 'ð 'ð,'ð 'ð 'ð 'ð3ð 3ð 3ð[ð [ð [ð [ð< Ð WÐ-Ñ-Ô-ð"ð "ð "ñ .Ô-ð"ð: Ð WÐ-Ñ-Ô-ð ð  ð  ñ .Ô-ð ð  ð  r,   )rW   )rZ   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.ddmrW   rZ   rO   r,   r$   ú<module>r8     sY  ððT -Ð ,Ð ,Ð ,Ð ,Ð ,Ø 4Ð 4Ð 4Ð 4Ð 4Ð 4Ø 8Ð 8Ð 8Ð 8Ð 8Ð 8à &Ð &Ð &Ð &Ð &Ð &Ð &Ð &ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð �7ÒÐØ�uÐð 	ˆ�gÑÔ€ð ˆ'€ð Ð ' Ð+Ñ+Ô+ðwð wð wð wð wñ wô wñ ,Ô+ðwðv )Ð (Ð (Ð (Ð (Ð (Ø (Ð (Ð (Ð (Ð (Ð (Ð (Ð (r,   