primes.py 24 KB

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