Elements of p-Adic Rings with Fixed Modulus

AUTHORS:

• David Roe
• Genya Zaytman: documentation
• David Harvey: doctests
class sage.rings.padics.padic_fixed_mod_element.ExpansionIter

Bases: object

An iterator over a $$p$$-adic expansion.

This class should not be instantiated directly, but instead using expansion().

INPUT:

• elt – the $$p$$-adic element
• prec – the number of terms to be emitted
• mode – either simple_mode, smallest_mode or teichmuller_mode

EXAMPLES:

sage: E = Zp(5,4)(373).expansion()
sage: I = iter(E) # indirect doctest
sage: type(I)

class sage.rings.padics.padic_fixed_mod_element.ExpansionIterable

Bases: object

An iterable storing a $$p$$-adic expansion of an element.

This class should not be instantiated directly, but instead using expansion().

INPUT:

• elt – the $$p$$-adic element
• prec – the number of terms to be emitted
• val_shift – how many zeros to add at the beginning of the expansion, or the number of initial terms to truncate (if negative)
• mode – either simple_mode, smallest_mode or teichmuller_mode

EXAMPLES:

sage: E = Zp(5,4)(373).expansion() # indirect doctest
sage: type(E)

class sage.rings.padics.padic_fixed_mod_element.FMElement
add_bigoh(absprec)

Returns a new element truncated modulo $$\pi^{\mbox{absprec}}$$.

INPUT:

• absprec – an integer or infinity

OUTPUT:

• a new element truncated modulo $$\pi^{\mbox{absprec}}$$.

EXAMPLES:

sage: R = Zp(7,4,'fixed-mod','series'); a = R(8); a.add_bigoh(1)
1

is_equal_to(_right, absprec=None)

Returns whether this element is equal to right modulo $$p^{\mbox{absprec}}$$.

If absprec is None, returns if self == 0.

INPUT:

• right – a p-adic element with the same parent
• absprec – a positive integer or None (default: None)

EXAMPLES:

sage: R = ZpFM(2, 6)
sage: R(13).is_equal_to(R(13))
True
sage: R(13).is_equal_to(R(13+2^10))
True
sage: R(13).is_equal_to(R(17), 2)
True
sage: R(13).is_equal_to(R(17), 5)
False

is_zero(absprec=None)

Returns whether self is zero modulo $$\pi^{\mbox{absprec}}$$.

INPUT:

• absprec – an integer

EXAMPLES:

sage: R = ZpFM(17, 6)
sage: R(0).is_zero()
True
sage: R(17^6).is_zero()
True
sage: R(17^2).is_zero(absprec=2)
True

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: R.<a> = ZqFM(5^3)
sage: a.polynomial()
x
sage: a.polynomial(var='y')
y
sage: (5*a^2 + 25).polynomial()
5*x^2 + 5^2

precision_absolute()

The absolute precision of this element.

EXAMPLES:

sage: R = Zp(7,4,'fixed-mod'); a = R(7); a.precision_absolute()
4

precision_relative()

The relative precision of this element.

EXAMPLES:

sage: R = Zp(7,4,'fixed-mod'); a = R(7); a.precision_relative()
3
sage: a = R(0); a.precision_relative()
0

unit_part()

Returns the unit part of self.

If the valuation of self is positive, then the high digits of the result will be zero.

EXAMPLES:

sage: R = Zp(17, 4, 'fixed-mod')
sage: R(5).unit_part()
5
sage: R(18*17).unit_part()
1 + 17
sage: R(0).unit_part()
0
sage: type(R(5).unit_part())
sage: R = ZpFM(5, 5); a = R(75); a.unit_part()
3

val_unit()

Returns a 2-tuple, the first element set to the valuation of self, and the second to the unit part of self.

If self == 0, then the unit part is O(p^self.parent().precision_cap()).

EXAMPLES:

sage: R = ZpFM(5,5)
sage: a = R(75); b = a - a
sage: a.val_unit()
(2, 3)
sage: b.val_unit()
(5, 0)

