Witt vector rings

This module provides the class WittVectorRing of rings of truncated Witt vectors.

AUTHORS:

  • Jacob Dennerlein (2022-11-28): initial version

  • Rubén Muñoz--Bertrand (2025-02-13, 2025-12-23): major refactoring and new features

class sage.rings.padics.witt_vector_ring.WittVectorFrobeniusMorphism(domain, truncate=False)[source]

Bases: RingHomomorphism

A class implementing Frobenius homomorphisms on Witt vector rings.

Warning

This class should not be called directly, use WittVectorRing.frobenius_morphism() instead.

EXAMPLES:

sage: R.<x,y,z> = PolynomialRing(ZZ)
sage: W = WittVectorRing(R, p=3, prec=3)
sage: w = W([x, y, z])
sage: frob = W.frobenius_morphism()
sage: frob(w)
(x^3 + 3*y, -3*x^6*y - 9*x^3*y^2 - 8*y^3 + 3*z)

sage: W = WittVectorRing(R, p=3, prec=1)
sage: W.frobenius_morphism()
Traceback (most recent call last):
...
ValueError: the ring of Witt vectors must have precision at least 2
when truncate=True
>>> from sage.all import *
>>> R = PolynomialRing(ZZ, names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
>>> W = WittVectorRing(R, p=Integer(3), prec=Integer(3))
>>> w = W([x, y, z])
>>> frob = W.frobenius_morphism()
>>> frob(w)
(x^3 + 3*y, -3*x^6*y - 9*x^3*y^2 - 8*y^3 + 3*z)

>>> W = WittVectorRing(R, p=Integer(3), prec=Integer(1))
>>> W.frobenius_morphism()
Traceback (most recent call last):
...
ValueError: the ring of Witt vectors must have precision at least 2
when truncate=True
class sage.rings.padics.witt_vector_ring.WittVectorRing(coefficient_ring, prec, prime, algorithm)[source]

Bases: Parent, UniqueRepresentation

Return the appropriate \(p\)-typical truncated Witt vector ring.

INPUT:

  • coefficient_ring – commutative ring of coefficients

  • prec – integer (default: \(1\)), length of the truncated Witt vectors in the ring

  • p – a prime number (default: None); when it is not set, it defaults to the characteristic of coefficient_ring when it is prime.

  • algorithm – the name of the algorithm to use for the ring laws (default: None); when it is not set, the most adequate algorithm is chosen

Available algorithms are:

  • standard – the schoolbook algorithm;

  • finotti – Finotti’s algorithm; it can be used when the coefficient ring has characteristic \(p\);

  • phantom – computes the ring laws using the phantom components using a lift of coefficient_ring, assuming that it is either \(\GF{q}\) for a power \(q\) of \(p\), or a polynomial ring on that field;

  • p_invertible – uses some optimisations when \(p\) is invertible in the coefficient ring.

EXAMPLES:

sage: WittVectorRing(QQ, p=5)
Ring of truncated 5-typical Witt vectors of length 1 over
Rational Field
>>> from sage.all import *
>>> WittVectorRing(QQ, p=Integer(5))
Ring of truncated 5-typical Witt vectors of length 1 over
Rational Field

sage: WittVectorRing(GF(3))
Ring of truncated 3-typical Witt vectors of length 1 over
Finite Field of size 3
[Python]
>>> from sage.all import *
>>> WittVectorRing(GF(Integer(3)))
Ring of truncated 3-typical Witt vectors of length 1 over
Finite Field of size 3

sage: WittVectorRing(GF(3)['t'])
Ring of truncated 3-typical Witt vectors of length 1 over
Univariate Polynomial Ring in t over Finite Field of size 3
>>> from sage.all import *
>>> WittVectorRing(GF(Integer(3))['t'])
Ring of truncated 3-typical Witt vectors of length 1 over
Univariate Polynomial Ring in t over Finite Field of size 3

sage: WittVectorRing(Qp(7), prec=30, p=5)
Ring of truncated 5-typical Witt vectors of length 30 over
7-adic Field with capped relative precision 20
[Python]
>>> from sage.all import *
>>> WittVectorRing(Qp(Integer(7)), prec=Integer(30), p=Integer(5))
Ring of truncated 5-typical Witt vectors of length 30 over
7-adic Field with capped relative precision 20

sage: p = 5
sage: W = WittVectorRing(ZZ, prec=3, p=p)
sage: W
Ring of truncated 5-typical Witt vectors of length 3 over Integer Ring
sage: V = W.verschiebung(extend=True)
sage: WW = V.codomain()
sage: WW
Ring of truncated 5-typical Witt vectors of length 4 over Integer Ring
sage: F = WW.frobenius_morphism()
sage: w = W.random_element(x=-100, y=100)
sage: w  # random
(-13, 20, -33)
sage: p*w == F(V(w))
True
>>> from sage.all import *
>>> p = Integer(5)
>>> W = WittVectorRing(ZZ, prec=Integer(3), p=p)
>>> W
Ring of truncated 5-typical Witt vectors of length 3 over Integer Ring
>>> V = W.verschiebung(extend=True)
>>> WW = V.codomain()
>>> WW
Ring of truncated 5-typical Witt vectors of length 4 over Integer Ring
>>> F = WW.frobenius_morphism()
>>> w = W.random_element(x=-Integer(100), y=Integer(100))
>>> w  # random
(-13, 20, -33)
>>> p*w == F(V(w))
True

sage: p = 7
sage: W = WittVectorRing(GF(p)['x,y'], prec=5)
sage: W
Ring of truncated 7-typical Witt vectors of length 5 over Multivariate
Polynomial Ring in x, y over Finite Field of size 7
sage: V = W.verschiebung()
sage: F = W.frobenius_morphism()
sage: w = W.random_element()
sage: w  # random
(-3*x^2 + 2*y^2 - 3*y + 2, -2*x*y - y^2 - y - 2, -x^2 + y^2,
x^2 + 2*y^2 + 3*x + y, 2*x^2 - 3*x*y + y^2 + y + 1)
sage: p*w == F(V(w))
True
sage: p*w == V(F(w))
True
[Python]
>>> from sage.all import *
>>> p = Integer(7)
>>> W = WittVectorRing(GF(p)['x,y'], prec=Integer(5))
>>> W
Ring of truncated 7-typical Witt vectors of length 5 over Multivariate
Polynomial Ring in x, y over Finite Field of size 7
>>> V = W.verschiebung()
>>> F = W.frobenius_morphism()
>>> w = W.random_element()
>>> w  # random
(-3*x^2 + 2*y^2 - 3*y + 2, -2*x*y - y^2 - y - 2, -x^2 + y^2,
x^2 + 2*y^2 + 3*x + y, 2*x^2 - 3*x*y + y^2 + y + 1)
>>> p*w == F(V(w))
True
>>> p*w == V(F(w))
True
cardinality()[source]

Return the cardinality of self.

EXAMPLES:

sage: WittVectorRing(GF(17), prec=2).cardinality()
289
sage: WittVectorRing(QQ, p=2).cardinality()
+Infinity
>>> from sage.all import *
>>> WittVectorRing(GF(Integer(17)), prec=Integer(2)).cardinality()
289
>>> WittVectorRing(QQ, p=Integer(2)).cardinality()
+Infinity
characteristic()[source]

Return the characteristic of self.

EXAMPLES:

sage: WittVectorRing(GF(25), p=5, prec=3).characteristic()
125
sage: WittVectorRing(ZZ, p=2, prec=4).characteristic()
0
sage: WittVectorRing(Integers(18), p=3, prec=3).characteristic()
162
>>> from sage.all import *
>>> WittVectorRing(GF(Integer(25)), p=Integer(5), prec=Integer(3)).characteristic()
125
>>> WittVectorRing(ZZ, p=Integer(2), prec=Integer(4)).characteristic()
0
>>> WittVectorRing(Integers(Integer(18)), p=Integer(3), prec=Integer(3)).characteristic()
162
coefficient_ring()[source]

Return the coefficient ring of self.

EXAMPLES:

sage: W = WittVectorRing(Zp(5), p=5)
sage: W.coefficient_ring()
5-adic Ring with capped relative precision 20
>>> from sage.all import *
>>> W = WittVectorRing(Zp(Integer(5)), p=Integer(5))
>>> W.coefficient_ring()
5-adic Ring with capped relative precision 20
frobenius_morphism(truncate=False)[source]

Return the Frobenius homomorphism of this ring of Witt vectors.

INPUT:

  • truncate – boolean (default: False); when the coefficient ring has positive characteristic \(p\), chose whether to lower the precision of the codomain by \(1\). This is always the case when the characteristic of the coefficient ring is not \(p\).

EXAMPLES:

sage: R.<x,y> = PolynomialRing(QQ)
sage: W = WittVectorRing(R, p=5, prec=2)
sage: w = W([x, y])
sage: frob = W.frobenius_morphism()
sage: frob(w)
(x^5 + 5*y)
>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2)
>>> W = WittVectorRing(R, p=Integer(5), prec=Integer(2))
>>> w = W([x, y])
>>> frob = W.frobenius_morphism()
>>> frob(w)
(x^5 + 5*y)
frobenius_polynomials(variables=None)[source]

