primes.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. """Prime ideals in number fields. """
  2. from sympy.polys.polytools import Poly
  3. from sympy.polys.domains.finitefield import FF
  4. from sympy.polys.domains.rationalfield import QQ
  5. from sympy.polys.domains.integerring import ZZ
  6. from sympy.polys.matrices.domainmatrix import DomainMatrix
  7. from sympy.polys.polyerrors import CoercionFailed
  8. from sympy.polys.polyutils import IntegerPowerable
  9. from sympy.utilities.decorator import public
  10. from .basis import round_two, nilradical_mod_p
  11. from .exceptions import StructureError
  12. from .modules import ModuleEndomorphism, find_min_poly
  13. from .utilities import coeff_search, supplement_a_subspace
  14. def _check_formal_conditions_for_maximal_order(submodule):
  15. r"""
  16. Several functions in this module accept an argument which is to be a
  17. :py:class:`~.Submodule` representing the maximal order in a number field,
  18. such as returned by the :py:func:`~sympy.polys.numberfields.basis.round_two`
  19. algorithm.
  20. We do not attempt to check that the given ``Submodule`` actually represents
  21. a maximal order, but we do check a basic set of formal conditions that the
  22. ``Submodule`` must satisfy, at a minimum. The purpose is to catch an
  23. obviously ill-formed argument.
  24. """
  25. prefix = 'The submodule representing the maximal order should '
  26. cond = None
  27. if not submodule.is_power_basis_submodule():
  28. cond = 'be a direct submodule of a power basis.'
  29. elif not submodule.starts_with_unity():
  30. cond = 'have 1 as its first generator.'
  31. elif not submodule.is_sq_maxrank_HNF():
  32. cond = 'have square matrix, of maximal rank, in Hermite Normal Form.'
  33. if cond is not None:
  34. raise StructureError(prefix + cond)
  35. class PrimeIdeal(IntegerPowerable):
  36. r"""
  37. A prime ideal in a ring of algebraic integers.
  38. """
  39. def __init__(self, ZK, p, alpha, f, e=None):
  40. """
  41. Parameters
  42. ==========
  43. ZK : :py:class:`~.Submodule`
  44. The maximal order where this ideal lives.
  45. p : int
  46. The rational prime this ideal divides.
  47. alpha : :py:class:`~.PowerBasisElement`
  48. Such that the ideal is equal to ``p*ZK + alpha*ZK``.
  49. f : int
  50. The inertia degree.
  51. e : int, ``None``, optional
  52. The ramification index, if already known. If ``None``, we will
  53. compute it here.
  54. """
  55. _check_formal_conditions_for_maximal_order(ZK)
  56. self.ZK = ZK
  57. self.p = p
  58. self.alpha = alpha
  59. self.f = f
  60. self._test_factor = None
  61. self.e = e if e is not None else self.valuation(p * ZK)
  62. def __str__(self):
  63. if self.is_inert:
  64. return f'({self.p})'
  65. return f'({self.p}, {self.alpha.as_expr()})'
  66. @property
  67. def is_inert(self):
  68. """
  69. Say whether the rational prime we divide is inert, i.e. stays prime in
  70. our ring of integers.
  71. """
  72. return self.f == self.ZK.n
  73. def repr(self, field_gen=None, just_gens=False):
  74. """
  75. Print a representation of this prime ideal.
  76. Examples
  77. ========
  78. >>> from sympy import cyclotomic_poly, QQ
  79. >>> from sympy.abc import x, zeta
  80. >>> T = cyclotomic_poly(7, x)
  81. >>> K = QQ.algebraic_field((T, zeta))
  82. >>> P = K.primes_above(11)
  83. >>> print(P[0].repr())
  84. [ (11, x**3 + 5*x**2 + 4*x - 1) e=1, f=3 ]
  85. >>> print(P[0].repr(field_gen=zeta))
  86. [ (11, zeta**3 + 5*zeta**2 + 4*zeta - 1) e=1, f=3 ]
  87. >>> print(P[0].repr(field_gen=zeta, just_gens=True))
  88. (11, zeta**3 + 5*zeta**2 + 4*zeta - 1)
  89. Parameters
  90. ==========
  91. field_gen : :py:class:`~.Symbol`, ``None``, optional (default=None)
  92. The symbol to use for the generator of the field. This will appear
  93. in our representation of ``self.alpha``. If ``None``, we use the
  94. variable of the defining polynomial of ``self.ZK``.
  95. just_gens : bool, optional (default=False)
  96. If ``True``, just print the "(p, alpha)" part, showing "just the
  97. generators" of the prime ideal. Otherwise, print a string of the
  98. form "[ (p, alpha) e=..., f=... ]", giving the ramification index
  99. and inertia degree, along with the generators.
  100. """
  101. field_gen = field_gen or self.ZK.parent.T.gen
  102. p, alpha, e, f = self.p, self.alpha, self.e, self.f
  103. alpha_rep = str(alpha.numerator(x=field_gen).as_expr())
  104. if alpha.denom > 1:
  105. alpha_rep = f'({alpha_rep})/{alpha.denom}'
  106. gens = f'({p}, {alpha_rep})'
  107. if just_gens:
  108. return gens
  109. return f'[ {gens} e={e}, f={f} ]'
  110. def __repr__(self):
  111. return self.repr()
  112. def as_submodule(self):
  113. r"""
  114. Represent this prime ideal as a :py:class:`~.Submodule`.
  115. Explanation
  116. ===========
  117. The :py:class:`~.PrimeIdeal` class serves to bundle information about
  118. a prime ideal, such as its inertia degree, ramification index, and
  119. two-generator representation, as well as to offer helpful methods like
  120. :py:meth:`~.PrimeIdeal.valuation` and
  121. :py:meth:`~.PrimeIdeal.test_factor`.
  122. However, in order to be added and multiplied by other ideals or
  123. rational numbers, it must first be converted into a
  124. :py:class:`~.Submodule`, which is a class that supports these
  125. operations.
  126. In many cases, the user need not perform this conversion deliberately,
  127. since it is automatically performed by the arithmetic operator methods
  128. :py:meth:`~.PrimeIdeal.__add__` and :py:meth:`~.PrimeIdeal.__mul__`.
  129. Raising a :py:class:`~.PrimeIdeal` to a non-negative integer power is
  130. also supported.
  131. Examples
  132. ========
  133. >>> from sympy import Poly, cyclotomic_poly, prime_decomp
  134. >>> T = Poly(cyclotomic_poly(7))
  135. >>> P0 = prime_decomp(7, T)[0]
  136. >>> print(P0**6 == 7*P0.ZK)
  137. True
  138. Note that, on both sides of the equation above, we had a
  139. :py:class:`~.Submodule`. In the next equation we recall that adding
  140. ideals yields their GCD. This time, we need a deliberate conversion
  141. to :py:class:`~.Submodule` on the right:
  142. >>> print(P0 + 7*P0.ZK == P0.as_submodule())
  143. True
  144. Returns
  145. =======
  146. :py:class:`~.Submodule`
  147. Will be equal to ``self.p * self.ZK + self.alpha * self.ZK``.
  148. See Also
  149. ========
  150. __add__
  151. __mul__
  152. """
  153. M = self.p * self.ZK + self.alpha * self.ZK
  154. # Pre-set expensive boolean properties whose value we already know:
  155. M._starts_with_unity = False
  156. M._is_sq_maxrank_HNF = True
  157. return M
  158. def __eq__(self, other):
  159. if isinstance(other, PrimeIdeal):
  160. return self.as_submodule() == other.as_submodule()
  161. return NotImplemented
  162. def __add__(self, other):
  163. """
  164. Convert to a :py:class:`~.Submodule` and add to another
  165. :py:class:`~.Submodule`.
  166. See Also
  167. ========
  168. as_submodule
  169. """
  170. return self.as_submodule() + other
  171. __radd__ = __add__
  172. def __mul__(self, other):
  173. """
  174. Convert to a :py:class:`~.Submodule` and multiply by another
  175. :py:class:`~.Submodule` or a rational number.
  176. See Also
  177. ========
  178. as_submodule
  179. """
  180. return self.as_submodule() * other
  181. __rmul__ = __mul__
  182. def _zeroth_power(self):
  183. return self.ZK
  184. def _first_power(self):
  185. return self
  186. def test_factor(self):
  187. r"""
  188. Compute a test factor for this prime ideal.
  189. Explanation
  190. ===========
  191. Write $\mathfrak{p}$ for this prime ideal, $p$ for the rational prime
  192. it divides. Then, for computing $\mathfrak{p}$-adic valuations it is
  193. useful to have a number $\beta \in \mathbb{Z}_K$ such that
  194. $p/\mathfrak{p} = p \mathbb{Z}_K + \beta \mathbb{Z}_K$.
  195. Essentially, this is the same as the number $\Psi$ (or the "reagent")
  196. from Kummer's 1847 paper (*Ueber die Zerlegung...*, Crelle vol. 35) in
  197. which ideal divisors were invented.
  198. """
  199. if self._test_factor is None:
  200. self._test_factor = _compute_test_factor(self.p, [self.alpha], self.ZK)
  201. return self._test_factor
  202. def valuation(self, I):
  203. r"""
  204. Compute the $\mathfrak{p}$-adic valuation of integral ideal I at this
  205. prime ideal.
  206. Parameters
  207. ==========
  208. I : :py:class:`~.Submodule`
  209. See Also
  210. ========
  211. prime_valuation
  212. """
  213. return prime_valuation(I, self)
  214. def reduce_element(self, elt):
  215. """
  216. Reduce a :py:class:`~.PowerBasisElement` to a "small representative"
  217. modulo this prime ideal.
  218. Parameters
  219. ==========
  220. elt : :py:class:`~.PowerBasisElement`
  221. The element to be reduced.
  222. Returns
  223. =======
  224. :py:class:`~.PowerBasisElement`
  225. The reduced element.
  226. See Also
  227. ========
  228. reduce_ANP
  229. reduce_alg_num
  230. .Submodule.reduce_element
  231. """
  232. return self.as_submodule().reduce_element(elt)
  233. def reduce_ANP(self, a):
  234. """
  235. Reduce an :py:class:`~.ANP` to a "small representative" modulo this
  236. prime ideal.
  237. Parameters
  238. ==========
  239. elt : :py:class:`~.ANP`
  240. The element to be reduced.
  241. Returns
  242. =======
  243. :py:class:`~.ANP`
  244. The reduced element.
  245. See Also
  246. ========
  247. reduce_element
  248. reduce_alg_num
  249. .Submodule.reduce_element
  250. """
  251. elt = self.ZK.parent.element_from_ANP(a)
  252. red = self.reduce_element(elt)
  253. return red.to_ANP()
  254. def reduce_alg_num(self, a):
  255. """
  256. Reduce an :py:class:`~.AlgebraicNumber` to a "small representative"
  257. modulo this prime ideal.
  258. Parameters
  259. ==========
  260. elt : :py:class:`~.AlgebraicNumber`
  261. The element to be reduced.
  262. Returns
  263. =======
  264. :py:class:`~.AlgebraicNumber`
  265. The reduced element.
  266. See Also
  267. ========
  268. reduce_element
  269. reduce_ANP
  270. .Submodule.reduce_element
  271. """
  272. elt = self.ZK.parent.element_from_alg_num(a)
  273. red = self.reduce_element(elt)
  274. return a.field_element(list(reversed(red.QQ_col.flat())))
  275. def _compute_test_factor(p, gens, ZK):
  276. r"""
  277. Compute the test factor for a :py:class:`~.PrimeIdeal` $\mathfrak{p}$.
  278. Parameters
  279. ==========
  280. p : int
  281. The rational prime $\mathfrak{p}$ divides
  282. gens : list of :py:class:`PowerBasisElement`
  283. A complete set of generators for $\mathfrak{p}$ over *ZK*, EXCEPT that
  284. an element equivalent to rational *p* can and should be omitted (since
  285. it has no effect except to waste time).
  286. ZK : :py:class:`~.Submodule`
  287. The maximal order where the prime ideal $\mathfrak{p}$ lives.
  288. Returns
  289. =======
  290. :py:class:`~.PowerBasisElement`
  291. References
  292. ==========
  293. .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*
  294. (See Proposition 4.8.15.)
  295. """
  296. _check_formal_conditions_for_maximal_order(ZK)
  297. E = ZK.endomorphism_ring()
  298. matrices = [E.inner_endomorphism(g).matrix(modulus=p) for g in gens]
  299. B = DomainMatrix.zeros((0, ZK.n), FF(p)).vstack(*matrices)
  300. # A nonzero element of the nullspace of B will represent a
  301. # lin comb over the omegas which (i) is not a multiple of p
  302. # (since it is nonzero over FF(p)), while (ii) is such that
  303. # its product with each g in gens _is_ a multiple of p (since
  304. # B represents multiplication by these generators). Theory
  305. # predicts that such an element must exist, so nullspace should
  306. # be non-trivial.
  307. x = B.nullspace()[0, :].transpose()
  308. beta = ZK.parent(ZK.matrix * x, denom=ZK.denom)
  309. return beta
  310. @public
  311. def prime_valuation(I, P):
  312. r"""
  313. Compute the *P*-adic valuation for an integral ideal *I*.
  314. Examples
  315. ========
  316. >>> from sympy import QQ
  317. >>> from sympy.polys.numberfields import prime_valuation
  318. >>> K = QQ.cyclotomic_field(5)
  319. >>> P = K.primes_above(5)
  320. >>> ZK = K.maximal_order()
  321. >>> print(prime_valuation(25*ZK, P[0]))
  322. 8
  323. Parameters
  324. ==========
  325. I : :py:class:`~.Submodule`
  326. An integral ideal whose valuation is desired.
  327. P : :py:class:`~.PrimeIdeal`
  328. The prime at which to compute the valuation.
  329. Returns
  330. =======
  331. int
  332. See Also
  333. ========
  334. .PrimeIdeal.valuation
  335. References
  336. ==========
  337. .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*
  338. (See Algorithm 4.8.17.)
  339. """
  340. p, ZK = P.p, P.ZK
  341. n, W, d = ZK.n, ZK.matrix, ZK.denom
  342. A = W.convert_to(QQ).inv() * I.matrix * d / I.denom
  343. # Although A must have integer entries, given that I is an integral ideal,
  344. # as a DomainMatrix it will still be over QQ, so we convert back:
  345. A = A.convert_to(ZZ)
  346. D = A.det()
  347. if D % p != 0:
  348. return 0
  349. beta = P.test_factor()
  350. f = d ** n // W.det()
  351. need_complete_test = (f % p == 0)
  352. v = 0
  353. while True:
  354. # Entering the loop, the cols of A represent lin combs of omegas.
  355. # Turn them into lin combs of thetas:
  356. A = W * A
  357. # And then one column at a time...
  358. for j in range(n):
  359. c = ZK.parent(A[:, j], denom=d)
  360. c *= beta
  361. # ...turn back into lin combs of omegas, after multiplying by beta:
  362. c = ZK.represent(c).flat()
  363. for i in range(n):
  364. A[i, j] = c[i]
  365. if A[n - 1, n - 1].element % p != 0:
  366. break
  367. A = A / p
  368. # As noted above, domain converts to QQ even when division goes evenly.
  369. # So must convert back, even when we don't "need_complete_test".
  370. if need_complete_test:
  371. # In this case, having a non-integer entry is actually just our
  372. # halting condition.
  373. try:
  374. A = A.convert_to(ZZ)
  375. except CoercionFailed:
  376. break
  377. else:
  378. # In this case theory says we should not have any non-integer entries.
  379. A = A.convert_to(ZZ)
  380. v += 1
  381. return v
  382. def _two_elt_rep(gens, ZK, p, f=None, Np=None):
  383. r"""
  384. Given a set of *ZK*-generators of a prime ideal, compute a set of just two
  385. *ZK*-generators for the same ideal, one of which is *p* itself.
  386. Parameters
  387. ==========
  388. gens : list of :py:class:`PowerBasisElement`
  389. Generators for the prime ideal over *ZK*, the ring of integers of the
  390. field $K$.
  391. ZK : :py:class:`~.Submodule`
  392. The maximal order in $K$.
  393. p : int
  394. The rational prime divided by the prime ideal.
  395. f : int, optional
  396. The inertia degree of the prime ideal, if known.
  397. Np : int, optional
  398. The norm $p^f$ of the prime ideal, if known.
  399. NOTE: There is no reason to supply both *f* and *Np*. Either one will
  400. save us from having to compute the norm *Np* ourselves. If both are known,
  401. *Np* is preferred since it saves one exponentiation.
  402. Returns
  403. =======
  404. :py:class:`~.PowerBasisElement` representing a single algebraic integer
  405. alpha such that the prime ideal is equal to ``p*ZK + alpha*ZK``.
  406. References
  407. ==========
  408. .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*
  409. (See Algorithm 4.7.10.)
  410. """
  411. _check_formal_conditions_for_maximal_order(ZK)
  412. pb = ZK.parent
  413. T = pb.T
  414. # Detect the special cases in which either (a) all generators are multiples
  415. # of p, or (b) there are no generators (so `all` is vacuously true):
  416. if all((g % p).equiv(0) for g in gens):
  417. return pb.zero()
  418. if Np is None:
  419. if f is not None:
  420. Np = p**f
  421. else:
  422. Np = abs(pb.submodule_from_gens(gens).matrix.det())
  423. omega = ZK.basis_element_pullbacks()
  424. beta = [p*om for om in omega[1:]] # note: we omit omega[0] == 1
  425. beta += gens
  426. search = coeff_search(len(beta), 1)
  427. for c in search:
  428. alpha = sum(ci*betai for ci, betai in zip(c, beta))
  429. # Note: It may be tempting to reduce alpha mod p here, to try to work
  430. # with smaller numbers, but must not do that, as it can result in an
  431. # infinite loop! E.g. try factoring 2 in Q(sqrt(-7)).
  432. n = alpha.norm(T) // Np
  433. if n % p != 0:
  434. # Now can reduce alpha mod p.
  435. return alpha % p
  436. def _prime_decomp_easy_case(p, ZK):
  437. r"""
  438. Compute the decomposition of rational prime *p* in the ring of integers
  439. *ZK* (given as a :py:class:`~.Submodule`), in the "easy case", i.e. the
  440. case where *p* does not divide the index of $\theta$ in *ZK*, where
  441. $\theta$ is the generator of the ``PowerBasis`` of which *ZK* is a
  442. ``Submodule``.
  443. """
  444. T = ZK.parent.T
  445. T_bar = Poly(T, modulus=p)
  446. lc, fl = T_bar.factor_list()
  447. if len(fl) == 1 and fl[0][1] == 1:
  448. return [PrimeIdeal(ZK, p, ZK.parent.zero(), ZK.n, 1)]
  449. return [PrimeIdeal(ZK, p,
  450. ZK.parent.element_from_poly(Poly(t, domain=ZZ)),
  451. t.degree(), e)
  452. for t, e in fl]
  453. def _prime_decomp_compute_kernel(I, p, ZK):
  454. r"""
  455. Parameters
  456. ==========
  457. I : :py:class:`~.Module`
  458. An ideal of ``ZK/pZK``.
  459. p : int
  460. The rational prime being factored.
  461. ZK : :py:class:`~.Submodule`
  462. The maximal order.
  463. Returns
  464. =======
  465. Pair ``(N, G)``, where:
  466. ``N`` is a :py:class:`~.Module` representing the kernel of the map
  467. ``a |--> a**p - a`` on ``(O/pO)/I``, guaranteed to be a module with
  468. unity.
  469. ``G`` is a :py:class:`~.Module` representing a basis for the separable
  470. algebra ``A = O/I`` (see Cohen).
  471. """
  472. W = I.matrix
  473. n, r = W.shape
  474. # Want to take the Fp-basis given by the columns of I, adjoin (1, 0, ..., 0)
  475. # (which we know is not already in there since I is a basis for a prime ideal)
  476. # and then supplement this with additional columns to make an invertible n x n
  477. # matrix. This will then represent a full basis for ZK, whose first r columns
  478. # are pullbacks of the basis for I.
  479. if r == 0:
  480. B = W.eye(n, ZZ)
  481. else:
  482. B = W.hstack(W.eye(n, ZZ)[:, 0])
  483. if B.shape[1] < n:
  484. B = supplement_a_subspace(B.convert_to(FF(p))).convert_to(ZZ)
  485. G = ZK.submodule_from_matrix(B)
  486. # Must compute G's multiplication table _before_ discarding the first r
  487. # columns. (See Step 9 in Alg 6.2.9 in Cohen, where the betas are actually
  488. # needed in order to represent each product of gammas. However, once we've
  489. # found the representations, then we can ignore the betas.)
  490. G.compute_mult_tab()
  491. G = G.discard_before(r)
  492. phi = ModuleEndomorphism(G, lambda x: x**p - x)
  493. N = phi.kernel(modulus=p)
  494. assert N.starts_with_unity()
  495. return N, G
  496. def _prime_decomp_maximal_ideal(I, p, ZK):
  497. r"""
  498. We have reached the case where we have a maximal (hence prime) ideal *I*,
  499. which we know because the quotient ``O/I`` is a field.
  500. Parameters
  501. ==========
  502. I : :py:class:`~.Module`
  503. An ideal of ``O/pO``.
  504. p : int
  505. The rational prime being factored.
  506. ZK : :py:class:`~.Submodule`
  507. The maximal order.
  508. Returns
  509. =======
  510. :py:class:`~.PrimeIdeal` instance representing this prime
  511. """
  512. m, n = I.matrix.shape
  513. f = m - n
  514. G = ZK.matrix * I.matrix
  515. gens = [ZK.parent(G[:, j], denom=ZK.denom) for j in range(G.shape[1])]
  516. alpha = _two_elt_rep(gens, ZK, p, f=f)
  517. return PrimeIdeal(ZK, p, alpha, f)
  518. def _prime_decomp_split_ideal(I, p, N, G, ZK):
  519. r"""
  520. Perform the step in the prime decomposition algorithm where we have determined
  521. the the quotient ``ZK/I`` is _not_ a field, and we want to perform a non-trivial
  522. factorization of *I* by locating an idempotent element of ``ZK/I``.
  523. """
  524. assert I.parent == ZK and G.parent is ZK and N.parent is G
  525. # Since ZK/I is not a field, the kernel computed in the previous step contains
  526. # more than just the prime field Fp, and our basis N for the nullspace therefore
  527. # contains at least a second column (which represents an element outside Fp).
  528. # Let alpha be such an element:
  529. alpha = N(1).to_parent()
  530. assert alpha.module is G
  531. alpha_powers = []
  532. m = find_min_poly(alpha, FF(p), powers=alpha_powers)
  533. # TODO (future work):
  534. # We don't actually need full factorization, so might use a faster method
  535. # to just break off a single non-constant factor m1?
  536. lc, fl = m.factor_list()
  537. m1 = fl[0][0]
  538. m2 = m.quo(m1)
  539. U, V, g = m1.gcdex(m2)
  540. # Sanity check: theory says m is squarefree, so m1, m2 should be coprime:
  541. assert g == 1
  542. E = list(reversed(Poly(U * m1, domain=ZZ).rep.rep))
  543. eps1 = sum(E[i]*alpha_powers[i] for i in range(len(E)))
  544. eps2 = 1 - eps1
  545. idemps = [eps1, eps2]
  546. factors = []
  547. for eps in idemps:
  548. e = eps.to_parent()
  549. assert e.module is ZK
  550. D = I.matrix.convert_to(FF(p)).hstack(*[
  551. (e * om).column(domain=FF(p)) for om in ZK.basis_elements()
  552. ])
  553. W = D.columnspace().convert_to(ZZ)
  554. H = ZK.submodule_from_matrix(W)
  555. factors.append(H)
  556. return factors
  557. @public
  558. def prime_decomp(p, T=None, ZK=None, dK=None, radical=None):
  559. r"""
  560. Compute the decomposition of rational prime *p* in a number field.
  561. Explanation
  562. ===========
  563. Ordinarily this should be accessed through the
  564. :py:meth:`~.AlgebraicField.primes_above` method of an
  565. :py:class:`~.AlgebraicField`.
  566. Examples
  567. ========
  568. >>> from sympy import Poly, QQ
  569. >>> from sympy.abc import x, theta
  570. >>> T = Poly(x ** 3 + x ** 2 - 2 * x + 8)
  571. >>> K = QQ.algebraic_field((T, theta))
  572. >>> print(K.primes_above(2))
  573. [[ (2, x**2 + 1) e=1, f=1 ], [ (2, (x**2 + 3*x + 2)/2) e=1, f=1 ],
  574. [ (2, (3*x**2 + 3*x)/2) e=1, f=1 ]]
  575. Parameters
  576. ==========
  577. p : int
  578. The rational prime whose decomposition is desired.
  579. T : :py:class:`~.Poly`, optional
  580. Monic irreducible polynomial defining the number field $K$ in which to
  581. factor. NOTE: at least one of *T* or *ZK* must be provided.
  582. ZK : :py:class:`~.Submodule`, optional
  583. The maximal order for $K$, if already known.
  584. NOTE: at least one of *T* or *ZK* must be provided.
  585. dK : int, optional
  586. The discriminant of the field $K$, if already known.
  587. radical : :py:class:`~.Submodule`, optional
  588. The nilradical mod *p* in the integers of $K$, if already known.
  589. Returns
  590. =======
  591. List of :py:class:`~.PrimeIdeal` instances.
  592. References
  593. ==========
  594. .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*
  595. (See Algorithm 6.2.9.)
  596. """
  597. if T is None and ZK is None:
  598. raise ValueError('At least one of T or ZK must be provided.')
  599. if ZK is not None:
  600. _check_formal_conditions_for_maximal_order(ZK)
  601. if T is None:
  602. T = ZK.parent.T
  603. radicals = {}
  604. if dK is None or ZK is None:
  605. ZK, dK = round_two(T, radicals=radicals)
  606. dT = T.discriminant()
  607. f_squared = dT // dK
  608. if f_squared % p != 0:
  609. return _prime_decomp_easy_case(p, ZK)
  610. radical = radical or radicals.get(p) or nilradical_mod_p(ZK, p)
  611. stack = [radical]
  612. primes = []
  613. while stack:
  614. I = stack.pop()
  615. N, G = _prime_decomp_compute_kernel(I, p, ZK)
  616. if N.n == 1:
  617. P = _prime_decomp_maximal_ideal(I, p, ZK)
  618. primes.append(P)
  619. else:
  620. I1, I2 = _prime_decomp_split_ideal(I, p, N, G, ZK)
  621. stack.extend([I1, I2])
  622. return primes