§
    OŠtjâB  ã                   ó’   — d Z ddlmZ ddlmZ ddlmZmZ ddlm	Z	 ddl
mZmZ d„ Zd	„ Zd
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zdddœd„ZdS )z,Functions returning normal forms of matricesé    )Údefaultdicté   )ÚDomainMatrix)ÚDMDomainErrorÚDMShapeError)Úsymmetric_residue)ÚQQÚZZc                 ód   — t          | ¦  «        }t          j        || j        | j        ¦  «        }|S )aI  
    Return the Smith Normal Form of a matrix `m` over the ring `domain`.
    This will only work if the ring is a principal ideal domain.

    Examples
    ========

    >>> from sympy import ZZ
    >>> from sympy.polys.matrices import DomainMatrix
    >>> from sympy.polys.matrices.normalforms import smith_normal_form
    >>> m = DomainMatrix([[ZZ(12), ZZ(6), ZZ(4)],
    ...                   [ZZ(3), ZZ(9), ZZ(6)],
    ...                   [ZZ(2), ZZ(16), ZZ(14)]], (3, 3), ZZ)
    >>> print(smith_normal_form(m).to_Matrix())
    Matrix([[1, 0, 0], [0, 10, 0], [0, 0, 30]])

    )Úinvariant_factorsr   ÚdiagÚdomainÚshape)ÚmÚinvsÚsmfs      ú^/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/sympy/polys/matrices/normalforms.pyÚsmith_normal_formr      s.   € õ$ ˜QÑÔ€DÝ
