Ë
    O/æj\3  ã                   ó~   — 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ddœd„Zy)z,Functions returning normal forms of matricesé    )Údefaultdicté   )ÚDomainMatrix)ÚDMDomainErrorÚDMShapeError)Úsymmetric_residue)ÚQQÚZZc                 ór   — t        | «      }t        j                  || j                  | j                  «      }|S )aJ  
    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      úc/root/repos/pocs/video-evals/.venv/lib/python3.12/site-packages/sympy/polys/matrices/normalforms.pyÚsmith_normal_formr      s/   € ô$ ˜QÓ€DÜ
×
Ñ
˜D !§(¡(¨A¯G©GÓ
4€CØ€Jó    c                 ó¢   — t        t        | «      «      D ]8  }| |   |   }||z  || |   |   z  z   | |   |<   ||z  || |   |   z  z   | |   |<   Œ: y ©N)ÚrangeÚlen)	r   ÚiÚjÚaÚbÚcÚdÚkÚes	            r   Úadd_columnsr"   (   sj   € ô ”3�q“6‹]ò "ˆØˆa‰D�‰GˆØ�A‘#˜˜!˜A™$˜q™'™	‘/ˆˆ!‰ˆQ‰Ø�A‘#˜˜!˜A™$˜q™'™	‘/ˆˆ!‰ˆQŠñ"r   c                 óš  ‡ ‡‡‡‡— ‰ j                   Š‰j                  sd}t        |«      ‚d‰ j                  v ry‰ j                  x\  ŠŠ}t	        ‰ j                  «       j                  j                  «       «      Š ˆfd„Šˆˆˆfd„}ˆˆfd„}t        ‰«      D �cg c]  }‰ |   d   dk7  sŒ|‘Œ }}|r |d   dk7  r‰ |d      ‰ d   c‰ d<   ‰ |d   <   nLt        ‰«      D �cg c]  }‰ d   |   dk7  sŒ|‘Œ }}|r&|d   dk7  r‰ D ]  }||d      |d   c|d<   ||d   <   Œ t        ˆ fd„t        d‰«      D «       «      st        ˆ fd	„t        d‰«      D «       «      rN |‰ «      Š  |‰ «      Š t        ˆ fd„t        d‰«      D «       «      rŒ/t        ˆ fd	„t        d‰«      D «       «      rŒNd|v rd}	n4t        ‰ dd
 D �
cg c]  }
|
dd
 ‘Œ	 c}
‰dz
  ‰dz
  f‰«      }t        |«      }	‰ d   d   rº‰ d   d   g}|j                  |	«       t        t        |«      dz
  «      D ]{  }||   ri‰j                  ||dz      ||   «      d   dk7  rH‰j                  ||dz      ||   «      }‰j                  ||   |«      d   ||dz      z  ||dz   <   |||<   Œq t!        |«      S  t!        |«      S |	‰ d   d   fz   }t!        |«      S c c}w c c}w c c}
w )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

    z8The matrix entries must be over a principal ideal domainr   © c                 ó’   •— t        ‰	«      D ]8  }| |   |   }||z  || |   |   z  z   | |   |<   ||z  || |   |   z  z   | |   |<   Œ: y r   )r   )
