\(p\)-Adic ZZ_pX
CA Element¶
This file implements elements of Eisenstein and unramified extensions
of Zp
with capped absolute precision.
For the parent class see padic_extension_leaves.pyx.
The underlying implementation is through NTL’s ZZ_pX
class. Each
element contains the following data:
absprec
(long) – An integer giving the precision to which this element is defined. This is the power of the uniformizer modulo which the element is well defined.value
(ZZ_pX_c
) – An ntlZZ_pX
storing the value. The variable \(x\) is the uniformizer in the case of Eisenstein extensions. This ZZ_pX is created with global ntl modulus determined by absprec. Let \(a\) be absprec and \(e\) be the ramification index over \(\QQ_p\) or \(\ZZ_p\). Then the modulus is given by \(p^{ceil(a/e)}\). Note that all kinds of problems arise if you try to mix moduli.ZZ_pX_conv_modulus
gives a semi-safe way to convert between different moduli without having to pass through ZZX.prime_pow
(some subclass ofPowComputer_ZZ_pX
) – a class, identical among all elements with the same parent, holding common data.prime_pow.deg
– The degree of the extensionprime_pow.e
– The ramification indexprime_pow.f
– The inertia degreeprime_pow.prec_cap
– the unramified precision cap. For Eisenstein extensions this is the smallest power of p that is zero.prime_pow.ram_prec_cap
– the ramified precision cap. For Eisenstein extensions this will be the smallest power of \(x\) that is indistinguishable from zero.prime_pow.pow_ZZ_tmp
, prime_pow.pow_mpz_t_tmp``,prime_pow.pow_Integer
– functions for accessing powers of \(p\). The first two return pointers. Seesage/rings/padics/pow_computer_ext
for examples and important warnings.prime_pow.get_context
,prime_pow.get_context_capdiv
,prime_pow.get_top_context
– obtain anntl_ZZ_pContext_class
corresponding to \(p^n\). The capdiv version divides byprime_pow.e
as appropriate.top_context
corresponds to \(p^{prec_cap}\).prime_pow.restore_context
,prime_pow.restore_context_capdiv
,prime_pow.restore_top_context
– restores the given context.prime_pow.get_modulus
,get_modulus_capdiv
,get_top_modulus
– Returns aZZ_pX_Modulus_c*
pointing to a polynomial modulus defined modulo \(p^n\) (appropriately divided byprime_pow.e
in the capdiv case).
EXAMPLES:
An Eisenstein extension:
sage: R = ZpCA(5,5)
sage: S.<x> = ZZ[]
sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5
sage: W.<w> = R.ext(f); W
5-adic Eisenstein Extension Ring in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
sage: z = (1+w)^5; z
1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25)
sage: y = z >> 1; y
w^4 + w^5 + 2*w^6 + 4*w^7 + 3*w^9 + w^11 + 4*w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^19 + w^20 + 4*w^23 + O(w^24)
sage: y.valuation()
4
sage: y.precision_relative()
20
sage: y.precision_absolute()
24
sage: z - (y << 1)
1 + O(w^25)
sage: (1/w)^12+w
w^-12 + w + O(w^12)
sage: (1/w).parent()
5-adic Eisenstein Extension Field in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
An unramified extension:
sage: g = x^3 + 3*x + 3
sage: A.<a> = R.ext(g)
sage: z = (1+a)^5; z
(2*a^2 + 4*a) + (3*a^2 + 3*a + 1)*5 + (4*a^2 + 3*a + 4)*5^2 + (4*a^2 + 4*a + 4)*5^3 + (4*a^2 + 4*a + 4)*5^4 + O(5^5)
sage: z - 1 - 5*a - 10*a^2 - 10*a^3 - 5*a^4 - a^5
O(5^5)
sage: y = z >> 1; y
(3*a^2 + 3*a + 1) + (4*a^2 + 3*a + 4)*5 + (4*a^2 + 4*a + 4)*5^2 + (4*a^2 + 4*a + 4)*5^3 + O(5^4)
sage: 1/a
(3*a^2 + 4) + (a^2 + 4)*5 + (3*a^2 + 4)*5^2 + (a^2 + 4)*5^3 + (3*a^2 + 4)*5^4 + O(5^5)
sage: FFA = A.residue_field()
sage: a0 = FFA.gen(); A(a0^3)
(2*a + 2) + O(5)
Different printing modes:
sage: R = ZpCA(5, print_mode='digits'); S.<x> = ZZ[]; f = x^5 + 75*x^3 - 15*x^2 + 125*x -5; W.<w> = R.ext(f)
sage: z = (1+w)^5; repr(z)
'...4110403113210310442221311242000111011201102002023303214332011214403232013144001400444441030421100001'
sage: R = ZpCA(5, print_mode='bars'); S.<x> = ZZ[]; g = x^3 + 3*x + 3; A.<a> = R.ext(g)
sage: z = (1+a)^5; repr(z)
'...[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 4, 4]|[4, 3, 4]|[1, 3, 3]|[0, 4, 2]'
sage: R = ZpCA(5, print_mode='terse'); S.<x> = ZZ[]; f = x^5 + 75*x^3 - 15*x^2 + 125*x -5; W.<w> = R.ext(f)
sage: z = (1+w)^5; z
6 + 95367431640505*w + 25*w^2 + 95367431640560*w^3 + 5*w^4 + O(w^100)
sage: R = ZpCA(5, print_mode='val-unit'); S.<x> = ZZ[]; f = x^5 + 75*x^3 - 15*x^2 + 125*x -5; W.<w> = R.ext(f)
sage: y = (1+w)^5 - 1; y
w^5 * (2090041 + 19073486126901*w + 1258902*w^2 + 674*w^3 + 16785*w^4) + O(w^100)
You can get at the underlying ntl representation:
sage: z._ntl_rep()
[6 95367431640505 25 95367431640560 5]
sage: y._ntl_rep()
[5 95367431640505 25 95367431640560 5]
sage: y._ntl_rep_abs()
([5 95367431640505 25 95367431640560 5], 0)
Note
If you get an error internal error: can't grow this _ntl_gbigint,
it indicates that moduli are being mixed inappropriately somewhere.
For example, when calling a function with a ZZ_pX_c
as an
argument, it copies. If the modulus is not
set to the modulus of the ZZ_pX_c
, you can get errors.
AUTHORS:
David Roe (2008-01-01): initial version
Robert Harron (2011-09): fixes/enhancements
Julian Rueth (2012-10-15): fixed an initialization bug
- sage.rings.padics.padic_ZZ_pX_CA_element.make_ZZpXCAElement(parent, value, absprec, version)¶
For pickling. Makes a
pAdicZZpXCAElement
with givenparent
,value
,absprec
.EXAMPLES:
sage: from sage.rings.padics.padic_ZZ_pX_CA_element import make_ZZpXCAElement sage: R = ZpCA(5,5) sage: S.<x> = ZZ[] sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5 sage: W.<w> = R.ext(f) sage: make_ZZpXCAElement(W, ntl.ZZ_pX([3,2,4],5^3),13,0) 3 + 2*w + 4*w^2 + O(w^13)
- class sage.rings.padics.padic_ZZ_pX_CA_element.pAdicZZpXCAElement¶
Bases:
sage.rings.padics.padic_ZZ_pX_element.pAdicZZpXElement
Creates an element of a capped absolute precision, unramified or Eisenstein extension of Zp or Qp.
INPUT:
parent
– either anEisensteinRingCappedAbsolute
orUnramifiedRingCappedAbsolute
\(x\) – an integer, rational, \(p\)-adic element, polynomial, list, integer_mod, pari int/frac/poly_t/pol_mod, an
ntl_ZZ_pX
, anntl_ZZ
, anntl_ZZ_p
, anntl_ZZX
, or something convertible into parent.residue_field()absprec
– an upper bound on the absolute precision of the element createdrelprec
– an upper bound on the relative precision of the element createdempty
– whether to return after initializing to zero.
EXAMPLES:
sage: R = ZpCA(5,5) sage: S.<x> = ZZ[] sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5 sage: W.<w> = R.ext(f) sage: z = (1+w)^5; z # indirect doctest 1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25) sage: W(R(3,3)) 3 + O(w^15) sage: W(pari('3 + O(5^3)')) 3 + O(w^15) sage: W(w, 14) w + O(w^14)
- expansion(n=None, lift_mode='simple')¶
Return a list giving a series representation of
self
.If
lift_mode == 'simple'
or'smallest'
, the returned list will consist of integers (in the Eisenstein case) or a list of lists of integers (in the unramified case).self
can be reconstructed as a sum of elements of the list times powers of the uniformiser (in the Eisenstein case), or as a sum of powers of \(p\) times polynomials in the generator (in the unramified case).If
lift_mode == 'simple'
, all integers will be in the interval \([0,p-1]\)If
lift_mod == 'smallest'
they will be in the interval \([(1-p)/2, p/2]\).
If
lift_mode == 'teichmuller'
, returns a list ofpAdicZZpXCAElements
, all of which are Teichmuller representatives and such thatself
is the sum of that list times powers of the uniformizer.
INPUT:
n
– integer (defaultNone
). If given, returns the corresponding entry in the expansion.
EXAMPLES:
sage: R = ZpCA(5,5) sage: S.<x> = ZZ[] sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5 sage: W.<w> = R.ext(f) sage: y = W(775, 19); y w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19) sage: (y>>9).expansion() [0, 1, 0, 4, 0, 2, 1, 2, 4, 1] sage: (y>>9).expansion(lift_mode='smallest') [0, 1, 0, -1, 0, 2, 1, 2, 0, 1] sage: w^10 - w^12 + 2*w^14 + w^15 + 2*w^16 + w^18 + O(w^19) w^10 + 4*w^12 + 2*w^14 + w^15 + 2*w^16 + 4*w^17 + w^18 + O(w^19) sage: g = x^3 + 3*x + 3 sage: A.<a> = R.ext(g) sage: y = 75 + 45*a + 1200*a^2; y 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^5) sage: E = y.expansion(); E 5-adic expansion of 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^5) sage: list(E) [[], [0, 4], [3, 1, 3], [0, 0, 4], [0, 0, 1]] sage: list(y.expansion(lift_mode='smallest')) [[], [0, -1], [-2, 2, -2], [1], [0, 0, 2]] sage: 5*((-2*5 + 25) + (-1 + 2*5)*a + (-2*5 + 2*125)*a^2) 4*a*5 + (3*a^2 + a + 3)*5^2 + 4*a^2*5^3 + a^2*5^4 + O(5^5) sage: W(0).expansion() [] sage: list(A(0,4).expansion()) []
Check that trac ticket #25879 has been resolved:
sage: K = ZpCA(3,5) sage: R.<a> = K[] sage: L.<a> = K.extension(a^2 - 3) sage: a.residue() 0
- is_equal_to(right, absprec=None)¶
Returns whether
self
is equal toright
moduloself.uniformizer()^absprec
.If
absprec
isNone
, returns ifself
is equal toright
modulo the lower of their two precisions.EXAMPLES:
sage: R = ZpCA(5,5) sage: S.<x> = ZZ[] sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5 sage: W.<w> = R.ext(f) sage: a = W(47); b = W(47 + 25) sage: a.is_equal_to(b) False sage: a.is_equal_to(b, 7) True
- is_zero(absprec=None)¶
Return whether the valuation of
self
is at leastabsprec
.If
absprec
isNone
, returns ifself
is indistinguishable from zero.If
self
is an inexact zero of valuation less thanabsprec
, raises aPrecisionError
.EXAMPLES:
sage: R = ZpCA(5,5) sage: S.<x> = ZZ[] sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5 sage: W.<w> = R.ext(f) sage: O(w^189).is_zero() True sage: W(0).is_zero() True sage: a = W(675) sage: a.is_zero() False sage: a.is_zero(7) True sage: a.is_zero(21) False
- lift_to_precision(absprec=None)¶
Returns a
pAdicZZpXCAElement
congruent toself
but with absolute precision at leastabsprec
.INPUT:
absprec
– (defaultNone
) the absolute precision of the result. IfNone
, lifts to the maximum precision allowed.
Note
If setting
absprec
that high would violate the precision cap, raises a precision error.Note that the new digits will not necessarily be zero.
EXAMPLES:
sage: R = ZpCA(5,5) sage: S.<x> = ZZ[] sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5 sage: W.<w> = R.ext(f) sage: a = W(345, 17); a 4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15 + O(w^17) sage: b = a.lift_to_precision(19); b # indirect doctest 4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15 + w^17 + 2*w^18 + O(w^19) sage: c = a.lift_to_precision(24); c 4*w^5 + 3*w^7 + w^9 + 3*w^10 + 2*w^11 + 4*w^12 + w^13 + 2*w^14 + 2*w^15 + w^17 + 2*w^18 + 4*w^19 + 4*w^20 + 2*w^21 + 4*w^23 + O(w^24) sage: a._ntl_rep() [345] sage: b._ntl_rep() [345] sage: c._ntl_rep() [345] sage: a.lift_to_precision().precision_absolute() == W.precision_cap() True
- matrix_mod_pn()¶
Returns the matrix of right multiplication by the element on the power basis \(1, x, x^2, \ldots, x^{d-1}\) for this extension field. Thus the rows of this matrix give the images of each of the \(x^i\). The entries of the matrices are
IntegerMod
elements, defined modulop^(self.absprec() / e)
.EXAMPLES:
sage: R = ZpCA(5,5) sage: S.<x> = ZZ[] sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5 sage: W.<w> = R.ext(f) sage: a = (3+w)^7 sage: a.matrix_mod_pn() [2757 333 1068 725 2510] [ 50 1507 483 318 725] [ 500 50 3007 2358 318] [1590 1375 1695 1032 2358] [2415 590 2370 2970 1032]
- polynomial(var='x')¶
Return a polynomial over the base ring that yields this element when evaluated at the generator of the parent.
INPUT:
var
– string, the variable name for the polynomial
EXAMPLES:
sage: S.<x> = ZZ[] sage: W.<w> = ZpCA(5).extension(x^2 - 5) sage: (w + W(5, 7)).polynomial() (1 + O(5^3))*x + 5 + O(5^4)
- precision_absolute()¶
Returns the absolute precision of
self
, ie the power of the uniformizer modulo which this element is defined.EXAMPLES:
sage: R = ZpCA(5,5) sage: S.<x> = ZZ[] sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5 sage: W.<w> = R.ext(f) sage: a = W(75, 19); a 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19) sage: a.valuation() 10 sage: a.precision_absolute() 19 sage: a.precision_relative() 9 sage: a.unit_part() 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
- precision_relative()¶
Returns the relative precision of
self
, ie the power of the uniformizer modulo which the unit part ofself
is defined.EXAMPLES:
sage: R = ZpCA(5,5) sage: S.<x> = ZZ[] sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5 sage: W.<w> = R.ext(f) sage: a = W(75, 19); a 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19) sage: a.valuation() 10 sage: a.precision_absolute() 19 sage: a.precision_relative() 9 sage: a.unit_part() 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)
- teichmuller_expansion(n=None)¶
Returns a list [\(a_0\), \(a_1\),…, \(a_n\)] such that
\(a_i^q = a_i\)
self.unit_part()
= \(\sum_{i = 0}^n a_i \pi^i\), where \(\pi\) is a uniformizer of self.parent()if \(a_i \ne 0\), the absolute precision of \(a_i\) is
self.precision_relative() - i
INPUT:
n
– integer (defaultNone
). If given, returns the corresponding entry in the expansion.
EXAMPLES:
sage: R.<a> = Zq(5^4,4) sage: E = a.teichmuller_expansion(); E 5-adic expansion of a + O(5^4) (teichmuller) sage: list(E) [a + (2*a^3 + 2*a^2 + 3*a + 4)*5 + (4*a^3 + 3*a^2 + 3*a + 2)*5^2 + (4*a^2 + 2*a + 2)*5^3 + O(5^4), (3*a^3 + 3*a^2 + 2*a + 1) + (a^3 + 4*a^2 + 1)*5 + (a^2 + 4*a + 4)*5^2 + O(5^3), (4*a^3 + 2*a^2 + a + 1) + (2*a^3 + 2*a^2 + 2*a + 4)*5 + O(5^2), (a^3 + a^2 + a + 4) + O(5)] sage: sum([c * 5^i for i, c in enumerate(E)]) a + O(5^4) sage: all(c^625 == c for c in E) True sage: S.<x> = ZZ[] sage: f = x^3 - 98*x + 7 sage: W.<w> = ZpCA(7,3).ext(f) sage: b = (1+w)^5; L = b.teichmuller_expansion(); L [1 + O(w^9), 5 + 5*w^3 + w^6 + 4*w^7 + O(w^8), 3 + 3*w^3 + O(w^7), 3 + 3*w^3 + O(w^6), O(w^5), 4 + 5*w^3 + O(w^4), 3 + O(w^3), 6 + O(w^2), 6 + O(w)] sage: sum([w^i*L[i] for i in range(9)]) == b True sage: all(L[i]^(7^3) == L[i] for i in range(9)) True sage: L = W(3).teichmuller_expansion(); L [3 + 3*w^3 + w^7 + O(w^9), O(w^8), O(w^7), 4 + 5*w^3 + O(w^6), O(w^5), O(w^4), 3 + O(w^3), 6 + O(w^2)] sage: sum([w^i*L[i] for i in range(len(L))]) 3 + O(w^9)
- to_fraction_field()¶
Returns
self
cast into the fraction field ofself.parent()
.EXAMPLES:
sage: R = ZpCA(5,5) sage: S.<x> = ZZ[] sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5 sage: W.<w> = R.ext(f) sage: z = (1 + w)^5; z 1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25) sage: y = z.to_fraction_field(); y #indirect doctest 1 + w^5 + w^6 + 2*w^7 + 4*w^8 + 3*w^10 + w^12 + 4*w^13 + 4*w^14 + 4*w^15 + 4*w^16 + 4*w^17 + 4*w^20 + w^21 + 4*w^24 + O(w^25) sage: y.parent() 5-adic Eisenstein Extension Field in w defined by x^5 + 75*x^3 - 15*x^2 + 125*x - 5
- unit_part()¶
Returns the unit part of
self
, ieself / uniformizer^(self.valuation())
EXAMPLES:
sage: R = ZpCA(5,5) sage: S.<x> = ZZ[] sage: f = x^5 + 75*x^3 - 15*x^2 +125*x - 5 sage: W.<w> = R.ext(f) sage: a = W(75, 19); a 3*w^10 + 2*w^12 + w^14 + w^16 + w^17 + 3*w^18 + O(w^19) sage: a.valuation() 10 sage: a.precision_absolute() 19 sage: a.precision_relative() 9 sage: a.unit_part() 3 + 2*w^2 + w^4 + w^6 + w^7 + 3*w^8 + O(w^9)