class sage.rings.padics.padic_fixed_mod_element.PowComputer_

A PowComputer for a fixed-modulus padic ring.

sage.rings.padics.padic_fixed_mod_element.make_pAdicFixedModElement(parent, value)

Unpickles a fixed modulus element.

EXAMPLES:

sage: from sage.rings.padics.padic_fixed_mod_element import make_pAdicFixedModElement
sage: R = ZpFM(5)
sage: a = make_pAdicFixedModElement(R, 17*25); a
2*5^2 + 3*5^3

class sage.rings.padics.padic_fixed_mod_element.pAdicCoercion_FM_frac_field

The canonical inclusion of Zq into its fraction field.

EXAMPLES:

sage: R.<a> = ZqFM(27, implementation='FLINT')
sage: K = R.fraction_field()
sage: f = K.coerce_map_from(R); f
Ring morphism:
From: 3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1
To:   3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1

is_injective()

Return whether this map is injective.

EXAMPLES:

sage: R.<a> = ZqFM(9)
sage: K = R.fraction_field()
sage: f = K.coerce_map_from(R)
sage: f.is_injective()
True

is_surjective()

Return whether this map is surjective.

EXAMPLES:

sage: R.<a> = ZqFM(9)
sage: K = R.fraction_field()
sage: f = K.coerce_map_from(R)
sage: f.is_surjective()
False

section()

Returns a map back to the ring that converts elements of non-negative valuation.

EXAMPLES:

sage: R.<a> = ZqFM(27)
sage: K = R.fraction_field()
sage: f = K.coerce_map_from(R)
sage: f.section()(K.gen())
a

class sage.rings.padics.padic_fixed_mod_element.pAdicCoercion_ZZ_FM

The canonical inclusion from ZZ to a fixed modulus ring.

EXAMPLES:

sage: f = ZpFM(5).coerce_map_from(ZZ); f
Ring morphism:
From: Integer Ring
To:   5-adic Ring of fixed modulus 5^20

section()

Returns a map back to ZZ that approximates an element of this $$p$$-adic ring by an integer.

EXAMPLES:

sage: f = ZpFM(5).coerce_map_from(ZZ).section()
sage: f(ZpFM(5)(-1)) - 5^20
-1

class sage.rings.padics.padic_fixed_mod_element.pAdicConvert_FM_ZZ

The map from a fixed modulus ring back to ZZ that returns the smallest non-negative integer approximation to its input which is accurate up to the precision.

If the input is not in the closure of the image of ZZ, raises a ValueError.

EXAMPLES:

sage: f = ZpFM(5).coerce_map_from(ZZ).section(); f
Set-theoretic ring morphism:
From: 5-adic Ring of fixed modulus 5^20
To:   Integer Ring

class sage.rings.padics.padic_fixed_mod_element.pAdicConvert_FM_frac_field

The section of the inclusion from $$\ZZ_q$$ to its fraction field.

EXAMPLES:

sage: R.<a> = ZqFM(27)
sage: K = R.fraction_field()
sage: f = R.convert_map_from(K); f
Generic morphism:
From: 3-adic Unramified Extension Field in a defined by x^3 + 2*x + 1
To:   3-adic Unramified Extension Ring in a defined by x^3 + 2*x + 1

class sage.rings.padics.padic_fixed_mod_element.pAdicConvert_QQ_FM

The inclusion map from QQ to a fixed modulus ring that is defined on all elements with non-negative p-adic valuation.

EXAMPLES:

sage: f = ZpFM(5).convert_map_from(QQ); f
Generic morphism:
From: Rational Field
To:   5-adic Ring of fixed modulus 5^20

class sage.rings.padics.padic_fixed_mod_element.pAdicFixedModElement

INPUT:

• parent – a pAdicRingFixedMod object.
• x – input data to be converted into the parent.
• absprec – ignored; for compatibility with other $$p$$-adic rings
• relprec – ignored; for compatibility with other $$p$$-adic rings

Note

The following types are currently supported for x:

