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): major refactoring and clean-up

class sage.rings.padics.witt_vector_ring.WittVectorRing(coefficient_ring, prec, prime)[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 \(\mathbb F_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
>>> 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
>>> 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
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
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
precision()[source]

Return the length of the truncated Witt vectors in length.

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)
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

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
>>> 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
>>> 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