Return the Witt Frobenius polynomials.

INPUT:

  • variables – names of the indeterminates (default: None), given as a string, or as a list of strings, whose length must be the precision of the ring. When nothing is given, variables indexed by \(X\) are used.

EXAMPLES:

sage: W = WittVectorRing(GF(5), prec=4)
sage: W.frobenius_polynomials()
[X0^5, X1^5, X2^5]

sage: W = WittVectorRing(ZZ, p=2, prec=3)
sage: W.frobenius_polynomials('T0, T1, T2')
[T0^2 + 2*T1, -2*T0^2*T1 - T1^2 + 2*T2]

sage: W = WittVectorRing(ZZ, p=3, prec=3)
sage: W.frobenius_polynomials('T0, T1, T2')
[T0^3 + 3*T1, -3*T0^6*T1 - 9*T0^3*T1^2 - 8*T1^3 + 3*T2]
>>> from sage.all import *
>>> W = WittVectorRing(GF(Integer(5)), prec=Integer(4))
>>> W.frobenius_polynomials()
[X0^5, X1^5, X2^5]

>>> W = WittVectorRing(ZZ, p=Integer(2), prec=Integer(3))
>>> W.frobenius_polynomials('T0, T1, T2')
[T0^2 + 2*T1, -2*T0^2*T1 - T1^2 + 2*T2]

