
    \hP                     N   S r SSKJr  SSKrSSKJrJr  SSKJr  SSK	J
r
  SSKJr  SSKJr  SS	KJr  SS
KJrJr  SSKJrJrJrJr  SSKJr  SSKJrJrJrJr  SSK J!r!  SSK"J#r#   " S S\5      r$  SS jr%S r&SS jr'SS jr(SS jr)SS jr*SS jr+SS jr,\#SSSS.S j5       r-g) z
Compute Galois groups of polynomials.

We use algorithms from [1], with some modifications to use lookup tables for
resolvents.

References
==========

.. [1] Cohen, H. *A Course in Computational Algebraic Number Theory*.

    )defaultdictN)Dummysymbols)	is_square)ZZ)
dup_random)dup_eval)dup_discriminant)dup_factor_listdup_irreducible_p)GaloisGroupExceptionget_resolvent_by_lookupdefine_resolvents	Resolvent)coeff_search)Polypoly_from_exprPolificationFailedComputationFailed)	dup_sqf_p)publicc                       \ rS rSrSrg)MaxTriesException#    N)__name__
__module____qualname____firstlineno____static_attributes__r       ]/var/www/auris/envauris/lib/python3.13/site-packages/sympy/polys/numberfields/galoisgroups.pyr   r   #   s    r!   r      c                 l  ^ [        S5      nU R                  5       nUc
  [        5       nUR                  U R                  5        U(       a  0 mSnSnU4S jn	[        U5       GHC  n
U(       a  U	" W5      n[        U5      n[        S U 5       5      nX-   W:  a)  US:X  a  US-  nUS-
  nOUS-  nU	" U5      n[        U5      n[        S5      /U Vs/ s H  n[        U5      PM     sn-   nO?[        U
S-  S-   U5      n[        R                  " SUS-
  5      n[        UU* U[        5      n[        XR                  5      n[        U R                  UU-
  5      U5      nUR                  U;  d  GM  [!        UR                  R#                  5       [        5      (       d  GM@  UU4s  $    [$        es  snf )a  
Given a univariate, monic, irreducible polynomial over the integers, find
another such polynomial defining the same number field.

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

See Alg 6.3.4 of [1].

Parameters
==========

T : Poly
    The given polynomial
max_coeff : int
    When choosing a transformation as part of the process,
    keep the coeffs between plus and minus this.
max_tries : int
    Consider at most this many transformations.
history : set, None, optional (default=None)
    Pass a set of ``Poly.rep``'s in order to prevent any of these
    polynomials from being returned as the polynomial ``U`` i.e. the
    transformation of the given polynomial *T*. The given poly *T* will
    automatically be added to this set, before we try to find a new one.
fixed_order : bool, default True
    If ``True``, work through candidate transformations A(x) in a fixed
    order, from small coeffs to large, resulting in deterministic behavior.
    If ``False``, the A(x) are chosen randomly, while still working our way
    up from small coefficients to larger ones.

Returns
=======

Pair ``(A, U)``

    ``A`` and ``U`` are ``Poly``, ``A`` is the
    transformation, and ``U`` is the transformed polynomial that defines
    the same number field as *T*. The polynomial ``A`` maps the roots of
    *T* to the roots of ``U``.

Raises
======

MaxTriesException
    if could not find a polynomial before exceeding *max_tries*.

X      c                 J   > TR                  U [        U S5      5      nUTU '   U$ )N   )getr   )degreegencoeff_generatorss     r"   get_coeff_generator9tschirnhausen_transformation.<locals>.get_coeff_generatorc   s,    ""6<+BC#& 
r!   c              3   8   #    U  H  n[        U5      v   M     g 7f)N)abs).0cs     r"   	<genexpr>/tschirnhausen_transformation.<locals>.<genexpr>x   s     +FqCFFFs   r)      )r   r+   setaddreprangenextmaxr   minrandomrandintr   r   r,   	resultantr   to_listr   )T	max_coeff	max_trieshistoryfixed_orderr%   ndeg_coeff_sumcurrent_degreer.   ir,   coeffsmr3   aCdAUr-   s                       @r"   tschirnhausen_transformationrR   '   s   b 	c
A	
A%KK
 9  &n5C#YF+F++A!M1!Q&!Q&M%2Q%6N"a'N).9cA&1&Q2a5&11A AqD1Hi(Aq!a%(A1qb!R(AEENQU#Q'55Iaeemmor$B$Ba4KM N  2s   F1c                     [        U [        5      (       a  U R                  5       O[        U [        5      n[        U5      $ )z?Convenience to check if a Poly or dup has square discriminant. )
isinstancer   discriminantr
   r   r   )rB   rO   s     r"   has_square_discrV      s.    &q$//5Ea5LAQ<r!   Fc                 f    SSK Jn  [        U 5      (       a  UR                  S4$ UR                  S4$ )zj
Compute the Galois group of a polynomial of degree 3.

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

Uses Prop 6.3.5 of [1].

r   )S3TransitiveSubgroupsTF)sympy.combinatorics.galoisrX   rV   A3S3)rB   rD   	randomizerX   s       r"   _galois_group_degree_3r]      s9     A0?0B0B"%%t, 4'**E24r!   c           	         SSK Jn  SSKJn  [	        S5      nUS   US   -  US   US   -  -   nU" S5      U" S5      " SS5      U" S5      " SS5      /n[        XeU5      nUS   US   S-  -  US   US   S-  -  -   US   US   S-  -  -   US   US   S-  -  -   n	U" S5      U" S5      " SS5      /n
[        5       n[        U5       GH6  nUS:  a  [        XUU(       + S9u  pUR                  U S	S
9u  pn[        U[        5      (       d  MF  [        U 5      nUc'  U(       a  UR                  S	4s  $ UR                  S4s  $ U(       a  UR                  S	4s  $ X   nU	R!                  [#        UU" U5      5      S	S9nU
 Vs/ s H  nUU-  U-  PM     nn[        UUU5      nUR                  U 5      u  n  n[%        U[        5      nUS:X  a  GM	  ['        U5      (       a  UR(                  S4s  $ UR*                  S4s  $    [,        es  snf )z
Compute the Galois group of a polynomial of degree 4.

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

Follows Alg 6.3.7 of [1], using a pure root approximation approach.

r   PermutationS4TransitiveSubgroupszX0 X1 X2 X3r'   r)   r&   rD   rE   rF   T)find_integer_rootFsimultaneous) sympy.combinatorics.permutationsr`   rY   rb   r   r   r7   r:   rR   eval_for_polyr   r   rV   A4S4Vsubszipr
   r   C4D4r   )rB   rD   r\   r`   rb   r%   F1s1R1F2_pres2_prerE   rJ   _R_dupi0sq_discsigmaF2taus2R2rO   s                          r"   "_galois_group_degree_4_root_approxr~      sN    =@A
 
1adQqT!A$Y	BAAq!Aq!
B
 
2"	B
 qT!A$'\AaD1qL(1Q4!a<7!A$qtQw,FFAAq!F
 eG9q5/8?@IMKDA ''T'B"## "!$: 9@*--t4 </22E:< )++T22  [[Qa)[=)/0#eCio0r1b!&&q)q!UB'6Q<<),,e44),,e44] `  1s   Hc                 P   SSK Jn  [        5       n[        U5       H8  n[	        U S5      n[        U[        5      (       a    O[        XUU(       + S9u  ppM:     [        e[        U[        5      n[        [        US    V	V
s/ s H  u  p[        U	5      S-
  /U
-  PM     sn
n	/ 5      5      nUS/:X  a,  [        U 5      (       a  UR                  S4$ UR                  S4$ U/ SQ:X  a  UR                   S4$ U/ S	Q:X  a  UR"                  S4$ US
S/:X  d   eUR$                  S4$ s  sn
n	f )z
Compute the Galois group of a polynomial of degree 4.

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

Based on Alg 6.3.6 of [1], but uses resolvent coeff lookup.

r   ra   rc   r)      TFr)   r)      )r'   r'   r'   r'   r   )rY   rb   r7   r:   r   r   r   rR   r   r   sortedsumlenrV   ri   rj   rn   rk   ro   )rB   rD   r\   rb   rE   rJ   rv   ru   flreLs               r"   _galois_group_degree_4_lookupr      s=    AeG9'1-UB+A4;<EG1	    
	#Bs%'U%*TQQ!qU	 	A 	QCx4CA4F4F&))40 	4'**E2	4 	I~%((%00I~%''..A;;!$$e,,s    D"c           	         SSK Jn  SSKJn  [	        S5      n[        5       nUS   u  pxn	UR                  " U6 n[        XuU	5      n
[        5       nSn[        U5       GH  nUS:  a  [        XUU(       + S9u  p[        U S5      n[        U[        5      (       d  M?  U(       d^  [        U 5      n[        U[        5      (       a'  U(       a  UR                   S	4s  $ UR"                  S4s  $ U(       d  UR$                  S4s  $ S	nU
R'                  U 5      nUR)                  5        H  u  nn[+        UU[        5      (       a  M    O   UnUS   US   S
-  -  US   US
   S
-  -  -   US
   US   S
-  -  -   US   US   S
-  -  -   US   US   S
-  -  -   nU" S5      U" S5      " SS5      " S
S5      /nWnU	U   nUR-                  [/        UU" U5      5      S	S9nU Vs/ s H  nUU-  U-  PM     nn[        UUU5      nUR1                  U 5      u  n  n[3        U[        5      nUS:X  a  GM  [5        U5      (       a  UR6                  S	4s  $ UR8                  S	4s  $    [:        es  snf )z
Compute the Galois group of a polynomial of degree 5.

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

Based on Alg 6.3.9 of [1], but uses a hybrid approach, combining resolvent
coeff lookup, with root approximation.

r   S5TransitiveSubgroupsr_   zX0,X1,X2,X3,X4)r6   r)   Frc   r)   Tr'   r&   r   re   )rY   r   rg   r`   r   r   as_exprr   r7   r:   rR   r   r   r   rV   r   A5S5M20 round_roots_to_integers_for_polyitemsr	   rl   rm   rh   r
   r   C5D5r   )rB   rD   r\   r   r`   X5resF51ru   s51R51rE   reached_second_stagerJ   R51_duprx   rounded_rootspermutation_indexcandidate_rootr%   rs   rt   rw   ry   rz   r{   r|   r}   rv   rO   s                                 r"   _galois_group_degree_5_hybridr   )  s    A<	!	"B

Cf+KCC
++r
C
CS
!CeG 9q5/8?@IMKDA *!Q/"%%
 $%a(G "--<C.1148 @366>@ -11599  $ <<Q? 2?1D1D1F-~G^R88 2G 1adAg!QqT1W,qtAaD!G|;ad1Q47lJQqTRSTURVXYRY\YNN1a A&

 B[[Qa)[=)/0#eCio0r1b!&&q)q!UB'6Q<<),,d33),,d33m p  1s   I!c                 $   SSK Jn  U n[        5       n[        U5       H8  n[	        U S5      n[        U[        5      (       a    O[        XUU(       + S9u  pM:     [        e[        U 5      n	[        U[        5      (       a#  U	(       a  UR                  S4$ UR                  S4$ U	(       d  UR                  S4$ [        U[        R                  " U5      S9R!                  5       S   n
[#        U
5      S:X  a  UR$                  S4$ UR&                  S4$ )	z
Compute the Galois group of a polynomial of degree 5.

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

Based on Alg 6.3.9 of [1], but uses resolvent coeff lookup, plus
factorization over an algebraic extension.

r   r   r)   rc   TF)domainr6   )rY   r   r7   r:   r   r   r   rR   r   rV   r   r   r   r   r   alg_field_from_polyfactor_listr   r   r   )rB   rD   r\   r   _TrE   rJ   rv   ru   rx   r   s              r"   (_galois_group_degree_5_lookup_ext_factorr   z  s
    A	
BeG9'1-UB+A4;<EG1	   a G##4;&))40 	8+..6	8 %))511
 
b//3	4	@	@	B1	EB
2w!|%(($//%(($//r!   c                     SSK Jn  [        5       n[        U5       H8  n[	        U S5      n[        U[        5      (       a    O[        XUU(       + S9u  ppM:     [        e[        U[        5      n[        [        5      n	US    H%  u  pU	[        U
5      S-
     R                  U
5        M'     [        [        U	R!                  5        VVs/ s H  u  pU/[        U5      -  PM     snn/ 5      5      n[#        U 5      nU/ SQ:X  a4  U	S   S   n[#        U5      (       a  UR$                  S4$ UR&                  S4$ USS/:X  aH  U	S   u  nn[#        U5      =(       d    [#        U5      nU(       a  UR(                  S4$ UR*                  S4$ USS	/:X  aI  U(       a  UR,                  S
4$ U	S	   S   n[#        U5      (       a  UR.                  S4$ UR0                  S4$ U/ SQ:X  a#  U(       a  UR2                  S
4$ UR4                  S4$ USS/:X  a#  U(       a  UR6                  S
4$ UR8                  S4$ U/ SQ:X  a  UR:                  S4$ US/:X  d   e[        5       n[        U5       H8  n[	        U S5      n[        U[        5      (       a    O[        XUU(       + S9u  ppM:     [        e[#        U 5      n[=        U[        5      (       a#  U(       a  UR>                  S
4$ UR@                  S4$ U(       a  URB                  S
4$ URD                  S4$ s  snnf )z
Compute the Galois group of a polynomial of degree 6.

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

Based on Alg 6.3.10 of [1], but uses resolvent coeff lookup.

r   )S6TransitiveSubgroupsr)   rc   )r)   r'   r&   r&   Fr'   r   Tr   r6   )r)   r)   r)   r&   r   )#rY   r   r7   r:   r   r   r   rR   r   r   r   listr   appendr   r   r   rV   C6D6G18G36mS4pA4xC2S4xC2ri   S4mPSL2F5PGL2F5r[   r   A6S6G36pG72)rB   rD   r\   r   rE   rJ   rv   ru   r   factors_by_degr   rO   ffr   T_has_sq_discf1f2
any_squares                     r"   _galois_group_degree_6_lookupr     sF    A eG9'1-UB+A4;<EG1	   		#B !&N1s1vz"))!,  	s#1#7#7#9#9%!c"g#9	 	A $A&MI~Aq!5DR5H5H&))51 	8+..6	8 
q!f"B$R(?OB,?
6@&**E2 	:+00%8	: 
q!f)--t44"1%B<KB<O<O*00%8 ?/55u=? 
i4A&))40 	9+//7	9 
q!f8E&--t4 	<+22E:	< 
l	%((%008O8 eG9'1-UB+A4;<EG1	   #A&M##4A&))40 	8+..6	8 7D&++T2 	9+//7	9ss   L
by_namerD   r\   c                    U=(       d    / nU=(       d    0 n [        U /UQ70 UD6u  pgUR                  XUS9$ ! [         a  n[        SSU5      eSnAff = f)al
  
Compute the Galois group for polynomials *f* up to degree 6.

Examples
========

>>> from sympy import galois_group
>>> from sympy.abc import x
>>> f = x**4 + 1
>>> G, alt = galois_group(f)
>>> print(G)
PermutationGroup([
(0 1)(2 3),
(0 2)(1 3)])

The group is returned along with a boolean, indicating whether it is
contained in the alternating group $A_n$, where $n$ is the degree of *T*.
Along with other group properties, this can help determine which group it
is:

>>> alt
True
>>> G.order()
4

Alternatively, the group can be returned by name:

>>> G_name, _ = galois_group(f, by_name=True)
>>> print(G_name)
S4TransitiveSubgroups.V

The group itself can then be obtained by calling the name's
``get_perm_group()`` method:

>>> G_name.get_perm_group()
PermutationGroup([
(0 1)(2 3),
(0 2)(1 3)])

Group names are values of the enum classes
:py:class:`sympy.combinatorics.galois.S1TransitiveSubgroups`,
:py:class:`sympy.combinatorics.galois.S2TransitiveSubgroups`,
etc.

Parameters
==========

f : Expr
    Irreducible polynomial over :ref:`ZZ` or :ref:`QQ`, whose Galois group
    is to be determined.
gens : optional list of symbols
    For converting *f* to Poly, and will be passed on to the
    :py:func:`~.poly_from_expr` function.
by_name : bool, default False
    If ``True``, the Galois group will be returned by name.
    Otherwise it will be returned as a :py:class:`~.PermutationGroup`.
max_tries : int, default 30
    Make at most this many attempts in those steps that involve
    generating Tschirnhausen transformations.
randomize : bool, default False
    If ``True``, then use random coefficients when generating Tschirnhausen
    transformations. Otherwise try transformations in a fixed order. Both
    approaches start with small coefficients and degrees and work upward.
args : optional
    For converting *f* to Poly, and will be passed on to the
    :py:func:`~.poly_from_expr` function.

Returns
=======

Pair ``(G, alt)``
    The first element ``G`` indicates the Galois group. It is an instance
    of one of the :py:class:`sympy.combinatorics.galois.S1TransitiveSubgroups`
    :py:class:`sympy.combinatorics.galois.S2TransitiveSubgroups`, etc. enum
    classes if *by_name* was ``True``, and a :py:class:`~.PermutationGroup`
    if ``False``.

    The second element is a boolean, saying whether the group is contained
    in the alternating group $A_n$ ($n$ the degree of *T*).

Raises
======

ValueError
    if *f* is of an unsupported degree.

MaxTriesException
    if could not complete before exceeding *max_tries* in those steps
    that involve generating Tschirnhausen transformations.

See Also
========

.Poly.galois_group

galois_groupr)   Nr   )r   r   r   r   )	fr   rD   r\   gensargsFoptexcs	            r"   r   r     sp    D :2D:2D81D1D1 >>'$-  / /  83778s   9 
AAA)
   r#   NT)r#   F).__doc__collectionsr   r>   sympy.core.symbolr   r   sympy.ntheory.primetestr   sympy.polys.domainsr   sympy.polys.densebasicr   sympy.polys.densetoolsr	   sympy.polys.euclidtoolsr
   sympy.polys.factortoolsr   r   *sympy.polys.numberfields.galois_resolventsr   r   r   r   "sympy.polys.numberfields.utilitiesr   sympy.polys.polytoolsr   r   r   r   sympy.polys.sqfreetoolsr   sympy.utilitiesr   r   rR   rV   r]   r~   r   r   r   r   r   r   r!   r"   <module>r      s    $  , - " - + 4 F  <J J - ",  IM-1hV4Tn(-VNb*0ZZ9z #(B% j/ j/r!   