Ô
˜D !¤(¨A¬GÑ
4Ô
4€CØ€Jó    c                 ó2  — | j         }| j        }|j        }|                      ¦   «         } t	          |d         ¦  «        D ]7}t	          |d         ¦  «        D ]}||k    rŒ	| |         |         |k    s  dS Œ Œ8t          |d         |d         ¦  «        }t	          d|¦  «        D ]s}| |dz
           |dz
           |k    r| |         |         |k    r dS Œ0|                     | |         |         | |dz
           |dz
           ¦  «        d         }||k    r dS ŒtdS )z8
    Checks that the matrix is in Smith Normal Form
    r   r   FT)r   r   ÚzeroÚto_listÚrangeÚminÚdiv)r   r   r   r   ÚiÚjÚupperÚrs           r   Úis_smith_normal_formr    (   s>  € ð ŒX€FØŒG€EØŒ;€DØ	�	Š	‰Œ€Aå�5˜”8‰_Œ_ð ð ˆÝ�u˜Q”x‘”ð 	ð 	ˆAØ�AŠvˆvØØ�Q”4˜”7˜d’?�?Ø�u�u�uð #ð	õ ��a”˜% œ(Ñ#Ô#€EÝ�1�e‰_Œ_ð ð ˆØˆQˆq‰SŒ6�!�A‘#Œ;˜$ÒÐØ�Œt�AŒw˜$ŠˆØ�u�uð ð —
’
˜1˜Qœ4 œ7 A a¨¡c¤F¨1¨Q©3¤KÑ0Ô0°Ô3ˆAØ�DŠyˆyØ�u�uð ð ˆ4r   c                 óà   — t          t          | ¦  «        ¦  «        D ]P}| |         |         }||z  || |         |         z  z   | |         |<   ||z  || |         |         z  z   | |         |<   ŒQd S ©N©r   Úlen©	r   r   r   ÚaÚbÚcÚdÚkÚes	            r   Úadd_columnsr,   E   sz   € õ •3�q‘6”6‰]Œ]ð "ð "ˆØˆaŒD�ŒGˆØ�A‘#˜˜!˜Aœ$˜qœ'™	‘/ˆˆ!ŒˆQ‰Ø�A‘#˜˜!˜Aœ$˜qœ'™	‘/ˆˆ!ŒˆQ‰ˆð"ð "r   c                 ól   — | j         }| j        }|                      ¦   «         } t          | ||d¬¦  «        S )a3  
    Return the tuple of abelian invariants for a matrix `m`
    (as in the Smith-Normal form)

    References
    ==========

    [1] https://en.wikipedia.org/wiki/Smith_normal_form#Algorithm
    [2] https://web.archive.org/web/20200331143852/https://sierra.nmsu.edu/morandi/notes/SmithNormalForm.pdf

    F©r   Úfull)r   r   r   Ú_smith_normal_decomp)r   r   r   s      r   r   r   N   s6   € ð ŒX€FØŒG€EØ	�	Š	‰Œ€AÝ  6°¸UÐCÑCÔCÐCr   c                 ó(  — | j         }| j        x\  }}}|                      ¦   «         } t          | ||d¬¦  «        \  }}}t	          j        |||¦  «                             ¦   «         }t	          ||||f¬¦  «        }t	          ||||f¬¦  «        }|||fS )aå  
    Return the Smith-Normal form decomposition of matrix `m`.

    Examples
    ========

    >>> from sympy import ZZ
    >>> from sympy.polys.matrices import DomainMatrix
    >>> from sympy.polys.matrices.normalforms import smith_normal_decomp
    >>> m = DomainMatrix([[ZZ(12), ZZ(6), ZZ(4)],
    ...                   [ZZ(3), ZZ(9), ZZ(6)],
    ...                   [ZZ(2), ZZ(16), ZZ(14)]], (3, 3), ZZ)
    >>> a, s, t = smith_normal_decomp(m)
    >>> assert a == s * m * t
    Tr.   )r   r   )r   r   r   r0   r   r   Úto_dense)	r   r   ÚrowsÚcolsr   r   ÚsÚtr   s	            r   Úsmith_normal_decompr7   `   s    € ð  ŒX€FØœÐ �J€Dˆ$�Ø	�	Š	‰Œ€Aå% a¨°uÀ4ÐHÑHÔH�J€Dˆ!ˆQÝ
Ô
˜D &¨%Ñ
0Ô
0×
9Ò
9Ñ
;Ô
;€Cå�Q˜v¨d°D¨\Ð:Ñ:Ô:€AÝ�Q˜v¨d°D¨\Ð:Ñ:Ô:€AØ��1ˆ9Ðr   c           
      óà
  ‡ ‡‡‡‡‡‡‡‡ ‡!‡"— ‰j         sd‰› �}t          |¦  «        ‚|\  ŠŠ‰j        Š"‰j        Šˆˆ"fd„}d|v r‰rd |‰¦  «         |‰¦  «        fS dS ‰r |‰¦  «        Š  |‰¦  «        Š!d„ Šˆˆˆˆ ˆˆ ˆ"fd„}ˆˆˆˆ ˆ!ˆ"fd„}ˆ ˆ"fd„t	          ‰¦  «        D ¦   «         }|rU|d         ‰"k    rI‰ |d                  ‰ d         c‰ d<   ‰ |d         <   ‰r#‰ |d                  ‰ d         c‰ d<   ‰ |d         <   n|ˆ ˆ"fd	„t	          ‰¦  «        D ¦   «         }|r^|d         ‰"k    rR‰ D ]%}	|	|d                  |	d         c|	d<   |	|d         <   Œ&‰r(‰!D ]%}	|	|d                  |	d         c|	d<   |	|d         <   Œ&t          ˆ ˆ"fd
„t	          d‰¦  «        D ¦   «         ¦  «        s*t          ˆ ˆ"fd„t	          d‰¦  «        D ¦   «         ¦  «        rh |¦   «           |¦   «          t          ˆ ˆ"fd
„t	          d‰¦  «        D ¦   «         ¦  «        °>t          ˆ ˆ"fd„t	          d‰¦  «        D ¦   «         ¦  «        °hˆfd„}
‰ d         d         dk    rs‰                     ‰ d         d         ¦  «        Š‰j        rd‰ d         d         z  Š‰‰j        k    r/‰ d         dxx         ‰z  cc<   ‰rˆfd„‰ d         D ¦   «         ‰ d<   d|v rd}nÈd„ ‰ dd…         D ¦   «         }t          |‰‰dz
  ‰dz
  f‰¬¦  «        }‰r•|\  }}}dgdg‰dz
  z  z   gd„ |D ¦   «         z   }dgdg‰dz
  z  z   gd„ |D ¦   «         z   }t          t          |
‰ |‰!|g¦  «        ¦  «        \  Š }Š!}|‰ z  Š ‰!|z  Š!‰                      ¦   «         Š ‰!                     ¦   «         Š!n|}‰ d         d         �rk‰ d         d         g}|                     |¦  «         t	          t          |¦  «        dz
  ¦  «        D �]%}||         ||dz            }}|�r‰                     ||¦  «        d         ‰"k    rí‰r‰                     ||¦  «        \  }}}n‰                     ||¦  «        }‰                     ||¦  «        d         }‰rŠ‰                     ||¦  «        d         } ‰‰ ||dz   dd|d¦  «         t#          ‰!||dz   d|dd¦  «          ‰‰ ||dz   d| dd¦  «         t#          ‰!||dz   dd| d¦  «          ‰‰ ||dz   dddd¦  «         ||z  ||dz   <   |||<   �Œ& n@‰r,‰dk    r‰ dd…         ‰ d         gz   Š ‰dk    rd„ ‰!D ¦   «         Š!|‰ d         d         fz   }‰rt%          |¦  «        ‰ ‰!fS t%          |¦  «        S )zë
    Return the tuple of abelian invariants for a matrix `m`
    (as in the Smith-Normal form). If `full=True` then invertible matrices
    ``s, t`` such that the product ``s, m, t`` is the Smith Normal Form
    are also returned.
    zBThe matrix entries must be over a principal ideal domain, but got c                 ó@   •‡ — ˆ ˆˆfd„t          ‰ ¦  «        D ¦   «         S )Nc                 óL   •‡— g | ]Šˆˆˆfd „t          ‰¦  «        D ¦   «         ‘Œ S )c                 ó$   •— g | ]}|‰k    r‰n‰‘ŒS © r<   )Ú.0r   r   Úoner   s     €€€r   ú
<listcomp>z@_smith_normal_decomp.<locals>.eye.<locals>.<listcomp>.<listcomp>Œ   s%   ø€ Ð;Ð;Ð;¨Q˜˜Qš˜�� DÐ;Ð;Ð;r   ©r   )r=   r   Únr>   r   s    @€€€r   r?   z5_smith_normal_decomp.<locals>.eye.<locals>.<listcomp>Œ   s;   øø€ ÐNÐNÐNÀÐ;Ð;Ð;Ð;Ð;Ð;µ%¸±(´(Ð;Ñ;Ô;ÐNÐNÐNr   r@   )rA   r>   r   s   `€€r   Úeyez!_smith_normal_decomp.<locals>.eye‹   s*   øø€ ØNÐNÐNÐNÐNÐNÅUÈ1ÁXÄXÐNÑNÔNÐNr   r   r<   c                 óì   — t          t          | d         ¦  «        ¦  «        D ]P}| |         |         }||z  || |         |         z  z   | |         |<   ||z  || |         |         z  z   | |         |<   ŒQd S )Nr   r#   r%   s	            r   Úadd_rowsz&_smith_normal_decomp.<locals>.add_rows˜   s€   € õ •s˜1˜Qœ4‘y”yÑ!Ô!ð 	&ð 	&ˆAØ�!”�Q”ˆAØ˜‘c˜A˜a œd 1œg™I‘oˆAˆaŒD�‰GØ˜‘c˜A˜a œd 1œg™I‘oˆAˆaŒD�‰GˆGð	&ð 	&r   c            
      ó   •— ‰d         d         } t          d‰¦  «        D ]í}‰|         d         ‰k    rŒ‰
                     ‰|         d         | ¦  «        \  }}|‰k    r' ‰	‰d|dd| d¦  «         ‰r ‰	‰d|dd| d¦  «         Œg‰
                     | ‰|         d         ¦  «        \  }}}‰
                     ‰|         d         |¦  «        }‰
                     | |¦  «        } ‰	‰d||||| ¦  «         ‰r ‰	‰d||||| ¦  «         |} Œîd S ©Nr   r   )r   r   ÚgcdexÚexquo)Úpivotr   r)   r   r&   r'   ÚgÚd_0Úd_jrD   r   r/   r   r3   r5   r   s            €€€€€€€r   Úclear_columnz*_smith_normal_decomp.<locals>.clear_column    sL  ø€ à�!”�Q”ˆÝ�q˜$‘”ð 	ð 	ˆAØ�Œt�AŒw˜$ŠˆØØ—:’:˜a œd 1œg uÑ-Ô-‰DˆAˆqØ�DŠyˆyØ�˜˜A˜q ! Q¨¨¨AÑ.Ô.Ð.Øð 3Ø�H˜Q  1 a¨¨Q¨B°Ñ2Ô2Ð2øà Ÿ,š, u¨a°¬d°1¬gÑ6Ô6‘��1�aØ—l’l 1 Q¤4¨¤7¨AÑ.Ô.�Ø—l’l 5¨!Ñ,Ô,�Ø�˜˜A˜q ! Q¨¨c¨TÑ2Ô2Ð2Øð 7Ø�H˜Q  1 a¨¨C°#°Ñ6Ô6Ð6Ø��ð	ð 	r   c            
      ó@  •— ‰d         d         } t          d‰	¦  «        D ]ý}‰d         |         ‰k    rŒ‰
                     ‰d         |         | ¦  «        \  }}|‰k    r/t          ‰d|dd| d¦  «         ‰rt          ‰d|dd| d¦  «         Œo‰
                     | ‰d         |         ¦  «        \  }}}‰
                     ‰d         |         |¦  «        }‰
                     | |¦  «        }t          ‰d||||| ¦  «         ‰rt          ‰d||||| ¦  «         |} Œþd S rF   )r   r   r,   rG   rH   )rI   r   r)   r   r&   r'   rJ   rK   rL   r4   r   r/   r   r6   r   s            €€€€€€r   Ú	clear_rowz'_smith_normal_decomp.<locals>.clear_row´   sD  ø€ à�!”�Q”ˆÝ�q˜$‘”ð 	ð 	ˆAØ�Œt�AŒw˜$ŠˆØØ—:’:˜a œd 1œg uÑ-Ô-‰DˆAˆqØ�DŠyˆyÝ˜A˜q ! Q¨¨A¨2¨qÑ1Ô1Ð1Øð 6Ý  1 a¨¨A°¨r°1Ñ5Ô5Ð5øà Ÿ,š, u¨a°¬d°1¬gÑ6Ô6‘��1�aØ—l’l 1 Q¤4¨¤7¨AÑ.Ô.�Ø—l’l 5¨!Ñ,Ô,�Ý˜A˜q ! Q¨¨3°°Ñ5Ô5Ð5Øð :Ý  1 a¨¨A¨s°S°DÑ9Ô9Ð9Ø��ð	ð 	r   c                 ó8   •— g | ]}‰|         d          ‰k    ¯|‘ŒS ©r   r<   ©r=   r   r   r   s     €€r   r?   z(_smith_normal_decomp.<locals>.<listcomp>É   s&   ø€ Ð
5Ð
5Ð
5� Q q¤T¨!¤W°¢_ _ˆ1 _ _ _r   c                 ó8   •— g | ]}‰d          |         ‰k    ¯|‘ŒS rQ   r<   )r=   r   r   r   s     €€r   r?   z(_smith_normal_decomp.<locals>.<listcomp>Ï   s&   ø€ Ð9Ð9Ð9�Q¨¨1¬¨a¬°Dª¨ˆq¨¨¨r   c              3   ó<   •K  — | ]}‰d          |         ‰k    V — ŒdS ©r   Nr<   rR   s     €€r   ú	<genexpr>z'_smith_normal_decomp.<locals>.<genexpr>Ø   ó/   øè è € Ð6Ð6 1ˆq�Œt�AŒw˜$ŠÐ6Ð6Ð6Ð6Ð6Ð6r   r   c              3   ó<   •K  — | ]}‰|         d          ‰k    V — ŒdS rU   r<   rR   s     €€r   rV   z'_smith_normal_decomp.<locals>.<genexpr>Ù   rW   r   c                 ól   •— t          | t          | ¦  «        t          | d         ¦  «        f‰¬¦  «        S )Nr   )r   r   )r   r$   )r   r   s    €r   Úto_domain_matrixz._smith_normal_decomp.<locals>.to_domain_matrixÝ   s-   ø€ Ý˜A¥c¨!¡f¤f­c°!°A´$©i¬iÐ%8ÀÐHÑHÔHÐHr   c                 ó   •— g | ]}|‰z  ‘ŒS r<   r<   )r=   Úelemr(   s     €r   r?   z(_smith_normal_decomp.<locals>.<listcomp>ç   s   ø€ Ð2Ð2Ð2 T˜˜q™Ð2Ð2Ð2r   c                 ó"   — g | ]}|d d…         ‘ŒS )r   Nr<   )r=   r   s     r   r?   z(_smith_normal_decomp.<locals>.<listcomp>ì   s    € Ð,Ð,Ð, �q˜˜˜”uÐ,Ð,Ð,r   Nr.   c                 ó   — g | ]}d g|z   ‘Œ	S rQ   r<   ©r=   Úrows     r   r?   z(_smith_normal_decomp.<locals>.<listcomp>ñ   ó   € Ð(FÐ(FÐ(F°s¨!¨¨s©Ð(FÐ(FÐ(Fr   c                 ó   — g | ]}d g|z   ‘Œ	S rQ   r<   r_   s     r   r?   z(_smith_normal_decomp.<locals>.<listcomp>ò   ra   r   éÿÿÿÿc                 ó6   — g | ]}|d d…         |d         gz   ‘ŒS )r   Nr   r<   r_   s     r   r?   z(_smith_normal_decomp.<locals>.<listcomp>  s+   € Ð5Ð5Ð5¨C�S˜˜˜”W  A¤˜xÑ'Ð5Ð5Ð5r   )Úis_PIDÚ
ValueErrorr   r>   r   ÚanyÚcanonical_unitÚis_Fieldr0   ÚlistÚmapr   Úextendr$   r   rG   Úgcdr,   Útuple)#r   r   r   r/   ÚmsgrB   rM   rO   Úindr`   rZ   r   Úlower_rightÚretÚs_smallÚt_smallÚs2Út2Úresultr   r&   r'   ÚxÚyr)   ÚalphaÚbetarD   r(   r4   r>   r3   r5   r6   r   s#   `` `                       @@@@@@@@r   r0   r0   |   sQ  øøøøøøøøøøø€ ð Œ=ð Ø[ÐSYÐ[Ð[ˆÝ˜‰oŒoÐà�J€Dˆ$ØŒ;€DØ
Œ*€CðOð Oð Oð Oð Oð Oð 	ˆE€z€zØð 	Ø�s�s˜4‘y”y # # d¡)¤)Ð+Ð+à�2àð ØˆC�‰IŒIˆØˆC�‰IŒIˆð&ð &ð &ðð ð ð ð ð ð ð ð ð ð ð(ð ð ð ð ð ð ð ð ð ð* 6Ð
5Ð
5Ð
5Ð
5•e˜D‘k”kÐ
5Ñ
5Ô
5€CØ
ð >ˆs�1Œv˜Š~ˆ~Ø˜C œFœ) Q q¤Tˆˆˆ!‰ˆa��A”‰iØð 	.Ø  A¤œi¨¨1¬ˆOˆAˆa‰D�!�C˜”F‘)øà9Ð9Ð9Ð9Ð9�% ™+œ+Ð9Ñ9Ô9ˆØð 	>�3�q”6˜T’>�>Øð :ð :�Ø&)¨#¨a¬&¤k°3°q´6Ð#��A‘˜˜C œF™˜Øð >Øð >ð >�CØ*-¨c°!¬f¬+°s¸1´vÐ'�C˜‘F˜C  A¤™K˜Kõ Ð6Ð6Ð6Ð6Ð6­¨a°©¬Ð6Ñ6Ô6Ñ6Ô6ð ÝÐ6Ð6Ð6Ð6Ð6­¨a°©¬Ð6Ñ6Ô6Ñ6Ô6ðàˆ‰ŒˆØˆ	‰Œˆõ Ð6Ð6Ð6Ð6Ð6­¨a°©¬Ð6Ñ6Ô6Ñ6Ô6ð ÝÐ6Ð6Ð6Ð6Ð6­¨a°©¬Ð6Ñ6Ô6Ñ6Ô6ðð
Ið Ið Ið Ið Ið 	ˆ„tˆA„w�!‚|€|Ø×!Ò! ! A¤$ q¤'Ñ*Ô*ˆØŒ?ð 	Ø�A�a”D˜”G‘ˆAØ�”
Š?ˆ?ØˆaŒD�ˆGˆGŒG�q‰LˆGˆG‰GØð 3Ø2Ð2Ð2Ð2¨Q¨q¬TÐ2Ñ2Ô2��!‘àˆE€z€zØˆˆà,Ð, a¨¨¨¤eÐ,Ñ,Ô,ˆÝ" ;°Ø˜a‘x ¨¡Ð*°ð7ñ 7ô 7ˆàð 
	Ø%(Ñ"ˆD�'˜7Ø�#˜˜˜T !™V™Ñ$Ð%Ð(FÐ(F¸gÐ(FÑ(FÔ(FÑFˆBØ�#˜˜˜T !™V™Ñ$Ð%Ð(FÐ(F¸gÐ(FÑ(FÔ(FÑFˆBÝ¥Ð$4°q¸"¸aÀ°nÑ EÔ EÑFÔF‰LˆAˆr�1�bØ�Q‘ˆAØ�B‘ˆAØ—	’	‘”ˆAØ—	’	‘”ˆAˆAàˆDàˆ„tˆA„wñ #Ø�A”$�q”'�ˆØ�Š�dÑÔÐå•s˜6‘{”{ 1‘}Ñ%Ô%ð 	ñ 	ˆAØ˜!”9˜f Q q¡SœkˆqˆAØñ �V—Z’Z  1Ñ%Ô% aÔ(¨DÒ0Ð0Øð )Ø$Ÿlšl¨1¨aÑ0Ô0‘G�A�q˜!˜!àŸ
š
 1 aÑ(Ô(�AàŸ
š
 1 aÑ(Ô(¨Ô+�Øð 7Ø!Ÿ:š: a¨Ñ+Ô+¨AÔ.�DØ�H˜Q  1 q¡5¨!¨Q°°1Ñ5Ô5Ð5Ý  1 a¨!¡e¨Q°°1°aÑ8Ô8Ð8Ø�H˜Q  1 q¡5¨!¨e¨V°Q¸Ñ:Ô:Ð:Ý  1 a¨!¡e¨Q°°D°5¸!Ñ<Ô<Ð<Ø�H˜Q  1 q¡5¨!¨Q°°AÑ6Ô6Ð6à %™i��q˜‘s‘Ø��q‘	‘	àøàð 	6Ø�aŠxˆxØ�a�b�b”E˜Q˜qœT˜F‘N�Ø�aŠxˆxØ5Ð5°1Ð5Ñ5Ô5�Ø˜˜1œ˜aœ˜
Ñ"ˆàð Ý�V‰}Œ}˜a Ð"Ð"å�V‰}Œ}Ðr   c                 ót   — t          j        | |¦  «        \  }}}| dk    r|| z  dk    rd}| dk     rdnd}|||fS )a§  
    This supports the functions that compute Hermite Normal Form.

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

    Let x, y be the coefficients returned by the extended Euclidean
    Algorithm, so that x*a + y*b = g. In the algorithms for computing HNF,
    it is critical that x, y not only satisfy the condition of being small
    in magnitude -- namely that |x| <= |b|/g, |y| <- |a|/g -- but also that
    y == 0 when a | b.

    r   rc   r   )r
   rG   )r&   r'   rx   ry   rJ   s        r   Ú_gcdexr}   "  sO   € õ Œh�q˜!‰nŒn�G€A€qˆ!ØˆA‚v€v�!�a‘%˜1’*�*ØˆØ�a’%�%ˆBˆB˜QˆØˆa�ˆ7€Nr   c                 óR  — | j         j        st          d¦  «        ‚| j        \  }}|                      ¦   «                              ¦   «         } |}t          |dz
  dd¦  «        D �]}|dk    r �n	|dz  }t          |dz
  dd¦  «        D ]x}| |         |         dk    rdt          | |         |         | |         |         ¦  «        \  }}}| |         |         |z  | |         |         |z  }
}	t          | |||||
 |	¦  «         Œy| |         |         }|dk     rt          | ||dddd¦  «         | }|dk    r|dz  }ŒÖt          |dz   |¦  «        D ])}| |         |         |z  }t          | ||d| dd¦  «         Œ*�Œt          j
        |                      ¦   «         ¦  «        dd…|d…f         S )aè  
    Compute the Hermite Normal Form of DomainMatrix *A* over :ref:`ZZ`.

    Parameters
    ==========

    A : :py:class:`~.DomainMatrix` over domain :ref:`ZZ`.

    Returns
    =======

    :py:class:`~.DomainMatrix`
        The HNF of matrix *A*.

    Raises
    ======

    DMDomainError
        If the domain of the matrix is not :ref:`ZZ`.

    References
    ==========

    .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*
       (See Algorithm 2.4.5.)

    úMatrix must be over domain ZZ.r   rc   r   N)r   Úis_ZZr   r   Úto_ddmÚcopyr   r}   r,   r   Úfrom_repÚto_dfm_or_ddm)ÚAr   rA   r*   r   r   ÚuÚvr)   r   r5   r'   Úqs                r   Ú_hermite_normal_formr‰   7  sæ  € ð8 Œ8Œ>ð >ÝÐ<Ñ=Ô=Ð=ð Œ7�D€A€qØ	�Š‰