>>> W = WittVectorRing(ZZ, p=Integer(3), prec=Integer(3))
>>> W.frobenius_polynomials('T0, T1, T2')
[T0^3 + 3*T1, -3*T0^6*T1 - 9*T0^3*T1^2 - 8*T1^3 + 3*T2]
gen(n=0)[source]

Return the n-th generator of self.

Warning

This is not the n-th generator of self as a self.base_ring()-algebra.

See also

gens()

EXAMPLES:

sage: R.<x, y> = ZZ[]
sage: W = WittVectorRing(R, p=3, prec=3)
sage: W.gen()
(x, 0, 0)
sage: W.gen(1)
(y, 0, 0)
sage: W.gen(n=2)
Traceback (most recent call last):
...
ValueError: Generator not defined.
>>> from sage.all import *
>>> R = ZZ['x, y']; (x, y,) = R._first_ngens(2)
>>> W = WittVectorRing(R, p=Integer(3), prec=Integer(3))
>>> W.gen()
(x, 0, 0)
>>> W.gen(Integer(1))
(y, 0, 0)
>>> W.gen(n=Integer(2))
Traceback (most recent call last):
...
ValueError: Generator not defined.
gens()[source]

Return a tuple of generators of self.

Warning

These are not the generators of self as a self.base_ring()-algebra. Rather, this set generates a sub-self.base_ring()-algebra \(A\) of self such that every element of self can be written as \(\sum_{i=0}^{prec}V^i(a_i)\) where all \(a_i\in A\).

EXAMPLES:

sage: W = WittVectorRing(GF(29), prec=3)
sage: W.gens()
((1, 0, 0),)

sage: F.<a> = GF(27)
sage: W = WittVectorRing(F, prec=3)
sage: W.gens()
((a, 0, 0),)

sage: R.<x> = ZZ[]
sage: W = WittVectorRing(R, p=7, prec=2)
sage: W.gens()
((x, 0),)
>>> from sage.all import *
>>> W = WittVectorRing(GF(Integer(29)), prec=Integer(3))
>>> W.gens()
((1, 0, 0),)

>>> F = GF(Integer(27), names=('a',)); (a,) = F._first_ngens(1)
>>> W = WittVectorRing(F, prec=Integer(3))
>>> W.gens()
((a, 0, 0),)

>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> W = WittVectorRing(R, p=Integer(7), prec=Integer(2))
>>> W.gens()
((x, 0),)
is_exact()[source]

Return whether the elements of self are represented exactly.

EXAMPLES:

sage: WittVectorRing(ZZ, p=3, prec=3).is_exact()
True
sage: WittVectorRing(Qp(7), p=7, prec=2).is_exact()
False
>>> from sage.all import *
>>> WittVectorRing(ZZ, p=Integer(3), prec=Integer(3)).is_exact()
True
>>> WittVectorRing(Qp(Integer(7)), p=Integer(7), prec=Integer(2)).is_exact()
False
is_field(proof=True)[source]

