Local Generic Element#
This file contains a common superclass for \(p\)-adic elements and power series elements.
AUTHORS:
David Roe: initial version
Julian Rueth (2012-10-15, 2014-06-25, 2017-08-04): added inverse_of_unit(); improved add_bigoh(); added _test_expansion()
- class sage.rings.padics.local_generic_element.LocalGenericElement#
Bases:
CommutativeRingElement
- add_bigoh(absprec)#
Return a copy of this element with absolute precision decreased to
absprec
.INPUT:
absprec
– an integer or positive infinity
EXAMPLES:
sage: K = QpCR(3,4) sage: o = K(1); o 1 + O(3^4) sage: o.add_bigoh(2) 1 + O(3^2) sage: o.add_bigoh(-5) O(3^-5)
One cannot use
add_bigoh
to lift to a higher precision; this can be accomplished withlift_to_precision()
:sage: o.add_bigoh(5) 1 + O(3^4)
Negative values of
absprec
return an element in the fraction field of the element’s parent:sage: R = ZpCA(3,4) sage: R(3).add_bigoh(-5) O(3^-5)
For fixed-mod elements this method truncates the element:
sage: R = ZpFM(3,4) sage: R(3).add_bigoh(1) 0
If
absprec
exceeds the precision of the element, then this method has no effect:sage: R(3).add_bigoh(5) 3
A negative value for
absprec
returns an element in the fraction field:sage: R(3).add_bigoh(-1).parent() 3-adic Field with floating precision 4
- euclidean_degree()#
Return the degree of this element as an element of an Euclidean domain.
EXAMPLES:
For a field, this is always zero except for the zero element:
sage: K = Qp(2) sage: K.one().euclidean_degree() 0 sage: K.gen().euclidean_degree() 0 sage: K.zero().euclidean_degree() Traceback (most recent call last): ... ValueError: euclidean degree not defined for the zero element
For a ring which is not a field, this is the valuation of the element:
sage: R = Zp(2) sage: R.one().euclidean_degree() 0 sage: R.gen().euclidean_degree() 1 sage: R.zero().euclidean_degree() Traceback (most recent call last): ... ValueError: euclidean degree not defined for the zero element
- inverse_of_unit()#
Returns the inverse of
self
ifself
is a unit.OUTPUT:
an element in the same ring as
self
EXAMPLES:
sage: R = ZpCA(3,5) sage: a = R(2); a 2 + O(3^5) sage: b = a.inverse_of_unit(); b 2 + 3 + 3^2 + 3^3 + 3^4 + O(3^5)
A
ZeroDivisionError
is raised if an element has no inverse in the ring:sage: R(3).inverse_of_unit() Traceback (most recent call last): ... ZeroDivisionError: inverse of 3 + O(3^5) does not exist
Unlike the usual inverse of an element, the result is in the same ring as
self
and not just in its fraction field:sage: c = ~a; c 2 + 3 + 3^2 + 3^3 + 3^4 + O(3^5) sage: a.parent() 3-adic Ring with capped absolute precision 5 sage: b.parent() 3-adic Ring with capped absolute precision 5 sage: c.parent() 3-adic Field with capped relative precision 5
For fields this does of course not make any difference:
sage: R = QpCR(3,5) sage: a = R(2) sage: b = a.inverse_of_unit() sage: c = ~a sage: a.parent() 3-adic Field with capped relative precision 5 sage: b.parent() 3-adic Field with capped relative precision 5 sage: c.parent() 3-adic Field with capped relative precision 5
- is_integral()#
Returns whether self is an integral element.
INPUT:
self
– a local ring element
OUTPUT:
boolean – whether
self
is an integral element.
EXAMPLES:
sage: R = Qp(3,20) sage: a = R(7/3); a.is_integral() False sage: b = R(7/5); b.is_integral() True
- is_padic_unit()#
Returns whether self is a \(p\)-adic unit. That is, whether it has zero valuation.
INPUT:
self
– a local ring element
OUTPUT:
boolean – whether
self
is a unit
EXAMPLES:
sage: R = Zp(3,20,'capped-rel'); K = Qp(3,20,'capped-rel') sage: R(0).is_padic_unit() False sage: R(1).is_padic_unit() True sage: R(2).is_padic_unit() True sage: R(3).is_padic_unit() False sage: Qp(5,5)(5).is_padic_unit() False
- is_unit()#
Returns whether self is a unit
INPUT:
self
– a local ring element
OUTPUT:
boolean – whether
self
is a unit
Note
For fields all nonzero elements are units. For DVR’s, only those elements of valuation 0 are. An older implementation ignored the case of fields, and returned always the negation of self.valuation()==0. This behavior is now supported with self.is_padic_unit().
EXAMPLES:
sage: R = Zp(3,20,'capped-rel'); K = Qp(3,20,'capped-rel') sage: R(0).is_unit() False sage: R(1).is_unit() True sage: R(2).is_unit() True sage: R(3).is_unit() False sage: Qp(5,5)(5).is_unit() # Note that 5 is invertible in `QQ_5`, even if it has positive valuation! True sage: Qp(5,5)(5).is_padic_unit() False
- normalized_valuation()#
Returns the normalized valuation of this local ring element, i.e., the valuation divided by the absolute ramification index.
INPUT:
self
– a local ring element.OUTPUT:
rational – the normalized valuation of
self
.EXAMPLES:
sage: Q7 = Qp(7) sage: R.<x> = Q7[] sage: F.<z> = Q7.ext(x^3+7*x+7) sage: z.normalized_valuation() 1/3
- quo_rem(other, integral=False)#
Return the quotient with remainder of the division of this element by
other
.INPUT:
other
– an element in the same ringintegral
– if True, use integral-style remainders even when the parent is a field. Namely, the remainder will have no terms in its p-adic expansion above the valuation ofother
.
EXAMPLES:
sage: R = Zp(3, 5) sage: R(12).quo_rem(R(2)) (2*3 + O(3^6), 0) sage: R(2).quo_rem(R(12)) (O(3^4), 2 + O(3^5)) sage: K = Qp(3, 5) sage: K(12).quo_rem(K(2)) (2*3 + O(3^6), 0) sage: K(2).quo_rem(K(12)) (2*3^-1 + 1 + 3 + 3^2 + 3^3 + O(3^4), 0)
You can get the same behavior for fields as for rings by using integral=True:
sage: K(12).quo_rem(K(2), integral=True) (2*3 + O(3^6), 0) sage: K(2).quo_rem(K(12), integral=True) (O(3^4), 2 + O(3^5))
- slice(i, j, k=1, lift_mode='simple')#
Returns the sum of the \(pi^{i + l \cdot k}\) terms of the series expansion of this element, where pi is the uniformizer, for \(i + l \cdot k\) between
i
andj-1
inclusive, and nonnegative integers \(l\). Behaves analogously to the slice function for lists.INPUT:
i
– an integer; if set toNone
, the sum will start with the first non-zero term of the series.j
– an integer; if set toNone
or \(\infty\), this method behaves as if it was set to the absolute precision of this element.k
– (default: 1) a positive integer
EXAMPLES:
sage: R = Zp(5, 6, 'capped-rel') sage: a = R(1/2); a 3 + 2*5 + 2*5^2 + 2*5^3 + 2*5^4 + 2*5^5 + O(5^6) sage: a.slice(2, 4) 2*5^2 + 2*5^3 + O(5^4) sage: a.slice(1, 6, 2) 2*5 + 2*5^3 + 2*5^5 + O(5^6)
The step size
k
has to be positive:sage: a.slice(0, 3, 0) Traceback (most recent call last): ... ValueError: slice step must be positive sage: a.slice(0, 3, -1) Traceback (most recent call last): ... ValueError: slice step must be positive
If
i
exceedsj
, then the result will be zero, with the precision given byj
:sage: a.slice(5, 4) O(5^4) sage: a.slice(6, 5) O(5^5)
However, the precision cannot exceed the precision of the element:
sage: a.slice(101,100) O(5^6) sage: a.slice(0,5,2) 3 + 2*5^2 + 2*5^4 + O(5^5) sage: a.slice(0,6,2) 3 + 2*5^2 + 2*5^4 + O(5^6) sage: a.slice(0,7,2) 3 + 2*5^2 + 2*5^4 + O(5^6)
If start is left blank, it is set to the valuation:
sage: K = Qp(5, 6) sage: x = K(1/25 + 5); x 5^-2 + 5 + O(5^4) sage: x.slice(None, 3) 5^-2 + 5 + O(5^3) sage: x[:3] doctest:warning ... DeprecationWarning: __getitem__ is changing to match the behavior of number fields. Please use expansion instead. See https://github.com/sagemath/sage/issues/14825 for details. 5^-2 + 5 + O(5^3)
- sqrt(extend=True, all=False, algorithm=None)#
Return the square root of this element.
INPUT:
self
– a \(p\)-adic element.extend
– a boolean (default:True
); ifTrue
, return a square root in an extension if necessary; ifFalse
and no root exists in the given ring or field, raise a ValueError.all
– a boolean (default:False
); ifTrue
, return a list of all square roots.algorithm
–"pari"
,"sage"
orNone
(default:None
); Sage provides an implementation for any extension of \(Q_p\) whereas only square roots over \(Q_p\) is implemented in Pari; the default is"pari"
if the ground field is \(Q_p\),"sage"
otherwise.
OUTPUT:
The square root or the list of all square roots of this element.
Note
The square root is chosen (resp. the square roots are ordered) in a deterministic way, which is compatible with change of precision.
EXAMPLES:
sage: R = Zp(3, 20) sage: sqrt(R(0)) 0 sage: sqrt(R(1)) 1 + O(3^20) sage: R(2).sqrt(extend=False) Traceback (most recent call last): ... ValueError: element is not a square sage: s = sqrt(R(4)); -s 2 + O(3^20) sage: s = sqrt(R(9)); s 3 + O(3^21)
Over the \(2\)-adics, the precision of the square root is less than the input:
sage: R2 = Zp(2, 20) sage: sqrt(R2(1)) 1 + O(2^19) sage: sqrt(R2(4)) 2 + O(2^20) sage: R.<t> = Zq(2^10, 10) sage: u = 1 + 8*t sage: sqrt(u) 1 + t*2^2 + t^2*2^3 + t^2*2^4 + (t^4 + t^3 + t^2)*2^5 + (t^4 + t^2)*2^6 + (t^5 + t^2)*2^7 + (t^6 + t^5 + t^4 + t^2)*2^8 + O(2^9) sage: R.<a> = Zp(2).extension(x^3 - 2) sage: u = R(1 + a^4 + a^5 + a^7 + a^8, 10); u 1 + a^4 + a^5 + a^7 + a^8 + O(a^10) sage: v = sqrt(u); v 1 + a^2 + a^4 + a^6 + O(a^7)
However, observe that the precision increases to its original value when we recompute the square of the square root:
sage: v^2 1 + a^4 + a^5 + a^7 + a^8 + O(a^10)
If the input does not have enough precision in order to determine if the given element has a square root in the ground field, an error is raised:
sage: R(1, 6).sqrt() Traceback (most recent call last): ... PrecisionError: not enough precision to be sure that this element has a square root sage: R(1, 7).sqrt() 1 + O(a^4) sage: R(1+a^6, 7).sqrt(extend=False) Traceback (most recent call last): ... ValueError: element is not a square
In particular, an error is raised when we try to compute the square root of an inexact