K iP>dZddlmZddlZddlmZmZddlmZddl m Z ddl m Z ddl mZdd lmZdd lmZmZdd lmZmZmZmZdd lmZdd lmZmZmZmZddl m!Z!ddl"m#Z#GddeZ$ ddZ%dZ&ddZ'ddZ(ddZ)ddZ*ddZ+ddZ,e#dddddZ-y) 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)Dummysymbols) is_square)ZZ) dup_random)dup_eval)dup_discriminant)dup_factor_listdup_irreducible_p)GaloisGroupExceptionget_resolvent_by_lookupdefine_resolvents Resolvent) coeff_search)Polypoly_from_exprPolificationFailedComputationFailed) dup_sqf_p)publicc eZdZy)MaxTriesExceptionN)__name__ __module__ __qualname__k/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/polys/numberfields/galoisgroups.pyrr#srrc8td}|j}| t}|j|j|rid}d}fd} t |D]1} |r|| } t | } td| D} || zkDr(|dk(r |dz }|dz }n|dz}| |} t | } tdg| Dcgc] }t|c}z}n>t| dzdz|}tjd|dz }t|| |t}t||j}t|j||z |}|j|vst!|jj#ts.||fcSt$cc}w)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*. XcJj|t|d}||<|S)N)getr)degreegencoeff_generatorss rget_coeff_generatorz9tschirnhausen_transformation..get_coeff_generatorcs,""6<+BC#&  rc32K|]}t|yw)N)abs).0cs r z/tschirnhausen_transformation..xs+qCF+sr&)rr(setaddreprangenextmaxrminrandomrandintrrr) resultantrto_listr)T max_coeff max_trieshistory fixed_orderr"n deg_coeff_sumcurrent_degreer+ir)coeffsmr/aCdAUr*s @rtschirnhausen_transformationrM'sb c A  A% KK  9 &  &n5C#YF+F++A!M1!Q&!Q&M%2Q%6N"a'N).9cA&1Q2a511A AqD1Hi(Aq!a%(A1qb!R(A AEEN QU#Q ' 55 Iaeemmor$Ba4KM&N 2sFcxt|tr|jnt|t}t |S)z?Convenience to check if a Poly or dup has square discriminant. ) isinstancer discriminantr rr)r=rJs rhas_square_discrQs+&q$/5Ea5LA Q<rFc\ddlm}t|r|jdfS|jdfS)z~ Compute the Galois group of a polynomial of degree 3. Explanation =========== Uses Prop 6.3.5 of [1]. r)S3TransitiveSubgroupsTF)sympy.combinatorics.galoisrSrQA3S3)r=r? randomizerSs r_galois_group_degree_3rXs6A0?0B " % %t ,4'**E24rc ddlm}ddlm}t d}|d|dz|d|dzz}|d|ddd|dddg}t |||}|d|ddzz|d|ddzzz|d|ddzzz|d|ddzzz} |d|dddg} t } t|D]"} | dkDrt||| | \} }|j|d \}} }t|tsDt|}|"|r|jd fcS|jd fcS|r|jd fcS||}| j!t#|||d }| Dcgc] }||z|z }}t |||}|j|\}} } t%|t}|dk(rt'|r|j(d fcS|j*d fcSt,cc}w) 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 PermutationS4TransitiveSubgroupsz X0 X1 X2 X3r$r&r#r?r@rAT)find_integer_rootF simultaneous) sympy.combinatorics.permutationsr[rTr]rrr2r5rM eval_for_polyrrrQA4S4Vsubszipr rC4D4r)r=r?rWr[r]r"F1s1R1F2_pres2_prer@rE_R_dupi0sq_discsigmaF2taus2R2rJs r"_galois_group_degree_4_root_approxrys]=@ A 1adQqT!A$Y BA Aq! Aq! B 2q" B qT!A$'\AaD1qL (1Q4!a< 7!A$qtQw, FFA Aq!F eG 9 .5 q5/Y8?@IMKDAq''T'B q"# "!$ :9@*--t4 </22E: < )++T2 2 2[[Qa)[ =)/ 0#eCio 0 0 r1b !&&q) q! UB ' 6  Q<),,e4 4),,e4 4].5` 1s9G4c .ddlm}t}t|D]3}t |d}t |t rnt|||| \}}5tt|t }tt|dD cgc]\} } t| dz g| zc} } g} | dgk(r't|r|jdfS|jdfS| gdk(r|j dfS| gd k(r|j"dfS| d d gk(sJ|j$dfScc} } w) 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. rr\r^r&TFr&r&)r$r$r$r$r})rTr]r2r5rrrrMrr sortedsumlenrQrdrerirfrj) r=r?rWr]r@rErqrpflreLs r_galois_group_degree_4_lookuprs<AeG 9  '1- UB  +A4;@-11599 $<H:cddlm}|}t}t|D]3}t |d}t |t rnt|||| \}}5tt|} t|t r| r|jdfS|jdfS| s|jdfSt|t j|j!d} t#| dk(r|j$dfS|j&dfS) 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. rrr&r^TF)domainr1)rTrr2r5rrrrMrrQr rrrralg_field_from_poly factor_listrrr) r=r?rWr_Tr@rErqrprsrs r(_galois_group_degree_5_lookup_ext_factorrzs A BeG 9  '1- UB  +A4;| d\}}t#|xs t#|}|r|j(dfS|j*dfS| dd gk(r?|r|j,d fS| d d}t#|r|j.dfS|j0dfS| gd k(r|r|j2d fS|j4dfS| dd gk(r|r|j6d fS|j8dfS| gd k(r|j:dfS| dgk(sJt}t|D]3}t |d}t |t rnt|||| \}}5tt#|}t=|t r|r|j>d fS|j@dfS|r|jBd fS|jDdfScc} } w)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&r^)r&r$r#r#Fr$r}Tr|r1)r&r&r&r#r{)#rTrr2r5rrrrMrr rlistrappendr~rrrQC6D6G18G36mS4pA4xC2S4xC2rdS4mPSL2F5PGL2F5rVr A6S6G36pG72)r=r?rWrr@rErqrprfactors_by_degrrJffr T_has_sq_discf1f2 any_squares r_galois_group_degree_6_lookuprsIAeG 9  '1- UB  +A4;>> 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)rrrr) frr?rWgensargsFoptexcs rrrstD :2D :2D81D1D13 >>'Y$-  // 83778s4 A A  A) r NT)r F).__doc__ collectionsrr9sympy.core.symbolrrsympy.ntheory.primetestrsympy.polys.domainsrsympy.polys.densebasicrsympy.polys.densetoolsr sympy.polys.euclidtoolsr sympy.polys.factortoolsr r *sympy.polys.numberfields.galois_resolventsr rrr"sympy.polys.numberfields.utilitiesrsympy.polys.polytoolsrrrrsympy.polys.sqfreetoolsrsympy.utilitiesrrrMrQrXryrrrrrrrrrs $ ,-"-+4F<JJ-",IM-1hV 4Tn(-VNb*0ZZ9z#(B%j/j/r