Return True if this ring is a field.

INPUT:

  • proof – boolean (default: True); if set to True, the returned value is correct but the method might throw an exception. Otherwise, if it is set to False, the method returns True if it can establish that self is a field, and False otherwise.

EXAMPLES:

sage: WittVectorRing(QQ, p=2).is_field()
True
sage: WittVectorRing(QQ, p=2, prec=2).is_field()
False
sage: WittVectorRing(GF(9, 'a')).is_field()
True
sage: WittVectorRing(GF(9, 'a'), prec=3).is_field()
False
sage: WittVectorRing(ZZ, p=5).is_field()
False
sage: L.<z> = LazyLaurentSeriesRing(ZZ)
sage: W = WittVectorRing(L, p=7, algorithm="standard")
sage: W.is_field(proof=True)
Traceback (most recent call last):
...
NotImplementedError: unable to determine whether or not Lazy
Laurent Series Ring in z over Integer Ring is a field.
sage: W.is_field(proof=False)
False
>>> from sage.all import *
>>> WittVectorRing(QQ, p=Integer(2)).is_field()
True
>>> WittVectorRing(QQ, p=Integer(2), prec=Integer(2)).is_field()
False
>>> WittVectorRing(GF(Integer(9), 'a')).is_field()
True
>>> WittVectorRing(GF(Integer(9), 'a'), prec=Integer(3)).is_field()
False
>>> WittVectorRing(ZZ, p=Integer(5)).is_field()
False
>>> L = LazyLaurentSeriesRing(ZZ, names=('z',)); (z,) = L._first_ngens(1)
>>> W = WittVectorRing(L, p=Integer(7), algorithm="standard")
>>> W.is_field(proof=True)
Traceback (most recent call last):
...
NotImplementedError: unable to determine whether or not Lazy
Laurent Series Ring in z over Integer Ring is a field.
>>> W.is_field(proof=False)
False
is_finite()[source]

Return whether self is a finite ring.

EXAMPLES:

sage: WittVectorRing(GF(23)).is_finite()
True
sage: WittVectorRing(ZZ, p=2).is_finite()
False
>>> from sage.all import *
>>> WittVectorRing(GF(Integer(23))).is_finite()
True
>>> WittVectorRing(ZZ, p=Integer(2)).is_finite()
False
is_integral_domain(proof=True)[source]

Return True if this ring is an integral domain.

INPUT:

  • proof – boolean (default: True); if set to True, the returned value is correct but the method might throw an exception. Otherwise, if it is set to False, the method returns True if it can establish that self is an integral domain, and False otherwise.

EXAMPLES:

sage: WittVectorRing(ZZ, p=2).is_integral_domain()
True
sage: WittVectorRing(ZZ, p=2, prec=2).is_integral_domain()
False
sage: WittVectorRing(GF(9, 'a')).is_integral_domain()
True
sage: WittVectorRing(GF(9, 'a'), prec=3).is_integral_domain()
False
sage: R.<x> = ZZ[]
sage: S.<y> = R.quo(x^2 + 7*x + 8)
sage: T.<t> = S[]
sage: Q.<z> = T.quo(t^2)
sage: W = WittVectorRing(Q, p=7, algorithm="standard")
sage: W.is_integral_domain(proof=True)
Traceback (most recent call last):
...
NotImplementedError: cannot rewrite Univariate Quotient
Polynomial Ring in y over Integer Ring with modulus
x^2 + 7*x + 8 as an isomorphic ring
sage: W.is_integral_domain(proof=False)
False
>>> from sage.all import *
>>> WittVectorRing(ZZ, p=Integer(2)).is_integral_domain()
True
>>> WittVectorRing(ZZ, p=Integer(2), prec=Integer(2)).is_integral_domain()
False
>>> WittVectorRing(GF(Integer(9), 'a')).is_integral_domain()
True
>>> WittVectorRing(GF(Integer(9), 'a'), prec=Integer(3)).is_integral_domain()
False
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> S = R.quo(x**Integer(2) + Integer(7)*x + Integer(8), names=('y',)); (y,) = S._first_ngens(1)
>>> T = S['t']; (t,) = T._first_ngens(1)
>>> Q = T.quo(t**Integer(2), names=('z',)); (z,) = Q._first_ngens(1)
>>> W = WittVectorRing(Q, p=Integer(7), algorithm="standard")
>>> W.is_integral_domain(proof=True)
Traceback (most recent call last):
...
NotImplementedError: cannot rewrite Univariate Quotient
Polynomial Ring in y over Integer Ring with modulus
x^2 + 7*x + 8 as an isomorphic ring
>>> W.is_integral_domain(proof=False)
False
is_integrally_closed()[source]

