K iE dZddlmZddlmZddlmZddlmZddl m Z ddl m Z m Z mZdd lmZd Zdd Zd Ze ddZy )z,Computing integral bases for number fields. )Poly)AlgebraicField)ZZ)QQ)public)ModuleEndomorphismModuleHomomorphism PowerBasis) extract_fundamental_discriminantc|j}t||}|j\}}|dk(sJtd||}|D] \}}||z} ||z} t|t} t| t} | | z|z |z} t| |} | }|| fD]}|j |}||z}|j }||fS)zz Apply the "Dedekind criterion" to test whether the order needs to be enlarged relative to a given prime *p*. modulusrdomain)genr factor_listrgcddegree)TpxT_barlcflg_barti_bar_h_barghff_barZ_barbU_barms d/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/polys/numberfields/basis.py_apply_Dedekind_criterionr) s A A E    FB 7N7 Aq !E   UNE U2A U2A QqA A E EU^ !  UNE A !8ONc|j}||kr |z|kr t|fd}|j|S)a Compute the nilradical mod *p* for a given order *H*, and prime *p*. Explanation =========== This is the ideal $I$ in $H/pH$ consisting of all elements some positive power of which is zero in this quotient ring, i.e. is a multiple of *p*. Parameters ========== H : :py:class:`~.Submodule` The given order. p : int The rational prime. q : int, optional If known, the smallest power of *p* that is $>=$ the dimension of *H*. If not provided, we compute it here. Returns ======= :py:class:`~.Module` representing the nilradical mod *p* in *H*. References ========== .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory*. (See Lemma 6.1.6.) c|zSN)rqs r(z"nilradical_mod_p..Ks !Q$r*r)nr kernel)Hrr/r1phis ` r(nilradical_mod_pr5%sOB Ay !e FA!e Q /C ::a:  r*c t|||}|jj|j|jz|j}|||zz}|j t | fd}|j|}|jj|j|jz|j|z}||z} | |fS)zD Perform the second enlargement in the Round Two algorithm. )r/)denomc&j|Sr-)inner_endomorphism)rEs r(r0z%_second_enlargement..WsQ-A-A!-Dr*r)r5parentsubmodule_from_matrixmatrixr7endomorphism_ringr r2) r3rr/IpBCr4gammaGH1r:s @r(_second_enlargementrEOs !Q! $B &&qxx"))';177&KA AaCA A Q#D EC JJqJ !E &&qxx%,,'>aggPQk&RA QB r6Mr*cd}t|tr||jj}}|jr$|j r|j ttfvr td|j\}}|j}|j}tjt|}t|\}}t!|xs|}|j#} d} |r|j%\} } t'|| \} }|dk(r*|j)t+| t}| j-|| z| z|} | |kri| }||kr || z}||kr t/| | |\}} || k7r|} t/| | |\}} || k7r|r| t|t0r| | <| }d|_d|_||j6j9dzz|j:d|zzz}||fS)a Zassenhaus's "Round 2" algorithm. Explanation =========== Carry out Zassenhaus's "Round 2" algorithm on an irreducible polynomial *T* over :ref:`ZZ` or :ref:`QQ`. This computes an integral basis and the discriminant for the field $K = \mathbb{Q}[x]/(T(x))$. Alternatively, you may pass an :py:class:`~.AlgebraicField` instance, in place of the polynomial *T*, in which case the algorithm is applied to the minimal polynomial for the field's primitive element. Ordinarily this function need not be called directly, as one can instead access the :py:meth:`~.AlgebraicField.maximal_order`, :py:meth:`~.AlgebraicField.integral_basis`, and :py:meth:`~.AlgebraicField.discriminant` methods of an :py:class:`~.AlgebraicField`. Examples ======== Working through an AlgebraicField: >>> from sympy import Poly, QQ >>> from sympy.abc import x >>> T = Poly(x ** 3 + x ** 2 - 2 * x + 8) >>> K = QQ.alg_field_from_poly(T, "theta") >>> print(K.maximal_order()) Submodule[[2, 0, 0], [0, 2, 0], [0, 1, 1]]/2 >>> print(K.discriminant()) -503 >>> print(K.integral_basis(fmt='sympy')) [1, theta, theta/2 + theta**2/2] Calling directly: >>> from sympy import Poly >>> from sympy.abc import x >>> from sympy.polys.numberfields.basis import round_two >>> T = Poly(x ** 3 + x ** 2 - 2 * x + 8) >>> print(round_two(T)) (Submodule[[2, 0, 0], [0, 2, 0], [0, 1, 1]]/2, -503) The nilradicals mod $p$ that are sometimes computed during the Round Two algorithm may be useful in further calculations. Pass a dictionary under `radicals` to receive these: >>> T = Poly(x**3 + 3*x**2 + 5) >>> rad = {} >>> ZK, dK = round_two(T, radicals=rad) >>> print(rad) {3: Submodule[[-1, 1, 0], [-1, 0, 1]]} Parameters ========== T : :py:class:`~.Poly`, :py:class:`~.AlgebraicField` Either (1) the irreducible polynomial over :ref:`ZZ` or :ref:`QQ` defining the number field, or (2) an :py:class:`~.AlgebraicField` representing the number field itself. radicals : dict, optional This is a way for any $p$-radicals (if computed) to be returned by reference. If desired, pass an empty dictionary. If the algorithm reaches the point where it computes the nilradical mod $p$ of the ring of integers $Z_K$, then an $\mathbb{F}_p$-basis for this ideal will be stored in this dictionary under the key ``p``. This can be useful for other algorithms, such as prime decomposition. Returns ======= Pair ``(ZK, dK)``, where: ``ZK`` is a :py:class:`~sympy.polys.numberfields.modules.Submodule` representing the maximal order. ``dK`` is the discriminant of the field $K = \mathbb{Q}[x]/(T(x))$. See Also ======== .AlgebraicField.maximal_order .AlgebraicField.integral_basis .AlgebraicField.discriminant References ========== .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.* NzDRound 2 requires an irreducible univariate polynomial over ZZ or QQ.rr) hnf_modulusT) isinstancerextminpoly_of_element is_univariateis_irreduciblerrr ValueError)make_monic_over_integers_by_scaling_rootsr discriminant from_sympyabsr r whole_submodulepopitemr)element_from_polyraddrEdict_starts_with_unity_is_sq_maxrank_HNFr=detr7)rradicalsKrr1D D_modulusFZthetar3nilradrer&r'Ur/rDZKdKs r( round_tworf^s@ A!^$!%%**,1 88B8 #_`` 6 6 8DAq  A A c!f%I ,A .DAq Q F A F yy{1,Q2q 6   $ $T%%; < EE!q&1*)E 4 6  !e FA!e(Aq1 FAgA,Q15JBAg- @j48 B B B biimmo" "rxxAE': :B r6Mr*r-)__doc__sympy.polys.polytoolsr"sympy.polys.domains.algebraicfieldrsympy.polys.domains.integerringr!sympy.polys.domains.rationalfieldrsympy.utilities.decoratorrmodulesr r r utilitiesr r)r5rErfr.r*r(rosF2&=.0,GG72'!T WWr*