• Integers
• Rationals – denominator must be relatively prime to $$p$$
• FixedMod $$p$$-adics
• Elements of IntegerModRing(p^k) for k less than or equal to the modulus

The following types should be supported eventually:

• Finite precision $$p$$-adics
• Lazy $$p$$-adics
• Elements of local extensions of THIS $$p$$-adic ring that actually lie in $$\ZZ_p$$

EXAMPLES:

sage: R = Zp(5, 20, 'fixed-mod', 'terse')


Construct from integers:

sage: R(3)
3
sage: R(75)
75
sage: R(0)
0

sage: R(-1)
95367431640624
sage: R(-5)
95367431640620


Construct from rationals:

sage: R(1/2)
47683715820313
sage: R(-7875/874)
9493096742250
sage: R(15/425)
Traceback (most recent call last):
...
ValueError: p divides denominator


Construct from IntegerMod:

sage: R(Integers(125)(3))
3
sage: R(Integers(5)(3))
3
sage: R(Integers(5^30)(3))
3
sage: R(Integers(5^30)(1+5^23))
1
sage: R(Integers(49)(3))
Traceback (most recent call last):
...
TypeError: p does not divide modulus 49

sage: R(Integers(48)(3))
Traceback (most recent call last):
...
TypeError: p does not divide modulus 48


Some other conversions:

sage: R(R(5))
5


Todo

doctests for converting from other types of $$p$$-adic rings

lift()

Return an integer congruent to self modulo the precision.

Warning

Since fixed modulus elements don’t track their precision, the result may not be correct modulo $$i^{\mathrm{prec_cap}}$$ if the element was defined by constructions that lost precision.

EXAMPLES:

sage: R = Zp(7,4,'fixed-mod'); a = R(8); a.lift()
8
sage: type(a.lift())
<type 'sage.rings.integer.Integer'>

multiplicative_order()

Return the minimum possible multiplicative order of self.

OUTPUT:

an integer – the multiplicative order of this element. This is the minimum multiplicative order of all elements of $$\ZZ_p$$ lifting this element to infinite precision.

EXAMPLES:

sage: R = ZpFM(7, 6)
sage: R(1/3)
5 + 4*7 + 4*7^2 + 4*7^3 + 4*7^4 + 4*7^5
sage: R(1/3).multiplicative_order()
+Infinity
sage: R(7).multiplicative_order()
+Infinity
sage: R(1).multiplicative_order()
1
sage: R(-1).multiplicative_order()
2
sage: R.teichmuller(3).multiplicative_order()
6

residue(absprec=1, field=None, check_prec=False)

Reduce self modulo $$p^\mathrm{absprec}$$.

INPUT:

• absprec – an integer (default: 1)
• field – boolean (default None). Whether to return an element of GF(p) or Zmod(p).
• check_prec – boolean (default False). No effect (for compatibility with other types).

OUTPUT:

This element reduced modulo $$p^\mathrm{absprec}$$ as an element of $$\ZZ/p^\mathrm{absprec}\ZZ$$.

EXAMPLES:

sage: R = Zp(7,4,'fixed-mod')
sage: a = R(8)
sage: a.residue(1)
1


This is different from applying % p^n which returns an element in the same ring:

sage: b = a.residue(2); b
8
sage: b.parent()
Ring of integers modulo 49
sage: c = a % 7^2; c
1 + 7
sage: c.parent()
7-adic Ring of fixed modulus 7^4


_mod_()

class sage.rings.padics.padic_fixed_mod_element.pAdicTemplateElement

A class for common functionality among the $$p$$-adic template classes.

INPUT:

• parent – a local ring or field
• x – data defining this element. Various types are supported, including ints, Integers, Rationals, PARI p-adics, integers mod $$p^k$$ and other Sage p-adics.
• absprec – a cap on the absolute precision of this element
• relprec – a cap on the relative precision of this element

EXAMPLES:

sage: Zp(17)(17^3, 8, 4)
17^3 + O(17^7)

expansion(n=None, lift_mode='simple', start_val=None)