Return True if this ring is an integrally closed domain.

EXAMPLES:

sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 + 189*x + 394)
sage: R = K.order(2*a)
sage: WittVectorRing(R, p=79).is_integrally_closed()
False
sage: WittVectorRing(ZZ, p=101).is_integrally_closed()
True
sage: WittVectorRing(ZZ, p=101, prec=2).is_integrally_closed()
False
sage: S.<t> = ZZ[]
sage: WittVectorRing(S, p=101).is_integrally_closed()
Traceback (most recent call last):
...
NotImplementedError
>>> from sage.all import *
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(189)*x + Integer(394), names=('a',)); (a,) = K._first_ngens(1)
>>> R = K.order(Integer(2)*a)
>>> WittVectorRing(R, p=Integer(79)).is_integrally_closed()
False
>>> WittVectorRing(ZZ, p=Integer(101)).is_integrally_closed()
True
>>> WittVectorRing(ZZ, p=Integer(101), prec=Integer(2)).is_integrally_closed()
False
>>> S = ZZ['t']; (t,) = S._first_ngens(1)
>>> WittVectorRing(S, p=Integer(101)).is_integrally_closed()
Traceback (most recent call last):
...
NotImplementedError
is_prime_field()[source]

Return True if self is isomorphic to one of the prime fields \(\QQ\) or \(\GF{p}\).

EXAMPLES:

sage: WittVectorRing(QQ, p=2).is_prime_field()
True
sage: WittVectorRing(QQ, p=2, prec=2).is_prime_field()
False
sage: WittVectorRing(GF(9, 'a')).is_prime_field()
False
sage: WittVectorRing(GF(7)).is_prime_field()
True
sage: WittVectorRing(GF(7), prec=3).is_prime_field()
False
>>> from sage.all import *
>>> WittVectorRing(QQ, p=Integer(2)).is_prime_field()
True
>>> WittVectorRing(QQ, p=Integer(2), prec=Integer(2)).is_prime_field()
False
>>> WittVectorRing(GF(Integer(9), 'a')).is_prime_field()
False
>>> WittVectorRing(GF(Integer(7))).is_prime_field()
True
>>> WittVectorRing(GF(Integer(7)), prec=Integer(3)).is_prime_field()
False
ngens()[source]

Return the number of generators of self.

Warning

This is not the number of generators of self as a self.base_ring()-algebra.

See also

gens()

EXAMPLES:

sage: W = WittVectorRing(GF(2), p=3, prec=3)
sage: W.ngens()
1
sage: W = WittVectorRing(GF(2)['t'], p=3, prec=3)
sage: W.ngens()
1
sage: W = WittVectorRing(GF(3), p=3, prec=3)
sage: W.ngens()
1
sage: W = WittVectorRing(GF(3)['t'], p=3, prec=3)
sage: W.ngens()
1
sage: W = WittVectorRing(GF(9,'a'), p=3, prec=3)
sage: W.ngens()
1
sage: W = WittVectorRing(GF(9,'a')['t'], p=3, prec=3)
sage: W.ngens()
1
>>> from sage.all import *
>>> W = WittVectorRing(GF(Integer(2)), p=Integer(3), prec=Integer(3))
>>> W.ngens()
1
>>> W = WittVectorRing(GF(Integer(2))['t'], p=Integer(3), prec=Integer(3))
>>> W.ngens()
1
>>> W = WittVectorRing(GF(Integer(3)), p=Integer(3), prec=Integer(3))
>>> W.ngens()
1
>>> W = WittVectorRing(GF(Integer(3))['t'], p=Integer(3), prec=Integer(3))
>>> W.ngens()
1
>>> W = WittVectorRing(GF(Integer(9),'a'), p=Integer(3), prec=Integer(3))
>>> W.ngens()
1
>>> W = WittVectorRing(GF(Integer(9),'a')['t'], p=Integer(3), prec=Integer(3))
>>> W.ngens()
1
precision()[source]

Return the length of the truncated Witt vectors in self.

EXAMPLES:

sage: WittVectorRing(GF(9), p=3, prec=3).precision()
3
>>> from sage.all import *
>>> WittVectorRing(GF(Integer(9)), p=Integer(3), prec=Integer(3)).precision()
3
prime()[source]

Return the prime from which the truncated Witt vector ring has been constructed.

EXAMPLES:

sage: W = WittVectorRing(GF(81), prec=3)
sage: W.prime()
3

sage: W = WittVectorRing(ZZ, p=7, prec=2)
sage: W.prime()
7
>>> from sage.all import *
>>> W = WittVectorRing(GF(Integer(81)), prec=Integer(3))
>>> W.prime()
3

>>> W = WittVectorRing(ZZ, p=Integer(7), prec=Integer(2))
>>> W.prime()
7
prod_polynomials(variables=None)[source]

Return the Witt product polynomials.

INPUT:

  • variables – names of the indeterminates (default: None), given as a string, or as a list of strings, whose length must be the double of the precision of the ring. When nothing is given, variables indexed by \(X\) and \(Y\) are used.

EXAMPLES:

sage: W = WittVectorRing(GF(5), prec=3)
sage: W.prod_polynomials()
[X0*Y0,
X1*Y0^5 + X0^5*Y1,
-X0^5*X1^4*Y0^20*Y1 - 2*X0^10*X1^3*Y0^15*Y1^2 - 2*X0^15*X1^2*Y0^10*Y1^3 - X0^20*X1*Y0^5*Y1^4 + X2*Y0^25 + X0^25*Y2 + X1^5*Y1^5]

sage: W = WittVectorRing(ZZ, p=2, prec=2)
sage: W.prod_polynomials('T0, T1, U0, U1')
[T0*U0, T1*U0^2 + T0^2*U1 + 2*T1*U1]
>>> from sage.all import *
>>> W = WittVectorRing(GF(Integer(5)), prec=Integer(3))
>>> W.prod_polynomials()
[X0*Y0,
X1*Y0^5 + X0^5*Y1,
-X0^5*X1^4*Y0^20*Y1 - 2*X0^10*X1^3*Y0^15*Y1^2 - 2*X0^15*X1^2*Y0^10*Y1^3 - X0^20*X1*Y0^5*Y1^4 + X2*Y0^25 + X0^25*Y2 + X1^5*Y1^5]

>>> W = WittVectorRing(ZZ, p=Integer(2), prec=Integer(2))
>>> W.prod_polynomials('T0, T1, U0, U1')
[T0*U0, T1*U0^2 + T0^2*U1 + 2*T1*U1]
random_element(*args, **kwds)[source]

Return a random truncated Witt vector.

Extra arguments are passed to the random generator of the coefficient ring.

EXAMPLES:

sage: WittVectorRing(GF(27,'t'), prec=2).random_element()  # random
(z3, 2*z3^2 + 1)

sage: W = WittVectorRing(PolynomialRing(ZZ,'x'), p=3, prec=3)
sage: W.random_element(5)  # random
(x^5 - 2*x^4 - 4*x^3 - 2*x^2 + 1, -x^5 + 2*x^4 - x - 1,
-x^5 + 7*x^4 + 3*x^3 - 24*x^2 - 1)
>>> from sage.all import *
>>> WittVectorRing(GF(Integer(27),'t'), prec=Integer(2)).random_element()  # random
(z3, 2*z3^2 + 1)

>>> W = WittVectorRing(PolynomialRing(ZZ,'x'), p=Integer(3), prec=Integer(3))
>>> W.random_element(Integer(5))  # random
(x^5 - 2*x^4 - 4*x^3 - 2*x^2 + 1, -x^5 + 2*x^4 - x - 1,
-x^5 + 7*x^4 + 3*x^3 - 24*x^2 - 1)
sum_polynomials(variables=None)[source]

Return the Witt sum polynomials.

INPUT:

  • variables – names of the indeterminates (default: None), given as a string, or as a list of strings, whose length must be the double of the precision of the ring. When nothing is given, variables indexed by \(X\) and \(Y\) are used.

EXAMPLES:

sage: W = WittVectorRing(GF(5), prec=2)
sage: W.sum_polynomials(['T0', 'T1', 'U0', 'U1'])
[T0 + U0, -T0^4*U0 - 2*T0^3*U0^2 - 2*T0^2*U0^3 - T0*U0^4 + T1 + U1]

