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,1241 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-schemes
|
|
2
|
+
# sage.doctest: needs sage.rings.number_field
|
|
3
|
+
r"""
|
|
4
|
+
Lists of Manin symbols over number fields, elements of `\mathbb{P}^1(R/N)`
|
|
5
|
+
|
|
6
|
+
Lists of elements of `\mathbb{P}^1(R/N)` where `R` is the ring of integers of a number
|
|
7
|
+
field `K` and `N` is an integral ideal.
|
|
8
|
+
|
|
9
|
+
AUTHORS:
|
|
10
|
+
|
|
11
|
+
- Maite Aranes (2009): Initial version
|
|
12
|
+
|
|
13
|
+
EXAMPLES:
|
|
14
|
+
|
|
15
|
+
We define a P1NFList:
|
|
16
|
+
|
|
17
|
+
::
|
|
18
|
+
|
|
19
|
+
sage: x = polygen(QQ, 'x')
|
|
20
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
21
|
+
sage: N = k.ideal(5, a^2 - a + 1)
|
|
22
|
+
sage: P = P1NFList(N); P
|
|
23
|
+
The projective line over
|
|
24
|
+
the ring of integers modulo the Fractional ideal (5, a^2 - a + 1)
|
|
25
|
+
|
|
26
|
+
List operations with the P1NFList:
|
|
27
|
+
|
|
28
|
+
::
|
|
29
|
+
|
|
30
|
+
sage: len(P)
|
|
31
|
+
26
|
|
32
|
+
sage: [p for p in P]
|
|
33
|
+
[M-symbol (0: 1) of level Fractional ideal (5, a^2 - a + 1),
|
|
34
|
+
...
|
|
35
|
+
M-symbol (1: 2*a^2 + 2*a) of level Fractional ideal (5, a^2 - a + 1)]
|
|
36
|
+
|
|
37
|
+
The elements of the P1NFList are M-symbols:
|
|
38
|
+
|
|
39
|
+
::
|
|
40
|
+
|
|
41
|
+
sage: type(P[2])
|
|
42
|
+
<class 'sage.modular.modsym.p1list_nf.MSymbol'>
|
|
43
|
+
|
|
44
|
+
Definition of MSymbols:
|
|
45
|
+
|
|
46
|
+
::
|
|
47
|
+
|
|
48
|
+
sage: alpha = MSymbol(N, 3, a^2); alpha
|
|
49
|
+
M-symbol (3: a^2) of level Fractional ideal (5, a^2 - a + 1)
|
|
50
|
+
|
|
51
|
+
Find the index of the class of an M-Symbol `(c: d)` in the list:
|
|
52
|
+
|
|
53
|
+
::
|
|
54
|
+
|
|
55
|
+
sage: i = P.index(alpha)
|
|
56
|
+
sage: P[i].c*alpha.d - P[i].d*alpha.c in N
|
|
57
|
+
True
|
|
58
|
+
|
|
59
|
+
Lift an MSymbol to a matrix in `SL(2, R)`:
|
|
60
|
+
|
|
61
|
+
::
|
|
62
|
+
|
|
63
|
+
sage: alpha = MSymbol(N, a + 2, 3*a^2)
|
|
64
|
+
sage: alpha.lift_to_sl2_Ok()
|
|
65
|
+
[-a - 1, 15*a^2 - 38*a + 86, a + 2, -a^2 + 9*a - 19]
|
|
66
|
+
sage: Ok = k.ring_of_integers()
|
|
67
|
+
sage: M = Matrix(Ok, 2, alpha.lift_to_sl2_Ok())
|
|
68
|
+
sage: det(M)
|
|
69
|
+
1
|
|
70
|
+
sage: M[1][1] - alpha.d in N
|
|
71
|
+
True
|
|
72
|
+
|
|
73
|
+
Lift an MSymbol from P1NFList to a matrix in `SL(2, R)`
|
|
74
|
+
|
|
75
|
+
::
|
|
76
|
+
|
|
77
|
+
sage: P[3]
|
|
78
|
+
M-symbol (1: -2*a) of level Fractional ideal (5, a^2 - a + 1)
|
|
79
|
+
sage: P.lift_to_sl2_Ok(3)
|
|
80
|
+
[0, -1, 1, -2*a]
|
|
81
|
+
"""
|
|
82
|
+
# ****************************************************************************
|
|
83
|
+
# Copyright (C) 2009, Maite Aranes <M.T.Aranes@warwick.ac.uk>
|
|
84
|
+
#
|
|
85
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
86
|
+
# https://www.gnu.org/licenses/
|
|
87
|
+
# ****************************************************************************
|
|
88
|
+
|
|
89
|
+
from sage.structure.richcmp import richcmp_method, richcmp
|
|
90
|
+
from sage.structure.sage_object import SageObject
|
|
91
|
+
|
|
92
|
+
from sage.misc.search import search
|
|
93
|
+
|
|
94
|
+
_level_cache = {} # The info stored here is used in the normalization of MSymbols.
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def P1NFList_clear_level_cache():
|
|
98
|
+
"""
|
|
99
|
+
Clear the global cache of data for the level ideals.
|
|
100
|
+
|
|
101
|
+
EXAMPLES::
|
|
102
|
+
|
|
103
|
+
sage: x = polygen(QQ, 'x')
|
|
104
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
105
|
+
sage: N = k.ideal(a+1)
|
|
106
|
+
sage: alpha = MSymbol(N, 2*a^2, 5)
|
|
107
|
+
sage: alpha.normalize()
|
|
108
|
+
M-symbol (-4*a^2: 5*a^2) of level Fractional ideal (a + 1)
|
|
109
|
+
sage: sage.modular.modsym.p1list_nf._level_cache
|
|
110
|
+
{Fractional ideal (a + 1): (...)}
|
|
111
|
+
sage: sage.modular.modsym.p1list_nf.P1NFList_clear_level_cache()
|
|
112
|
+
sage: sage.modular.modsym.p1list_nf._level_cache
|
|
113
|
+
{}
|
|
114
|
+
"""
|
|
115
|
+
global _level_cache
|
|
116
|
+
_level_cache = {}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@richcmp_method
|
|
120
|
+
class MSymbol(SageObject):
|
|
121
|
+
r"""
|
|
122
|
+
The constructor for an M-symbol over a number field.
|
|
123
|
+
|
|
124
|
+
INPUT:
|
|
125
|
+
|
|
126
|
+
- ``N`` -- integral ideal (the modulus or level)
|
|
127
|
+
|
|
128
|
+
- ``c`` -- integral element of the underlying number field or an MSymbol of
|
|
129
|
+
level N
|
|
130
|
+
|
|
131
|
+
- ``d`` -- (optional) when present, it must be an integral element such
|
|
132
|
+
that `\langle c\rangle + \langle d\rangle + N = R`, where `R` is the
|
|
133
|
+
corresponding ring of integers
|
|
134
|
+
|
|
135
|
+
- ``check`` -- boolean (default: ``True``); if ``check=False`` the
|
|
136
|
+
constructor does not check the condition
|
|
137
|
+
`\langle c\rangle + \langle d\rangle + N = R`
|
|
138
|
+
|
|
139
|
+
OUTPUT:
|
|
140
|
+
|
|
141
|
+
An M-symbol modulo the given ideal `N`, i.e. an element of the
|
|
142
|
+
projective line `\mathbb{P}^1(R/N)`, where `R` is the ring of integers of
|
|
143
|
+
the underlying number field.
|
|
144
|
+
|
|
145
|
+
EXAMPLES::
|
|
146
|
+
|
|
147
|
+
sage: x = polygen(QQ, 'x')
|
|
148
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
149
|
+
sage: N = k.ideal(a + 1, 2)
|
|
150
|
+
sage: MSymbol(N, 3, a^2 + 1)
|
|
151
|
+
M-symbol (3: a^2 + 1) of level Fractional ideal (2, a + 1)
|
|
152
|
+
|
|
153
|
+
We can give a tuple as input:
|
|
154
|
+
|
|
155
|
+
::
|
|
156
|
+
|
|
157
|
+
sage: MSymbol(N, (1, 0))
|
|
158
|
+
M-symbol (1: 0) of level Fractional ideal (2, a + 1)
|
|
159
|
+
|
|
160
|
+
We get an error if `\langle c\rangle`, `\langle d\rangle` and `N` are not coprime:
|
|
161
|
+
|
|
162
|
+
::
|
|
163
|
+
|
|
164
|
+
sage: MSymbol(N, 2*a, a - 1)
|
|
165
|
+
Traceback (most recent call last):
|
|
166
|
+
...
|
|
167
|
+
ValueError: (2*a, a - 1) is not an element of P1(R/N).
|
|
168
|
+
sage: MSymbol(N, (0, 0))
|
|
169
|
+
Traceback (most recent call last):
|
|
170
|
+
...
|
|
171
|
+
ValueError: (0, 0) is not an element of P1(R/N).
|
|
172
|
+
|
|
173
|
+
Saving and loading works:
|
|
174
|
+
|
|
175
|
+
::
|
|
176
|
+
|
|
177
|
+
sage: alpha = MSymbol(N, 3, a^2 + 1)
|
|
178
|
+
sage: loads(dumps(alpha))==alpha
|
|
179
|
+
True
|
|
180
|
+
"""
|
|
181
|
+
def __init__(self, N, c, d=None, check=True):
|
|
182
|
+
"""
|
|
183
|
+
See ``MSymbol`` for full documentation.
|
|
184
|
+
|
|
185
|
+
EXAMPLES::
|
|
186
|
+
|
|
187
|
+
sage: x = polygen(QQ, 'x')
|
|
188
|
+
sage: k.<a> = NumberField(x^4 + 13*x - 7)
|
|
189
|
+
sage: N = k.ideal(5)
|
|
190
|
+
sage: MSymbol(N, 0, 6*a)
|
|
191
|
+
M-symbol (0: 6*a) of level Fractional ideal (5)
|
|
192
|
+
sage: MSymbol(N, a^2 + 3, 7)
|
|
193
|
+
M-symbol (a^2 + 3: 7) of level Fractional ideal (5)
|
|
194
|
+
"""
|
|
195
|
+
k = N.number_field()
|
|
196
|
+
R = k.ring_of_integers()
|
|
197
|
+
self.__N = N
|
|
198
|
+
if d is None: # if we give a list (c, d) or an MSymbol as input
|
|
199
|
+
if isinstance(c, MSymbol):
|
|
200
|
+
if c.N() is N:
|
|
201
|
+
c1 = R(c[0])
|
|
202
|
+
d1 = R(c[1])
|
|
203
|
+
else:
|
|
204
|
+
raise ValueError("Cannot change level of an MSymbol")
|
|
205
|
+
else:
|
|
206
|
+
try:
|
|
207
|
+
c1 = R(c[0])
|
|
208
|
+
d1 = R(c[1])
|
|
209
|
+
except (ValueError, TypeError):
|
|
210
|
+
raise TypeError("Unable to create a Manin symbol from %s" % c)
|
|
211
|
+
else:
|
|
212
|
+
try:
|
|
213
|
+
c1 = R(c)
|
|
214
|
+
d1 = R(d)
|
|
215
|
+
except (ValueError, TypeError):
|
|
216
|
+
raise TypeError("Unable to create a Manin symbol from (%s, %s)" % (c, d))
|
|
217
|
+
if check:
|
|
218
|
+
if (c1.is_zero() and d1.is_zero()) or not N.is_coprime(k.ideal(c1, d1)):
|
|
219
|
+
raise ValueError("(%s, %s) is not an element of P1(R/N)." % (c1, d1))
|
|
220
|
+
self.__c, self.__d = (c1, d1)
|
|
221
|
+
|
|
222
|
+
def __repr__(self):
|
|
223
|
+
r"""
|
|
224
|
+
Return the string representation of this MSymbol.
|
|
225
|
+
|
|
226
|
+
EXAMPLES::
|
|
227
|
+
|
|
228
|
+
sage: x = polygen(QQ, 'x')
|
|
229
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
230
|
+
sage: N = k.ideal(3, a - 1)
|
|
231
|
+
sage: MSymbol(N, 3, a)
|
|
232
|
+
M-symbol (3: a) of level Fractional ideal (3, 1/2*a - 1/2)
|
|
233
|
+
"""
|
|
234
|
+
return "M-symbol (%s: %s) of level %s" % (self.__c, self.__d, self.__N)
|
|
235
|
+
|
|
236
|
+
def _latex_(self):
|
|
237
|
+
r"""
|
|
238
|
+
Return latex representation of ``self``.
|
|
239
|
+
|
|
240
|
+
EXAMPLES::
|
|
241
|
+
|
|
242
|
+
sage: x = polygen(QQ, 'x')
|
|
243
|
+
sage: k.<a> = NumberField(x^4 + 13*x - 7)
|
|
244
|
+
sage: N = k.ideal(a^3 - 1)
|
|
245
|
+
sage: alpha = MSymbol(N, 3, 5*a^2 - 1)
|
|
246
|
+
sage: latex(alpha) # indirect doctest
|
|
247
|
+
\(3: 5 a^{2} - 1\)
|
|
248
|
+
"""
|
|
249
|
+
return r"\(%s: %s\)" % (self.c._latex_(), self.d._latex_())
|
|
250
|
+
|
|
251
|
+
def __richcmp__(self, other, op):
|
|
252
|
+
r"""
|
|
253
|
+
Comparison function for objects of the class MSymbol.
|
|
254
|
+
|
|
255
|
+
The order is the same as for the underlying lists of lists.
|
|
256
|
+
|
|
257
|
+
EXAMPLES::
|
|
258
|
+
|
|
259
|
+
sage: x = polygen(QQ, 'x')
|
|
260
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
261
|
+
sage: N = k.ideal(3, a - 1)
|
|
262
|
+
sage: alpha = MSymbol(N, 3, a)
|
|
263
|
+
sage: beta = MSymbol(N, 1, 0)
|
|
264
|
+
sage: alpha < beta
|
|
265
|
+
False
|
|
266
|
+
sage: beta = MSymbol(N, 3, a + 1)
|
|
267
|
+
sage: alpha < beta
|
|
268
|
+
True
|
|
269
|
+
"""
|
|
270
|
+
if not isinstance(other, MSymbol):
|
|
271
|
+
raise ValueError("You can only compare with another M-symbol")
|
|
272
|
+
return richcmp([self.__c.list(), self.__d.list()],
|
|
273
|
+
[other.__c.list(), other.__d.list()], op)
|
|
274
|
+
|
|
275
|
+
def N(self):
|
|
276
|
+
r"""
|
|
277
|
+
Return the level or modulus of this MSymbol.
|
|
278
|
+
|
|
279
|
+
EXAMPLES::
|
|
280
|
+
|
|
281
|
+
sage: x = polygen(QQ, 'x')
|
|
282
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
283
|
+
sage: N = k.ideal(3, a - 1)
|
|
284
|
+
sage: alpha = MSymbol(N, 3, a)
|
|
285
|
+
sage: alpha.N()
|
|
286
|
+
Fractional ideal (3, 1/2*a - 1/2)
|
|
287
|
+
"""
|
|
288
|
+
return self.__N
|
|
289
|
+
|
|
290
|
+
def tuple(self):
|
|
291
|
+
r"""
|
|
292
|
+
Return the :class:`MSymbol` as a list `(c, d)`.
|
|
293
|
+
|
|
294
|
+
EXAMPLES::
|
|
295
|
+
|
|
296
|
+
sage: x = polygen(QQ, 'x')
|
|
297
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
298
|
+
sage: N = k.ideal(3, a - 1)
|
|
299
|
+
sage: alpha = MSymbol(N, 3, a); alpha
|
|
300
|
+
M-symbol (3: a) of level Fractional ideal (3, 1/2*a - 1/2)
|
|
301
|
+
sage: alpha.tuple()
|
|
302
|
+
(3, a)
|
|
303
|
+
"""
|
|
304
|
+
return self.__c, self.__d
|
|
305
|
+
|
|
306
|
+
def __getitem__(self, n):
|
|
307
|
+
r"""
|
|
308
|
+
Indexing function for the list defined by an M-symbol.
|
|
309
|
+
|
|
310
|
+
INPUT:
|
|
311
|
+
|
|
312
|
+
- ``n`` -- integer (0 or 1, since the list defined by an M-symbol has
|
|
313
|
+
length 2)
|
|
314
|
+
|
|
315
|
+
EXAMPLES::
|
|
316
|
+
|
|
317
|
+
sage: x = polygen(QQ, 'x')
|
|
318
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
319
|
+
sage: N = k.ideal(3, a - 1)
|
|
320
|
+
sage: alpha = MSymbol(N, 3, a); alpha
|
|
321
|
+
M-symbol (3: a) of level Fractional ideal (3, 1/2*a - 1/2)
|
|
322
|
+
sage: alpha[0]
|
|
323
|
+
3
|
|
324
|
+
sage: alpha[1]
|
|
325
|
+
a
|
|
326
|
+
"""
|
|
327
|
+
return self.tuple()[n]
|
|
328
|
+
|
|
329
|
+
def __get_c(self):
|
|
330
|
+
r"""
|
|
331
|
+
Return the first coefficient of the M-symbol.
|
|
332
|
+
|
|
333
|
+
EXAMPLES::
|
|
334
|
+
|
|
335
|
+
sage: x = polygen(QQ, 'x')
|
|
336
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
337
|
+
sage: N = k.ideal(a + 1, 2)
|
|
338
|
+
sage: alpha = MSymbol(N, 3, a^2 + 1)
|
|
339
|
+
sage: alpha.c # indirect doctest
|
|
340
|
+
3
|
|
341
|
+
"""
|
|
342
|
+
return self.__c
|
|
343
|
+
c = property(__get_c)
|
|
344
|
+
|
|
345
|
+
def __get_d(self):
|
|
346
|
+
r"""
|
|
347
|
+
Return the second coefficient of the M-symbol.
|
|
348
|
+
|
|
349
|
+
EXAMPLES::
|
|
350
|
+
|
|
351
|
+
sage: x = polygen(QQ, 'x')
|
|
352
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
353
|
+
sage: N = k.ideal(a + 1, 2)
|
|
354
|
+
sage: alpha = MSymbol(N, 3, a^2 + 1)
|
|
355
|
+
sage: alpha.d # indirect doctest
|
|
356
|
+
a^2 + 1
|
|
357
|
+
"""
|
|
358
|
+
return self.__d
|
|
359
|
+
d = property(__get_d)
|
|
360
|
+
|
|
361
|
+
def lift_to_sl2_Ok(self):
|
|
362
|
+
r"""
|
|
363
|
+
Lift the :class:`MSymbol` to an element of `SL(2, O_k)`, where `O_k` is the ring
|
|
364
|
+
of integers of the corresponding number field.
|
|
365
|
+
|
|
366
|
+
OUTPUT:
|
|
367
|
+
|
|
368
|
+
A list of integral elements `[a, b, c', d']` that are the entries of
|
|
369
|
+
a `2\times 2` matrix with determinant 1. The lower two entries are congruent
|
|
370
|
+
(modulo the level) to the coefficients `c`, `d` of the :class:`MSymbol` ``self``.
|
|
371
|
+
|
|
372
|
+
EXAMPLES::
|
|
373
|
+
|
|
374
|
+
sage: x = polygen(QQ, 'x')
|
|
375
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
376
|
+
sage: N = k.ideal(3, a - 1)
|
|
377
|
+
sage: alpha = MSymbol(N, 3*a + 1, a)
|
|
378
|
+
sage: alpha.lift_to_sl2_Ok()
|
|
379
|
+
[0, -1, 1, a]
|
|
380
|
+
"""
|
|
381
|
+
return lift_to_sl2_Ok(self.__N, self.__c, self.__d)
|
|
382
|
+
|
|
383
|
+
def normalize(self, with_scalar=False):
|
|
384
|
+
r"""
|
|
385
|
+
Return a normalized :class:`MSymbol` (a canonical representative of an element
|
|
386
|
+
of `\mathbb{P}^1(R/N)`) equivalent to ``self``.
|
|
387
|
+
|
|
388
|
+
INPUT:
|
|
389
|
+
|
|
390
|
+
- ``with_scalar`` -- boolean (default: ``False``)
|
|
391
|
+
|
|
392
|
+
OUTPUT:
|
|
393
|
+
|
|
394
|
+
- (only if ``with_scalar=True``) a transforming scalar `u`, such that
|
|
395
|
+
`(u*c', u*d')` is congruent to `(c: d)` (mod `N`), where `(c: d)`
|
|
396
|
+
are the coefficients of ``self`` and `N` is the level.
|
|
397
|
+
|
|
398
|
+
- a normalized :class:`MSymbol` `(c': d')` equivalent to ``self``.
|
|
399
|
+
|
|
400
|
+
EXAMPLES::
|
|
401
|
+
|
|
402
|
+
sage: x = polygen(QQ, 'x')
|
|
403
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
404
|
+
sage: N = k.ideal(3, a - 1)
|
|
405
|
+
sage: alpha1 = MSymbol(N, 3, a); alpha1
|
|
406
|
+
M-symbol (3: a) of level Fractional ideal (3, 1/2*a - 1/2)
|
|
407
|
+
sage: alpha1.normalize()
|
|
408
|
+
M-symbol (0: 1) of level Fractional ideal (3, 1/2*a - 1/2)
|
|
409
|
+
sage: alpha2 = MSymbol(N, 4, a + 1)
|
|
410
|
+
sage: alpha2.normalize()
|
|
411
|
+
M-symbol (1: -a) of level Fractional ideal (3, 1/2*a - 1/2)
|
|
412
|
+
|
|
413
|
+
We get the scaling factor by setting ``with_scalar=True``:
|
|
414
|
+
|
|
415
|
+
::
|
|
416
|
+
|
|
417
|
+
sage: alpha1.normalize(with_scalar=True)
|
|
418
|
+
(a, M-symbol (0: 1) of level Fractional ideal (3, 1/2*a - 1/2))
|
|
419
|
+
sage: r, beta1 = alpha1.normalize(with_scalar=True)
|
|
420
|
+
sage: r*beta1.c - alpha1.c in N
|
|
421
|
+
True
|
|
422
|
+
sage: r*beta1.d - alpha1.d in N
|
|
423
|
+
True
|
|
424
|
+
sage: r, beta2 = alpha2.normalize(with_scalar=True)
|
|
425
|
+
sage: r*beta2.c - alpha2.c in N
|
|
426
|
+
True
|
|
427
|
+
sage: r*beta2.d - alpha2.d in N
|
|
428
|
+
True
|
|
429
|
+
"""
|
|
430
|
+
N = self.__N
|
|
431
|
+
k = N.number_field()
|
|
432
|
+
R = k.ring_of_integers()
|
|
433
|
+
|
|
434
|
+
if self.__c in N:
|
|
435
|
+
if with_scalar:
|
|
436
|
+
return N.reduce(self.d), MSymbol(N, 0, 1)
|
|
437
|
+
else:
|
|
438
|
+
return MSymbol(N, 0, 1)
|
|
439
|
+
if self.d in N:
|
|
440
|
+
if with_scalar:
|
|
441
|
+
return N.reduce(self.c), MSymbol(N, 1, 0)
|
|
442
|
+
else:
|
|
443
|
+
return MSymbol(N, 1, 0)
|
|
444
|
+
if N.is_coprime(self.c):
|
|
445
|
+
cinv = R(self.c).inverse_mod(N)
|
|
446
|
+
if with_scalar:
|
|
447
|
+
return N.reduce(self.c), MSymbol(N, 1, N.reduce(self.d*cinv))
|
|
448
|
+
else:
|
|
449
|
+
return MSymbol(N, 1, N.reduce(self.d*cinv))
|
|
450
|
+
|
|
451
|
+
if N in _level_cache:
|
|
452
|
+
Lfacs, Lxs = _level_cache[N]
|
|
453
|
+
else:
|
|
454
|
+
Lfacs = [p**e for p, e in N.factor()]
|
|
455
|
+
Lxs = [(N/p).element_1_mod(p) for p in Lfacs]
|
|
456
|
+
# Lfacs, Lxs only depend of the ideal: same lists every time we
|
|
457
|
+
# call normalize for a given level, so we store the lists.
|
|
458
|
+
_level_cache[N] = (Lfacs, Lxs)
|
|
459
|
+
u = 0 # normalizer factor
|
|
460
|
+
p_i = 0
|
|
461
|
+
for p in Lfacs:
|
|
462
|
+
if p.is_coprime(self.c):
|
|
463
|
+
inv = self.c.inverse_mod(p)
|
|
464
|
+
else:
|
|
465
|
+
inv = self.d.inverse_mod(p)
|
|
466
|
+
u = u + inv*Lxs[p_i]
|
|
467
|
+
p_i = p_i + 1
|
|
468
|
+
c, d = (N.reduce(u*self.c), N.reduce(u*self.d))
|
|
469
|
+
if (c - 1) in N:
|
|
470
|
+
c = R(1)
|
|
471
|
+
if with_scalar:
|
|
472
|
+
return u.inverse_mod(N), MSymbol(N, c, d)
|
|
473
|
+
else:
|
|
474
|
+
return MSymbol(N, c, d)
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
# ************************************************************************
|
|
478
|
+
# P1NFList class *
|
|
479
|
+
# ************************************************************************
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
@richcmp_method
|
|
483
|
+
class P1NFList(SageObject):
|
|
484
|
+
r"""
|
|
485
|
+
The class for `\mathbb{P}^1(R/N)`, the projective line modulo `N`, where
|
|
486
|
+
`R` is the ring of integers of a number field `K` and `N` is an integral ideal.
|
|
487
|
+
|
|
488
|
+
INPUT:
|
|
489
|
+
|
|
490
|
+
- ``N`` -- integral ideal (the modulus or level)
|
|
491
|
+
|
|
492
|
+
OUTPUT:
|
|
493
|
+
|
|
494
|
+
A :class:`P1NFList` object representing `\mathbb{P}^1(R/N)`.
|
|
495
|
+
|
|
496
|
+
EXAMPLES::
|
|
497
|
+
|
|
498
|
+
sage: x = polygen(QQ, 'x')
|
|
499
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
500
|
+
sage: N = k.ideal(5, a + 1)
|
|
501
|
+
sage: P = P1NFList(N); P
|
|
502
|
+
The projective line over the ring of integers modulo the Fractional ideal (5, a + 1)
|
|
503
|
+
|
|
504
|
+
Saving and loading works.
|
|
505
|
+
|
|
506
|
+
::
|
|
507
|
+
|
|
508
|
+
sage: loads(dumps(P)) == P
|
|
509
|
+
True
|
|
510
|
+
"""
|
|
511
|
+
def __init__(self, N):
|
|
512
|
+
r"""
|
|
513
|
+
The constructor for the class P1NFList. See ``P1NFList`` for full
|
|
514
|
+
documentation.
|
|
515
|
+
|
|
516
|
+
EXAMPLES::
|
|
517
|
+
|
|
518
|
+
sage: x = polygen(QQ, 'x')
|
|
519
|
+
sage: k.<a> = NumberField(x^2 + 5)
|
|
520
|
+
sage: N = k.ideal(3, a - 1)
|
|
521
|
+
sage: P = P1NFList(N); P
|
|
522
|
+
The projective line over the ring of integers modulo the Fractional ideal (3, a + 2)
|
|
523
|
+
"""
|
|
524
|
+
self.__N = N
|
|
525
|
+
self.__list = p1NFlist(N)
|
|
526
|
+
self.__list.sort()
|
|
527
|
+
|
|
528
|
+
def __richcmp__(self, other, op):
|
|
529
|
+
r"""
|
|
530
|
+
Comparison function for objects of the class P1NFList.
|
|
531
|
+
|
|
532
|
+
The order is the same as for the underlying modulus.
|
|
533
|
+
|
|
534
|
+
EXAMPLES::
|
|
535
|
+
|
|
536
|
+
sage: x = polygen(QQ, 'x')
|
|
537
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
538
|
+
sage: N1 = k.ideal(3, a + 1)
|
|
539
|
+
sage: P1 = P1NFList(N1)
|
|
540
|
+
sage: N2 = k.ideal(a + 2)
|
|
541
|
+
sage: P2 = P1NFList(N2)
|
|
542
|
+
sage: P1 < P2
|
|
543
|
+
True
|
|
544
|
+
sage: P1 > P2
|
|
545
|
+
False
|
|
546
|
+
sage: P1 == P1NFList(N1)
|
|
547
|
+
True
|
|
548
|
+
"""
|
|
549
|
+
if not isinstance(other, P1NFList):
|
|
550
|
+
raise ValueError("You can only compare with another P1NFList")
|
|
551
|
+
return richcmp(self.__N, other.__N, op)
|
|
552
|
+
|
|
553
|
+
def __getitem__(self, n):
|
|
554
|
+
r"""
|
|
555
|
+
Standard indexing function for the class P1NFList.
|
|
556
|
+
|
|
557
|
+
EXAMPLES::
|
|
558
|
+
|
|
559
|
+
sage: x = polygen(QQ, 'x')
|
|
560
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
561
|
+
sage: N = k.ideal(a)
|
|
562
|
+
sage: P = P1NFList(N)
|
|
563
|
+
sage: list(P) == P._P1NFList__list
|
|
564
|
+
True
|
|
565
|
+
sage: j = randint(0,len(P)-1)
|
|
566
|
+
sage: P[j] == P._P1NFList__list[j]
|
|
567
|
+
True
|
|
568
|
+
"""
|
|
569
|
+
return self.__list[n]
|
|
570
|
+
|
|
571
|
+
def __len__(self):
|
|
572
|
+
r"""
|
|
573
|
+
Return the length of this P1NFList.
|
|
574
|
+
|
|
575
|
+
EXAMPLES::
|
|
576
|
+
|
|
577
|
+
sage: x = polygen(QQ, 'x')
|
|
578
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
579
|
+
sage: N = k.ideal(5, a^2 - a + 1)
|
|
580
|
+
sage: P = P1NFList(N)
|
|
581
|
+
sage: len(P)
|
|
582
|
+
26
|
|
583
|
+
"""
|
|
584
|
+
return len(self.__list)
|
|
585
|
+
|
|
586
|
+
def __repr__(self):
|
|
587
|
+
r"""
|
|
588
|
+
Return the string representation of this P1NFList.
|
|
589
|
+
|
|
590
|
+
EXAMPLES::
|
|
591
|
+
|
|
592
|
+
sage: x = polygen(QQ, 'x')
|
|
593
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
594
|
+
sage: N = k.ideal(5, a + 1)
|
|
595
|
+
sage: P = P1NFList(N); P
|
|
596
|
+
The projective line over the ring of integers modulo the Fractional ideal (5, a + 1)
|
|
597
|
+
"""
|
|
598
|
+
return "The projective line over the ring of integers modulo the %s" % self.__N
|
|
599
|
+
|
|
600
|
+
def list(self):
|
|
601
|
+
r"""
|
|
602
|
+
Return the underlying list of this :class:`P1NFList` object.
|
|
603
|
+
|
|
604
|
+
EXAMPLES::
|
|
605
|
+
|
|
606
|
+
sage: x = polygen(QQ, 'x')
|
|
607
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
608
|
+
sage: N = k.ideal(5, a+1)
|
|
609
|
+
sage: P = P1NFList(N)
|
|
610
|
+
sage: type(P)
|
|
611
|
+
<class 'sage.modular.modsym.p1list_nf.P1NFList'>
|
|
612
|
+
sage: type(P.list())
|
|
613
|
+
<... 'list'>
|
|
614
|
+
"""
|
|
615
|
+
return self.__list
|
|
616
|
+
|
|
617
|
+
def normalize(self, c, d=None, with_scalar=False):
|
|
618
|
+
r"""
|
|
619
|
+
Return a normalised element of `\mathbb{P}^1(R/N)`.
|
|
620
|
+
|
|
621
|
+
INPUT:
|
|
622
|
+
|
|
623
|
+
- ``c`` -- integral element of the underlying number field, or an
|
|
624
|
+
MSymbol
|
|
625
|
+
|
|
626
|
+
- ``d`` -- (optional) when present, it must be an integral element of
|
|
627
|
+
the number field such that `(c, d)` defines an M-symbol of level `N`
|
|
628
|
+
|
|
629
|
+
- ``with_scalar`` -- boolean (default: ``False``)
|
|
630
|
+
|
|
631
|
+
OUTPUT:
|
|
632
|
+
|
|
633
|
+
- (only if ``with_scalar=True``) a transforming scalar `u`, such that
|
|
634
|
+
`(u*c', u*d')` is congruent to `(c: d)` (mod `N`).
|
|
635
|
+
|
|
636
|
+
- a normalized :class:`MSymbol` `(c': d')` equivalent to `(c: d)`.
|
|
637
|
+
|
|
638
|
+
EXAMPLES::
|
|
639
|
+
|
|
640
|
+
sage: x = polygen(QQ, 'x')
|
|
641
|
+
sage: k.<a> = NumberField(x^2 + 31)
|
|
642
|
+
sage: N = k.ideal(5, a + 3)
|
|
643
|
+
sage: P = P1NFList(N)
|
|
644
|
+
sage: P.normalize(3, a)
|
|
645
|
+
M-symbol (1: 2*a) of level Fractional ideal (5, 1/2*a + 3/2)
|
|
646
|
+
|
|
647
|
+
We can use an :class:`MSymbol` as input:
|
|
648
|
+
|
|
649
|
+
::
|
|
650
|
+
|
|
651
|
+
sage: alpha = MSymbol(N, 3, a)
|
|
652
|
+
sage: P.normalize(alpha)
|
|
653
|
+
M-symbol (1: 2*a) of level Fractional ideal (5, 1/2*a + 3/2)
|
|
654
|
+
|
|
655
|
+
If we are interested in the normalizing scalar:
|
|
656
|
+
|
|
657
|
+
::
|
|
658
|
+
|
|
659
|
+
sage: P.normalize(alpha, with_scalar=True)
|
|
660
|
+
(-a, M-symbol (1: 2*a) of level Fractional ideal (5, 1/2*a + 3/2))
|
|
661
|
+
sage: r, beta = P.normalize(alpha, with_scalar=True)
|
|
662
|
+
sage: (r*beta.c - alpha.c in N) and (r*beta.d - alpha.d in N)
|
|
663
|
+
True
|
|
664
|
+
"""
|
|
665
|
+
if d is None:
|
|
666
|
+
try:
|
|
667
|
+
c = MSymbol(self.__N, c) # check that c is an MSymbol
|
|
668
|
+
except ValueError: # catch special case of wrong level
|
|
669
|
+
raise ValueError("The MSymbol is of a different level")
|
|
670
|
+
return c.normalize(with_scalar)
|
|
671
|
+
return MSymbol(self.N(), c, d).normalize(with_scalar)
|
|
672
|
+
|
|
673
|
+
def N(self):
|
|
674
|
+
r"""
|
|
675
|
+
Return the level or modulus of this :class:`P1NFList`.
|
|
676
|
+
|
|
677
|
+
EXAMPLES::
|
|
678
|
+
|
|
679
|
+
sage: x = polygen(QQ, 'x')
|
|
680
|
+
sage: k.<a> = NumberField(x^2 + 31)
|
|
681
|
+
sage: N = k.ideal(5, a + 3)
|
|
682
|
+
sage: P = P1NFList(N)
|
|
683
|
+
sage: P.N()
|
|
684
|
+
Fractional ideal (5, 1/2*a + 3/2)
|
|
685
|
+
"""
|
|
686
|
+
return self.__N
|
|
687
|
+
|
|
688
|
+
def index(self, c, d=None, with_scalar=False):
|
|
689
|
+
r"""
|
|
690
|
+
Return the index of the class of the pair `(c, d)` in the fixed list
|
|
691
|
+
of representatives of `\mathbb{P}^1(R/N)`.
|
|
692
|
+
|
|
693
|
+
INPUT:
|
|
694
|
+
|
|
695
|
+
- ``c`` -- integral element of the corresponding number field, or an
|
|
696
|
+
:class:`MSymbol`
|
|
697
|
+
|
|
698
|
+
- ``d`` -- (optional) when present, it must be an integral element of
|
|
699
|
+
the number field such that `(c, d)` defines an M-symbol of level `N`
|
|
700
|
+
|
|
701
|
+
- ``with_scalar`` -- boolean (default: ``False``)
|
|
702
|
+
|
|
703
|
+
OUTPUT:
|
|
704
|
+
|
|
705
|
+
- ``u`` -- the normalizing scalar (only if ``with_scalar=True``)
|
|
706
|
+
|
|
707
|
+
- ``i`` -- the index of `(c, d)` in the list
|
|
708
|
+
|
|
709
|
+
EXAMPLES::
|
|
710
|
+
|
|
711
|
+
sage: x = polygen(QQ, 'x')
|
|
712
|
+
sage: k.<a> = NumberField(x^2 + 31)
|
|
713
|
+
sage: N = k.ideal(5, a + 3)
|
|
714
|
+
sage: P = P1NFList(N)
|
|
715
|
+
sage: P.index(3,a)
|
|
716
|
+
5
|
|
717
|
+
sage: P[5]==MSymbol(N, 3, a).normalize()
|
|
718
|
+
True
|
|
719
|
+
|
|
720
|
+
We can give an :class:`MSymbol` as input:
|
|
721
|
+
|
|
722
|
+
::
|
|
723
|
+
|
|
724
|
+
sage: alpha = MSymbol(N, 3, a)
|
|
725
|
+
sage: P.index(alpha)
|
|
726
|
+
5
|
|
727
|
+
|
|
728
|
+
We cannot look for the class of an :class:`MSymbol` of a different level:
|
|
729
|
+
|
|
730
|
+
::
|
|
731
|
+
|
|
732
|
+
sage: M = k.ideal(a + 1)
|
|
733
|
+
sage: beta = MSymbol(M, 0, 1)
|
|
734
|
+
sage: P.index(beta)
|
|
735
|
+
Traceback (most recent call last):
|
|
736
|
+
...
|
|
737
|
+
ValueError: The MSymbol is of a different level
|
|
738
|
+
|
|
739
|
+
If we are interested in the transforming scalar:
|
|
740
|
+
|
|
741
|
+
::
|
|
742
|
+
|
|
743
|
+
sage: alpha = MSymbol(N, 3, a)
|
|
744
|
+
sage: P.index(alpha, with_scalar=True)
|
|
745
|
+
(-a, 5)
|
|
746
|
+
sage: u, i = P.index(alpha, with_scalar=True)
|
|
747
|
+
sage: (u*P[i].c - alpha.c in N) and (u*P[i].d - alpha.d in N)
|
|
748
|
+
True
|
|
749
|
+
"""
|
|
750
|
+
if d is None:
|
|
751
|
+
try:
|
|
752
|
+
c = MSymbol(self.__N, c) # check that c is an MSymbol
|
|
753
|
+
except ValueError: # catch special case of wrong level
|
|
754
|
+
raise ValueError("The MSymbol is of a different level")
|
|
755
|
+
if with_scalar:
|
|
756
|
+
u, norm_c = c.normalize(with_scalar=True)
|
|
757
|
+
else:
|
|
758
|
+
norm_c = c.normalize()
|
|
759
|
+
else:
|
|
760
|
+
if with_scalar:
|
|
761
|
+
u, norm_c = MSymbol(self.__N, c, d).normalize(with_scalar=True)
|
|
762
|
+
else:
|
|
763
|
+
norm_c = MSymbol(self.__N, c, d).normalize()
|
|
764
|
+
t, i = search(self.__list, norm_c)
|
|
765
|
+
if t:
|
|
766
|
+
if with_scalar:
|
|
767
|
+
return u, i
|
|
768
|
+
else:
|
|
769
|
+
return i
|
|
770
|
+
return False
|
|
771
|
+
|
|
772
|
+
def index_of_normalized_pair(self, c, d=None):
|
|
773
|
+
r"""
|
|
774
|
+
Return the index of the class `(c, d)` in the fixed list of
|
|
775
|
+
representatives of `\mathbb(P)^1(R/N)`.
|
|
776
|
+
|
|
777
|
+
INPUT:
|
|
778
|
+
|
|
779
|
+
- ``c`` -- integral element of the corresponding number field, or a
|
|
780
|
+
normalized :class:`MSymbol`
|
|
781
|
+
|
|
782
|
+
- ``d`` -- (optional) when present, it must be an integral element of
|
|
783
|
+
the number field such that `(c, d)` defines a normalized M-symbol of
|
|
784
|
+
level `N`
|
|
785
|
+
|
|
786
|
+
OUTPUT: ``i`` -- the index of `(c, d)` in the list
|
|
787
|
+
|
|
788
|
+
EXAMPLES::
|
|
789
|
+
|
|
790
|
+
sage: x = polygen(QQ, 'x')
|
|
791
|
+
sage: k.<a> = NumberField(x^2 + 31)
|
|
792
|
+
sage: N = k.ideal(5, a + 3)
|
|
793
|
+
sage: P = P1NFList(N)
|
|
794
|
+
sage: P.index_of_normalized_pair(1, 0)
|
|
795
|
+
3
|
|
796
|
+
sage: j = randint(0,len(P)-1)
|
|
797
|
+
sage: P.index_of_normalized_pair(P[j])==j
|
|
798
|
+
True
|
|
799
|
+
"""
|
|
800
|
+
if d is None:
|
|
801
|
+
try:
|
|
802
|
+
c = MSymbol(self.__N, c) # check that c is an MSymbol
|
|
803
|
+
except ValueError: # catch special case of wrong level
|
|
804
|
+
raise ValueError("The MSymbol is of a different level")
|
|
805
|
+
t, i = search(self.__list, c)
|
|
806
|
+
else:
|
|
807
|
+
t, i = search(self.__list, MSymbol(self.__N, c, d))
|
|
808
|
+
if t:
|
|
809
|
+
return i
|
|
810
|
+
return False
|
|
811
|
+
|
|
812
|
+
def lift_to_sl2_Ok(self, i):
|
|
813
|
+
r"""
|
|
814
|
+
Lift the `i`-th element of this :class:`P1NFList` to an element of `SL(2, R)`,
|
|
815
|
+
where `R` is the ring of integers of the corresponding number field.
|
|
816
|
+
|
|
817
|
+
INPUT:
|
|
818
|
+
|
|
819
|
+
- ``i`` -- integer (index of the element to lift)
|
|
820
|
+
|
|
821
|
+
OUTPUT:
|
|
822
|
+
|
|
823
|
+
If the `i`-th element is `(c : d)`, the function returns a list of
|
|
824
|
+
integral elements `[a, b, c', d']` that defines a `2\times 2` matrix with
|
|
825
|
+
determinant 1 and such that `c=c'` (mod `N`) and `d=d'` (mod `N`).
|
|
826
|
+
|
|
827
|
+
EXAMPLES::
|
|
828
|
+
|
|
829
|
+
sage: x = polygen(QQ, 'x')
|
|
830
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
831
|
+
sage: N = k.ideal(3)
|
|
832
|
+
sage: P = P1NFList(N)
|
|
833
|
+
sage: len(P)
|
|
834
|
+
16
|
|
835
|
+
sage: P[5]
|
|
836
|
+
M-symbol (1/2*a + 1/2: -a) of level Fractional ideal (3)
|
|
837
|
+
sage: P.lift_to_sl2_Ok(5)
|
|
838
|
+
[-a, 2*a - 2, 1/2*a + 1/2, -a]
|
|
839
|
+
|
|
840
|
+
::
|
|
841
|
+
|
|
842
|
+
sage: Ok = k.ring_of_integers()
|
|
843
|
+
sage: L = [Matrix(Ok, 2, P.lift_to_sl2_Ok(i)) for i in range(len(P))]
|
|
844
|
+
sage: all(det(L[i]) == 1 for i in range(len(L)))
|
|
845
|
+
True
|
|
846
|
+
"""
|
|
847
|
+
return self[i].lift_to_sl2_Ok()
|
|
848
|
+
|
|
849
|
+
def apply_S(self, i):
|
|
850
|
+
r"""
|
|
851
|
+
Applies the matrix `S` = [0, -1, 1, 0] to the `i`-th M-Symbol of the list.
|
|
852
|
+
|
|
853
|
+
INPUT:
|
|
854
|
+
|
|
855
|
+
- ``i`` -- integer
|
|
856
|
+
|
|
857
|
+
OUTPUT:
|
|
858
|
+
|
|
859
|
+
integer -- the index of the M-Symbol obtained by the right action of
|
|
860
|
+
the matrix `S` = [0, -1, 1, 0] on the `i`-th M-Symbol.
|
|
861
|
+
|
|
862
|
+
EXAMPLES::
|
|
863
|
+
|
|
864
|
+
sage: x = polygen(QQ, 'x')
|
|
865
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
866
|
+
sage: N = k.ideal(5, a + 1)
|
|
867
|
+
sage: P = P1NFList(N)
|
|
868
|
+
sage: j = P.apply_S(P.index_of_normalized_pair(1, 0))
|
|
869
|
+
sage: P[j]
|
|
870
|
+
M-symbol (0: 1) of level Fractional ideal (5, a + 1)
|
|
871
|
+
|
|
872
|
+
We test that S has order 2:
|
|
873
|
+
|
|
874
|
+
::
|
|
875
|
+
|
|
876
|
+
sage: j = randint(0,len(P)-1)
|
|
877
|
+
sage: P.apply_S(P.apply_S(j))==j
|
|
878
|
+
True
|
|
879
|
+
"""
|
|
880
|
+
c, d = self.__list[i].tuple()
|
|
881
|
+
t, j = search(self.__list, self.normalize(d, -c))
|
|
882
|
+
return j
|
|
883
|
+
|
|
884
|
+
def apply_TS(self, i):
|
|
885
|
+
r"""
|
|
886
|
+
Applies the matrix `TS` = [1, -1, 0, 1] to the `i`-th M-Symbol of the list.
|
|
887
|
+
|
|
888
|
+
INPUT:
|
|
889
|
+
|
|
890
|
+
- ``i`` -- integer
|
|
891
|
+
|
|
892
|
+
OUTPUT:
|
|
893
|
+
|
|
894
|
+
integer -- the index of the M-Symbol obtained by the right action of
|
|
895
|
+
the matrix `TS` = [1, -1, 0, 1] on the `i`-th M-Symbol.
|
|
896
|
+
|
|
897
|
+
EXAMPLES::
|
|
898
|
+
|
|
899
|
+
sage: x = polygen(QQ, 'x')
|
|
900
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
901
|
+
sage: N = k.ideal(5, a + 1)
|
|
902
|
+
sage: P = P1NFList(N)
|
|
903
|
+
sage: P.apply_TS(3)
|
|
904
|
+
2
|
|
905
|
+
|
|
906
|
+
We test that `TS` has order 3:
|
|
907
|
+
|
|
908
|
+
::
|
|
909
|
+
|
|
910
|
+
sage: j = randint(0,len(P)-1)
|
|
911
|
+
sage: P.apply_TS(P.apply_TS(P.apply_TS(j)))==j
|
|
912
|
+
True
|
|
913
|
+
"""
|
|
914
|
+
c, d = self.__list[i].tuple()
|
|
915
|
+
t, j = search(self.__list, self.normalize(c + d, -c))
|
|
916
|
+
return j
|
|
917
|
+
|
|
918
|
+
def apply_T_alpha(self, i, alpha=1):
|
|
919
|
+
r"""
|
|
920
|
+
Applies the matrix `T_{alpha}` = [1, `alpha`, 0, 1] to the `i`-th
|
|
921
|
+
M-Symbol of the list.
|
|
922
|
+
|
|
923
|
+
INPUT:
|
|
924
|
+
|
|
925
|
+
- ``i`` -- integer
|
|
926
|
+
|
|
927
|
+
- ``alpha`` -- (default: 1) element of the corresponding ring of integers
|
|
928
|
+
|
|
929
|
+
OUTPUT:
|
|
930
|
+
|
|
931
|
+
integer -- the index of the M-Symbol obtained by the right action of
|
|
932
|
+
the matrix `T_{alpha}` = [1, `alpha`, 0, 1] on the `i`-th M-Symbol.
|
|
933
|
+
|
|
934
|
+
EXAMPLES::
|
|
935
|
+
|
|
936
|
+
sage: x = polygen(QQ, 'x')
|
|
937
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
938
|
+
sage: N = k.ideal(5, a + 1)
|
|
939
|
+
sage: P = P1NFList(N)
|
|
940
|
+
sage: P.apply_T_alpha(4, a^ 2 - 2)
|
|
941
|
+
3
|
|
942
|
+
|
|
943
|
+
We test that `T_a*T_b = T_{(a+b)}`:
|
|
944
|
+
|
|
945
|
+
::
|
|
946
|
+
|
|
947
|
+
sage: P.apply_T_alpha(3, a^2 - 2)==P.apply_T_alpha(P.apply_T_alpha(3,a^2),-2)
|
|
948
|
+
True
|
|
949
|
+
"""
|
|
950
|
+
c, d = self.__list[i].tuple()
|
|
951
|
+
t, j = search(self.__list, self.normalize(c, alpha*c + d))
|
|
952
|
+
return j
|
|
953
|
+
|
|
954
|
+
def apply_J_epsilon(self, i, e1, e2=1):
|
|
955
|
+
r"""
|
|
956
|
+
Apply the matrix `J_{\epsilon}` = [e1, 0, 0, e2] to the `i`-th
|
|
957
|
+
M-Symbol of the list.
|
|
958
|
+
|
|
959
|
+
e1, e2 are units of the underlying number field.
|
|
960
|
+
|
|
961
|
+
INPUT:
|
|
962
|
+
|
|
963
|
+
- ``i`` -- integer
|
|
964
|
+
|
|
965
|
+
- ``e1`` -- unit
|
|
966
|
+
|
|
967
|
+
- ``e2`` -- unit (default: 1)
|
|
968
|
+
|
|
969
|
+
OUTPUT:
|
|
970
|
+
|
|
971
|
+
integer -- the index of the M-Symbol obtained by the right action of
|
|
972
|
+
the matrix `J_{\epsilon}` = [e1, 0, 0, e2] on the `i`-th M-Symbol.
|
|
973
|
+
|
|
974
|
+
EXAMPLES::
|
|
975
|
+
|
|
976
|
+
sage: x = polygen(QQ, 'x')
|
|
977
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
978
|
+
sage: N = k.ideal(5, a + 1)
|
|
979
|
+
sage: P = P1NFList(N)
|
|
980
|
+
sage: u = k.unit_group().gens_values(); u
|
|
981
|
+
[-1, 2*a^2 + 4*a - 1]
|
|
982
|
+
sage: P.apply_J_epsilon(4, -1)
|
|
983
|
+
2
|
|
984
|
+
sage: P.apply_J_epsilon(4, u[0], u[1])
|
|
985
|
+
1
|
|
986
|
+
|
|
987
|
+
::
|
|
988
|
+
|
|
989
|
+
sage: k.<a> = NumberField(x^4 + 13*x - 7)
|
|
990
|
+
sage: N = k.ideal(a + 1)
|
|
991
|
+
sage: P = P1NFList(N)
|
|
992
|
+
sage: u = k.unit_group().gens_values(); u
|
|
993
|
+
[-1, -a^3 - a^2 - a - 12, -a^3 - 3*a^2 + 1]
|
|
994
|
+
sage: P.apply_J_epsilon(3, u[2]^2)==P.apply_J_epsilon(P.apply_J_epsilon(3, u[2]),u[2])
|
|
995
|
+
True
|
|
996
|
+
"""
|
|
997
|
+
c, d = self.__list[i].tuple()
|
|
998
|
+
t, j = search(self.__list, self.normalize(c*e1, d*e2))
|
|
999
|
+
return j
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
# *************************************************************************
|
|
1003
|
+
# Global functions:
|
|
1004
|
+
# - p1NFList --compute list of M-symbols
|
|
1005
|
+
# - lift_to_sl2_Ok
|
|
1006
|
+
# - make_coprime -- need it for ``lift_to_sl2_Ok``
|
|
1007
|
+
# - psi -- useful to check cardinality of the M-symbols list
|
|
1008
|
+
# *************************************************************************
|
|
1009
|
+
|
|
1010
|
+
def p1NFlist(N):
|
|
1011
|
+
r"""
|
|
1012
|
+
Return a list of the normalized elements of `\mathbb{P}^1(R/N)`, where
|
|
1013
|
+
`N` is an integral ideal.
|
|
1014
|
+
|
|
1015
|
+
INPUT:
|
|
1016
|
+
|
|
1017
|
+
- ``N`` -- integral ideal (the level or modulus)
|
|
1018
|
+
|
|
1019
|
+
EXAMPLES::
|
|
1020
|
+
|
|
1021
|
+
sage: x = polygen(QQ, 'x')
|
|
1022
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
1023
|
+
sage: N = k.ideal(3)
|
|
1024
|
+
sage: from sage.modular.modsym.p1list_nf import p1NFlist, psi
|
|
1025
|
+
sage: len(p1NFlist(N))==psi(N)
|
|
1026
|
+
True
|
|
1027
|
+
"""
|
|
1028
|
+
k = N.number_field()
|
|
1029
|
+
|
|
1030
|
+
L = [MSymbol(N, k(0), k(1), check=False)]
|
|
1031
|
+
# N.residues() = iterator through the residues mod N
|
|
1032
|
+
L = L + [MSymbol(N, k(1), r, check=False) for r in N.residues()]
|
|
1033
|
+
|
|
1034
|
+
from sage.arith.misc import divisors
|
|
1035
|
+
for D in divisors(N):
|
|
1036
|
+
if not D.is_trivial() and D != N:
|
|
1037
|
+
# we find Dp ideal coprime to N, in inverse class to D
|
|
1038
|
+
if D.is_principal():
|
|
1039
|
+
Dp = k.ideal(1)
|
|
1040
|
+
c = D.gens_reduced()[0]
|
|
1041
|
+
else:
|
|
1042
|
+
it = k.primes_of_degree_one_iter()
|
|
1043
|
+
Dp = next(it)
|
|
1044
|
+
while not Dp.is_coprime(N) or not (Dp*D).is_principal():
|
|
1045
|
+
Dp = next(it)
|
|
1046
|
+
c = (D*Dp).gens_reduced()[0]
|
|
1047
|
+
# now we find all the (c,d)'s which have associated divisor D
|
|
1048
|
+
I = D + N/D
|
|
1049
|
+
for d in (N/D).residues():
|
|
1050
|
+
if I.is_coprime(d):
|
|
1051
|
+
M = D.prime_to_idealM_part(N/D)
|
|
1052
|
+
u = (Dp*M).element_1_mod(N/D)
|
|
1053
|
+
d1 = u*d + (1-u)
|
|
1054
|
+
L.append(MSymbol(N, c, d1, check=False).normalize())
|
|
1055
|
+
return L
|
|
1056
|
+
|
|
1057
|
+
|
|
1058
|
+
def lift_to_sl2_Ok(N, c, d):
|
|
1059
|
+
r"""
|
|
1060
|
+
Lift a pair (c, d) to an element of `SL(2, O_k)`, where `O_k` is the ring
|
|
1061
|
+
of integers of the corresponding number field.
|
|
1062
|
+
|
|
1063
|
+
INPUT:
|
|
1064
|
+
|
|
1065
|
+
- ``N`` -- number field ideal
|
|
1066
|
+
|
|
1067
|
+
- ``c`` -- integral element of the number field
|
|
1068
|
+
|
|
1069
|
+
- ``d`` -- integral element of the number field
|
|
1070
|
+
|
|
1071
|
+
OUTPUT:
|
|
1072
|
+
|
|
1073
|
+
A list `[a, b, c', d']` of integral elements that are the entries of
|
|
1074
|
+
a `2\times 2` matrix with determinant 1. The lower two entries are congruent to
|
|
1075
|
+
`c`, `d` modulo the ideal `N`.
|
|
1076
|
+
|
|
1077
|
+
EXAMPLES::
|
|
1078
|
+
|
|
1079
|
+
sage: from sage.modular.modsym.p1list_nf import lift_to_sl2_Ok
|
|
1080
|
+
sage: x = polygen(QQ, 'x')
|
|
1081
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
1082
|
+
sage: Ok = k.ring_of_integers()
|
|
1083
|
+
sage: N = k.ideal(3)
|
|
1084
|
+
sage: M = Matrix(Ok, 2, lift_to_sl2_Ok(N, 1, a))
|
|
1085
|
+
sage: det(M)
|
|
1086
|
+
1
|
|
1087
|
+
sage: M = Matrix(Ok, 2, lift_to_sl2_Ok(N, 0, a))
|
|
1088
|
+
sage: det(M)
|
|
1089
|
+
1
|
|
1090
|
+
sage: (M[1][0] in N) and (M[1][1] - a in N)
|
|
1091
|
+
True
|
|
1092
|
+
sage: M = Matrix(Ok, 2, lift_to_sl2_Ok(N, 0, 0))
|
|
1093
|
+
Traceback (most recent call last):
|
|
1094
|
+
...
|
|
1095
|
+
ValueError: Cannot lift (0, 0) to an element of Sl2(Ok).
|
|
1096
|
+
|
|
1097
|
+
::
|
|
1098
|
+
|
|
1099
|
+
sage: k.<a> = NumberField(x^3 + 11)
|
|
1100
|
+
sage: Ok = k.ring_of_integers()
|
|
1101
|
+
sage: N = k.ideal(3, a - 1)
|
|
1102
|
+
sage: M = Matrix(Ok, 2, lift_to_sl2_Ok(N, 2*a, 0))
|
|
1103
|
+
sage: det(M)
|
|
1104
|
+
1
|
|
1105
|
+
sage: (M[1][0] - 2*a in N) and (M[1][1] in N)
|
|
1106
|
+
True
|
|
1107
|
+
sage: M = Matrix(Ok, 2, lift_to_sl2_Ok(N, 4*a^2, a + 1))
|
|
1108
|
+
sage: det(M)
|
|
1109
|
+
1
|
|
1110
|
+
sage: (M[1][0] - 4*a^2 in N) and (M[1][1] - (a+1) in N)
|
|
1111
|
+
True
|
|
1112
|
+
|
|
1113
|
+
::
|
|
1114
|
+
|
|
1115
|
+
sage: k.<a> = NumberField(x^4 - x^3 -21*x^2 + 17*x + 133)
|
|
1116
|
+
sage: Ok = k.ring_of_integers()
|
|
1117
|
+
sage: N = k.ideal(7, a)
|
|
1118
|
+
sage: M = Matrix(Ok, 2, lift_to_sl2_Ok(N, 0, a^2 - 1))
|
|
1119
|
+
sage: det(M)
|
|
1120
|
+
1
|
|
1121
|
+
sage: (M[1][0] in N) and (M[1][1] - (a^2-1) in N)
|
|
1122
|
+
True
|
|
1123
|
+
sage: M = Matrix(Ok, 2, lift_to_sl2_Ok(N, 0, 7))
|
|
1124
|
+
Traceback (most recent call last):
|
|
1125
|
+
...
|
|
1126
|
+
ValueError: <0> + <7> and the Fractional ideal (7, -4/7*a^3 + 13/7*a^2 + 39/7*a - 19) are not coprime.
|
|
1127
|
+
"""
|
|
1128
|
+
k = N.number_field()
|
|
1129
|
+
# check the input
|
|
1130
|
+
if c.is_zero() and d.is_zero():
|
|
1131
|
+
raise ValueError("Cannot lift (%s, %s) to an element of Sl2(Ok)." % (c, d))
|
|
1132
|
+
if not N.is_coprime(k.ideal(c, d)):
|
|
1133
|
+
raise ValueError("<%s> + <%s> and the %s are not coprime." % (c, d, N))
|
|
1134
|
+
# a few special cases
|
|
1135
|
+
if c - 1 in N:
|
|
1136
|
+
return [k(0), k(-1), 1, d]
|
|
1137
|
+
if d - 1 in N:
|
|
1138
|
+
return [k(1), k(0), c, 1]
|
|
1139
|
+
if c.is_zero(): # and d!=1, so won't happen for normalized M-symbols (c: d)
|
|
1140
|
+
it = k.primes_of_degree_one_iter()
|
|
1141
|
+
q = k.ideal(1)
|
|
1142
|
+
while not (q.is_coprime(d) and (q*N).is_principal()):
|
|
1143
|
+
q = next(it)
|
|
1144
|
+
m = (q*N).gens_reduced()[0]
|
|
1145
|
+
B = k.ideal(m).element_1_mod(k.ideal(d))
|
|
1146
|
+
return [(1-B)/d, -B/m, m, d]
|
|
1147
|
+
if d.is_zero(): # and c!=1, so won't happen for normalized M-symbols (c: d)
|
|
1148
|
+
it = k.primes_of_degree_one_iter()
|
|
1149
|
+
q = k.ideal(1)
|
|
1150
|
+
while not (q.is_coprime(c) and (q*N).is_principal()):
|
|
1151
|
+
q = next(it)
|
|
1152
|
+
m = (q*N).gens_reduced()[0]
|
|
1153
|
+
B = k.ideal(c).element_1_mod(k.ideal(m))
|
|
1154
|
+
return [(1-B)/m, -B/c, c, m]
|
|
1155
|
+
|
|
1156
|
+
c, d = make_coprime(N, c, d)
|
|
1157
|
+
|
|
1158
|
+
B = k.ideal(c).element_1_mod(k.ideal(d))
|
|
1159
|
+
b = -B/c
|
|
1160
|
+
a = (1-B)/d
|
|
1161
|
+
return [a, b, c, d]
|
|
1162
|
+
|
|
1163
|
+
|
|
1164
|
+
def make_coprime(N, c, d):
|
|
1165
|
+
r"""
|
|
1166
|
+
Return (c, d') so d' is congruent to d modulo N, and such that c and d' are
|
|
1167
|
+
coprime (`\langle c\rangle + \langle d'\rangle = R`).
|
|
1168
|
+
|
|
1169
|
+
INPUT:
|
|
1170
|
+
|
|
1171
|
+
- ``N`` -- number field ideal
|
|
1172
|
+
|
|
1173
|
+
- ``c`` -- integral element of the number field
|
|
1174
|
+
|
|
1175
|
+
- ``d`` -- integral element of the number field
|
|
1176
|
+
|
|
1177
|
+
OUTPUT:
|
|
1178
|
+
|
|
1179
|
+
A pair `(c, d')` where `c`, `d'` are integral elements of the corresponding
|
|
1180
|
+
number field, with `d'` congruent to `d` mod `N`, and such that `\langle c\rangle + \langle d'\rangle = R`
|
|
1181
|
+
(`R` being the corresponding ring of integers).
|
|
1182
|
+
|
|
1183
|
+
EXAMPLES::
|
|
1184
|
+
|
|
1185
|
+
sage: from sage.modular.modsym.p1list_nf import make_coprime
|
|
1186
|
+
sage: x = polygen(QQ, 'x')
|
|
1187
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
1188
|
+
sage: N = k.ideal(3, a - 1)
|
|
1189
|
+
sage: c = 2*a; d = a + 1
|
|
1190
|
+
sage: N.is_coprime(k.ideal(c, d))
|
|
1191
|
+
True
|
|
1192
|
+
sage: k.ideal(c).is_coprime(d)
|
|
1193
|
+
False
|
|
1194
|
+
sage: c, dp = make_coprime(N, c, d)
|
|
1195
|
+
sage: k.ideal(c).is_coprime(dp)
|
|
1196
|
+
True
|
|
1197
|
+
"""
|
|
1198
|
+
k = N.number_field()
|
|
1199
|
+
if k.ideal(c).is_coprime(d):
|
|
1200
|
+
return c, d
|
|
1201
|
+
else:
|
|
1202
|
+
q = k.ideal(c).prime_to_idealM_part(d)
|
|
1203
|
+
it = k.primes_of_degree_one_iter()
|
|
1204
|
+
r = k.ideal(1)
|
|
1205
|
+
qN = q*N
|
|
1206
|
+
while not (r.is_coprime(c) and (r*qN).is_principal()):
|
|
1207
|
+
r = next(it)
|
|
1208
|
+
m = (r*qN).gens_reduced()[0]
|
|
1209
|
+
d1 = d + m
|
|
1210
|
+
return c, d1
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
def psi(N):
|
|
1214
|
+
r"""
|
|
1215
|
+
The index `[\Gamma : \Gamma_0(N)]`, where `\Gamma = GL(2, R)` for `R` the
|
|
1216
|
+
corresponding ring of integers, and `\Gamma_0(N)` standard congruence
|
|
1217
|
+
subgroup.
|
|
1218
|
+
|
|
1219
|
+
EXAMPLES::
|
|
1220
|
+
|
|
1221
|
+
sage: from sage.modular.modsym.p1list_nf import psi
|
|
1222
|
+
sage: x = polygen(QQ, 'x')
|
|
1223
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
1224
|
+
sage: N = k.ideal(3, a - 1)
|
|
1225
|
+
sage: psi(N)
|
|
1226
|
+
4
|
|
1227
|
+
|
|
1228
|
+
::
|
|
1229
|
+
|
|
1230
|
+
sage: k.<a> = NumberField(x^2 + 23)
|
|
1231
|
+
sage: N = k.ideal(5)
|
|
1232
|
+
sage: psi(N)
|
|
1233
|
+
26
|
|
1234
|
+
"""
|
|
1235
|
+
if not N.is_integral():
|
|
1236
|
+
raise ValueError("psi only defined for integral ideals")
|
|
1237
|
+
|
|
1238
|
+
from sage.misc.misc_c import prod
|
|
1239
|
+
return prod([(np + 1) * np**(e - 1)
|
|
1240
|
+
for np, e in [(p.absolute_norm(), e)
|
|
1241
|
+
for p, e in N.factor()]])
|