Return the coefficients in a $$\pi$$-adic expansion. If this is a field element, start at $$\pi^{\mbox{valuation}}$$, if a ring element at $$\pi^0$$.

For each lift mode, this function returns a list of $$a_i$$ so that this element can be expressed as

$\pi^v \cdot \sum_{i=0}^\infty a_i \pi^i$

where $$v$$ is the valuation of this element when the parent is a field, and $$v = 0$$ otherwise.

Different lift modes affect the choice of $$a_i$$. When lift_mode is 'simple', the resulting $$a_i$$ will be non-negative: if the residue field is $$\GF{p}$$ then they will be integers with $$0 \le a_i < p$$; otherwise they will be a list of integers in the same range giving the coefficients of a polynomial in the indeterminant representing the maximal unramified subextension.

Choosing lift_mode as 'smallest' is similar to 'simple', but uses a balanced representation $$-p/2 < a_i \le p/2$$.

Finally, setting lift_mode = 'teichmuller' will yield Teichmuller representatives for the $$a_i$$: $$a_i^q = a_i$$. In this case the $$a_i$$ will lie in the ring of integers of the maximal unramified subextension of the parent of this element.

INPUT:

• n – integer (default None). If given, returns the corresponding entry in the expansion. Can also accept a slice (see slice())
• lift_mode'simple', 'smallest' or 'teichmuller' (default: 'simple')
• start_val – start at this valuation rather than the default ($$0$$ or the valuation of this element).

OUTPUT:

• If n is None, an iterable giving a $$\pi$$-adic expansion of this element. For base elements the contents will be integers if lift_mode is 'simple' or 'smallest', and elements of self.parent() if lift_mode is 'teichmuller'.
• If n is an integer, the coefficient of $$\pi^n$$ in the $$\pi$$-adic expansion of this element.

Note

Use slice operators to get a particular range.

EXAMPLES:

sage: R = Zp(7,6); a = R(12837162817); a
3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6)
sage: E = a.expansion(); E
7-adic expansion of 3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6)
sage: list(E)
[3, 4, 4, 0, 4, 0]
sage: sum([c * 7^i for i, c in enumerate(E)]) == a
True
sage: E = a.expansion(lift_mode='smallest'); E
7-adic expansion of 3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6) (balanced)
sage: list(E)
[3, -3, -2, 1, -3, 1]
sage: sum([c * 7^i for i, c in enumerate(E)]) == a
True
sage: E = a.expansion(lift_mode='teichmuller'); E
7-adic expansion of 3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6) (teichmuller)
sage: list(E)
[3 + 4*7 + 6*7^2 + 3*7^3 + 2*7^5 + O(7^6),
0,
5 + 2*7 + 3*7^3 + O(7^4),
1 + O(7^3),
3 + 4*7 + O(7^2),
5 + O(7)]
sage: sum(c * 7^i for i, c in enumerate(E))
3 + 4*7 + 4*7^2 + 4*7^4 + O(7^6)


If the element has positive valuation then the list will start with some zeros:

sage: a = R(7^3 * 17)
sage: E = a.expansion(); E
7-adic expansion of 3*7^3 + 2*7^4 + O(7^9)
sage: list(E)
[0, 0, 0, 3, 2, 0, 0, 0, 0]


The expansion of 0 is truncated:

sage: E = R(0, 7).expansion(); E
sage: len(E)
0
sage: list(E)
[]


In fields, on the other hand, the expansion starts at the valuation:

sage: R = Qp(7,4); a = R(6*7+7**2); E = a.expansion(); E
7-adic expansion of 6*7 + 7^2 + O(7^5)
sage: list(E)
[6, 1, 0, 0]
sage: list(a.expansion(lift_mode='smallest'))
[-1, 2, 0, 0]
sage: list(a.expansion(lift_mode='teichmuller'))
[6 + 6*7 + 6*7^2 + 6*7^3 + O(7^4),
2 + 4*7 + 6*7^2 + O(7^3),
3 + 4*7 + O(7^2),
3 + O(7)]


You can ask for a specific entry in the expansion:

sage: a.expansion(1)
6
sage: a.expansion(1, lift_mode='smallest')
-1
sage: a.expansion(2, lift_mode='teichmuller')
2 + 4*7 + 6*7^2 + O(7^3)

lift_to_precision(absprec=None)

Returns another element of the same parent with absolute precision at least absprec, congruent to this $$p$$-adic element modulo the precision of this element.

INPUT:

• absprec – an integer or None (default: None), the absolute precision of the result. If None, 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(17)
sage: R(-1,2).lift_to_precision(10)
16 + 16*17 + O(17^10)
sage: R(1,15).lift_to_precision(10)
1 + O(17^15)
sage: R(1,15).lift_to_precision(30)
Traceback (most recent call last):
...
PrecisionError: Precision higher than allowed by the precision cap.
sage: R(-1,2).lift_to_precision().precision_absolute() == R.precision_cap()
True

sage: R = Zp(5); c = R(17,3); c.lift_to_precision(8)
2 + 3*5 + O(5^8)
sage: c.lift_to_precision().precision_relative() == R.precision_cap()
True


Fixed modulus elements don’t raise errors:

sage: R = ZpFM(5); a = R(5); a.lift_to_precision(7)
5
sage: a.lift_to_precision(10000)
5

residue(absprec=1, field=None, check_prec=True)

Reduce this element modulo $$p^\mathrm{absprec}$$.

INPUT:

• absprec0 or 1.
• field – boolean (default None). For precision 1, whether to return an element of the residue field or a residue ring. Currently unused.
• check_prec – boolean (default True). Whether to raise an error if this element has insufficient precision to determine the reduction. Errors are never raised for fixed-mod or floating-point types.

OUTPUT:

This element reduced modulo $$p^\mathrm{absprec}$$ as an element of the residue field or the null ring.

EXAMPLES:

sage: R.<a> = Zq(27, 4)
sage: (3 + 3*a).residue()
0
sage: (a + 1).residue()
a0 + 1

teichmuller_expansion(n=None)

Returns an iterator over coefficients $$a_0, a_1, \dots, a_n$$ such that

• $$a_i^q = a_i$$, where $$q$$ is the cardinality of the residue field,
• this element can be expressed as
$\pi^v \cdot \sum_{i=0}^\infty a_i \pi^i$

where $$v$$ is the valuation of this element when the parent is a field, and $$v = 0$$ otherwise.

• if $$a_i \ne 0$$, the precision of $$a_i$$ is $$i$$ less than the precision of this element (relative in the case that the parent is a field, absolute otherwise)

Note

The coefficients will lie in the ring of integers of the maximal unramified subextension.

INPUT:

• n – integer (default None). If given, returns the coefficient of $$\pi^n$$ in the expansion.

EXAMPLES:

For fields, the expansion starts at the valuation:

sage: R = Qp(5,5); list(R(70).teichmuller_expansion())
[4 + 4*5 + 4*5^2 + 4*5^3 + 4*5^4 + O(5^5),
3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4),
2 + 5 + 2*5^2 + O(5^3),
1 + O(5^2),
4 + O(5)]


But if you specify n, you get the coefficient of $$\pi^n$$:

sage: R(70).teichmuller_expansion(2)
3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4)

unit_part()

Returns the unit part of this element.

This is the $$p$$-adic element $$u$$ in the same ring so that this element is $$\pi^v u$$, where $$\pi$$ is a uniformizer and $$v$$ is the valuation of this element.

EXAMPLES:

sage: R.<a> = Zq(125)
sage: (5*a).unit_part()
a + O(5^20)

sage.rings.padics.padic_fixed_mod_element.unpickle_fme_v2(cls, parent, value)

Unpickles a fixed-mod element.

EXAMPLES:

sage: from sage.rings.padics.padic_fixed_mod_element import pAdicFixedModElement, unpickle_fme_v2
sage: R = ZpFM(5)
sage: a = unpickle_fme_v2(pAdicFixedModElement, R, 17*25); a
2*5^2 + 3*5^3
sage: a.parent() is R
True