sage: W = WittVectorRing(ZZ, p=2, prec=3)
sage: W.sum_polynomials()
[X0 + Y0,
-X0*Y0 + X1 + Y1,
-X0^3*Y0 - 2*X0^2*Y0^2 - X0*Y0^3 + X0*X1*Y0 + X0*Y0*Y1 - X1*Y1 + X2 + Y2]
>>> from sage.all import *
>>> W = WittVectorRing(GF(Integer(5)), prec=Integer(2))
>>> W.sum_polynomials(['T0', 'T1', 'U0', 'U1'])
[T0 + U0, -T0^4*U0 - 2*T0^3*U0^2 - 2*T0^2*U0^3 - T0*U0^4 + T1 + U1]

>>> W = WittVectorRing(ZZ, p=Integer(2), prec=Integer(3))
>>> W.sum_polynomials()
[X0 + Y0,
-X0*Y0 + X1 + Y1,
-X0^3*Y0 - 2*X0^2*Y0^2 - X0*Y0^3 + X0*X1*Y0 + X0*Y0*Y1 - X1*Y1 + X2 + Y2]
teichmuller_lift(x)[source]

Return the Teichmüller lift of x in self.

This lift is sometimes known as the multiplicative lift of x.

EXAMPLES:

sage: WittVectorRing(GF(125,'t'), prec=2).teichmuller_lift(3)
(3, 0)
>>> from sage.all import *
>>> WittVectorRing(GF(Integer(125),'t'), prec=Integer(2)).teichmuller_lift(Integer(3))
(3, 0)
verschiebung(extend=False)[source]

Return the Verschiebung map of this ring of Witt vectors.

INPUT:

  • extend – boolean (default: False); whether the codomain of the map has precision \(1\) more than self.

EXAMPLES:

sage: R.<x,y> = PolynomialRing(QQ)
sage: W = WittVectorRing(R, p=5, prec=2)
sage: w = W([x, y])
sage: V = W.verschiebung()
sage: V(w)
(0, x)
>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2)
>>> W = WittVectorRing(R, p=Integer(5), prec=Integer(2))
>>> w = W([x, y])
>>> V = W.verschiebung()
>>> V(w)
(0, x)
class sage.rings.padics.witt_vector_ring.WittVectorRing_finotti(coefficient_ring, prec, prime)[source]

Bases: WittVectorRing

Child class for truncated Witt vectors using Finotti’s algorithm.

Warning

This class should never be called directly, use WittVectorRing instead.

EXAMPLES:

sage: W = WittVectorRing(GF(49), prec=3, algorithm='finotti')
sage: W
Ring of truncated 7-typical Witt vectors of length 3 over Finite Field in z2 of size 7^2

sage: W = WittVectorRing(ZZ, p=11, prec=3, algorithm='finotti')
Traceback (most recent call last):
...
ValueError: the 'finotti' algorithm only works for coefficients rings of characteristic p
>>> from sage.all import *
>>> W = WittVectorRing(GF(Integer(49)), prec=Integer(3), algorithm='finotti')
>>> W
Ring of truncated 7-typical Witt vectors of length 3 over Finite Field in z2 of size 7^2

>>> W = WittVectorRing(ZZ, p=Integer(11), prec=Integer(3), algorithm='finotti')
Traceback (most recent call last):
...
ValueError: the 'finotti' algorithm only works for coefficients rings of characteristic p
Element[source]

alias of WittVector_finotti

class sage.rings.padics.witt_vector_ring.WittVectorRing_phantom(coefficient_ring, prec, prime)[source]

Bases: WittVectorRing

Child class for truncated Witt vectors using the phantom algorithm.

Warning

This class should never be called directly, use WittVectorRing instead.

EXAMPLES:

sage: W = WittVectorRing(GF(19), prec=20)
sage: W
Ring of truncated 19-typical Witt vectors of length 20 over Finite Field of size 19

sage: W = WittVectorRing(QQ, p=23, prec=3, algorithm='phantom')
Traceback (most recent call last):
...
ValueError: the 'phantom' algorithm only works when the coefficient ring is a finite field of char. p, or a polynomial ring on that field
>>> from sage.all import *
>>> W = WittVectorRing(GF(Integer(19)), prec=Integer(20))
>>> W
Ring of truncated 19-typical Witt vectors of length 20 over Finite Field of size 19

>>> W = WittVectorRing(QQ, p=Integer(23), prec=Integer(3), algorithm='phantom')
Traceback (most recent call last):
...
ValueError: the 'phantom' algorithm only works when the coefficient ring is a finite field of char. p, or a polynomial ring on that field
Element[source]

alias of WittVector_phantom

