Modular Functions and their Action¶
Some Modular Functions and their Actions
This file implements (the numerical evaluation of) the modular functions
\(\gamma_2\) – the cube root of the \(j\)-invariant satisfying \(\gamma_2(i) = 12\), which is a modular function of level \(3\);
\(\mathfrak{f}\) – Weber’s modular \(\mathfrak{f}\) function of level \(48\);
\(\mathfrak{f_1}\) – Weber’s modular \(\mathfrak{f_1}\) function of level \(48\);
\(\mathfrak{f_2}\) – Weber’s modular \(\mathfrak{f_2}\) function of level \(48\).
We also implement functions printing the action of \(GL_2(\ZZ/3\ZZ)\) on \(\gamma_2\) and the action of \(GL_2(\ZZ/48\ZZ)\) on \(\mathfrak{f}\) and \(\mathfrak{f_2}\).
REFERENCES:
[Her2021] Mathé Hertogh, Computing with adèles and idèles, master’s thesis, Leiden University, 2021.
This file is part of the master’s thesis [Her2021]. See Chapter 9 for context on the utility of these functions, in particular Section 9.3.4.
AUTHORS:
Mathé Hertogh (2021-07): initial version based on [Her2021]
-
adeles.modular.
ST_factor
(A, return_homomorphism=False)¶ Factor \(A \in SL_2(\ZZ/N\ZZ)\) into a product of the standard generators \(S\) and \(T\)
Here we have \(S = (0, -1; 1, 0)\) and \(T = (1, 1; 0, 1)\). Together they generate \(SL_2(\ZZ)\) and hence also \(SL_2(\ZZ/N\ZZ)\) for any integer \(N\).
INPUT:
A
– a matrix in \(SL_2(\ZZ/N\ZZ)\) for some integer \(N\)return_homomorphism
– boolean (default:False
); whether or not to return the homomorphism \(f\) described below as well
OUPUT:
An element of the free multiplicative group G generated by \(S\) and \(T\) which is mapped to
A
by the homomorphism \(f: G \to SL_2(\ZZ/N\ZZ)\) that maps S to (0, -1; 1, 0) and T to (1, 1; 0, 1).If
return_homomorphism
isTrue
, also returns \(f\).EXAMPLES:
sage: G = SL(2, Zmod(10)) sage: A = G([7, 5, 8, 3]); A [7 5] [8 3] sage: STs, f = ST_factor(A, True); STs T^7*(T*(S^3*T^-1*S)^2)^2 sage: STs.parent() Free Group on generators {S, T} sage: f Group morphism: From: Free Group on generators {S, T} To: Special Linear Group of degree 2 over Ring of integers modulo 10 sage: f(STs) == A True
TESTS:
sage: A = G.random_element() sage: STs, f = ST_factor(A, True) sage: f(STs) == A True
-
adeles.modular.
apply_fractional_linear_transformation
(M, tau)¶ Apply the fractional linear transformation given by
M
totau
INPUT:
M
– a matrix in \(GL_2(\QQ)\) with positive determinanttau
– a non-zero field element
OUTPUT:
Writing
M = (a, b; c, d)
, return the element(a*tau+b)/(c*tau+d)
.EXAMPLES:
sage: M = matrix([[1, 0], [0, 2]]) sage: apply_fractional_linear_transformation(M, I) 1/2*I sage: N = matrix([[1, 2], [3, 4]]) sage: apply_fractional_linear_transformation(N, I) -2/25*I + 11/25
-
adeles.modular.
gamma_2
(x, prec=53)¶ Evaluate the modular function \(\gamma_2\) of level \(3\) in
x
The function \(\gamma_2\) is the cube root of the \(j\)-invariant satisfying \(\gamma_2(i) = 12\). It can be given in terms of Weber’s \(f\) function (cf.
weber_f()
) as follows, for \(z \in \CC\) with \(Im(z)>0\):\[\gamma_2(z) = (f(z)^{24} - 16) / f(z)^8.\]INPUT:
x
– complex point in the upper half planeprec
– positive integer (default: 53); number of bits of precision to use
OUTPUT:
The value \(\gamma_2(x)\) as an element of
ComplexField(prec)
.EXAMPLES:
sage: gamma_2(I) 12.0000000000000 + 6.72179444308389e-15*I sage: gamma_2(1+I, prec=20) -6.0000 - 10.392*I sage: gamma_2(-1.2345+10*I, prec=100) -1.0590687206704318964160589464e9 + 6.5818683636617232191130875508e8*I
-
adeles.modular.
print_action_on_gamma_2
(B)¶ Print the action of \(B \in GL_2(\ZZ/3\ZZ)\) on the function \(\gamma_2\)
See
gamma_2()
for information on the modular function \(\gamma_2\) of level \(3\).INPUT:
B
– a \(GL_2(\ZZ/3\ZZ)\)-matrix
ALGORITHM:
We factor \(B\) as \(B = (1, 0; 0, d) \cdot U\) where with \(d = \det(B)\) and \(U \in SL_2(\ZZ)\). Next we write \(U\) on the standard generators \(S = (0, -1; 1, 0)\) and \(T = (1, 1; 0, 1)\) of \(SL_2(\ZZ)\). Then we use the fact that \((\ZZ/3\ZZ)^*\) and \(S\) act trivially on \(\gamma_2\), while \(T\) acts as multiplication by \(\zeta_3 = \exp(2 \pi i/3)\).
EXAMPLES:
sage: S = matrix(Zmod(3), [[0, -1], [-1, 0]]) sage: print_action_on_gamma_2(S) gamma_2 ]--> gamma_2 sage: T = matrix(Zmod(3), [[1, 1], [0, 1]]) sage: print_action_on_gamma_2(T) gamma_2 ]--> zeta_3^2 * gamma_2 sage: B = matrix(Zmod(3), [[0, 1], [1, 2]]) sage: print_action_on_gamma_2(B) gamma_2 ]--> zeta_3 * gamma_2
TESTS:
sage: B = matrix(Zmod(3), [[1, 1], [2, 2]]) sage: print_action_on_gamma_2(B) Traceback (most recent call last): ... ValueError: B does not lie in GL_2(ZZ/48ZZ)
-
adeles.modular.
print_action_on_weber_f
(B)¶ Print the action of \(B \in GL_2(\ZZ/48\ZZ)\) on Weber’s \(f\) function
See
weber_f()
for information on Weber’s \(f\) function.INPUT:
B
– a \(GL_2(\ZZ/48\ZZ)\)-matrix
ALGORITHM:
We factor \(B\) as \(B = (1, 0; 0, d) \cdot U\) where with \(d = \det(B)\) and \(U \in SL_2(\ZZ)\). Next we write \(U\) on the standard generators \(S = (0, -1; 1, 0)\) and \(T = (1, 1; 0, 1)\) of \(SL_2(\ZZ)\). Then we use the following (hard-coded) knowledge.
Writing \(\zeta_{48} = exp(2 \pi i/48)\), the generators \(S\) and \(T\) act as follows on \(\QQ(\zeta_{48}, f, f_1, f_2)\):
\(S: (f, f_1, f_2) \mapsto (f, f_2, f_1)\);
\(T: (f, f_1, f_2) \mapsto (\zeta_{48}^{-1} f_1, \zeta_{48}^{-1} f, \zeta_{48}^2 f_2)\).
and \((\ZZ/48\ZZ)^*\) acts trivially on \(f\).
EXAMPLES:
sage: S = matrix(Zmod(48), [[0, -1], [-1, 0]]) sage: print_action_on_weber_f(S) f ]--> f sage: T = matrix(Zmod(48), [[1, 1], [0, 1]]) sage: print_action_on_weber_f(T) f ]--> zeta48^-1*f1 sage: B = matrix(Zmod(48), [[-1, 4], [3, 7]]) sage: print_action_on_weber_f(B) f ]--> zeta48^-23*f2
TESTS:
sage: B = matrix(Zmod(48), [[1, 0], [0, 2]]) sage: print_action_on_weber_f(B) Traceback (most recent call last): ... ValueError: B does not lie in GL_2(ZZ/48ZZ)
-
adeles.modular.
print_action_on_weber_f2
(B)¶ Print the action of \(B \in GL_2(\ZZ/48\ZZ)\) on Weber’s \(f_2\) function
See
weber_f2()
for information on Weber’s \(f_2\) function.INPUT:
B
– a \(GL_2(\ZZ/48\ZZ)\)-matrix
ALGORITHM:
We factor \(B\) as \(B = (1, 0; 0, d) \cdot U\) where with \(d = \det(B)\) and \(U \in SL_2(\ZZ)\). Next we write \(U\) on the standard generators \(S = (0, -1; 1, 0)\) and \(T = (1, 1; 0, 1)\) of \(SL_2(\ZZ)\). Then we use the following (hard-coded) knowledge.
Writing \(\zeta_{48} = exp(2 \pi i/48)\), the generators \(S\) and \(T\) act as follows on \(\QQ(\zeta_{48}, f, f_1, f_2)\):
\(S: (f, f_1, f_2) \mapsto (f, f_2, f_1)\);
\(T: (f, f_1, f_2) \mapsto (\zeta_{48}^{-1} f_1, \zeta_{48}^{-1} f, \zeta_{48}^2 f_2)\).
and the action of \((\ZZ/48\ZZ)^*\) is given by \(f_2^d = -f_2\) for \(d \equiv 3, 5 \mod 8\) and \(f_2\) is invariant under all other \(d \in (\ZZ/48\ZZ)^*\).
EXAMPLES:
sage: S = matrix(Zmod(48), [[0, -1], [-1, 0]]) sage: print_action_on_weber_f2(S) f2 ]--> f1 sage: T = matrix(Zmod(48), [[1, 1], [0, 1]]) sage: print_action_on_weber_f2(T) f2 ]--> zeta48^2*f2 sage: B = matrix(Zmod(48), [[8, 3], [-33, 5]]) sage: print_action_on_weber_f2(B) f2 ]--> zeta48^21*f
TESTS:
sage: B = matrix(Zmod(48), [[10, 33], [-21, 9]]) sage: print_action_on_weber_f2(B) Traceback (most recent call last): ... ValueError: B does not lie in GL_2(ZZ/48ZZ)
-
adeles.modular.
weber_f
(x, prec=53)¶ Evaluate Weber’s \(f\) function in
x
Weber’s \(f\) function is a modular function of level 48 given for \(z \in \CC\) with \(Im(z)>0\) by
\[f(z) = \zeta_{48}^{-1} \eta((z+1)/2) / \eta(z)\]where \(\zeta_{48} = \exp(2 \pi i/48)\) and \(\eta\) denotes the Dedekind \(\eta\)-function (cf.
sage.misc.functional.eta()
).INPUT:
x
– complex point in the upper half planeprec
– positive integer (default: 53); number of bits of precision to use
OUTPUT:
The value \(f(x)\) as an element of
ComplexField(prec)
.EXAMPLES:
sage: weber_f(I) 1.18920711500272 + 2.77555756156289e-17*I sage: weber_f(1+I, prec=20) 1.0812 - 0.14234*I sage: weber_f(-1.2345+10*I, prec=100) 3.6542217197057340054214271813 + 0.59570067343661179281710012847*I
-
adeles.modular.
weber_f1
(x, prec=53)¶ Evaluate Weber’s \(f_1\) function in
x
Weber’s \(f_1\) function is a modular function of level 48 given for \(z \in \CC\) with \(Im(z)>0\) by
\[f_1(z) = \eta(x/2) / \eta(x)\]where \(\eta\) denotes the Dedekind \(\eta\)-function (cf.
sage.misc.functional.eta()
).INPUT:
x
– complex point in the upper half planeprec
– positive integer (default: 53); number of bits of precision to use
OUTPUT:
The value \(f_1(x)\) as an element of
ComplexField(prec)
.EXAMPLES:
sage: weber_f1(I) 1.09050773266526 sage: weber_f1(1+I, prec=20) 1.1790 - 0.15522*I sage: weber_f1(-1.2345+10*I, prec=100) 3.6542217197058751251562566155 + 0.59570067343652031920472325046*I
-
adeles.modular.
weber_f2
(x, prec=53)¶ Evaluate Weber’s \(f_2\) function in
x
Weber’s \(f_2\) function is a modular function of level 48 given for \(z \in \CC\) with \(Im(z)>0\) by
\[f_2(x) = \sqrt{2} \eta(2x) / \eta(x)\]where \(\eta\) denotes the Dedekind \(\eta\)-function (cf.
sage.misc.functional.eta()
).INPUT:
x
– complex point in the upper half planeprec
– positive integer (default: 53); number of bits of precision to use
OUTPUT:
The value \(f_2(x)\) as an element of
ComplexField(prec)
.EXAMPLES:
sage: weber_f2(I) 1.09050773266526 sage: weber_f2(1+I, prec=20) 1.0533 + 0.28224*I sage: weber_f2(-1.2345+10*I, prec=100) 0.097824329747547433152328660118 - 0.032764790050361566443041641916*I