Œ
�ŠÑÔ€Að 	
€AÝ�1�q‘5˜"˜bÑ!Ô!ð !2ñ !2ˆØ�Š6ˆ6ð ‰EØ	ˆQ‰ˆõ �q˜1‘u˜b "Ñ%Ô%ð 	2ð 	2ˆAØ�Œt�AŒw˜!Š|ˆ|õ !  1¤ a¤¨!¨A¬$¨q¬'Ñ2Ô2‘��1�aØ˜”t˜A”w !‘| Q q¤T¨!¤W°¡\�1�Ý˜A˜q ! Q¨¨A¨2¨qÑ1Ô1Ð1øØˆaŒD�ŒGˆàˆqŠ5ˆ5Ý˜˜1˜a  Q¨¨AÑ.Ô.Ð.Ø�ˆAð �Š6ˆ6Ø�‰FˆAˆAõ
 ˜1˜q™5 !‘_”_ð 2ð 2�Ø�a”D˜”G˜q‘L�Ý˜A˜q ! Q¨¨¨A¨qÑ1Ô1Ð1Ð1ñ2õ
 Ô  §¢Ñ!2Ô!2Ñ3Ô3°A°A°A°q°r°r°EÔ:Ð:r   c                 óh  — | j         j        st          d¦  «        ‚t          j        |¦  «        r|dk     rt          d¦  «        ‚d„ }t          t          ¦  «        }| j        \  }}||k     rt          d¦  «        ‚|  	                    ¦   «         } |}|}t          |dz
  dd¦  «        D �]a}|dz  }t          |dz
  dd¦  «        D ]u}	| |         |	         dk    rat          | |         |         | |         |	         ¦  «        \  }
}}| |         |         |z  | |         |	         |z  }} || |||	|
|| |¦  «         Œv| |         |         }|dk    r|x| |         |<   }t          ||¦  «        \  }
}}t          |¦  «        D ]}|
| |         |         z  |z  ||         |<   Œ ||         |         dk    r|||         |<   t          |dz   |¦  «        D ]5}	||         |	         ||         |         z  }t          ||	|d| dd¦  «         Œ6||z  }�Œct          |||ft          ¦  «                             ¦   «         S )a[  
    Perform the mod *D* Hermite Normal Form reduction algorithm on
    :py:class:`~.DomainMatrix` *A*.

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

    If *A* is an $m \times n$ matrix of rank $m$, having Hermite Normal Form
    $W$, and if *D* is any positive integer known in advance to be a multiple
    of $\det(W)$, then the HNF of *A* can be computed by an algorithm that
    works mod *D* in order to prevent coefficient explosion.

    Parameters
    ==========

    A : :py:class:`~.DomainMatrix` over :ref:`ZZ`
        $m \times n$ matrix, having rank $m$.
    D : :ref:`ZZ`
        Positive integer, known to be a multiple of the determinant of the
        HNF of *A*.

    Returns
    =======

    :py:class:`~.DomainMatrix`
        The HNF of matrix *A*.

    Raises
    ======

    DMDomainError
        If the domain of the matrix is not :ref:`ZZ`, or
        if *D* is given but is not in :ref:`ZZ`.

    DMShapeError
        If the matrix has more rows than columns.

    References
    ==========

    .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*
       (See Algorithm 2.4.8.)

    r   r   z0Modulus D must be positive element of domain ZZ.c                 ó$  — t          t          | ¦  «        ¦  «        D ]r}| |         |         }	t          ||	z  || |         |         z  z   |z  |¦  «        | |         |<   t          ||	z  || |         |         z  z   |z  |¦  «        | |         |<   Œsd S r"   )r   r$   r   )