class sage.rings.padics.witt_vector_ring.WittVectorRing_pinvertible(coefficient_ring, prec, prime)[source]

Bases: WittVectorRing

Child class for truncated Witt vectors using the p_invertible algorithm.

Warning

This class should never be called directly, use WittVectorRing instead.

EXAMPLES:

sage: W = WittVectorRing(QQ, p=31, prec=20)
sage: W
Ring of truncated 31-typical Witt vectors of length 20 over Rational Field

sage: W = WittVectorRing(GF(3), prec=3, algorithm='p_invertible')
Traceback (most recent call last):
...
ValueError: the 'p_invertible' algorithm only works when p is a unit in the ring of coefficients
>>> from sage.all import *
>>> W = WittVectorRing(QQ, p=Integer(31), prec=Integer(20))
>>> W
Ring of truncated 31-typical Witt vectors of length 20 over Rational Field

>>> W = WittVectorRing(GF(Integer(3)), prec=Integer(3), algorithm='p_invertible')
Traceback (most recent call last):
...
ValueError: the 'p_invertible' algorithm only works when p is a unit in the ring of coefficients
Element[source]

alias of WittVector_pinvertible

class sage.rings.padics.witt_vector_ring.WittVectorRing_standard(coefficient_ring, prec, prime)[source]

Bases: WittVectorRing

Child class for truncated Witt vectors using the standard algorithm.

Warning

This class should never be called directly, use WittVectorRing instead.

EXAMPLES:

sage: W = WittVectorRing(GF(3), prec=3, algorithm='standard')
sage: W
Ring of truncated 3-typical Witt vectors of length 3 over Finite Field of size 3
>>> from sage.all import *
>>> W = WittVectorRing(GF(Integer(3)), prec=Integer(3), algorithm='standard')
>>> W
Ring of truncated 3-typical Witt vectors of length 3 over Finite Field of size 3
Element[source]

alias of WittVector_standard

class sage.rings.padics.witt_vector_ring.WittVectorVerschiebung(domain, extend=False)[source]

Bases: RingMap

A class implementing Veschiebung maps on Witt vector rings.

Warning

This class should not be called directly, use WittVectorRing.verschiebung() instead.

EXAMPLES:

sage: R.<x,y,z> = PolynomialRing(ZZ)
sage: W = WittVectorRing(R, p=3, prec=3)
sage: w = W([x, y, z])
sage: V = W.verschiebung()
sage: V(w)
(0, x, y)
>>> from sage.all import *
>>> R = PolynomialRing(ZZ, names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
>>> W = WittVectorRing(R, p=Integer(3), prec=Integer(3))
>>> w = W([x, y, z])
>>> V = W.verschiebung()
>>> V(w)
(0, x, y)
sage.rings.padics.witt_vector_ring.fast_char_p_power(x, n, p=None)[source]

Return \(x^n\) assuming that \(x\) lives in a ring of characteristic \(p\).

If \(x\) is not an element of a ring of characteristic \(p\), this throws an error.

EXAMPLES:

sage: from sage.rings.padics.witt_vector_ring import fast_char_p_power
sage: t = GF(1913)(33)
sage: fast_char_p_power(t, 77)
1371
>>> from sage.all import *
>>> from sage.rings.padics.witt_vector_ring import fast_char_p_power
>>> t = GF(Integer(1913))(Integer(33))
>>> fast_char_p_power(t, Integer(77))
1371

sage: K.<t> = GF(5^3)
sage: fast_char_p_power(t, 385)
4*t^2 + 1
sage: t^385
4*t^2 + 1
[Python]
>>> from sage.all import *
>>> K = GF(Integer(5)**Integer(3), names=('t',)); (t,) = K._first_ngens(1)
>>> fast_char_p_power(t, Integer(385))
4*t^2 + 1
>>> t**Integer(385)
4*t^2 + 1

sage: A.<x> = K[]
sage: fast_char_p_power(x + 1, 10)
x^10 + 2*x^5 + 1
>>> from sage.all import *
>>> A = K['x']; (x,) = A._first_ngens(1)
>>> fast_char_p_power(x + Integer(1), Integer(10))
x^10 + 2*x^5 + 1

sage: B.<u,v> = K[]
sage: fast_char_p_power(u + v, 1250)
u^1250 + 2*u^625*v^625 + v^1250
[Python]
>>> from sage.all import *
>>> B = K['u, v']; (u, v,) = B._first_ngens(2)
>>> fast_char_p_power(u + v, Integer(1250))
u^1250 + 2*u^625*v^625 + v^1250