r   r   r   r   r   r   r   r    r!   Úcolss
            €r   Úadd_rowsz#invariant_factors.<locals>.add_rowsH   sg   ø€ ô �t“ò 	&ˆ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ñ	&r   c           
      ó†  •— | d   d   dk(  r| S | d   d   }t        d‰«      D ]›  }| |   d   dk(  rŒ‰j                  | |   d   |«      \  }}|dk(  r ‰
| d|dd| d«       Œ?‰j                  || |   d   «      \  }}}‰j                  | |   d   |«      d   }‰j                  ||«      d   }	 ‰
| d|||||	 «       |}Œ� | S ©Nr   r   )r   ÚdivÚgcdex)r   Úpivotr   r   Úrr   r   ÚgÚd_0Úd_jr'   r   Úrowss             €€€r   Úclear_columnz'invariant_factors.<locals>.clear_columnP   sö   ø€ àˆQ‰4�‰7�aŠ<ØˆHØ�!‘�Q‘ˆÜ�q˜$“ò 	ˆAØ�‰t�A‰w˜!Š|ØØ—:‘:˜a ™d 1™g uÓ-‰DˆAˆqØ�AŠvÙ˜˜A˜q ! Q¨¨¨AÕ.à Ÿ,™, u¨a°©d°1©gÓ6‘��1�aØ—j‘j  1¡ a¡¨!Ó,¨QÑ/�Ø—j‘j ¨Ó*¨1Ñ-�Ù˜˜A˜q ! Q¨¨c¨TÔ2Ø‘ð	ð ˆr   c           
      ó’  •— | d   d   dk(  r| S | d   d   }t        d‰
«      D ]¡  }| d   |   dk(  rŒ‰j                  | d   |   |«      \  }}|dk(  rt        | d|dd| d«       ŒB‰j                  || d   |   «      \  }}}‰j                  | d   |   |«      d   }‰j                  ||«      d   }	t        | d|||||	 «       |}Œ£ | S r)   )r   r*   r"   r+   )r   r,   r   r   r-   r   r   r.   r/   r0   r&   r   s             €€r   Ú	clear_rowz$invariant_factors.<locals>.clear_rowc   sö   ø€ àˆQ‰4�‰7�aŠ<ØˆHØ�!‘�Q‘ˆÜ�q˜$“ò 	ˆAØ�‰t�A‰w˜!Š|ØØ—:‘:˜a ™d 1™g uÓ-‰DˆAˆqØ�AŠvÜ˜A˜q ! Q¨¨A¨2¨qÕ1à Ÿ,™, u¨a°©d°1©gÓ6‘��1�aØ—j‘j  1¡ a¡¨!Ó,¨QÑ/�Ø—j‘j ¨Ó*¨1Ñ-�Ü˜A˜q ! Q¨¨3°°Ô5Ø‘ð	ð ˆr   c              3   ó4   •K  — | ]  }‰d    |   d k7  –— Œ y­w©r   Nr$   ©Ú.0r   r   s     €r   ú	<genexpr>z$invariant_factors.<locals>.<genexpr>�   ó   øè ø€ Ò3 ˆq�‰t�A‰w˜!�|Ñ3ùó   ƒr   c              3   ó4   •K  — | ]  }‰|   d    d k7  –— Œ y­wr6   r$   r7   s     €r   r9   z$invariant_factors.<locals>.<genexpr>‚   r:   r;   N)r   Úis_PIDÚ
ValueErrorr   ÚlistÚto_denseÚrepÚto_ddmr   Úanyr   r   Úextendr   r*   ÚgcdÚtuple)r   Úmsgr   r2   r4   r   Úindr   Úrowr   r-   Úlower_rightÚresultr.   r'   r&   r   r1   s   `             @@@@r   r   r   1   sè  ü€ ð �X‰X€FØ�=Š=ØHˆÜ˜‹oÐàˆA�G‰G�|ØàŸ™Ð �J€Dˆ$�ÜˆQ�Z‰Z‹\×Ñ×$Ñ$Ó&Ó'€Aô&öõ&ô( ˜D“kÖ
2� Q q¡T¨!¡W°£\Š1Ð
2€CÐ
2Ù
ˆs�1‰v˜Š{Ø˜C ™F™) Q q¡Tˆˆˆ!‰ˆa��A‘Šiä ›+Ö6�Q¨¨1©¨a©°A«ŠqÐ6ˆÐ6Ù�3�q‘6˜Q’;Øò :�Ø&)¨#¨a©&¡k°3°q±6Ð#��A‘˜˜C ™Fšð:ô Ó3¤U¨1¨T£]Ô3Ô3ÜÓ3¤U¨1¨T£]Ô3Ô3Ù˜‹OˆÙ�a‹Lˆô Ó3¤U¨1¨T£]Ô3Õ3ÜÓ3¤U¨1¨T£]Ô3Õ3ð 	ˆE�zØ‰ä"°1°Q°R°5Ö#9¨a A a b¢EÒ#9¸DÀ¹FÀDÈÁFÐ;KÈVÓTˆÜ  Ó-ˆàˆ�tˆA‚wØ�A‘$�q‘'�ˆØ�‰�dÔä”s˜6“{ 1‘}Ó%ò 	ˆAØ�aŠy˜VŸZ™Z¨¨q°©s©°V¸A±YÓ?ÀÑBÀaÒGØ—J‘J˜v a¨¡c™{¨F°1©IÓ6�Ø$Ÿj™j¨°©°AÓ6°qÑ9¸&ÀÀ1Á¹+ÑE��q˜‘s‘Ø��q’	àô �‹=Ðð	ô �‹=Ðð ˜˜1™˜a™˜
Ñ"ˆÜ�‹=ÐùòE 3ùò 7ùò $:s   ÂJ>Â,J>Ã!KÃ2KÆ=Kc                 óp   — t        j                  | |«      \  }}}| dk7  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   éÿÿÿÿr   )r
   r+   )r   r   ÚxÚyr.   s        r   Ú_gcdexrP   œ   sG   € ô �h‰h�q˜!‹n�G€A€qˆ!ØˆA‚v�!�a‘%˜1’*ØˆØ�a’%‰B˜QˆØˆa�ˆ7€Nr   c                 óð  — | j                   j                  st        d«      ‚| j                  \  }}| j	                  «       j
                  j                  «       j                  «       } |}t        |dz
  dd«      D ]Ð  }|dk(  r nÉ|dz  }t        |dz
  dd«      D ]R  }| |   |   dk7  sŒt        | |   |   | |   |   «      \  }}}| |   |   |z  | |   |   |z  }
}	t        | |||||
 |	«       ŒT | |   |   }|dk  rt        | ||dddd«       | }|dk(  r|dz  }Œ t        |dz   |«      D ]  }| |   |   |z  }t        | ||d| dd«       Œ! ŒÒ t        j                  | 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   rM   r   N)r   Úis_ZZr   r   r@   rA   rB   Úcopyr   rP   r"   r   Úfrom_repÚto_dfm_or_ddm)ÚAr   Únr    r   r   ÚuÚvr   r-   Úsr   Úqs                r   Ú_hermite_normal_formr]   ±   s¸  € ð8 �8‰8�>Š>ÜÐ<Ó=Ð=ð �7‰7�D€A€qØ	�
‰
‹×Ñ×ÑÓ!×&Ñ&Ó(€Að 	
€AÜ�1�q‘5˜"˜bÓ!ò !2ˆØ�Š6ñ Ø	ˆQ‰ˆô �q˜1‘u˜b "Ó%ò 	2ˆAØ�‰t�A‰w˜!‹|ô !  1¡ a¡¨!¨A©$¨q©'Ó2‘��1�aØ˜‘t˜A‘w !‘| Q q¡T¨!¡W°¡\�1�Ü˜A˜q ! Q¨¨A¨2¨qÕ1ð	2ð ˆa‰D�‰GˆàˆqŠ5Ü˜˜1˜a  Q¨¨AÔ.Ø�ˆAð �Š6Ø�‰F‰Aô
 ˜1˜q™5 !“_ò 2�Ø�a‘D˜‘G˜q‘L�Ü˜A˜q ! Q¨¨¨A¨qÕ1ñ2ð?!2ôH × Ñ  §¡Ó!2Ó3²A°q±r°EÑ:Ð:r   c                 óØ  — | j                   j                  st        d«      ‚t        j                  |«      r|dk  rt        d«      ‚d„ }t        t        «      }| j                  \  }}||k  rt        d«      ‚| j                  «       j                  j                  «       j                  «       } |}|}t        |dz
  dd«      D �]  }|dz  }t        |dz
  dd«      D ]P  }	| |   |	   dk7  sŒt        | |   |   | |   |	   «      \  }
}}| |   |   |z  | |   |	   |z  }} || |||	|
|| |«       ŒR | |   |   }|dk(  r
|x| |   |<   }t        ||«      \  }
}}t        |«      D ]  }|
| |   |   z  |z  ||   |<   Œ ||   |   dk(  r|||   |<   t        |dz   |«      D ]%  }	||   |	   ||   |   z  }t        ||	|d| dd«       Œ' ||z  }�Œ t!        |||ft        «      j                  «       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.)

    rR   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  |«      | |   |<   ŒT y 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_R0  s†   € ô ”s˜1“v“ò 	FˆAØ�!‘�Q‘ˆAÜ'¨¨Q©°°Q°q±T¸!±W±Ñ)<ÀÑ(AÀ1ÓEˆAˆa‰D�‰GÜ'¨¨Q©°°Q°q±T¸!±W±Ñ)<ÀÑ(AÀ1ÓEˆAˆa‰D�ŠGñ	Fr   z2Matrix must have at least as many columns as rows.rM   r   )r   rS   r   r
   Úof_typer   Údictr   r   r@   rA   rB   rT   r   rP   r"   r   )rW   ÚDra   ÚWr   rX   r    r`   r   r   rY   rZ   r   r-   r[   r   Úiir\   s                     r   Ú_hermite_normal_form_modulo_Drg   þ   s9  € ðZ �8‰8�>Š>ÜÐ<Ó=Ð=Ü�:‰:�aŒ=˜A šEÜÐNÓOÐOòFô 	”DÓ€Aà�7‰7�D€A€qØˆ1‚uÜÐOÓPÐPØ	�
