passagemath-schemes 10.6.47__cp312-cp312-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
- passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
- passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
- passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
- passagemath_schemes/__init__.py +3 -0
- passagemath_schemes-10.6.47.dist-info/METADATA +204 -0
- passagemath_schemes-10.6.47.dist-info/METADATA.bak +205 -0
- passagemath_schemes-10.6.47.dist-info/RECORD +311 -0
- passagemath_schemes-10.6.47.dist-info/WHEEL +6 -0
- passagemath_schemes-10.6.47.dist-info/top_level.txt +3 -0
- sage/all__sagemath_schemes.py +23 -0
- sage/databases/all__sagemath_schemes.py +7 -0
- sage/databases/cremona.py +1723 -0
- sage/dynamics/all__sagemath_schemes.py +2 -0
- sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
- sage/dynamics/arithmetic_dynamics/all.py +14 -0
- sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
- sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
- sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
- sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
- sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
- sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
- sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-312-darwin.so +0 -0
- sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
- sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
- sage/lfunctions/all.py +18 -0
- sage/lfunctions/dokchitser.py +745 -0
- sage/lfunctions/pari.py +818 -0
- sage/lfunctions/zero_sums.cpython-312-darwin.so +0 -0
- sage/lfunctions/zero_sums.pyx +1847 -0
- sage/modular/abvar/abvar.py +5135 -0
- sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
- sage/modular/abvar/abvar_newform.py +244 -0
- sage/modular/abvar/all.py +8 -0
- sage/modular/abvar/constructor.py +186 -0
- sage/modular/abvar/cuspidal_subgroup.py +371 -0
- sage/modular/abvar/finite_subgroup.py +896 -0
- sage/modular/abvar/homology.py +720 -0
- sage/modular/abvar/homspace.py +998 -0
- sage/modular/abvar/lseries.py +415 -0
- sage/modular/abvar/morphism.py +935 -0
- sage/modular/abvar/torsion_point.py +274 -0
- sage/modular/abvar/torsion_subgroup.py +740 -0
- sage/modular/all.py +43 -0
- sage/modular/arithgroup/all.py +20 -0
- sage/modular/arithgroup/arithgroup_element.cpython-312-darwin.so +0 -0
- sage/modular/arithgroup/arithgroup_element.pyx +474 -0
- sage/modular/arithgroup/arithgroup_generic.py +1402 -0
- sage/modular/arithgroup/arithgroup_perm.py +2692 -0
- sage/modular/arithgroup/congroup.cpython-312-darwin.so +0 -0
- sage/modular/arithgroup/congroup.pyx +334 -0
- sage/modular/arithgroup/congroup_gamma.py +363 -0
- sage/modular/arithgroup/congroup_gamma0.py +692 -0
- sage/modular/arithgroup/congroup_gamma1.py +653 -0
- sage/modular/arithgroup/congroup_gammaH.py +1469 -0
- sage/modular/arithgroup/congroup_generic.py +628 -0
- sage/modular/arithgroup/congroup_sl2z.py +267 -0
- sage/modular/arithgroup/farey_symbol.cpython-312-darwin.so +0 -0
- sage/modular/arithgroup/farey_symbol.pyx +1066 -0
- sage/modular/arithgroup/tests.py +418 -0
- sage/modular/btquotients/all.py +4 -0
- sage/modular/btquotients/btquotient.py +3753 -0
- sage/modular/btquotients/pautomorphicform.py +2570 -0
- sage/modular/buzzard.py +100 -0
- sage/modular/congroup.py +29 -0
- sage/modular/congroup_element.py +13 -0
- sage/modular/cusps.py +1109 -0
- sage/modular/cusps_nf.py +1270 -0
- sage/modular/dims.py +569 -0
- sage/modular/dirichlet.py +3310 -0
- sage/modular/drinfeld_modform/all.py +2 -0
- sage/modular/drinfeld_modform/element.py +446 -0
- sage/modular/drinfeld_modform/ring.py +773 -0
- sage/modular/drinfeld_modform/tutorial.py +236 -0
- sage/modular/etaproducts.py +1065 -0
- sage/modular/hecke/algebra.py +746 -0
- sage/modular/hecke/all.py +20 -0
- sage/modular/hecke/ambient_module.py +1019 -0
- sage/modular/hecke/degenmap.py +119 -0
- sage/modular/hecke/element.py +325 -0
- sage/modular/hecke/hecke_operator.py +780 -0
- sage/modular/hecke/homspace.py +206 -0
- sage/modular/hecke/module.py +1767 -0
- sage/modular/hecke/morphism.py +174 -0
- sage/modular/hecke/submodule.py +989 -0
- sage/modular/hypergeometric_misc.cpython-312-darwin.so +0 -0
- sage/modular/hypergeometric_misc.pxd +4 -0
- sage/modular/hypergeometric_misc.pyx +166 -0
- sage/modular/hypergeometric_motive.py +2017 -0
- sage/modular/local_comp/all.py +2 -0
- sage/modular/local_comp/liftings.py +292 -0
- sage/modular/local_comp/local_comp.py +1071 -0
- sage/modular/local_comp/smoothchar.py +1825 -0
- sage/modular/local_comp/type_space.py +748 -0
- sage/modular/modform/all.py +30 -0
- sage/modular/modform/ambient.py +815 -0
- sage/modular/modform/ambient_R.py +177 -0
- sage/modular/modform/ambient_eps.py +306 -0
- sage/modular/modform/ambient_g0.py +124 -0
- sage/modular/modform/ambient_g1.py +204 -0
- sage/modular/modform/constructor.py +545 -0
- sage/modular/modform/cuspidal_submodule.py +708 -0
- sage/modular/modform/defaults.py +14 -0
- sage/modular/modform/eis_series.py +505 -0
- sage/modular/modform/eisenstein_submodule.py +663 -0
- sage/modular/modform/element.py +4131 -0
- sage/modular/modform/find_generators.py +59 -0
- sage/modular/modform/half_integral.py +154 -0
- sage/modular/modform/hecke_operator_on_qexp.py +247 -0
- sage/modular/modform/j_invariant.py +47 -0
- sage/modular/modform/l_series_gross_zagier.py +133 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.cpython-312-darwin.so +0 -0
- sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
- sage/modular/modform/notes.py +45 -0
- sage/modular/modform/numerical.py +514 -0
- sage/modular/modform/periods.py +14 -0
- sage/modular/modform/ring.py +1257 -0
- sage/modular/modform/space.py +1860 -0
- sage/modular/modform/submodule.py +118 -0
- sage/modular/modform/tests.py +64 -0
- sage/modular/modform/theta.py +110 -0
- sage/modular/modform/vm_basis.py +381 -0
- sage/modular/modform/weight1.py +220 -0
- sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
- sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
- sage/modular/modform_hecketriangle/all.py +30 -0
- sage/modular/modform_hecketriangle/analytic_type.py +590 -0
- sage/modular/modform_hecketriangle/constructor.py +416 -0
- sage/modular/modform_hecketriangle/element.py +351 -0
- sage/modular/modform_hecketriangle/functors.py +752 -0
- sage/modular/modform_hecketriangle/graded_ring.py +541 -0
- sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
- sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
- sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
- sage/modular/modform_hecketriangle/readme.py +1214 -0
- sage/modular/modform_hecketriangle/series_constructor.py +580 -0
- sage/modular/modform_hecketriangle/space.py +1037 -0
- sage/modular/modform_hecketriangle/subspace.py +423 -0
- sage/modular/modsym/all.py +17 -0
- sage/modular/modsym/ambient.py +3846 -0
- sage/modular/modsym/boundary.py +1420 -0
- sage/modular/modsym/element.py +336 -0
- sage/modular/modsym/g1list.py +178 -0
- sage/modular/modsym/ghlist.py +182 -0
- sage/modular/modsym/hecke_operator.py +73 -0
- sage/modular/modsym/manin_symbol.cpython-312-darwin.so +0 -0
- sage/modular/modsym/manin_symbol.pxd +5 -0
- sage/modular/modsym/manin_symbol.pyx +497 -0
- sage/modular/modsym/manin_symbol_list.py +1295 -0
- sage/modular/modsym/modsym.py +400 -0
- sage/modular/modsym/modular_symbols.py +384 -0
- sage/modular/modsym/p1list_nf.py +1241 -0
- sage/modular/modsym/relation_matrix.py +591 -0
- sage/modular/modsym/relation_matrix_pyx.cpython-312-darwin.so +0 -0
- sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
- sage/modular/modsym/space.py +2468 -0
- sage/modular/modsym/subspace.py +455 -0
- sage/modular/modsym/tests.py +375 -0
- sage/modular/multiple_zeta.py +2632 -0
- sage/modular/multiple_zeta_F_algebra.py +786 -0
- sage/modular/overconvergent/all.py +6 -0
- sage/modular/overconvergent/genus0.py +1878 -0
- sage/modular/overconvergent/hecke_series.py +1187 -0
- sage/modular/overconvergent/weightspace.py +778 -0
- sage/modular/pollack_stevens/all.py +4 -0
- sage/modular/pollack_stevens/distributions.py +874 -0
- sage/modular/pollack_stevens/fund_domain.py +1572 -0
- sage/modular/pollack_stevens/manin_map.py +859 -0
- sage/modular/pollack_stevens/modsym.py +1593 -0
- sage/modular/pollack_stevens/padic_lseries.py +417 -0
- sage/modular/pollack_stevens/sigma0.py +534 -0
- sage/modular/pollack_stevens/space.py +1076 -0
- sage/modular/quasimodform/all.py +3 -0
- sage/modular/quasimodform/element.py +845 -0
- sage/modular/quasimodform/ring.py +828 -0
- sage/modular/quatalg/all.py +3 -0
- sage/modular/quatalg/brandt.py +1642 -0
- sage/modular/ssmod/all.py +8 -0
- sage/modular/ssmod/ssmod.py +827 -0
- sage/rings/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/all__sagemath_schemes.py +1 -0
- sage/rings/polynomial/binary_form_reduce.py +585 -0
- sage/schemes/all.py +41 -0
- sage/schemes/berkovich/all.py +6 -0
- sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
- sage/schemes/berkovich/berkovich_space.py +748 -0
- sage/schemes/curves/affine_curve.py +2928 -0
- sage/schemes/curves/all.py +33 -0
- sage/schemes/curves/closed_point.py +434 -0
- sage/schemes/curves/constructor.py +381 -0
- sage/schemes/curves/curve.py +542 -0
- sage/schemes/curves/plane_curve_arrangement.py +1283 -0
- sage/schemes/curves/point.py +463 -0
- sage/schemes/curves/projective_curve.py +3026 -0
- sage/schemes/curves/zariski_vankampen.py +1932 -0
- sage/schemes/cyclic_covers/all.py +2 -0
- sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
- sage/schemes/cyclic_covers/constructor.py +137 -0
- sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
- sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
- sage/schemes/elliptic_curves/BSD.py +1036 -0
- sage/schemes/elliptic_curves/Qcurves.py +592 -0
- sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
- sage/schemes/elliptic_curves/all.py +49 -0
- sage/schemes/elliptic_curves/cardinality.py +609 -0
- sage/schemes/elliptic_curves/cm.py +1102 -0
- sage/schemes/elliptic_curves/constructor.py +1552 -0
- sage/schemes/elliptic_curves/ec_database.py +175 -0
- sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
- sage/schemes/elliptic_curves/ell_egros.py +459 -0
- sage/schemes/elliptic_curves/ell_field.py +2836 -0
- sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
- sage/schemes/elliptic_curves/ell_generic.py +3760 -0
- sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
- sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
- sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
- sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
- sage/schemes/elliptic_curves/ell_point.py +4787 -0
- sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
- sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
- sage/schemes/elliptic_curves/ell_torsion.py +436 -0
- sage/schemes/elliptic_curves/ell_wp.py +352 -0
- sage/schemes/elliptic_curves/formal_group.py +760 -0
- sage/schemes/elliptic_curves/gal_reps.py +1459 -0
- sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
- sage/schemes/elliptic_curves/gp_simon.py +152 -0
- sage/schemes/elliptic_curves/heegner.py +7335 -0
- sage/schemes/elliptic_curves/height.py +2109 -0
- sage/schemes/elliptic_curves/hom.py +1406 -0
- sage/schemes/elliptic_curves/hom_composite.py +934 -0
- sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
- sage/schemes/elliptic_curves/hom_scalar.py +531 -0
- sage/schemes/elliptic_curves/hom_sum.py +682 -0
- sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
- sage/schemes/elliptic_curves/homset.py +271 -0
- sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
- sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
- sage/schemes/elliptic_curves/jacobian.py +237 -0
- sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
- sage/schemes/elliptic_curves/kraus.py +1014 -0
- sage/schemes/elliptic_curves/lseries_ell.py +943 -0
- sage/schemes/elliptic_curves/mod5family.py +105 -0
- sage/schemes/elliptic_curves/mod_poly.py +197 -0
- sage/schemes/elliptic_curves/mod_sym_num.cpython-312-darwin.so +0 -0
- sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
- sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
- sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
- sage/schemes/elliptic_curves/padics.py +1816 -0
- sage/schemes/elliptic_curves/period_lattice.py +2234 -0
- sage/schemes/elliptic_curves/period_lattice_region.cpython-312-darwin.so +0 -0
- sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
- sage/schemes/elliptic_curves/saturation.py +715 -0
- sage/schemes/elliptic_curves/sha_tate.py +1158 -0
- sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
- sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
- sage/schemes/hyperelliptic_curves/all.py +6 -0
- sage/schemes/hyperelliptic_curves/constructor.py +291 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
- sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
- sage/schemes/hyperelliptic_curves/invariants.py +410 -0
- sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
- sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
- sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
- sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
- sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
- sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
- sage/schemes/hyperelliptic_curves/mestre.py +302 -0
- sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
- sage/schemes/jacobians/abstract_jacobian.py +277 -0
- sage/schemes/jacobians/all.py +2 -0
- sage/schemes/overview.py +161 -0
- sage/schemes/plane_conics/all.py +22 -0
- sage/schemes/plane_conics/con_field.py +1296 -0
- sage/schemes/plane_conics/con_finite_field.py +158 -0
- sage/schemes/plane_conics/con_number_field.py +456 -0
- sage/schemes/plane_conics/con_rational_field.py +406 -0
- sage/schemes/plane_conics/con_rational_function_field.py +580 -0
- sage/schemes/plane_conics/constructor.py +249 -0
- sage/schemes/plane_quartics/all.py +2 -0
- sage/schemes/plane_quartics/quartic_constructor.py +71 -0
- sage/schemes/plane_quartics/quartic_generic.py +73 -0
- sage/schemes/riemann_surfaces/all.py +1 -0
- sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
- sage_wheels/share/cremona/cremona_mini.db +0 -0
- sage_wheels/share/ellcurves/rank0 +30427 -0
- sage_wheels/share/ellcurves/rank1 +31871 -0
- sage_wheels/share/ellcurves/rank10 +6 -0
- sage_wheels/share/ellcurves/rank11 +6 -0
- sage_wheels/share/ellcurves/rank12 +1 -0
- sage_wheels/share/ellcurves/rank14 +1 -0
- sage_wheels/share/ellcurves/rank15 +1 -0
- sage_wheels/share/ellcurves/rank17 +1 -0
- sage_wheels/share/ellcurves/rank19 +1 -0
- sage_wheels/share/ellcurves/rank2 +2388 -0
- sage_wheels/share/ellcurves/rank20 +1 -0
- sage_wheels/share/ellcurves/rank21 +1 -0
- sage_wheels/share/ellcurves/rank22 +1 -0
- sage_wheels/share/ellcurves/rank23 +1 -0
- sage_wheels/share/ellcurves/rank24 +1 -0
- sage_wheels/share/ellcurves/rank28 +1 -0
- sage_wheels/share/ellcurves/rank3 +836 -0
- sage_wheels/share/ellcurves/rank4 +10 -0
- sage_wheels/share/ellcurves/rank5 +5 -0
- sage_wheels/share/ellcurves/rank6 +5 -0
- sage_wheels/share/ellcurves/rank7 +5 -0
- sage_wheels/share/ellcurves/rank8 +6 -0
- sage_wheels/share/ellcurves/rank9 +7 -0
|
@@ -0,0 +1,773 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
r"""
|
|
3
|
+
Graded rings of Drinfeld modular forms
|
|
4
|
+
|
|
5
|
+
This module defines a class named :class:`DrinfeldModularForms`.
|
|
6
|
+
Currently, the implementation only supports the full modular group
|
|
7
|
+
`\mathrm{GL}_r(A)` where `A = \mathbb{F}_q[T]`.
|
|
8
|
+
|
|
9
|
+
The implementation is based on the following identification:
|
|
10
|
+
|
|
11
|
+
.. MATH::
|
|
12
|
+
|
|
13
|
+
M^r(\mathrm{GL}_r(A))
|
|
14
|
+
= \mathbb{C}_{\infty}[g_1, \ldots, g_{r-1}, g_{r}].
|
|
15
|
+
|
|
16
|
+
where `g_i` is the `i`-th coefficient form of weight `q^{i} - 1`.
|
|
17
|
+
|
|
18
|
+
AUTHORS:
|
|
19
|
+
|
|
20
|
+
- David Ayotte (2022): initial version
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
# ****************************************************************************
|
|
24
|
+
# Copyright (C) 2022 DAVID AYOTTE <da.ayotte@outlook.com>
|
|
25
|
+
#
|
|
26
|
+
# This program is free software: you can redistribute it and/or modify
|
|
27
|
+
# it under the terms of the GNU General Public License as published by
|
|
28
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
29
|
+
# (at your option) any later version.
|
|
30
|
+
# https://www.gnu.org/licenses/
|
|
31
|
+
# ****************************************************************************
|
|
32
|
+
|
|
33
|
+
from sage.categories.graded_algebras import GradedAlgebras
|
|
34
|
+
|
|
35
|
+
from sage.structure.parent import Parent
|
|
36
|
+
|
|
37
|
+
from sage.rings.fraction_field import FractionField_generic
|
|
38
|
+
from sage.rings.polynomial.ore_polynomial_ring import OrePolynomialRing
|
|
39
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
40
|
+
from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
|
|
41
|
+
from sage.rings.polynomial.term_order import TermOrder
|
|
42
|
+
from sage.rings.integer_ring import ZZ
|
|
43
|
+
|
|
44
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
45
|
+
|
|
46
|
+
from .element import DrinfeldModularFormsElement
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class DrinfeldModularForms(Parent, UniqueRepresentation):
|
|
50
|
+
r"""
|
|
51
|
+
Base class for the graded ring of Drinfeld modular forms.
|
|
52
|
+
|
|
53
|
+
If `K = \mathrm{Frac}(A)` where `A = \mathbb{F}_q[T]`, then the
|
|
54
|
+
ring of Drinfeld modular forms over `K` of rank `r` and type zero
|
|
55
|
+
for `\mathrm{GL}_r(A)` is
|
|
56
|
+
|
|
57
|
+
.. MATH::
|
|
58
|
+
|
|
59
|
+
M^{r, 0}(\mathrm{GL}_r(A)) = K[g_1, \ldots, g_{r-1}, g_{r}].
|
|
60
|
+
|
|
61
|
+
where `g_i` the `i`-th coefficient form of weight `q^{i} - 1` at
|
|
62
|
+
`T`.
|
|
63
|
+
|
|
64
|
+
Similarly, the ring of Drinfeld modular forms over `K` of rank `r`
|
|
65
|
+
and arbitrary type is
|
|
66
|
+
|
|
67
|
+
.. MATH::
|
|
68
|
+
|
|
69
|
+
M^{r}(\mathrm{GL}_r(A)) = K[g_1, \ldots, g_{r-1}, h_{r}].
|
|
70
|
+
|
|
71
|
+
where `h_r` is a form of weight `(q^r - 1)/(q - 1)` and type `1`.
|
|
72
|
+
|
|
73
|
+
We will see the elements of this ring as formal objects given by
|
|
74
|
+
algebraic combination of the generator of the ring. See the class
|
|
75
|
+
:class:`~sage.modular.drinfeld_modform.element.DrinfeldModularFormsElement`
|
|
76
|
+
for more details about their implementation.
|
|
77
|
+
|
|
78
|
+
INPUT:
|
|
79
|
+
|
|
80
|
+
- ``base_ring`` -- the fraction field of a univariate polynomial
|
|
81
|
+
ring over `\mathbb{F}_q`
|
|
82
|
+
|
|
83
|
+
- ``rank`` integer (default: ``None``); the rank of the ring. If
|
|
84
|
+
the rank is ``None``, then the names of the generators must be
|
|
85
|
+
specified.
|
|
86
|
+
|
|
87
|
+
- ``group`` -- (not implemented, default: ``None``) the group of the
|
|
88
|
+
ring. The current implementation only supports the full modular
|
|
89
|
+
group `\mathrm{GL}_r(A)`.
|
|
90
|
+
|
|
91
|
+
- ``has_type`` -- boolean (default: ``False``); if set to ``True``,
|
|
92
|
+
returns the graded ring of arbitrary type
|
|
93
|
+
|
|
94
|
+
- ``names`` -- string, tuple or list (default: ``None``); a single
|
|
95
|
+
character, a tuple or list of character, or comma separated string
|
|
96
|
+
of character representing the names of the generators. If this
|
|
97
|
+
parameter is set to ``None`` and the rank is specified, then the
|
|
98
|
+
default names for the generators will be:
|
|
99
|
+
|
|
100
|
+
* ``g1, g2, ..., gr`` for the type zero forms
|
|
101
|
+
|
|
102
|
+
* ``g1, g2, ..., hr`` for the arbitrary type forms.
|
|
103
|
+
|
|
104
|
+
If this parameter is a single character, for example ``f``, and a
|
|
105
|
+
rank is specified, then the names will be of the form
|
|
106
|
+
``f1, f2, ..., fr``. Finally, if this parameter is a list, a tuple
|
|
107
|
+
or a string of comma separated characters, then each character
|
|
108
|
+
will corresponds to a generator. Note that in this case, it not
|
|
109
|
+
necessary to specify the rank.
|
|
110
|
+
|
|
111
|
+
EXAMPLES::
|
|
112
|
+
|
|
113
|
+
sage: q = 3
|
|
114
|
+
sage: A = GF(q)['T']
|
|
115
|
+
sage: K.<T> = Frac(A)
|
|
116
|
+
sage: M = DrinfeldModularForms(K, 3)
|
|
117
|
+
sage: M
|
|
118
|
+
Ring of Drinfeld modular forms of rank 3 over Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 3
|
|
119
|
+
|
|
120
|
+
Use the :meth:`gens` method to obtain the generators of the ring::
|
|
121
|
+
|
|
122
|
+
sage: M.gens()
|
|
123
|
+
(g1, g2, g3)
|
|
124
|
+
sage: M.inject_variables() # assign the variable g1, g2, g3
|
|
125
|
+
Defining g1, g2, g3
|
|
126
|
+
sage: T*g1*g2 + g3
|
|
127
|
+
g3 + T*g1*g2
|
|
128
|
+
|
|
129
|
+
When creating the ring, one can name the generators in various
|
|
130
|
+
ways::
|
|
131
|
+
|
|
132
|
+
sage: M.<F, G, H> = DrinfeldModularForms(K)
|
|
133
|
+
sage: M.gens()
|
|
134
|
+
(F, G, H)
|
|
135
|
+
sage: M = DrinfeldModularForms(K, 5, names='f') # must specify the rank
|
|
136
|
+
sage: M.gens()
|
|
137
|
+
(f1, f2, f3, f4, f5)
|
|
138
|
+
sage: M = DrinfeldModularForms(K, names='u, v, w, x')
|
|
139
|
+
sage: M.gens()
|
|
140
|
+
(u, v, w, x)
|
|
141
|
+
sage: M = DrinfeldModularForms(K, names=['F', 'G', 'H'])
|
|
142
|
+
sage: M.gens()
|
|
143
|
+
(F, G, H)
|
|
144
|
+
|
|
145
|
+
Set the keyword parameter ``has_type`` to ``True`` in order to create
|
|
146
|
+
the ring of Drinfeld modular forms of arbitrary type::
|
|
147
|
+
|
|
148
|
+
sage: M = DrinfeldModularForms(K, 4, has_type=True)
|
|
149
|
+
sage: M.gens()
|
|
150
|
+
(g1, g2, g3, h4)
|
|
151
|
+
sage: h4 = M.3
|
|
152
|
+
sage: h4.type()
|
|
153
|
+
1
|
|
154
|
+
|
|
155
|
+
To obtain a generating set of the subspace of forms of a fixed
|
|
156
|
+
weight, use the method :meth:`basis_of_weight`::
|
|
157
|
+
|
|
158
|
+
sage: M = DrinfeldModularForms(K, 2)
|
|
159
|
+
sage: M.basis_of_weight(q^3 - 1) # needs sage.combinat
|
|
160
|
+
[g1*g2^3, g1^5*g2^2, g1^9*g2, g1^13]
|
|
161
|
+
|
|
162
|
+
In order to compute the coefficient forms, use the methods
|
|
163
|
+
:meth:`coefficient_form` and :meth:`coefficient_forms`::
|
|
164
|
+
|
|
165
|
+
sage: M = DrinfeldModularForms(K, 3)
|
|
166
|
+
sage: M.coefficient_form(1)
|
|
167
|
+
g1
|
|
168
|
+
sage: M.coefficient_form(2)
|
|
169
|
+
g2
|
|
170
|
+
sage: M.coefficient_form(3)
|
|
171
|
+
g3
|
|
172
|
+
sage: M.coefficient_forms(T)
|
|
173
|
+
[g1, g2, g3]
|
|
174
|
+
sage: M.coefficient_forms(T^2)
|
|
175
|
+
[(T^3 + T)*g1,
|
|
176
|
+
g1^4 + (T^9 + T)*g2,
|
|
177
|
+
g1^9*g2 + g1*g2^3 + (T^27 + T)*g3,
|
|
178
|
+
g1^27*g3 + g1*g3^3 + g2^10,
|
|
179
|
+
g2^27*g3 + g2*g3^9,
|
|
180
|
+
g3^28]
|
|
181
|
+
|
|
182
|
+
REFERENCE:
|
|
183
|
+
|
|
184
|
+
For a quick introduction to Drinfeld modular forms, see the
|
|
185
|
+
:ref:`tutorial <sage.modular.drinfeld_modform.tutorial>`. For more
|
|
186
|
+
extensive references, see [Gek1988]_ and [BRP2018]_.
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
Element = DrinfeldModularFormsElement
|
|
190
|
+
|
|
191
|
+
@staticmethod
|
|
192
|
+
def __classcall_private__(cls, base_ring, rank=None, group=None,
|
|
193
|
+
has_type=False, names=None):
|
|
194
|
+
r"""
|
|
195
|
+
Check input validity and return a ``DrinfeldModularForms``
|
|
196
|
+
object.
|
|
197
|
+
|
|
198
|
+
TESTS::
|
|
199
|
+
|
|
200
|
+
sage: K = Frac(GF(2)['T'])
|
|
201
|
+
sage: DrinfeldModularForms(K, rank=x) # needs sage.symbolic
|
|
202
|
+
Traceback (most recent call last):
|
|
203
|
+
...
|
|
204
|
+
TypeError: unable to convert x to an integer
|
|
205
|
+
|
|
206
|
+
sage: DrinfeldModularForms(GF(2)['T'])
|
|
207
|
+
Traceback (most recent call last):
|
|
208
|
+
...
|
|
209
|
+
TypeError: base ring must be a fraction field of a polynomial ring
|
|
210
|
+
|
|
211
|
+
sage: k.<x, y> = GF(5)[]
|
|
212
|
+
sage: K = k.quotient(x+y).fraction_field()
|
|
213
|
+
sage: DrinfeldModularForms(K, 2)
|
|
214
|
+
Traceback (most recent call last):
|
|
215
|
+
...
|
|
216
|
+
NotImplementedError: Drinfeld modular forms are currently only implemented for A = Fq[T]
|
|
217
|
+
|
|
218
|
+
sage: DrinfeldModularForms(Frac(ZZ['T']))
|
|
219
|
+
Traceback (most recent call last):
|
|
220
|
+
...
|
|
221
|
+
ValueError: base ring characteristic must be finite
|
|
222
|
+
|
|
223
|
+
sage: R = GF(2)['u']
|
|
224
|
+
sage: K = Frac(R['T'])
|
|
225
|
+
sage: DrinfeldModularForms(K, 2)
|
|
226
|
+
Traceback (most recent call last):
|
|
227
|
+
...
|
|
228
|
+
ValueError: the ring of constants must be a field
|
|
229
|
+
|
|
230
|
+
sage: K = Frac(Frac(R)['T'])
|
|
231
|
+
sage: DrinfeldModularForms(K, 2)
|
|
232
|
+
Traceback (most recent call last):
|
|
233
|
+
...
|
|
234
|
+
ValueError: the ring of constants must be finite
|
|
235
|
+
|
|
236
|
+
sage: DrinfeldModularForms(Frac(GF(2)['T']), group=2)
|
|
237
|
+
Traceback (most recent call last):
|
|
238
|
+
...
|
|
239
|
+
NotImplementedError: Drinfeld modular forms are currently only implemented for the full group
|
|
240
|
+
|
|
241
|
+
sage: DrinfeldModularForms(Frac(GF(2)['T']), names=1)
|
|
242
|
+
Traceback (most recent call last):
|
|
243
|
+
...
|
|
244
|
+
TypeError: names must be None, a comma separated string or a list of string
|
|
245
|
+
|
|
246
|
+
sage: DrinfeldModularForms(Frac(GF(2)['T']), rank=3, names='f1, f2, f3, f4')
|
|
247
|
+
Traceback (most recent call last):
|
|
248
|
+
...
|
|
249
|
+
ValueError: the number of generators (=4) must be equal to the rank (=3)
|
|
250
|
+
|
|
251
|
+
sage: DrinfeldModularForms(Frac(GF(2)['T']), rank=3, names=['f1', 'f2', 'f3', 'f4'])
|
|
252
|
+
Traceback (most recent call last):
|
|
253
|
+
...
|
|
254
|
+
ValueError: the number of generators (=4) must be equal to the rank (=3)
|
|
255
|
+
|
|
256
|
+
sage: DrinfeldModularForms(Frac(GF(2)['T']), rank=3, names=('f1', 'f2', 'f3', 'f4'))
|
|
257
|
+
Traceback (most recent call last):
|
|
258
|
+
...
|
|
259
|
+
ValueError: the number of generators (=4) must be equal to the rank (=3)
|
|
260
|
+
|
|
261
|
+
sage: DrinfeldModularForms(Frac(GF(2)['T']))
|
|
262
|
+
Traceback (most recent call last):
|
|
263
|
+
...
|
|
264
|
+
TypeError: rank or names must be specified
|
|
265
|
+
"""
|
|
266
|
+
if not isinstance(base_ring, FractionField_generic):
|
|
267
|
+
raise TypeError("base ring must be a fraction field of a "
|
|
268
|
+
"polynomial ring")
|
|
269
|
+
if not isinstance(base_ring.base(), PolynomialRing_generic):
|
|
270
|
+
raise NotImplementedError("Drinfeld modular forms are currently "
|
|
271
|
+
"only implemented for A = Fq[T]")
|
|
272
|
+
if not base_ring.characteristic():
|
|
273
|
+
raise ValueError("base ring characteristic must be finite")
|
|
274
|
+
if not base_ring.base().base().is_field():
|
|
275
|
+
raise ValueError("the ring of constants must be a field")
|
|
276
|
+
if not base_ring.base().base().is_finite():
|
|
277
|
+
raise ValueError("the ring of constants must be finite")
|
|
278
|
+
if group is not None: # placeholder
|
|
279
|
+
raise NotImplementedError("Drinfeld modular forms are currently "
|
|
280
|
+
"only implemented for the full group")
|
|
281
|
+
if names is None: # default names
|
|
282
|
+
if rank is None:
|
|
283
|
+
raise TypeError("rank or names must be specified")
|
|
284
|
+
rank = ZZ(rank) # check the type of rank
|
|
285
|
+
names = [f'g{i}' for i in range(1, rank, 1)]
|
|
286
|
+
last = f"h{rank}" if has_type else f"g{rank}"
|
|
287
|
+
names.append(last)
|
|
288
|
+
elif isinstance(names, (str, list, tuple)):
|
|
289
|
+
if isinstance(names, str):
|
|
290
|
+
names = names.replace(' ', '').split(',')
|
|
291
|
+
nb_names = len(names)
|
|
292
|
+
if rank is None:
|
|
293
|
+
rank = nb_names
|
|
294
|
+
else:
|
|
295
|
+
rank = ZZ(rank)
|
|
296
|
+
if nb_names == 1 and rank > 1:
|
|
297
|
+
g = names[0]
|
|
298
|
+
names = [f'{g}{i}' for i in range(1, rank + 1)]
|
|
299
|
+
elif nb_names != rank:
|
|
300
|
+
raise ValueError(f"the number of generators (={nb_names}) "
|
|
301
|
+
f"must be equal to the rank (={rank})")
|
|
302
|
+
else:
|
|
303
|
+
raise TypeError("names must be None, a comma separated string "
|
|
304
|
+
"or a list of string")
|
|
305
|
+
return cls.__classcall__(cls, base_ring, rank, group, has_type,
|
|
306
|
+
tuple(names))
|
|
307
|
+
|
|
308
|
+
def __init__(self, base_ring, rank, group, has_type, names):
|
|
309
|
+
r"""
|
|
310
|
+
Initialize the ``DrinfeldModularForms`` class.
|
|
311
|
+
|
|
312
|
+
TESTS::
|
|
313
|
+
|
|
314
|
+
sage: K = Frac(GF(3)['T'])
|
|
315
|
+
sage: TestSuite(DrinfeldModularForms(K, 2)).run()
|
|
316
|
+
sage: TestSuite(DrinfeldModularForms(K, 3)).run()
|
|
317
|
+
sage: TestSuite(DrinfeldModularForms(K, 4)).run()
|
|
318
|
+
|
|
319
|
+
sage: K = Frac(GF(7)['T'])
|
|
320
|
+
sage: TestSuite(DrinfeldModularForms(K, 2)).run()
|
|
321
|
+
sage: TestSuite(DrinfeldModularForms(K, 3)).run()
|
|
322
|
+
sage: TestSuite(DrinfeldModularForms(K, 4)).run()
|
|
323
|
+
|
|
324
|
+
sage: K = Frac(GF(2^3)['T'])
|
|
325
|
+
sage: TestSuite(DrinfeldModularForms(K, 2)).run()
|
|
326
|
+
sage: TestSuite(DrinfeldModularForms(K, 3)).run()
|
|
327
|
+
sage: TestSuite(DrinfeldModularForms(K, 4)).run()
|
|
328
|
+
"""
|
|
329
|
+
self._has_type = has_type
|
|
330
|
+
self._rank = rank
|
|
331
|
+
self._base_ring = base_ring
|
|
332
|
+
q = base_ring.base_ring().cardinality()
|
|
333
|
+
if has_type:
|
|
334
|
+
degs = [q**i - 1 for i in range(1, rank, 1)]
|
|
335
|
+
degs.append((q**rank - 1) / (q - 1))
|
|
336
|
+
else:
|
|
337
|
+
degs = [q**i - 1 for i in range(1, rank + 1, 1)]
|
|
338
|
+
self._poly_ring = PolynomialRing(base_ring, rank, names=names,
|
|
339
|
+
order=TermOrder('wdeglex', degs))
|
|
340
|
+
self._assign_names(names)
|
|
341
|
+
cat = GradedAlgebras(base_ring).Commutative()
|
|
342
|
+
super().__init__(base=base_ring, category=cat)
|
|
343
|
+
|
|
344
|
+
def _an_element_(self):
|
|
345
|
+
r"""
|
|
346
|
+
Return an element of ``self``.
|
|
347
|
+
|
|
348
|
+
TESTS::
|
|
349
|
+
|
|
350
|
+
sage: q = 3
|
|
351
|
+
sage: A = GF(q)['T']
|
|
352
|
+
sage: K.<T> = Frac(A)
|
|
353
|
+
sage: M = DrinfeldModularForms(K, 2)
|
|
354
|
+
sage: M.an_element()
|
|
355
|
+
g1
|
|
356
|
+
"""
|
|
357
|
+
return self.element_class(self, self._poly_ring.an_element())
|
|
358
|
+
|
|
359
|
+
def _repr_(self):
|
|
360
|
+
r"""
|
|
361
|
+
Return the string representation of ``self``.
|
|
362
|
+
|
|
363
|
+
TESTS::
|
|
364
|
+
|
|
365
|
+
sage: A = GF(2)['T']
|
|
366
|
+
sage: K = Frac(A)
|
|
367
|
+
sage: M = DrinfeldModularForms(K, 3)
|
|
368
|
+
sage: M._repr_()
|
|
369
|
+
'Ring of Drinfeld modular forms of rank 3 over Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 2 (using GF2X)'
|
|
370
|
+
"""
|
|
371
|
+
return ("Ring of Drinfeld modular forms of rank %s over %s"
|
|
372
|
+
% (self._rank, self._base_ring))
|
|
373
|
+
|
|
374
|
+
def _generator_coefficient_form(self, i):
|
|
375
|
+
r"""
|
|
376
|
+
Return the `i`-th coefficient form at `T`.
|
|
377
|
+
|
|
378
|
+
For internal use only, the user should use
|
|
379
|
+
:meth:`coefficient_form` instead.
|
|
380
|
+
|
|
381
|
+
TESTS::
|
|
382
|
+
|
|
383
|
+
sage: q = 3
|
|
384
|
+
sage: A = GF(q)['T']
|
|
385
|
+
sage: K.<T> = Frac(A)
|
|
386
|
+
sage: M = DrinfeldModularForms(K, 3)
|
|
387
|
+
sage: M._generator_coefficient_form(1)
|
|
388
|
+
g1
|
|
389
|
+
sage: M._generator_coefficient_form(2)
|
|
390
|
+
g2
|
|
391
|
+
sage: M._generator_coefficient_form(3)
|
|
392
|
+
g3
|
|
393
|
+
|
|
394
|
+
::
|
|
395
|
+
|
|
396
|
+
sage: M = DrinfeldModularForms(K, 3, has_type=True)
|
|
397
|
+
sage: M._generator_coefficient_form(1)
|
|
398
|
+
g1
|
|
399
|
+
sage: M._generator_coefficient_form(2)
|
|
400
|
+
g2
|
|
401
|
+
sage: M._generator_coefficient_form(3)
|
|
402
|
+
h3^2
|
|
403
|
+
"""
|
|
404
|
+
if self._has_type and i == self.rank():
|
|
405
|
+
q = self._base_ring.base_ring().cardinality()
|
|
406
|
+
return self.gen(i-1)**(q - 1)
|
|
407
|
+
return self.gen(i - 1)
|
|
408
|
+
|
|
409
|
+
def _coefficient_forms(self, a):
|
|
410
|
+
r"""
|
|
411
|
+
Return the list of all coefficients of the universal Drinfeld
|
|
412
|
+
module at `a`.
|
|
413
|
+
|
|
414
|
+
This method is used in the methods :meth:`coefficient_form` and
|
|
415
|
+
:meth:`coefficient_forms`. The main difference is that we don't
|
|
416
|
+
check the input here.
|
|
417
|
+
|
|
418
|
+
INPUT:
|
|
419
|
+
|
|
420
|
+
- ``a`` -- an element in the ring of regular functions
|
|
421
|
+
|
|
422
|
+
OUTPUT: list of Drinfeld modular forms. The `i`-th element of
|
|
423
|
+
that list corresponds to the `(i+1)`-th coefficient form at `a`.
|
|
424
|
+
|
|
425
|
+
TESTS::
|
|
426
|
+
|
|
427
|
+
sage: K.<T> = Frac(GF(2)['T'])
|
|
428
|
+
sage: M = DrinfeldModularForms(K, 2)
|
|
429
|
+
sage: M._coefficient_forms(T)
|
|
430
|
+
[g1, g2]
|
|
431
|
+
sage: M._coefficient_forms(T^2)
|
|
432
|
+
[(T^2 + T)*g1, g1^3 + (T^4 + T)*g2, g1^4*g2 + g1*g2^2, g2^5]
|
|
433
|
+
"""
|
|
434
|
+
a = a.numerator()
|
|
435
|
+
poly_ring = PolynomialRing(self._base_ring, self.rank(), 'g')
|
|
436
|
+
poly_ring_gens = poly_ring.gens()
|
|
437
|
+
Frob = poly_ring.frobenius_endomorphism()
|
|
438
|
+
gen = [self._base_ring.gen()]
|
|
439
|
+
gen.extend(poly_ring_gens)
|
|
440
|
+
ore_pol_ring = OrePolynomialRing(poly_ring, Frob, 't')
|
|
441
|
+
gen = ore_pol_ring(gen)
|
|
442
|
+
f = sum(c*(gen**idx) for idx, c in enumerate(a.coefficients(sparse=False)))
|
|
443
|
+
coeff_forms = []
|
|
444
|
+
for i in range(1, a.degree()*self.rank()+1):
|
|
445
|
+
form = f[i]
|
|
446
|
+
coeff_forms.append(form.subs({g: self._generator_coefficient_form(j+1)
|
|
447
|
+
for j, g in enumerate(poly_ring_gens)}))
|
|
448
|
+
return coeff_forms
|
|
449
|
+
|
|
450
|
+
def coefficient_form(self, i, a=None):
|
|
451
|
+
r"""
|
|
452
|
+
Return the `i`-th coefficient form of the universal Drinfeld
|
|
453
|
+
module over `\Omega^r(\mathbb{C}_{\infty})`:
|
|
454
|
+
|
|
455
|
+
.. MATH::
|
|
456
|
+
|
|
457
|
+
\phi_{w, a} = a + g_{1, a}\tau + \cdots + g_{r d_a, a}\tau^{r d_a}
|
|
458
|
+
|
|
459
|
+
where `d_a := \mathrm{deg}(a)`.
|
|
460
|
+
|
|
461
|
+
INPUT:
|
|
462
|
+
|
|
463
|
+
- ``i`` -- integer between 1 and `r d_a`
|
|
464
|
+
|
|
465
|
+
- ``a`` -- (default: ``None``) an element in the ring of regular
|
|
466
|
+
functions. If `a` is ``None``, then the method returns the
|
|
467
|
+
`i`-th coefficient form of `\phi_{w, T}`.
|
|
468
|
+
|
|
469
|
+
EXAMPLES::
|
|
470
|
+
|
|
471
|
+
sage: q = 3
|
|
472
|
+
sage: A = GF(q)['T']
|
|
473
|
+
sage: K.<T> = Frac(A)
|
|
474
|
+
sage: M = DrinfeldModularForms(K, 3)
|
|
475
|
+
sage: M.coefficient_form(1)
|
|
476
|
+
g1
|
|
477
|
+
sage: M.coefficient_form(2)
|
|
478
|
+
g2
|
|
479
|
+
sage: M.coefficient_form(3)
|
|
480
|
+
g3
|
|
481
|
+
sage: M.coefficient_form(3, T^2)
|
|
482
|
+
g1^9*g2 + g1*g2^3 + (T^27 + T)*g3
|
|
483
|
+
|
|
484
|
+
::
|
|
485
|
+
|
|
486
|
+
sage: M = DrinfeldModularForms(K, 2, has_type=True)
|
|
487
|
+
sage: M.coefficient_form(1)
|
|
488
|
+
g1
|
|
489
|
+
sage: M.coefficient_form(2)
|
|
490
|
+
h2^2
|
|
491
|
+
sage: M.coefficient_form(2, T^3 + T^2 + T)
|
|
492
|
+
(T^9 + T^3 + T + 1)*g1^4 + (T^18 + T^10 + T^9 + T^2 + T + 1)*h2^2
|
|
493
|
+
|
|
494
|
+
TESTS::
|
|
495
|
+
|
|
496
|
+
sage: M.coefficient_form(0)
|
|
497
|
+
Traceback (most recent call last):
|
|
498
|
+
...
|
|
499
|
+
ValueError: index (=0) must be >= 1 and <= rank (=2)
|
|
500
|
+
sage: M.coefficient_form(3)
|
|
501
|
+
Traceback (most recent call last):
|
|
502
|
+
...
|
|
503
|
+
ValueError: index (=3) must be >= 1 and <= rank (=2)
|
|
504
|
+
sage: M.coefficient_form(9, T^2)
|
|
505
|
+
Traceback (most recent call last):
|
|
506
|
+
...
|
|
507
|
+
ValueError: index (=9) must be >= 1 and <= deg(a)*rank (=4)
|
|
508
|
+
sage: M.coefficient_form(1, 1/(T+1))
|
|
509
|
+
Traceback (most recent call last):
|
|
510
|
+
...
|
|
511
|
+
ValueError: a must be an integral element
|
|
512
|
+
sage: M.coefficient_form(1, 'x')
|
|
513
|
+
Traceback (most recent call last):
|
|
514
|
+
...
|
|
515
|
+
TypeError: unable to convert a to an element in Fq[T]
|
|
516
|
+
"""
|
|
517
|
+
i = ZZ(i)
|
|
518
|
+
if a is None:
|
|
519
|
+
if i < 1 or i > self.rank():
|
|
520
|
+
raise ValueError(f"index (={i}) must be >= 1 and <= rank "
|
|
521
|
+
f"(={self.rank()})")
|
|
522
|
+
return self._generator_coefficient_form(i)
|
|
523
|
+
try:
|
|
524
|
+
A = self._base_ring.base()
|
|
525
|
+
a = A(a)
|
|
526
|
+
except TypeError:
|
|
527
|
+
raise TypeError("unable to convert a to an element in Fq[T]")
|
|
528
|
+
except ValueError:
|
|
529
|
+
raise ValueError("a must be an integral element")
|
|
530
|
+
if i < 1 or i > a.degree()*self.rank():
|
|
531
|
+
raise ValueError(f"index (={i}) must be >= 1 and <= deg(a)*rank "
|
|
532
|
+
f"(={a.degree()*self.rank()})")
|
|
533
|
+
coeff_forms = self._coefficient_forms(a)
|
|
534
|
+
return coeff_forms[i - 1]
|
|
535
|
+
|
|
536
|
+
def coefficient_forms(self, a=None):
|
|
537
|
+
r"""
|
|
538
|
+
Return the list of all coefficients of the universal Drinfeld
|
|
539
|
+
module at `a`.
|
|
540
|
+
|
|
541
|
+
See also :meth:`coefficient_form` for definitions.
|
|
542
|
+
|
|
543
|
+
INPUT:
|
|
544
|
+
|
|
545
|
+
- ``a`` -- (default: ``None``) an element in the ring of regular
|
|
546
|
+
functions. If `a` is ``None``, then the method returns the
|
|
547
|
+
coefficients forms at `a = T`.
|
|
548
|
+
|
|
549
|
+
OUTPUT: list of Drinfeld modular forms. The `i`-th element of
|
|
550
|
+
that list corresponds to the `(i+1)`-th coefficient form at `a`.
|
|
551
|
+
|
|
552
|
+
EXAMPLES::
|
|
553
|
+
|
|
554
|
+
sage: q = 3
|
|
555
|
+
sage: A = GF(q)['T']
|
|
556
|
+
sage: K.<T> = Frac(A)
|
|
557
|
+
sage: M = DrinfeldModularForms(K, 2)
|
|
558
|
+
sage: M.coefficient_forms()
|
|
559
|
+
[g1, g2]
|
|
560
|
+
sage: M.coefficient_forms(T^2)
|
|
561
|
+
[(T^3 + T)*g1, g1^4 + (T^9 + T)*g2, g1^9*g2 + g1*g2^3, g2^10]
|
|
562
|
+
sage: M.coefficient_forms(T^3)
|
|
563
|
+
[(T^6 + T^4 + T^2)*g1,
|
|
564
|
+
(T^9 + T^3 + T)*g1^4 + (T^18 + T^10 + T^2)*g2,
|
|
565
|
+
g1^13 + (T^27 + T^9 + T)*g1^9*g2 + (T^27 + T^3 + T)*g1*g2^3,
|
|
566
|
+
g1^36*g2 + g1^28*g2^3 + g1^4*g2^9 + (T^81 + T^9 + T)*g2^10,
|
|
567
|
+
g1^81*g2^10 + g1^9*g2^28 + g1*g2^30,
|
|
568
|
+
g2^91]
|
|
569
|
+
|
|
570
|
+
TESTS::
|
|
571
|
+
|
|
572
|
+
sage: q = 3
|
|
573
|
+
sage: A = GF(q)['T']
|
|
574
|
+
sage: K.<T> = Frac(A)
|
|
575
|
+
sage: M = DrinfeldModularForms(K, 2)
|
|
576
|
+
sage: M.coefficient_forms(1/T)
|
|
577
|
+
Traceback (most recent call last):
|
|
578
|
+
...
|
|
579
|
+
ValueError: a must be an integral element
|
|
580
|
+
sage: M.coefficient_forms('x')
|
|
581
|
+
Traceback (most recent call last):
|
|
582
|
+
...
|
|
583
|
+
TypeError: unable to convert a to an element in Fq[T]
|
|
584
|
+
"""
|
|
585
|
+
if a is None:
|
|
586
|
+
return [self._generator_coefficient_form(i)
|
|
587
|
+
for i in range(1, self.rank() + 1)]
|
|
588
|
+
try:
|
|
589
|
+
A = self._base_ring.base()
|
|
590
|
+
a = A(a)
|
|
591
|
+
except TypeError:
|
|
592
|
+
raise TypeError("unable to convert a to an element in Fq[T]")
|
|
593
|
+
except ValueError:
|
|
594
|
+
raise ValueError("a must be an integral element")
|
|
595
|
+
return self._coefficient_forms(a)
|
|
596
|
+
|
|
597
|
+
def gen(self, n):
|
|
598
|
+
r"""
|
|
599
|
+
Return the `n`-th generator of this ring.
|
|
600
|
+
|
|
601
|
+
EXAMPLES::
|
|
602
|
+
|
|
603
|
+
sage: A = GF(3)['T']; K = Frac(A); T = K.gen()
|
|
604
|
+
sage: M = DrinfeldModularForms(K, 2)
|
|
605
|
+
sage: M.gen(0)
|
|
606
|
+
g1
|
|
607
|
+
sage: M.1 # equivalent to M.gen(1)
|
|
608
|
+
g2
|
|
609
|
+
|
|
610
|
+
.. NOTE::
|
|
611
|
+
|
|
612
|
+
Recall that the ring of Drinfeld modular forms is generated
|
|
613
|
+
by the `r` coefficient forms of the universal Drinfeld
|
|
614
|
+
module at `T`, `g_1, g_2, \ldots, g_r`, see
|
|
615
|
+
:meth:`coefficient_forms`. We highlight however that we make
|
|
616
|
+
a shift in the indexing so that the `i`-th generator
|
|
617
|
+
corresponds to the `i+1`-th coefficient form for
|
|
618
|
+
`0\leq i \leq r-1`.
|
|
619
|
+
"""
|
|
620
|
+
return self(self._poly_ring.gen(n))
|
|
621
|
+
|
|
622
|
+
def gens(self) -> tuple:
|
|
623
|
+
r"""
|
|
624
|
+
Return a tuple of generators of this ring.
|
|
625
|
+
|
|
626
|
+
EXAMPLES::
|
|
627
|
+
|
|
628
|
+
sage: A = GF(3)['T']; K = Frac(A); T = K.gen()
|
|
629
|
+
sage: M = DrinfeldModularForms(K, 5)
|
|
630
|
+
sage: M.gens()
|
|
631
|
+
(g1, g2, g3, g4, g5)
|
|
632
|
+
"""
|
|
633
|
+
return tuple(self(g) for g in self._poly_ring.gens())
|
|
634
|
+
|
|
635
|
+
def ngens(self):
|
|
636
|
+
r"""
|
|
637
|
+
Return the number of generators of this ring.
|
|
638
|
+
|
|
639
|
+
Note that the number of generators is equal to the rank.
|
|
640
|
+
|
|
641
|
+
EXAMPLES::
|
|
642
|
+
|
|
643
|
+
sage: A = GF(3)['T']; K = Frac(A); T = K.gen()
|
|
644
|
+
sage: M = DrinfeldModularForms(K, 5)
|
|
645
|
+
sage: M.ngens()
|
|
646
|
+
5
|
|
647
|
+
"""
|
|
648
|
+
return self._rank
|
|
649
|
+
|
|
650
|
+
def _element_constructor_(self, polynomial):
|
|
651
|
+
r"""
|
|
652
|
+
Return the element corresponding to the given polynomial.
|
|
653
|
+
|
|
654
|
+
TESTS::
|
|
655
|
+
|
|
656
|
+
sage: A = GF(3)['T']
|
|
657
|
+
sage: K = Frac(A)
|
|
658
|
+
sage: M = DrinfeldModularForms(K, 3)
|
|
659
|
+
sage: g1, g2, g3 = polygens(K, 3, 'g1, g2, g3')
|
|
660
|
+
sage: M(g1*g2 + g3^4)
|
|
661
|
+
g3^4 + g1*g2
|
|
662
|
+
"""
|
|
663
|
+
return self.element_class(self, polynomial)
|
|
664
|
+
|
|
665
|
+
def rank(self):
|
|
666
|
+
r"""
|
|
667
|
+
Return the rank of this ring of Drinfeld modular forms.
|
|
668
|
+
|
|
669
|
+
EXAMPLES::
|
|
670
|
+
|
|
671
|
+
sage: A = GF(3)['T']; K = Frac(A);
|
|
672
|
+
sage: DrinfeldModularForms(K, 2).rank()
|
|
673
|
+
2
|
|
674
|
+
sage: DrinfeldModularForms(K, 3).rank()
|
|
675
|
+
3
|
|
676
|
+
sage: DrinfeldModularForms(K, 4).rank()
|
|
677
|
+
4
|
|
678
|
+
"""
|
|
679
|
+
return self._rank
|
|
680
|
+
|
|
681
|
+
def one(self):
|
|
682
|
+
r"""
|
|
683
|
+
Return the multiplicative unit.
|
|
684
|
+
|
|
685
|
+
EXAMPLES::
|
|
686
|
+
|
|
687
|
+
sage: A = GF(3)['T']; K = Frac(A); T = K.gen()
|
|
688
|
+
sage: M = DrinfeldModularForms(K, 2)
|
|
689
|
+
sage: M.one()
|
|
690
|
+
1
|
|
691
|
+
sage: M.one() * M.0
|
|
692
|
+
g1
|
|
693
|
+
sage: M.one().is_one()
|
|
694
|
+
True
|
|
695
|
+
"""
|
|
696
|
+
return self(self._poly_ring.one())
|
|
697
|
+
|
|
698
|
+
def zero(self):
|
|
699
|
+
r"""
|
|
700
|
+
Return the additive identity.
|
|
701
|
+
|
|
702
|
+
EXAMPLES::
|
|
703
|
+
|
|
704
|
+
sage: A = GF(3)['T']; K = Frac(A); T = K.gen()
|
|
705
|
+
sage: M = DrinfeldModularForms(K, 2)
|
|
706
|
+
sage: M.zero()
|
|
707
|
+
0
|
|
708
|
+
sage: M.zero() + M.1
|
|
709
|
+
g2
|
|
710
|
+
sage: M.zero() * M.1
|
|
711
|
+
0
|
|
712
|
+
sage: M.zero().is_zero()
|
|
713
|
+
True
|
|
714
|
+
"""
|
|
715
|
+
return self(self._poly_ring.zero())
|
|
716
|
+
|
|
717
|
+
def basis_of_weight(self, k):
|
|
718
|
+
r"""
|
|
719
|
+
Return a list of Drinfeld modular forms which forms a basis for
|
|
720
|
+
the subspace of weight `k`.
|
|
721
|
+
|
|
722
|
+
Note that if `k\not\equiv 0` modulo `q-1`, then the subspace is
|
|
723
|
+
0.
|
|
724
|
+
|
|
725
|
+
An alias of this method is ``basis``.
|
|
726
|
+
|
|
727
|
+
INPUT:
|
|
728
|
+
|
|
729
|
+
- ``k`` -- integer
|
|
730
|
+
|
|
731
|
+
EXAMPLES::
|
|
732
|
+
|
|
733
|
+
sage: # needs sage.combinat
|
|
734
|
+
sage: q = 3; A = GF(q)['T']; K = Frac(A);
|
|
735
|
+
sage: M = DrinfeldModularForms(K, 2)
|
|
736
|
+
sage: M.basis_of_weight(q - 1)
|
|
737
|
+
[g1]
|
|
738
|
+
sage: M.basis_of_weight(q^2 - 1)
|
|
739
|
+
[g2, g1^4]
|
|
740
|
+
sage: M.basis_of_weight(q^3 - 1)
|
|
741
|
+
[g1*g2^3, g1^5*g2^2, g1^9*g2, g1^13]
|
|
742
|
+
sage: M.basis_of_weight(19*(q-1))
|
|
743
|
+
[g1^3*g2^4, g1^7*g2^3, g1^11*g2^2, g1^15*g2, g1^19]
|
|
744
|
+
"""
|
|
745
|
+
return [self(mon) for mon in self._poly_ring.monomials_of_degree(k)]
|
|
746
|
+
|
|
747
|
+
basis = basis_of_weight # alias
|
|
748
|
+
|
|
749
|
+
def polynomial_ring(self):
|
|
750
|
+
r"""
|
|
751
|
+
Return the multivariate polynomial ring over the base ring where
|
|
752
|
+
each variable corresponds to a generator of this Drinfeld
|
|
753
|
+
modular forms ring.
|
|
754
|
+
|
|
755
|
+
EXAMPLES::
|
|
756
|
+
|
|
757
|
+
sage: q = 3; A = GF(q)['T']; K = Frac(A);
|
|
758
|
+
sage: M = DrinfeldModularForms(K, 2)
|
|
759
|
+
sage: P = M.polynomial_ring()
|
|
760
|
+
sage: P
|
|
761
|
+
Multivariate Polynomial Ring in g1, g2 over Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 3
|
|
762
|
+
|
|
763
|
+
The degree of the variables corresponds to the weight of the
|
|
764
|
+
associated generator::
|
|
765
|
+
|
|
766
|
+
sage: P.inject_variables()
|
|
767
|
+
Defining g1, g2
|
|
768
|
+
sage: g1.degree()
|
|
769
|
+
2
|
|
770
|
+
sage: g2.degree()
|
|
771
|
+
8
|
|
772
|
+
"""
|
|
773
|
+
return self._poly_ring
|