Helper functions for local components¶
This module contains various functions relating to lifting elements of \(\SL_2(\ZZ / N\ZZ)\) to \(\SL_2(\ZZ)\), and other related problems.
- sage.modular.local_comp.liftings.lift_for_SL(A, N=None)[source]¶
Lift a matrix \(A\) from \(SL_m(\ZZ / N\ZZ)\) to \(SL_m(\ZZ)\).
This follows [Shi1971], Lemma 1.38, p. 21.
INPUT:
A
– a square matrix with coefficients in \(\ZZ / N\ZZ\) (or \(\ZZ\))N
– the modulus (optional) required only if the matrixA
has coefficients in \(\ZZ\)
EXAMPLES:
sage: from sage.modular.local_comp.liftings import lift_for_SL sage: A = matrix(Zmod(11), 4, 4, [6, 0, 0, 9, 1, 6, 9, 4, 4, 4, 8, 0, 4, 0, 0, 8]) sage: A.det() 1 sage: L = lift_for_SL(A) sage: L.det() 1 sage: (L - A) == 0 True sage: B = matrix(Zmod(19), 4, 4, [1, 6, 10, 4, 4, 14, 15, 4, 13, 0, 1, 15, 15, 15, 17, 10]) sage: B.det() 1 sage: L = lift_for_SL(B) sage: L.det() 1 sage: (L - B) == 0 True
>>> from sage.all import * >>> from sage.modular.local_comp.liftings import lift_for_SL >>> A = matrix(Zmod(Integer(11)), Integer(4), Integer(4), [Integer(6), Integer(0), Integer(0), Integer(9), Integer(1), Integer(6), Integer(9), Integer(4), Integer(4), Integer(4), Integer(8), Integer(0), Integer(4), Integer(0), Integer(0), Integer(8)]) >>> A.det() 1 >>> L = lift_for_SL(A) >>> L.det() 1 >>> (L - A) == Integer(0) True >>> B = matrix(Zmod(Integer(19)), Integer(4), Integer(4), [Integer(1), Integer(6), Integer(10), Integer(4), Integer(4), Integer(14), Integer(15), Integer(4), Integer(13), Integer(0), Integer(1), Integer(15), Integer(15), Integer(15), Integer(17), Integer(10)]) >>> B.det() 1 >>> L = lift_for_SL(B) >>> L.det() 1 >>> (L - B) == Integer(0) True
from sage.modular.local_comp.liftings import lift_for_SL A = matrix(Zmod(11), 4, 4, [6, 0, 0, 9, 1, 6, 9, 4, 4, 4, 8, 0, 4, 0, 0, 8]) A.det() L = lift_for_SL(A) L.det() (L - A) == 0 B = matrix(Zmod(19), 4, 4, [1, 6, 10, 4, 4, 14, 15, 4, 13, 0, 1, 15, 15, 15, 17, 10]) B.det() L = lift_for_SL(B) L.det() (L - B) == 0
- sage.modular.local_comp.liftings.lift_gen_to_gamma1(m, n)[source]¶
Return four integers defining a matrix in \(\SL_2(\ZZ)\) which is congruent to \(\begin{pmatrix} 0 & -1 \\ 1 & 0 \end{pmatrix} \pmod m\) and lies in the subgroup \(\begin{pmatrix} 1 & * \\ 0 & 1 \end{pmatrix} \pmod n\).
This is a special case of
lift_to_gamma1()
, and is coded as such.INPUT:
\(m\), \(n\) – coprime positive integers
EXAMPLES:
sage: from sage.modular.local_comp.liftings import lift_gen_to_gamma1 sage: A = matrix(ZZ, 2, lift_gen_to_gamma1(9, 8)); A [441 62] [ 64 9] sage: A.change_ring(Zmod(9)) [0 8] [1 0] sage: A.change_ring(Zmod(8)) [1 6] [0 1] sage: type(lift_gen_to_gamma1(9, 8)[0]) <class 'sage.rings.integer.Integer'>
>>> from sage.all import * >>> from sage.modular.local_comp.liftings import lift_gen_to_gamma1 >>> A = matrix(ZZ, Integer(2), lift_gen_to_gamma1(Integer(9), Integer(8))); A [441 62] [ 64 9] >>> A.change_ring(Zmod(Integer(9))) [0 8] [1 0] >>> A.change_ring(Zmod(Integer(8))) [1 6] [0 1] >>> type(lift_gen_to_gamma1(Integer(9), Integer(8))[Integer(0)]) <class 'sage.rings.integer.Integer'>
from sage.modular.local_comp.liftings import lift_gen_to_gamma1 A = matrix(ZZ, 2, lift_gen_to_gamma1(9, 8)); A A.change_ring(Zmod(9)) A.change_ring(Zmod(8)) type(lift_gen_to_gamma1(9, 8)[0])
- sage.modular.local_comp.liftings.lift_matrix_to_sl2z(A, N)[source]¶
Given a list of length 4 representing a 2x2 matrix over \(\ZZ / N\ZZ\) with determinant 1 (mod \(N\)), lift it to a 2x2 matrix over \(\ZZ\) with determinant 1.
This is a special case of
lift_to_gamma1()
, and is coded as such.INPUT:
A
– list of 4 integers defining a \(2 \times 2\) matrixN
– positive integer
EXAMPLES:
sage: from sage.modular.local_comp.liftings import lift_matrix_to_sl2z sage: lift_matrix_to_sl2z([10, 11, 3, 11], 19) [29, 106, 3, 11] sage: type(_[0]) <class 'sage.rings.integer.Integer'> sage: lift_matrix_to_sl2z([2,0,0,1], 5) Traceback (most recent call last): ... ValueError: Determinant is 2 mod 5, should be 1
>>> from sage.all import * >>> from sage.modular.local_comp.liftings import lift_matrix_to_sl2z >>> lift_matrix_to_sl2z([Integer(10), Integer(11), Integer(3), Integer(11)], Integer(19)) [29, 106, 3, 11] >>> type(_[Integer(0)]) <class 'sage.rings.integer.Integer'> >>> lift_matrix_to_sl2z([Integer(2),Integer(0),Integer(0),Integer(1)], Integer(5)) Traceback (most recent call last): ... ValueError: Determinant is 2 mod 5, should be 1
from sage.modular.local_comp.liftings import lift_matrix_to_sl2z lift_matrix_to_sl2z([10, 11, 3, 11], 19) type(_[0]) lift_matrix_to_sl2z([2,0,0,1], 5)
- sage.modular.local_comp.liftings.lift_ramified(g, p, u, n)[source]¶
Given four integers \(a,b,c,d\) with \(p \mid c\) and \(ad - bc = 1 \pmod{p^u}\), find \(a',b',c',d'\) congruent to \(a,b,c,d \pmod{p^u}\), with \(c' = c \pmod{p^{u+1}}\), such that \(a'd' - b'c'\) is exactly 1, and \(\begin{pmatrix} a & b \\ c & d \end{pmatrix}\) is in \(\Gamma_1(n)\).
Algorithm: Uses
lift_to_gamma1()
to get a lifting modulo \(p^u\), and then adds an appropriate multiple of the top row to the bottom row in order to get the bottom-left entry correct modulo \(p^{u+1}\).EXAMPLES:
sage: from sage.modular.local_comp.liftings import lift_ramified sage: lift_ramified([2,2,3,2], 3, 1, 1) [-1, -1, 3, 2] sage: lift_ramified([8,2,12,2], 3, 2, 23) [323, 110, -133584, -45493] sage: type(lift_ramified([8,2,12,2], 3, 2, 23)[0]) <class 'sage.rings.integer.Integer'>
>>> from sage.all import * >>> from sage.modular.local_comp.liftings import lift_ramified >>> lift_ramified([Integer(2),Integer(2),Integer(3),Integer(2)], Integer(3), Integer(1), Integer(1)) [-1, -1, 3, 2] >>> lift_ramified([Integer(8),Integer(2),Integer(12),Integer(2)], Integer(3), Integer(2), Integer(23)) [323, 110, -133584, -45493] >>> type(lift_ramified([Integer(8),Integer(2),Integer(12),Integer(2)], Integer(3), Integer(2), Integer(23))[Integer(0)]) <class 'sage.rings.integer.Integer'>
from sage.modular.local_comp.liftings import lift_ramified lift_ramified([2,2,3,2], 3, 1, 1) lift_ramified([8,2,12,2], 3, 2, 23) type(lift_ramified([8,2,12,2], 3, 2, 23)[0])
- sage.modular.local_comp.liftings.lift_to_gamma1(g, m, n)[source]¶
If
g = [a,b,c,d]
is a list of integers defining a \(2 \times 2\) matrix whose determinant is \(1 \pmod m\), return a list of integers giving the entries of a matrix which is congruent to \(g \pmod m\) and to \(\begin{pmatrix} 1 & * \\ 0 & 1 \end{pmatrix} \pmod n\). Here \(m\) and \(n\) must be coprime.INPUT:
g
– list of 4 integers defining a \(2 \times 2\) matrix\(m\), \(n\) – coprime positive integers
Here \(m\) and \(n\) should be coprime positive integers. Either of \(m\) and \(n\) can be \(1\). If \(n = 1\), this still makes perfect sense; this is what is called by the function
lift_matrix_to_sl2z()
. If \(m = 1\) this is a rather silly question, so we adopt the convention of always returning the identity matrix.The result is always a list of Sage integers (unlike
lift_to_sl2z
, which tends to return Python ints).EXAMPLES:
sage: from sage.modular.local_comp.liftings import lift_to_gamma1 sage: A = matrix(ZZ, 2, lift_to_gamma1([10, 11, 3, 11], 19, 5)); A [371 68] [ 60 11] sage: A.det() == 1 True sage: A.change_ring(Zmod(19)) [10 11] [ 3 11] sage: A.change_ring(Zmod(5)) [1 3] [0 1] sage: m = list(SL2Z.random_element()) sage: n = lift_to_gamma1(m, 11, 17) sage: assert matrix(Zmod(11), 2, n) == matrix(Zmod(11),2,m) sage: assert matrix(Zmod(17), 2, [n[0], 0, n[2], n[3]]) == 1 sage: type(lift_to_gamma1([10,11,3,11],19,5)[0]) <class 'sage.rings.integer.Integer'>
>>> from sage.all import * >>> from sage.modular.local_comp.liftings import lift_to_gamma1 >>> A = matrix(ZZ, Integer(2), lift_to_gamma1([Integer(10), Integer(11), Integer(3), Integer(11)], Integer(19), Integer(5))); A [371 68] [ 60 11] >>> A.det() == Integer(1) True >>> A.change_ring(Zmod(Integer(19))) [10 11] [ 3 11] >>> A.change_ring(Zmod(Integer(5))) [1 3] [0 1] >>> m = list(SL2Z.random_element()) >>> n = lift_to_gamma1(m, Integer(11), Integer(17)) >>> assert matrix(Zmod(Integer(11)), Integer(2), n) == matrix(Zmod(Integer(11)),Integer(2),m) >>> assert matrix(Zmod(Integer(17)), Integer(2), [n[Integer(0)], Integer(0), n[Integer(2)], n[Integer(3)]]) == Integer(1) >>> type(lift_to_gamma1([Integer(10),Integer(11),Integer(3),Integer(11)],Integer(19),Integer(5))[Integer(0)]) <class 'sage.rings.integer.Integer'>
from sage.modular.local_comp.liftings import lift_to_gamma1 A = matrix(ZZ, 2, lift_to_gamma1([10, 11, 3, 11], 19, 5)); A A.det() == 1 A.change_ring(Zmod(19)) A.change_ring(Zmod(5)) m = list(SL2Z.random_element()) n = lift_to_gamma1(m, 11, 17) assert matrix(Zmod(11), 2, n) == matrix(Zmod(11),2,m) assert matrix(Zmod(17), 2, [n[0], 0, n[2], n[3]]) == 1 type(lift_to_gamma1([10,11,3,11],19,5)[0])
Tests with \(m = 1\) and with \(n = 1\):
sage: lift_to_gamma1([1,1,0,1], 5, 1) [1, 1, 0, 1] sage: lift_to_gamma1([2,3,11,22], 1, 5) [1, 0, 0, 1]
>>> from sage.all import * >>> lift_to_gamma1([Integer(1),Integer(1),Integer(0),Integer(1)], Integer(5), Integer(1)) [1, 1, 0, 1] >>> lift_to_gamma1([Integer(2),Integer(3),Integer(11),Integer(22)], Integer(1), Integer(5)) [1, 0, 0, 1]
lift_to_gamma1([1,1,0,1], 5, 1) lift_to_gamma1([2,3,11,22], 1, 5)
- sage.modular.local_comp.liftings.lift_uniformiser_odd(p, u, n)[source]¶
Construct a matrix over \(\ZZ\) whose determinant is \(p\), and which is congruent to \(\begin{pmatrix} 0 & -1 \\ p & 0 \end{pmatrix} \pmod{p^u}\) and to \(\begin{pmatrix} p & 0 \\ 0 & 1\end{pmatrix} \pmod n\).
This is required for the local components machinery in the “ramified” case (when the exponent of \(p\) dividing the level is odd).
EXAMPLES:
sage: from sage.modular.local_comp.liftings import lift_uniformiser_odd sage: lift_uniformiser_odd(3, 2, 11) [432, 377, 165, 144] sage: type(lift_uniformiser_odd(3, 2, 11)[0]) <class 'sage.rings.integer.Integer'>
>>> from sage.all import * >>> from sage.modular.local_comp.liftings import lift_uniformiser_odd >>> lift_uniformiser_odd(Integer(3), Integer(2), Integer(11)) [432, 377, 165, 144] >>> type(lift_uniformiser_odd(Integer(3), Integer(2), Integer(11))[Integer(0)]) <class 'sage.rings.integer.Integer'>
from sage.modular.local_comp.liftings import lift_uniformiser_odd lift_uniformiser_odd(3, 2, 11) type(lift_uniformiser_odd(3, 2, 11)[0])