passagemath-schemes 10.6.40__cp314-cp314-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.

Potentially problematic release.


This version of passagemath-schemes might be problematic. Click here for more details.

Files changed (314) hide show
  1. passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
  2. passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
  3. passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
  4. passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
  5. passagemath_schemes/__init__.py +3 -0
  6. passagemath_schemes-10.6.40.dist-info/METADATA +204 -0
  7. passagemath_schemes-10.6.40.dist-info/METADATA.bak +205 -0
  8. passagemath_schemes-10.6.40.dist-info/RECORD +314 -0
  9. passagemath_schemes-10.6.40.dist-info/WHEEL +6 -0
  10. passagemath_schemes-10.6.40.dist-info/top_level.txt +3 -0
  11. sage/all__sagemath_schemes.py +23 -0
  12. sage/databases/all__sagemath_schemes.py +7 -0
  13. sage/databases/cremona.py +1723 -0
  14. sage/dynamics/all__sagemath_schemes.py +2 -0
  15. sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
  16. sage/dynamics/arithmetic_dynamics/all.py +14 -0
  17. sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
  18. sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
  19. sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
  20. sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
  21. sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
  22. sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
  23. sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
  24. sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314-darwin.so +0 -0
  25. sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
  26. sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
  27. sage/lfunctions/all.py +18 -0
  28. sage/lfunctions/dokchitser.py +745 -0
  29. sage/lfunctions/pari.py +818 -0
  30. sage/lfunctions/zero_sums.cpython-314-darwin.so +0 -0
  31. sage/lfunctions/zero_sums.pyx +1847 -0
  32. sage/modular/abvar/abvar.py +5135 -0
  33. sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
  34. sage/modular/abvar/abvar_newform.py +244 -0
  35. sage/modular/abvar/all.py +8 -0
  36. sage/modular/abvar/constructor.py +186 -0
  37. sage/modular/abvar/cuspidal_subgroup.py +371 -0
  38. sage/modular/abvar/finite_subgroup.py +896 -0
  39. sage/modular/abvar/homology.py +720 -0
  40. sage/modular/abvar/homspace.py +998 -0
  41. sage/modular/abvar/lseries.py +415 -0
  42. sage/modular/abvar/morphism.py +935 -0
  43. sage/modular/abvar/torsion_point.py +274 -0
  44. sage/modular/abvar/torsion_subgroup.py +740 -0
  45. sage/modular/all.py +43 -0
  46. sage/modular/arithgroup/all.py +20 -0
  47. sage/modular/arithgroup/arithgroup_element.cpython-314-darwin.so +0 -0
  48. sage/modular/arithgroup/arithgroup_element.pyx +474 -0
  49. sage/modular/arithgroup/arithgroup_generic.py +1402 -0
  50. sage/modular/arithgroup/arithgroup_perm.py +2692 -0
  51. sage/modular/arithgroup/congroup.cpython-314-darwin.so +0 -0
  52. sage/modular/arithgroup/congroup.pyx +334 -0
  53. sage/modular/arithgroup/congroup_gamma.py +363 -0
  54. sage/modular/arithgroup/congroup_gamma0.py +692 -0
  55. sage/modular/arithgroup/congroup_gamma1.py +653 -0
  56. sage/modular/arithgroup/congroup_gammaH.py +1469 -0
  57. sage/modular/arithgroup/congroup_generic.py +628 -0
  58. sage/modular/arithgroup/congroup_sl2z.py +267 -0
  59. sage/modular/arithgroup/farey_symbol.cpython-314-darwin.so +0 -0
  60. sage/modular/arithgroup/farey_symbol.pyx +1066 -0
  61. sage/modular/arithgroup/tests.py +418 -0
  62. sage/modular/btquotients/all.py +4 -0
  63. sage/modular/btquotients/btquotient.py +3753 -0
  64. sage/modular/btquotients/pautomorphicform.py +2570 -0
  65. sage/modular/buzzard.py +100 -0
  66. sage/modular/congroup.py +29 -0
  67. sage/modular/congroup_element.py +13 -0
  68. sage/modular/cusps.py +1109 -0
  69. sage/modular/cusps_nf.py +1270 -0
  70. sage/modular/dims.py +569 -0
  71. sage/modular/dirichlet.py +3310 -0
  72. sage/modular/drinfeld_modform/all.py +2 -0
  73. sage/modular/drinfeld_modform/element.py +446 -0
  74. sage/modular/drinfeld_modform/ring.py +773 -0
  75. sage/modular/drinfeld_modform/tutorial.py +236 -0
  76. sage/modular/etaproducts.py +1065 -0
  77. sage/modular/hecke/algebra.py +746 -0
  78. sage/modular/hecke/all.py +20 -0
  79. sage/modular/hecke/ambient_module.py +1019 -0
  80. sage/modular/hecke/degenmap.py +119 -0
  81. sage/modular/hecke/element.py +325 -0
  82. sage/modular/hecke/hecke_operator.py +780 -0
  83. sage/modular/hecke/homspace.py +206 -0
  84. sage/modular/hecke/module.py +1767 -0
  85. sage/modular/hecke/morphism.py +174 -0
  86. sage/modular/hecke/submodule.py +989 -0
  87. sage/modular/hypergeometric_misc.cpython-314-darwin.so +0 -0
  88. sage/modular/hypergeometric_misc.pxd +4 -0
  89. sage/modular/hypergeometric_misc.pyx +166 -0
  90. sage/modular/hypergeometric_motive.py +2017 -0
  91. sage/modular/local_comp/all.py +2 -0
  92. sage/modular/local_comp/liftings.py +292 -0
  93. sage/modular/local_comp/local_comp.py +1071 -0
  94. sage/modular/local_comp/smoothchar.py +1825 -0
  95. sage/modular/local_comp/type_space.py +748 -0
  96. sage/modular/modform/all.py +30 -0
  97. sage/modular/modform/ambient.py +815 -0
  98. sage/modular/modform/ambient_R.py +177 -0
  99. sage/modular/modform/ambient_eps.py +306 -0
  100. sage/modular/modform/ambient_g0.py +124 -0
  101. sage/modular/modform/ambient_g1.py +204 -0
  102. sage/modular/modform/constructor.py +545 -0
  103. sage/modular/modform/cuspidal_submodule.py +708 -0
  104. sage/modular/modform/defaults.py +14 -0
  105. sage/modular/modform/eis_series.py +505 -0
  106. sage/modular/modform/eisenstein_submodule.py +663 -0
  107. sage/modular/modform/element.py +4131 -0
  108. sage/modular/modform/find_generators.py +59 -0
  109. sage/modular/modform/half_integral.py +154 -0
  110. sage/modular/modform/hecke_operator_on_qexp.py +247 -0
  111. sage/modular/modform/j_invariant.py +47 -0
  112. sage/modular/modform/l_series_gross_zagier.py +133 -0
  113. sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314-darwin.so +0 -0
  114. sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
  115. sage/modular/modform/notes.py +45 -0
  116. sage/modular/modform/numerical.py +514 -0
  117. sage/modular/modform/periods.py +14 -0
  118. sage/modular/modform/ring.py +1257 -0
  119. sage/modular/modform/space.py +1860 -0
  120. sage/modular/modform/submodule.py +118 -0
  121. sage/modular/modform/tests.py +64 -0
  122. sage/modular/modform/theta.py +110 -0
  123. sage/modular/modform/vm_basis.py +381 -0
  124. sage/modular/modform/weight1.py +220 -0
  125. sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
  126. sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
  127. sage/modular/modform_hecketriangle/all.py +30 -0
  128. sage/modular/modform_hecketriangle/analytic_type.py +590 -0
  129. sage/modular/modform_hecketriangle/constructor.py +416 -0
  130. sage/modular/modform_hecketriangle/element.py +351 -0
  131. sage/modular/modform_hecketriangle/functors.py +752 -0
  132. sage/modular/modform_hecketriangle/graded_ring.py +541 -0
  133. sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
  134. sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
  135. sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
  136. sage/modular/modform_hecketriangle/readme.py +1214 -0
  137. sage/modular/modform_hecketriangle/series_constructor.py +580 -0
  138. sage/modular/modform_hecketriangle/space.py +1037 -0
  139. sage/modular/modform_hecketriangle/subspace.py +423 -0
  140. sage/modular/modsym/all.py +17 -0
  141. sage/modular/modsym/ambient.py +3846 -0
  142. sage/modular/modsym/boundary.py +1420 -0
  143. sage/modular/modsym/element.py +336 -0
  144. sage/modular/modsym/g1list.py +178 -0
  145. sage/modular/modsym/ghlist.py +182 -0
  146. sage/modular/modsym/hecke_operator.py +73 -0
  147. sage/modular/modsym/manin_symbol.cpython-314-darwin.so +0 -0
  148. sage/modular/modsym/manin_symbol.pxd +5 -0
  149. sage/modular/modsym/manin_symbol.pyx +497 -0
  150. sage/modular/modsym/manin_symbol_list.py +1295 -0
  151. sage/modular/modsym/modsym.py +400 -0
  152. sage/modular/modsym/modular_symbols.py +384 -0
  153. sage/modular/modsym/p1list.cpython-314-darwin.so +0 -0
  154. sage/modular/modsym/p1list.pxd +29 -0
  155. sage/modular/modsym/p1list.pyx +1372 -0
  156. sage/modular/modsym/p1list_nf.py +1241 -0
  157. sage/modular/modsym/relation_matrix.py +591 -0
  158. sage/modular/modsym/relation_matrix_pyx.cpython-314-darwin.so +0 -0
  159. sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
  160. sage/modular/modsym/space.py +2468 -0
  161. sage/modular/modsym/subspace.py +455 -0
  162. sage/modular/modsym/tests.py +375 -0
  163. sage/modular/multiple_zeta.py +2632 -0
  164. sage/modular/multiple_zeta_F_algebra.py +786 -0
  165. sage/modular/overconvergent/all.py +6 -0
  166. sage/modular/overconvergent/genus0.py +1878 -0
  167. sage/modular/overconvergent/hecke_series.py +1187 -0
  168. sage/modular/overconvergent/weightspace.py +778 -0
  169. sage/modular/pollack_stevens/all.py +4 -0
  170. sage/modular/pollack_stevens/distributions.py +874 -0
  171. sage/modular/pollack_stevens/fund_domain.py +1572 -0
  172. sage/modular/pollack_stevens/manin_map.py +859 -0
  173. sage/modular/pollack_stevens/modsym.py +1593 -0
  174. sage/modular/pollack_stevens/padic_lseries.py +417 -0
  175. sage/modular/pollack_stevens/sigma0.py +534 -0
  176. sage/modular/pollack_stevens/space.py +1076 -0
  177. sage/modular/quasimodform/all.py +3 -0
  178. sage/modular/quasimodform/element.py +845 -0
  179. sage/modular/quasimodform/ring.py +828 -0
  180. sage/modular/quatalg/all.py +3 -0
  181. sage/modular/quatalg/brandt.py +1642 -0
  182. sage/modular/ssmod/all.py +8 -0
  183. sage/modular/ssmod/ssmod.py +827 -0
  184. sage/rings/all__sagemath_schemes.py +1 -0
  185. sage/rings/polynomial/all__sagemath_schemes.py +1 -0
  186. sage/rings/polynomial/binary_form_reduce.py +585 -0
  187. sage/schemes/all.py +41 -0
  188. sage/schemes/berkovich/all.py +6 -0
  189. sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
  190. sage/schemes/berkovich/berkovich_space.py +748 -0
  191. sage/schemes/curves/affine_curve.py +2928 -0
  192. sage/schemes/curves/all.py +33 -0
  193. sage/schemes/curves/closed_point.py +434 -0
  194. sage/schemes/curves/constructor.py +381 -0
  195. sage/schemes/curves/curve.py +542 -0
  196. sage/schemes/curves/plane_curve_arrangement.py +1283 -0
  197. sage/schemes/curves/point.py +463 -0
  198. sage/schemes/curves/projective_curve.py +3026 -0
  199. sage/schemes/curves/zariski_vankampen.py +1932 -0
  200. sage/schemes/cyclic_covers/all.py +2 -0
  201. sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
  202. sage/schemes/cyclic_covers/constructor.py +137 -0
  203. sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
  204. sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
  205. sage/schemes/elliptic_curves/BSD.py +1036 -0
  206. sage/schemes/elliptic_curves/Qcurves.py +592 -0
  207. sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
  208. sage/schemes/elliptic_curves/all.py +49 -0
  209. sage/schemes/elliptic_curves/cardinality.py +609 -0
  210. sage/schemes/elliptic_curves/cm.py +1102 -0
  211. sage/schemes/elliptic_curves/constructor.py +1552 -0
  212. sage/schemes/elliptic_curves/ec_database.py +175 -0
  213. sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
  214. sage/schemes/elliptic_curves/ell_egros.py +459 -0
  215. sage/schemes/elliptic_curves/ell_field.py +2836 -0
  216. sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
  217. sage/schemes/elliptic_curves/ell_generic.py +3760 -0
  218. sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
  219. sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
  220. sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
  221. sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
  222. sage/schemes/elliptic_curves/ell_point.py +4787 -0
  223. sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
  224. sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
  225. sage/schemes/elliptic_curves/ell_torsion.py +436 -0
  226. sage/schemes/elliptic_curves/ell_wp.py +352 -0
  227. sage/schemes/elliptic_curves/formal_group.py +760 -0
  228. sage/schemes/elliptic_curves/gal_reps.py +1459 -0
  229. sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
  230. sage/schemes/elliptic_curves/gp_simon.py +152 -0
  231. sage/schemes/elliptic_curves/heegner.py +7335 -0
  232. sage/schemes/elliptic_curves/height.py +2109 -0
  233. sage/schemes/elliptic_curves/hom.py +1406 -0
  234. sage/schemes/elliptic_curves/hom_composite.py +934 -0
  235. sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
  236. sage/schemes/elliptic_curves/hom_scalar.py +531 -0
  237. sage/schemes/elliptic_curves/hom_sum.py +682 -0
  238. sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
  239. sage/schemes/elliptic_curves/homset.py +271 -0
  240. sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
  241. sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
  242. sage/schemes/elliptic_curves/jacobian.py +237 -0
  243. sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
  244. sage/schemes/elliptic_curves/kraus.py +1014 -0
  245. sage/schemes/elliptic_curves/lseries_ell.py +943 -0
  246. sage/schemes/elliptic_curves/mod5family.py +105 -0
  247. sage/schemes/elliptic_curves/mod_poly.py +197 -0
  248. sage/schemes/elliptic_curves/mod_sym_num.cpython-314-darwin.so +0 -0
  249. sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
  250. sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
  251. sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
  252. sage/schemes/elliptic_curves/padics.py +1816 -0
  253. sage/schemes/elliptic_curves/period_lattice.py +2234 -0
  254. sage/schemes/elliptic_curves/period_lattice_region.cpython-314-darwin.so +0 -0
  255. sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
  256. sage/schemes/elliptic_curves/saturation.py +715 -0
  257. sage/schemes/elliptic_curves/sha_tate.py +1158 -0
  258. sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
  259. sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
  260. sage/schemes/hyperelliptic_curves/all.py +6 -0
  261. sage/schemes/hyperelliptic_curves/constructor.py +291 -0
  262. sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
  263. sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
  264. sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
  265. sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
  266. sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
  267. sage/schemes/hyperelliptic_curves/invariants.py +410 -0
  268. sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
  269. sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
  270. sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
  271. sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
  272. sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
  273. sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
  274. sage/schemes/hyperelliptic_curves/mestre.py +302 -0
  275. sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
  276. sage/schemes/jacobians/abstract_jacobian.py +277 -0
  277. sage/schemes/jacobians/all.py +2 -0
  278. sage/schemes/overview.py +161 -0
  279. sage/schemes/plane_conics/all.py +22 -0
  280. sage/schemes/plane_conics/con_field.py +1296 -0
  281. sage/schemes/plane_conics/con_finite_field.py +158 -0
  282. sage/schemes/plane_conics/con_number_field.py +456 -0
  283. sage/schemes/plane_conics/con_rational_field.py +406 -0
  284. sage/schemes/plane_conics/con_rational_function_field.py +580 -0
  285. sage/schemes/plane_conics/constructor.py +249 -0
  286. sage/schemes/plane_quartics/all.py +2 -0
  287. sage/schemes/plane_quartics/quartic_constructor.py +71 -0
  288. sage/schemes/plane_quartics/quartic_generic.py +73 -0
  289. sage/schemes/riemann_surfaces/all.py +1 -0
  290. sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
  291. sage_wheels/share/cremona/cremona_mini.db +0 -0
  292. sage_wheels/share/ellcurves/rank0 +30427 -0
  293. sage_wheels/share/ellcurves/rank1 +31871 -0
  294. sage_wheels/share/ellcurves/rank10 +6 -0
  295. sage_wheels/share/ellcurves/rank11 +6 -0
  296. sage_wheels/share/ellcurves/rank12 +1 -0
  297. sage_wheels/share/ellcurves/rank14 +1 -0
  298. sage_wheels/share/ellcurves/rank15 +1 -0
  299. sage_wheels/share/ellcurves/rank17 +1 -0
  300. sage_wheels/share/ellcurves/rank19 +1 -0
  301. sage_wheels/share/ellcurves/rank2 +2388 -0
  302. sage_wheels/share/ellcurves/rank20 +1 -0
  303. sage_wheels/share/ellcurves/rank21 +1 -0
  304. sage_wheels/share/ellcurves/rank22 +1 -0
  305. sage_wheels/share/ellcurves/rank23 +1 -0
  306. sage_wheels/share/ellcurves/rank24 +1 -0
  307. sage_wheels/share/ellcurves/rank28 +1 -0
  308. sage_wheels/share/ellcurves/rank3 +836 -0
  309. sage_wheels/share/ellcurves/rank4 +10 -0
  310. sage_wheels/share/ellcurves/rank5 +5 -0
  311. sage_wheels/share/ellcurves/rank6 +5 -0
  312. sage_wheels/share/ellcurves/rank7 +5 -0
  313. sage_wheels/share/ellcurves/rank8 +6 -0
  314. sage_wheels/share/ellcurves/rank9 +7 -0