r   ÚRr   r   r&   r'   r(   r)   r*   r+   s
             r   Úadd_columns_mod_Rz8_hermite_normal_form_modulo_D.<locals>.add_columns_mod_R¶  sž   € õ •s˜1‘v”v‘”ð 	Fð 	FˆAØ�!”�Q”ˆAÝ'¨¨Q©°°Q°q´T¸!´W±Ñ)<ÀÑ(AÀ1ÑEÔEˆAˆaŒD�‰GÝ'¨¨Q©°°Q°q´T¸!´W±Ñ)<ÀÑ(AÀ1ÑEÔEˆAˆaŒD�‰GˆGð	Fð 	Fr   z2Matrix must have at least as many columns as rows.rc   r   )r   r€   r   r
   Úof_typer   Údictr   r   r   r   r}   r,   r   r2   )r…   ÚDr�   ÚWr   rA   r*   rŒ   r   r   r†   r‡   r)   r   r5   r'   Úiirˆ   s                     r   Ú_hermite_normal_form_modulo_Dr“   „  sp  € ðZ Œ8Œ>ð >ÝÐ<Ñ=Ô=Ð=ÝŒ:�a‰=Œ=ð P˜A šE˜EÝÐNÑOÔOÐOðFð Fð Fõ 	•DÑÔ€AàŒ7�D€A€qØˆ1‚u€uÝÐOÑPÔPÐPØ	�	Š	‰Œ€AØ	€AØ	€AÝ�1�q‘5˜"˜bÑ!Ô!ð ñ ˆØ	ˆQ‰ˆÝ�q˜1‘u˜b "Ñ%Ô%ð 	;ð 	;ˆAØ�Œt�AŒw˜!Š|ˆ|Ý   1¤ a¤¨!¨A¬$¨q¬'Ñ2Ô2‘��1�aØ˜”t˜A”w !‘| Q q¤T¨!¤W°¡\�1�Ø!Ð! ! Q¨¨1¨a°°Q°B¸Ñ:Ô:Ð:øØˆaŒD�ŒGˆØ�Š6ˆ6ØˆOˆAˆaŒD�‰G�aÝ˜˜A‘,”,‰ˆˆ1ˆaÝ˜‘(”(ð 	&ð 	&ˆBØ˜˜2œ˜qœ‘z A‘~ˆAˆbŒE�!‰HˆHØˆQŒ4�Œ7�aŠ<ˆ<ØˆAˆaŒD�‰GÝ�q˜1‘u˜a‘”ð 	.ð 	.ˆAØ�!”�Q”˜1˜Qœ4 œ7Ñ"ˆAÝ˜˜1˜a  Q B¨¨1Ñ-Ô-Ð-Ð-Ø	ˆa‰ˆ‰Ý˜˜A˜q˜6¥2Ñ&Ô&×/Ò/Ñ1Ô1Ð1r   NF)r�   Ú
check_rankc                óô   — | j         j        st          d¦  «        ‚|�M|r;|                      t          ¦  «                             ¦   «         | j        d         k    rt          | |¦  «        S t          | ¦  «        S )a)  
    Compute the Hermite Normal Form of :py:class:`~.DomainMatrix` *A* over
    :ref:`ZZ`.

    Examples
    ========

    >>> from sympy import ZZ
    >>> from sympy.polys.matrices import DomainMatrix
    >>> from sympy.polys.matrices.normalforms import hermite_normal_form
    >>> m = DomainMatrix([[ZZ(12), ZZ(6), ZZ(4)],
    ...                   [ZZ(3), ZZ(9), ZZ(6)],
    ...                   [ZZ(2), ZZ(16), ZZ(14)]], (3, 3), ZZ)
    >>> print(hermite_normal_form(m).to_Matrix())
    Matrix([[10, 0, 2], [0, 15, 3], [0, 0, 2]])

    Parameters
    ==========

    A : $m \times n$ ``DomainMatrix`` over :ref:`ZZ`.

    D : :ref:`ZZ`, optional
        Let $W$ be the HNF of *A*. If known in advance, a positive integer *D*
        being any multiple of $\det(W)$ may be provided. In this case, if *A*
        also has rank $m$, then we may use an alternative algorithm that works
        mod *D* in order to prevent coefficient explosion.

    check_rank : boolean, optional (default=False)
        The basic assumption is that, if you pass a value for *D*, then
        you already believe that *A* has rank $m$, so we do not waste time
        checking it for you. If you do want this to be checked (and the
        ordinary, non-modulo *D* algorithm to be used if the check fails), then
        set *check_rank* to ``True``.

    Returns
    =======

    :py:class:`~.DomainMatrix`
        The HNF of matrix *A*.

    Raises
    ======

    DMDomainError
        If the domain of the matrix is not :ref:`ZZ`, or
        if *D* is given but is not in :ref:`ZZ`.

    DMShapeError
        If the mod *D* algorithm is used but the matrix has more rows than
        columns.

    References
    ==========

    .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*
       (See Algorithms 2.4.5 and 2.4.8.)

    r   Nr   )	r   r€   r   Ú