‰
‹×Ñ×ÑÓ!×&Ñ&Ó(€AØ	€AØ	€AÜ�1�q‘5˜"˜bÓ!ó ˆØ	ˆQ‰ˆÜ�q˜1‘u˜b "Ó%ò 	;ˆAØ�‰t�A‰w˜!‹|Ü   1¡ a¡¨!¨A©$¨q©'Ó2‘��1�aØ˜‘t˜A‘w !‘| Q q¡T¨!¡W°¡\�1�Ù! ! Q¨¨1¨a°°Q°B¸Õ:ð		;ð
 ˆa‰D�‰GˆØ�Š6ØˆOˆAˆa‰D�‰G�aÜ˜˜A“,‰ˆˆ1ˆaÜ˜“(ò 	&ˆBØ˜˜2™˜q™‘z A‘~ˆAˆb‰E�!Š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Ð1r   NF)rd   Ú
check_rankc                óà   — | j                   j                  st        d«      ‚|�A|r3| j                  t        «      j                  «       | 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.)

    rR   r   )	r   rS   r   Ú
convert_tor	   Úrankr   rg   r]   )rW   rd   rh   s      r   Úhermite_normal_formrl   V  s\   € ðv �8‰8�>Š>ÜÐ<Ó=Ð=Ø€}™j¨A¯L©L¼Ó,<×,AÑ,AÓ,CÀqÇwÁwÈqÁzÒ,QÜ,¨Q°Ó2Ð2ä# AÓ&Ð&r   )Ú__doc__Úcollectionsr   Údomainmatrixr   Ú
exceptionsr   r   Úsympy.ntheory.modularr   Úsympy.polys.domainsr	   r
   r   r"   r   rP   r]   rg   rl   r$   r   r   ú<module>rs      sH   ðÙ 2å #å &ß 3Ý 3ß &òò."òhòVò*J;òZU2ðp !%°õ @'r   