@@ -0,0 +1,591 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ # sage.doctest: needs sage.libs.flint
3
+ """
4
+ Relation matrices for ambient modular symbols spaces
5
+
6
+ This file contains functions that are used by the various ambient modular
7
+ symbols classes to compute presentations of spaces in terms of generators and
8
+ relations, using the standard methods based on Manin symbols.
9
+ """
10
+ # ****************************************************************************
11
+ # Sage: Open Source Mathematical Software
12
+ #
13
+ # Copyright (C) 2005 William Stein <wstein@gmail.com>
14
+ #
15
+ # Distributed under the terms of the GNU General Public License (GPL)
16
+ #
17
+ # This code is distributed in the hope that it will be useful,
18
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20
+ # General Public License for more details.
21
+ #
22
+ # The full text of the GPL is available at:
23
+ #
24
+ # https://www.gnu.org/licenses/
25
+ # ****************************************************************************
26
+
27
+ from sage.matrix.matrix_space import MatrixSpace
28
+ from sage.misc.search import search
29
+ from sage.misc.verbose import verbose
30
+ from sage.modular.modsym.manin_symbol_list import ManinSymbolList
31
+ from sage.rings.rational_field import RationalField
32
+ from sage.categories.rings import Rings
33
+
34
+
35
+ SPARSE = True
36
+
37
+ # S = [0,-1; 1,0]
38
+ # T = [0,-1; 1,-1],
39
+ # T^2 = [-1, 1, -1, 0]
40
+ # I = [-1,0; 0,1]
41
+
42
+
43
+ ######################################################################
44
+ # The following four functions are used to compute the quotient
45
+ # modulo the S, I, and T relations more efficiently that the generic
46
+ # code in the relation_matrix file:
47
+ # modS_relations -- compute the S relations.
48
+ # modI_quotient -- compute the I relations.
49
+ # T_relation_matrix -- matrix whose echelon form gives
50
+ # the quotient by 3-term T relations.
51
+ # gens_to_basis_matrix -- compute echelon form of 3-term
52
+ # relation matrix, and read off each
53
+ # generator in terms of basis.
54
+ # These four functions are orchestrated in the function
55
+ # compute_presentation
56
+ # which is defined below. See the comment at the beginning
57
+ # of that function for an overall description of the algorithm.
58
+ ######################################################################
59
+
60
+
61
+ def modS_relations(syms):
62
+ r"""
63
+ Compute quotient of Manin symbols by the S relations.
64
+
65
+ Here S is the 2x2 matrix [0, -1; 1, 0].
66
+
67
+ INPUT:
68
+
69
+ - ``syms`` -- :class:`ManinSymbolList`
70
+
71
+ OUTPUT:
72
+
73
+ - ``rels`` -- set of pairs of pairs (j, s), where if
74
+ mod[i] = (j,s), then x_i = s\*x_j (mod S relations)
75
+
76
+ EXAMPLES::
77
+
78
+ sage: from sage.modular.modsym.manin_symbol_list import ManinSymbolList_gamma0
79
+ sage: from sage.modular.modsym.relation_matrix import modS_relations
80
+
81
+ ::
82
+
83
+ sage: syms = ManinSymbolList_gamma0(2, 4); syms
84
+ Manin Symbol List of weight 4 for Gamma0(2)
85
+ sage: modS_relations(syms)
86
+ {((0, 1), (7, 1)),
87
+ ((1, 1), (6, 1)),
88
+ ((2, 1), (8, 1)),
89
+ ((3, -1), (4, 1)),
90
+ ((3, 1), (4, -1)),
91
+ ((5, -1), (5, 1))}
92
+
93
+ ::
94
+
95
+ sage: syms = ManinSymbolList_gamma0(7, 2); syms
96
+ Manin Symbol List of weight 2 for Gamma0(7)
97
+ sage: modS_relations(syms)
98
+ {((0, 1), (1, 1)), ((2, 1), (7, 1)), ((3, 1), (4, 1)), ((5, 1), (6, 1))}
99
+
100
+ Next we do an example with Gamma1::
101
+
102
+ sage: from sage.modular.modsym.manin_symbol_list import ManinSymbolList_gamma1
103
+ sage: syms = ManinSymbolList_gamma1(3,2); syms
104
+ Manin Symbol List of weight 2 for Gamma1(3)
105
+ sage: modS_relations(syms)
106
+ {((0, 1), (2, 1)),
107
+ ((0, 1), (5, 1)),
108
+ ((1, 1), (2, 1)),
109
+ ((1, 1), (5, 1)),
110
+ ((3, 1), (4, 1)),
111
+ ((3, 1), (6, 1)),
112
+ ((4, 1), (7, 1)),
113
+ ((6, 1), (7, 1))}
114
+ """
115
+ if not isinstance(syms, ManinSymbolList):
116
+ raise TypeError("syms must be a ManinSymbolList")
117
+ tm = verbose()
118
+ # We will fill in this set with the relations x_i + s*x_j = 0,
119
+ # where the notation is as in _sparse_2term_quotient.
120
+ rels = set()
121
+ for i in range(len(syms)):
122
+ j, s = syms.apply_S(i)
123
+ assert j != -1
124
+ if i < j:
125
+ rels.add(((i, 1), (j, s)))
126
+ else:
127
+ rels.add(((j, s), (i, 1)))
128
+ verbose("finished creating S relations", tm)
129
+ return rels
130
+
131
+
132
+ def modI_relations(syms, sign):
133
+ r"""
134
+ Compute quotient of Manin symbols by the I relations.
135
+
136
+ INPUT:
137
+
138
+ - ``syms`` -- :class:`ManinSymbolList`
139
+
140
+ - ``sign`` -- integer (either -1, 0, or 1)
141
+
142
+ OUTPUT:
143
+
144
+ - ``rels`` -- set of pairs of pairs (j, s), where if
145
+ mod[i] = (j,s), then x_i = s\*x_j (mod S relations)
146
+
147
+ EXAMPLES::
148
+
149
+ sage: L = sage.modular.modsym.manin_symbol_list.ManinSymbolList_gamma1(4, 3)
150
+ sage: sage.modular.modsym.relation_matrix.modI_relations(L, 1)
151
+ {((0, 1), (0, -1)),
152
+ ((1, 1), (1, -1)),
153
+ ((2, 1), (8, -1)),
154
+ ((3, 1), (9, -1)),
155
+ ((4, 1), (10, -1)),
156
+ ((5, 1), (11, -1)),
157
+ ((6, 1), (6, -1)),
158
+ ((7, 1), (7, -1)),
159
+ ((8, 1), (2, -1)),
160
+ ((9, 1), (3, -1)),
161
+ ((10, 1), (4, -1)),
162
+ ((11, 1), (5, -1)),
163
+ ((12, 1), (12, 1)),
164
+ ((13, 1), (13, 1)),
165
+ ((14, 1), (20, 1)),
166
+ ((15, 1), (21, 1)),
167
+ ((16, 1), (22, 1)),
168
+ ((17, 1), (23, 1)),
169
+ ((18, 1), (18, 1)),
170
+ ((19, 1), (19, 1)),
171
+ ((20, 1), (14, 1)),
172
+ ((21, 1), (15, 1)),
173
+ ((22, 1), (16, 1)),
174
+ ((23, 1), (17, 1))}
175
+
176
+ .. warning::
177
+
178
+ We quotient by the involution eta((u,v)) = (-u,v), which has
179
+ the opposite sign as the involution in Merel's Springer LNM
180
+ 1585 paper! Thus our +1 eigenspace is his -1 eigenspace,
181
+ etc. We do this for consistency with MAGMA.
182
+ """
183
+ tm = verbose()
184
+ # We will fill in this set with the relations x_i - sign*s*x_j = 0,
185
+ # where the notation is as in _sparse_2term_quotient.
186
+ rels = set()
187
+ for i in range(len(syms)):
188
+ j, s = syms.apply_I(i)
189
+ assert j != -1
190
+ rels.add(((i, 1), (j, -sign * s)))
191
+ verbose("finished creating I relations", tm)
192
+ return rels
193
+
194
+
195
+ def T_relation_matrix_wtk_g0(syms, mod, field, sparse):
196
+ r"""
197
+ Compute a matrix whose echelon form gives the quotient by 3-term T
198
+ relations. Despite the name, this is used for all modular symbols spaces
199
+ (including those with character and those for `\Gamma_1` and `\Gamma_H`
200
+ groups), not just `\Gamma_0`.
201
+
202
+ INPUT:
203
+
204
+ - ``syms`` -- :class:`ManinSymbolList`
205
+
206
+ - ``mod`` -- list that gives quotient modulo some two-term relations, i.e.,
207
+ the S relations, and if sign is nonzero, the I relations
208
+
209
+ - ``field`` -- ``base_ring``
210
+
211
+ - ``sparse`` -- boolean; whether to use sparse rather than dense
212
+ linear algebra
213
+
214
+ OUTPUT: a sparse matrix whose rows correspond to the reduction of
215
+ the `T` relations modulo the `S` and `I` relations.
216
+
217
+ EXAMPLES::
218
+
219
+ sage: from sage.modular.modsym.relation_matrix import sparse_2term_quotient, T_relation_matrix_wtk_g0, modS_relations
220
+ sage: L = sage.modular.modsym.manin_symbol_list.ManinSymbolList_gamma_h(GammaH(36, [17,19]), 2)
221
+ sage: modS = sparse_2term_quotient(modS_relations(L), 216, QQ)
222
+ sage: T_relation_matrix_wtk_g0(L, modS, QQ, False)
223
+ 72 x 216 dense matrix over Rational Field (use the '.str()' method to see the entries)
224
+ sage: T_relation_matrix_wtk_g0(L, modS, GF(17), True)
225
+ 72 x 216 sparse matrix over Finite Field of size 17 (use the '.str()' method to see the entries)
226
+ """
227
+ tm = verbose()
228
+ row = 0
229
+ entries = {}
230
+ already_seen = set()
231
+ w = syms.weight()
232
+ for i in range(len(syms)):
233
+ if i in already_seen:
234
+ continue
235
+ iT_plus_iTT = syms.apply_T(i) + syms.apply_TT(i)
236
+ j0, s0 = mod[i]
237
+ v = {j0: s0}
238
+ for j, s in iT_plus_iTT:
239
+ if w == 2:
240
+ already_seen.add(j)
241
+ j0, s0 = mod[j]
242
+ s0 = s * s0
243
+ if j0 in v:
244
+ v[j0] += s0
245
+ else:
246
+ v[j0] = s0
247
+ for j0, vj0 in v.items():
248
+ entries[(row, j0)] = vj0
249
+ row += 1
250
+
251
+ MAT = MatrixSpace(field, row, len(syms), sparse=True)
252
+ R = MAT(entries)
253
+ if not sparse:
254
+ R = R.dense_matrix()
255
+ verbose("finished (number of rows=%s)" % row, tm)
256
+ return R
257
+
258
+
259
+ def gens_to_basis_matrix(syms, relation_matrix, mod, field, sparse):
260
+ """
261
+ Compute echelon form of 3-term relation matrix, and read off each
262
+ generator in terms of basis.
263
+
264
+ INPUT:
265
+
266
+ - ``syms`` -- :class:`ManinSymbolList`
267
+
268
+ - ``relation_matrix`` -- as output by
269
+ ``__compute_T_relation_matrix(self, mod)``
270
+
271
+ - ``mod`` -- quotient of modular symbols modulo the
272
+ 2-term S (and possibly I) relations
273
+
274
+ - ``field`` -- base field
275
+
276
+ - ``sparse`` -- boolean; whether or not matrix should be sparse
277
+
278
+ OUTPUT:
279
+
280
+ ``matrix`` -- a matrix whose `i`-th row expresses the Manin symbol
281
+ generators in terms of a basis of Manin symbols (modulo the S, (possibly
282
+ I,) and T rels). Note that the entries of the matrix need not be integers.
283
+
284
+ - ``list`` -- integers `i`, such that the Manin symbols `x_i` are a basis
285
+
286
+ EXAMPLES::
287
+
288
+ sage: from sage.modular.modsym.relation_matrix import sparse_2term_quotient, T_relation_matrix_wtk_g0, gens_to_basis_matrix, modS_relations
289
+ sage: L = sage.modular.modsym.manin_symbol_list.ManinSymbolList_gamma1(4, 3)
290
+ sage: modS = sparse_2term_quotient(modS_relations(L), 24, GF(3))
291
+ sage: gens_to_basis_matrix(L, T_relation_matrix_wtk_g0(L, modS, GF(3), 24), modS, GF(3), True)
292
+ (24 x 2 sparse matrix over Finite Field of size 3, [13, 23])
293
+ """
294
+ from sage.structure.element import Matrix
295
+ if not isinstance(relation_matrix, Matrix):
296
+ raise TypeError("relation_matrix must be a matrix")
297
+ if not isinstance(mod, list):
298
+ raise TypeError("mod must be a list")
299
+
300
+ verbose(str(relation_matrix.parent()))
301
+
302
+ try:
303
+ h = relation_matrix.height()
304
+ except AttributeError:
305
+ h = 9999999
306
+ tm = verbose("putting relation matrix in echelon form (height = %s)" % h)
307
+ if h < 10:
308
+ A = relation_matrix.echelon_form(algorithm='multimodular',
309
+ height_guess=1)
310
+ else:
311
+ A = relation_matrix.echelon_form()
312
+ A.set_immutable()
313
+ tm = verbose('finished echelon', tm)
314
+
315
+ tm = verbose("Now creating gens --> basis mapping")
316
+
317
+ basis_set = set(A.nonpivots())
318
+ pivots = A.pivots()
319
+
320
+ basis_mod2 = {j for j, c in mod if c != 0}
321
+
322
+ basis_set = basis_set.intersection(basis_mod2)
323
+ basis = sorted(basis_set)
324
+
325
+ ONE = field(1)
326
+
327
+ verbose("done doing setup", tm)
328
+
329
+ tm = verbose("now forming quotient matrix")
330
+ M = MatrixSpace(field, len(syms), len(basis), sparse=sparse)
331
+
332
+ B = M(0)
333
+ cols_index = {basis[i]: i for i in range(len(basis))}
334
+
335
+ for i in basis_mod2:
336
+ t, l = search(basis, i)
337
+ if t:
338
+ B[i, l] = ONE
339
+ else:
340
+ _, r = search(pivots, i) # so pivots[r] = i
341
+ # Set row i to -(row r of A), but where we only take
342
+ # the non-pivot columns of A:
343
+ B._set_row_to_negative_of_row_of_A_using_subset_of_columns(i, A, r, basis, cols_index)
344
+
345
+ verbose("done making quotient matrix", tm)
346
+
347
+ # The following is very fast (over Q at least).
348
+ tm = verbose('now filling in the rest of the matrix')
349
+ k = 0
350
+ for i in range(len(mod)):
351
+ j, s = mod[i]
352
+ if j != i and s != 0: # ignored in the above matrix
353
+ k += 1
354
+ B.set_row_to_multiple_of_row(i, j, s)
355
+ verbose("set %s rows" % k)
356
+ tm = verbose("time to fill in rest of matrix", tm)
357
+
358
+ return B, basis
359
+
360
+
361
+ def compute_presentation(syms, sign, field, sparse=None):
362
+ r"""
363
+ Compute the presentation for self, as a quotient of Manin symbols
364
+ modulo relations.
365
+
366
+ INPUT:
367
+
368
+ - ``syms`` -- :class:`ManinSymbolList`
369
+
370
+ - ``sign`` -- integer (-1, 0, 1)
371
+
372
+ - ``field`` -- a field
373
+
374
+ OUTPUT:
375
+
376
+ - sparse matrix whose rows give each generator
377
+ in terms of a basis for the quotient
378
+
379
+ - list of integers that give the basis for the
380
+ quotient
381
+
382
+ - mod: list where mod[i]=(j,s) means that x_i
383
+ = s\*x_j modulo the 2-term S (and possibly I) relations.
384
+
385
+
386
+ ALGORITHM:
387
+
388
+ #. Let `S = [0,-1; 1,0], T = [0,-1; 1,-1]`, and
389
+ `I = [-1,0; 0,1]`.
390
+
391
+ #. Let `x_0,\ldots, x_{n-1}` by a list of all
392
+ non-equivalent Manin symbols.
393
+
394
+ #. Form quotient by 2-term S and (possibly) I relations.
395
+
396
+ #. Create a sparse matrix `A` with `m` columns,
397
+ whose rows encode the relations
398
+
399
+ .. MATH::
400
+
401
+ [x_i] + [x_i T] + [x_i T^2] = 0.
402
+
403
+
404
+ There are about n such rows. The number of nonzero entries per row
405
+ is at most 3\*(k-1). Note that we must include rows for *all* i,
406
+ since even if `[x_i] = [x_j]`, it need not be the case
407
+ that `[x_i T] = [x_j T]`, since `S` and
408
+ `T` do not commute. However, in many cases we have an a
409
+ priori formula for the dimension of the quotient by all these
410
+ relations, so we can omit many relations and just check that there
411
+ are enough at the end--if there aren't, we add in more.
412
+
413
+ #. Compute the reduced row echelon form of `A` using sparse
414
+ Gaussian elimination.
415
+
416
+ #. Use what we've done above to read off a sparse matrix R that
417
+ uniquely expresses each of the n Manin symbols in terms of a subset
418
+ of Manin symbols, modulo the relations. This subset of Manin
419
+ symbols is a basis for the quotient by the relations.
420
+
421
+ EXAMPLES::
422
+
423
+ sage: L = sage.modular.modsym.manin_symbol_list.ManinSymbolList_gamma0(8,2)
424
+ sage: sage.modular.modsym.relation_matrix.compute_presentation(L, 1, GF(9,'a'), True)
425
+ (
426
+ [2 0 0]
427
+ [1 0 0]
428
+ [0 0 0]
429
+ [0 2 0]
430
+ [0 0 0]
431
+ [0 0 2]
432
+ [0 0 0]
433
+ [0 2 0]
434
+ [0 0 0]
435
+ [0 1 0]
436
+ [0 1 0]
437
+ [0 0 1], [1, 9, 11], [(1, 2), (1, 1), (0, 0), (9, 2), (0, 0), (11, 2), (0, 0), (9, 2), (0, 0), (9, 1), (9, 1), (11, 1)]
438
+ )
439
+ """
440
+ if sparse is None:
441
+ if syms.weight() >= 6:
442
+ sparse = False
443
+ else:
444
+ sparse = True
445
+ R, mod = relation_matrix_wtk_g0(syms, sign, field, sparse)
446
+ B, basis = gens_to_basis_matrix(syms, R, mod, field, sparse)
447
+ return B, basis, mod
448
+
449
+
450
+ def relation_matrix_wtk_g0(syms, sign, field, sparse):
451
+ r"""
452
+ Compute the matrix of relations. Despite the name, this is used for all
453
+ spaces (not just for Gamma0). For a description of the algorithm, see the
454
+ docstring for ``compute_presentation``.
455
+
456
+ INPUT:
457
+
458
+ - ``syms`` -- :class:`ManinSymbolList`
459
+
460
+ - ``sign`` -- integer (0, 1 or -1)
461
+
462
+ - ``field`` -- the base field (non-field base rings not supported at present)
463
+
464
+ - ``sparse`` -- boolean; whether to use sparse arithmetic
465
+
466
+ Note that ManinSymbolList objects already have a specific weight, so there
467
+ is no need for an extra ``weight`` parameter.
468
+
469
+ OUTPUT: a pair (R, mod) where
470
+
471
+ - R is a matrix as output by ``T_relation_matrix_wtk_g0``
472
+
473
+ - mod is a set of 2-term relations as output by ``sparse_2term_quotient``
474
+
475
+ EXAMPLES::
476
+
477
+ sage: L = sage.modular.modsym.manin_symbol_list.ManinSymbolList_gamma0(8,2)
478
+ sage: A = sage.modular.modsym.relation_matrix.relation_matrix_wtk_g0(L, 0, GF(2), True); A
479
+ (
480
+ [0 0 0 0 0 0 0 0 1 0 0 0]
481
+ [0 0 0 0 0 0 0 0 1 1 1 0]
482
+ [0 0 0 0 0 0 1 0 0 1 1 0]
483
+ [0 0 0 0 0 0 1 0 0 0 0 0], [(1, 1), (1, 1), (8, 1), (10, 1), (6, 1), (11, 1), (6, 1), (9, 1), (8, 1), (9, 1), (10, 1), (11, 1)]
484
+ )
485
+ sage: A[0].is_sparse()
486
+ True
487
+ """
488
+ rels = modS_relations(syms)
489
+ if sign != 0:
490
+ # Let rels = rels union I relations.
491
+ rels.update(modI_relations(syms, sign))
492
+
493
+ rels = sorted(rels)
494
+ # required for stability of doctests with python3
495
+
496
+ if syms._apply_S_only_0pm1() and isinstance(field, RationalField):
497
+ from . import relation_matrix_pyx
498
+ mod = relation_matrix_pyx.sparse_2term_quotient_only_pm1(rels, len(syms))
499
+ else:
500
+ mod = sparse_2term_quotient(rels, len(syms), field)
501
+
502
+ R = T_relation_matrix_wtk_g0(syms, mod, field, sparse)
503
+ return R, mod
504
+
505
+
506
+ def sparse_2term_quotient(rels, n, F):
507
+ r"""
508
+ Perform Sparse Gauss elimination on a matrix all of whose columns
509
+ have at most 2 nonzero entries. We use an obvious algorithm, which
510
+ runs fast enough. (Typically making the list of relations takes
511
+ more time than computing this quotient.) This algorithm is more
512
+ subtle than just "identify symbols in pairs", since complicated
513
+ relations can cause generators to surprisingly equal 0.
514
+
515
+ INPUT:
516
+
517
+ - ``rels`` -- iterable made of pairs ((i,s), (j,t)). The pair
518
+ represents the relation `s x_i + t x_j = 0`, where the `i, j` must
519
+ be Python int's.
520
+
521
+ - ``n`` -- integer, the `x_i` are `x_0, \ldots, x_{n-1}`
522
+
523
+ - ``F`` -- base field
524
+
525
+ OUTPUT:
526
+
527
+ ``mod`` -- list such that ``mod[i] = (j,s)``, which means that `x_i` is
528
+ equivalent to `s x_j`, where the `x_j` are a basis for the quotient.
529
+
530
+ EXAMPLES: We quotient out by the relations
531
+
532
+ .. MATH::
533
+
534
+ 3*x0 - x1 = 0,\qquad x1 + x3 = 0,\qquad x2 + x3 = 0,\qquad x4 - x5 = 0
535
+
536
+ to get::
537
+
538
+ sage: rels = [((int(0),3), (int(1),-1)), ((int(1),1), (int(3),1)), ((int(2),1),(int(3),1)), ((int(4),1),(int(5),-1))]
539
+ sage: n = 6
540
+ sage: from sage.modular.modsym.relation_matrix import sparse_2term_quotient
541
+ sage: sparse_2term_quotient(rels, n, QQ)
542
+ [(3, -1/3), (3, -1), (3, -1), (3, 1), (5, 1), (5, 1)]
543
+ """
544
+ n = int(n)
545
+ if F not in Rings():
546
+ raise TypeError("F must be a ring")
547
+
548
+ tm = verbose("Starting sparse 2-term quotient...")
549
+ free = list(range(n))
550
+ ONE = F.one()
551
+ ZERO = F.zero()
552
+ coef = [ONE for i in range(n)]
553
+ related_to_me = [[] for i in range(n)]
554
+ for v0, v1 in sorted(rels):
555
+ c0 = coef[v0[0]] * F(v0[1])
556
+ c1 = coef[v1[0]] * F(v1[1])
557
+
558
+ # Mod out by the following relation:
559
+ #
560
+ # c0*free[v0[0]] + c1*free[v1[0]] = 0.
561
+ #
562
+ die = None
563
+ if c0 == ZERO and c1 == ZERO:
564
+ pass
565
+ elif c0 == ZERO and c1 != ZERO: # free[v1[0]] --> 0
566
+ die = free[v1[0]]
567
+ elif c1 == ZERO and c0 != ZERO:
568
+ die = free[v0[0]]
569
+ elif free[v0[0]] == free[v1[0]]:
570
+ if c0 + c1 != 0:
571
+ # all xi equal to free[v0[0]] must now equal to zero.
572
+ die = free[v0[0]]
573
+ else: # x1 = -c1/c0 * x2.
574
+ x = free[v0[0]]
575
+ free[x] = free[v1[0]]
576
+ coef[x] = -c1 / c0
577
+ for i in related_to_me[x]:
578
+ free[i] = free[x]
579
+ coef[i] *= coef[x]
580
+ related_to_me[free[v1[0]]].append(i)
581
+ related_to_me[free[v1[0]]].append(x)
582
+ if die is not None:
583
+ for i in related_to_me[die]:
584
+ free[i] = 0
585
+ coef[i] = ZERO
586
+ free[die] = 0
587
+ coef[die] = ZERO
588
+
589
+ mod = [(free[i], coef[i]) for i in range(len(free))]
590
+ verbose("finished", tm)
591
+ return mod
@@ -0,0 +1,108 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ """
3
+ Optimized computing of relation matrices in certain cases
4
+ """
5
+
6
+ #############################################################################
7
+ # Copyright (C) 2010 William Stein <wstein@gmail.com>
8
+ # Distributed under the terms of the GNU General Public License (GPL) v2+.
9
+ # The full text of the GPL is available at:
10
+ # https://www.gnu.org/licenses/
11
+ #############################################################################
12
+
13
+ from sage.misc.verbose import verbose
14
+ from sage.rings.rational cimport Rational
15
+
16
+
17
+ def sparse_2term_quotient_only_pm1(rels, n):
18
+ r"""
19
+ Perform Sparse Gauss elimination on a matrix all of whose columns
20
+ have at most 2 nonzero entries with relations all 1 or -1.
21
+
22
+ This algorithm is more subtle than just "identify symbols in pairs",
23
+ since complicated relations can cause generators to equal 0.
24
+
25
+ .. NOTE::
26
+
27
+ Note the condition on the s,t coefficients in the relations
28
+ being 1 or -1 for this optimized function. There is a more
29
+ general function in relation_matrix.py, which is much, much
30
+ slower.
31
+
32
+ INPUT:
33
+
34
+ - ``rels`` -- iterable made of pairs ((i,s), (j,t)). The pair
35
+ represents the relation `s x_i + t x_j = 0`, where the `i, j` must
36
+ be Python int's, and the `s, t` must all be 1 or -1.
37
+
38
+ - ``n`` -- integer; the `x_i` are `x_0, \ldots, x_{n-1}`
39
+
40
+ OUTPUT:
41
+
42
+ - ``mod`` -- list such that mod[i] = (j,s), which means that x_i
43
+ is equivalent to s*x_j, where the x_j are a basis for the
44
+ quotient.
45
+
46
+ The output depends on the order of the input.
47
+
48
+ EXAMPLES::
49
+
50
+ sage: from sage.modular.modsym.relation_matrix_pyx import sparse_2term_quotient_only_pm1
51
+ sage: rels = [((0,1), (1,-1)), ((1,1), (3,1)), ((2,1),(3,1)), ((4,1),(5,-1))]
52
+ sage: n = 6
53
+ sage: sparse_2term_quotient_only_pm1(rels, n)
54
+ [(3, -1), (3, -1), (3, -1), (3, 1), (5, 1), (5, 1)]
55
+ """
56
+ n = int(n)
57
+
58
+ tm = verbose("Starting optimized integer sparse 2-term quotient...")
59
+
60
+ cdef int c0, c1, i, die
61
+ cdef list free = list(range(n))
62
+ cdef list coef = [1] * n
63
+ cdef list related_to_me = [[] for i in range(n)]
64
+
65
+ for v0, v1 in rels:
66
+ c0 = coef[v0[0]] * v0[1]
67
+ c1 = coef[v1[0]] * v1[1]
68
+
69
+ # Mod out by the following relation:
70
+ #
71
+ # c0*free[v0[0]] + c1*free[v1[0]] = 0.
72
+ #
73
+ die = -1
74
+ if c0 == 0 and c1 == 0:
75
+ pass
76
+ elif c0 == 0 and c1 != 0: # free[v1[0]] --> 0
77
+ die = free[v1[0]]
78
+ elif c1 == 0 and c0 != 0:
79
+ die = free[v0[0]]
80
+ elif free[v0[0]] == free[v1[0]]:
81
+ if c0 + c1 != 0:
82
+ # all xi equal to free[v0[0]] must now equal to zero.
83
+ die = free[v0[0]]
84
+ else: # x1 = -c1/c0 * x2.
85
+ x = free[v0[0]]
86
+ free[x] = free[v1[0]]
87
+ if c0 != 1 and c0 != -1:
88
+ raise ValueError("coefficients must all be -1 or 1.")
89
+ coef[x] = -c1 * c0
90
+ for i in related_to_me[x]:
91
+ free[i] = free[x]
92
+ coef[i] *= coef[x]
93
+ related_to_me[free[v1[0]]].append(i)
94
+ related_to_me[free[v1[0]]].append(x)
95
+ if die != -1:
96
+ for i in related_to_me[die]:
97
+ free[i] = 0
98
+ coef[i] = 0
99
+ free[die] = 0
100
+ coef[die] = 0
101
+
102
+ # Special casing the rationals leads to a huge speedup,
103
+ # actually. (All the code above is slower than just this line
104
+ # without this special case.)
105
+ mod = [(fi, Rational(ci)) for fi, ci in zip(free, coef)]
106
+
107
+ verbose("finished", tm)
108
+ return mod