convert_tor	   Úrankr   r“   r‰   )r…   r�   r”   s      r   Úhermite_normal_formr˜   Ü  so   € ðv Œ8Œ>ð >ÝÐ<Ñ=Ô=Ð=Ø€}˜j€}¨A¯LªL½Ñ,<Ô,<×,AÒ,AÑ,CÔ,CÀqÄwÈqÄzÒ,QÐ,QÝ,¨Q°Ñ2Ô2Ð2å# AÑ&Ô&Ð&r   )Ú__doc__Úcollectionsr   Údomainmatrixr   Ú
exceptionsr   r   Úsympy.ntheory.modularr   Úsympy.polys.domainsr	   r
   r   r    r,   r   r7   r0   r}   r‰   r“   r˜   r<   r   r   ú<module>rŸ      s8  ðØ 2Ð 2à #Ð #Ð #Ð #Ð #Ð #à &Ð &Ð &Ð &Ð &Ð &Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø &Ð &Ð &Ð &Ð &Ð &Ð &Ð &ðð ð ð.ð ð ð:"ð "ð "ðDð Dð Dð$ð ð ð8cð cð cðLð ð ð*J;ð J;ð J;ðZU2ð U2ð U2ðp !%°ð @'ð @'ð @'ð @'ð @'ð @'ð @'r   