passagemath-schemes 10.8.1a4__cp314-cp314t-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.
Files changed (312) 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.8.1a4.dist-info/METADATA +203 -0
  7. passagemath_schemes-10.8.1a4.dist-info/METADATA.bak +204 -0
  8. passagemath_schemes-10.8.1a4.dist-info/RECORD +312 -0
  9. passagemath_schemes-10.8.1a4.dist-info/WHEEL +6 -0
  10. passagemath_schemes-10.8.1a4.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 +9556 -0
  24. sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314t-darwin.so +0 -0
  25. sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
  26. sage/dynamics/arithmetic_dynamics/wehlerK3.py +2578 -0
  27. sage/lfunctions/all.py +18 -0
  28. sage/lfunctions/dokchitser.py +727 -0
  29. sage/lfunctions/pari.py +971 -0
  30. sage/lfunctions/zero_sums.cpython-314t-darwin.so +0 -0
  31. sage/lfunctions/zero_sums.pyx +1847 -0
  32. sage/modular/abvar/abvar.py +5132 -0
  33. sage/modular/abvar/abvar_ambient_jacobian.py +414 -0
  34. sage/modular/abvar/abvar_newform.py +246 -0
  35. sage/modular/abvar/all.py +8 -0
  36. sage/modular/abvar/constructor.py +187 -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 +721 -0
  40. sage/modular/abvar/homspace.py +989 -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 +741 -0
  45. sage/modular/all.py +43 -0
  46. sage/modular/arithgroup/all.py +20 -0
  47. sage/modular/arithgroup/arithgroup_element.cpython-314t-darwin.so +0 -0
  48. sage/modular/arithgroup/arithgroup_element.pyx +474 -0
  49. sage/modular/arithgroup/arithgroup_generic.py +1406 -0
  50. sage/modular/arithgroup/arithgroup_perm.py +2692 -0
  51. sage/modular/arithgroup/congroup.cpython-314t-darwin.so +0 -0
  52. sage/modular/arithgroup/congroup.pyx +334 -0
  53. sage/modular/arithgroup/congroup_gamma.py +361 -0
  54. sage/modular/arithgroup/congroup_gamma0.py +692 -0
  55. sage/modular/arithgroup/congroup_gamma1.py +659 -0
  56. sage/modular/arithgroup/congroup_gammaH.py +1491 -0
  57. sage/modular/arithgroup/congroup_generic.py +630 -0
  58. sage/modular/arithgroup/congroup_sl2z.py +266 -0
  59. sage/modular/arithgroup/farey_symbol.cpython-314t-darwin.so +0 -0
  60. sage/modular/arithgroup/farey_symbol.pyx +1067 -0
  61. sage/modular/arithgroup/tests.py +425 -0
  62. sage/modular/btquotients/all.py +4 -0
  63. sage/modular/btquotients/btquotient.py +3736 -0
  64. sage/modular/btquotients/pautomorphicform.py +2564 -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 +1107 -0
  69. sage/modular/cusps_nf.py +1270 -0
  70. sage/modular/dims.py +571 -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 +1076 -0
  77. sage/modular/hecke/algebra.py +725 -0
  78. sage/modular/hecke/all.py +19 -0
  79. sage/modular/hecke/ambient_module.py +994 -0
  80. sage/modular/hecke/degenmap.py +119 -0
  81. sage/modular/hecke/element.py +302 -0
  82. sage/modular/hecke/hecke_operator.py +736 -0
  83. sage/modular/hecke/homspace.py +185 -0
  84. sage/modular/hecke/module.py +1744 -0
  85. sage/modular/hecke/morphism.py +139 -0
  86. sage/modular/hecke/submodule.py +970 -0
  87. sage/modular/hypergeometric_misc.cpython-314t-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 +2020 -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 +1070 -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 +817 -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 +120 -0
  101. sage/modular/modform/ambient_g1.py +199 -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 +487 -0
  106. sage/modular/modform/eisenstein_submodule.py +663 -0
  107. sage/modular/modform/element.py +4105 -0
  108. sage/modular/modform/half_integral.py +154 -0
  109. sage/modular/modform/hecke_operator_on_qexp.py +247 -0
  110. sage/modular/modform/j_invariant.py +47 -0
  111. sage/modular/modform/l_series_gross_zagier.py +127 -0
  112. sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314t-darwin.so +0 -0
  113. sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
  114. sage/modular/modform/notes.py +45 -0
  115. sage/modular/modform/numerical.py +514 -0
  116. sage/modular/modform/periods.py +14 -0
  117. sage/modular/modform/ring.py +1257 -0
  118. sage/modular/modform/space.py +1859 -0
  119. sage/modular/modform/submodule.py +118 -0
  120. sage/modular/modform/tests.py +64 -0
  121. sage/modular/modform/theta.py +110 -0
  122. sage/modular/modform/vm_basis.py +380 -0
  123. sage/modular/modform/weight1.py +221 -0
  124. sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
  125. sage/modular/modform_hecketriangle/abstract_space.py +2527 -0
  126. sage/modular/modform_hecketriangle/all.py +30 -0
  127. sage/modular/modform_hecketriangle/analytic_type.py +590 -0
  128. sage/modular/modform_hecketriangle/constructor.py +416 -0
  129. sage/modular/modform_hecketriangle/element.py +351 -0
  130. sage/modular/modform_hecketriangle/functors.py +752 -0
  131. sage/modular/modform_hecketriangle/graded_ring.py +541 -0
  132. sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
  133. sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3349 -0
  134. sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1426 -0
  135. sage/modular/modform_hecketriangle/readme.py +1214 -0
  136. sage/modular/modform_hecketriangle/series_constructor.py +580 -0
  137. sage/modular/modform_hecketriangle/space.py +1037 -0
  138. sage/modular/modform_hecketriangle/subspace.py +423 -0
  139. sage/modular/modsym/all.py +17 -0
  140. sage/modular/modsym/ambient.py +3844 -0
  141. sage/modular/modsym/boundary.py +1420 -0
  142. sage/modular/modsym/element.py +336 -0
  143. sage/modular/modsym/g1list.py +178 -0
  144. sage/modular/modsym/ghlist.py +182 -0
  145. sage/modular/modsym/hecke_operator.py +73 -0
  146. sage/modular/modsym/manin_symbol.cpython-314t-darwin.so +0 -0
  147. sage/modular/modsym/manin_symbol.pxd +5 -0
  148. sage/modular/modsym/manin_symbol.pyx +497 -0
  149. sage/modular/modsym/manin_symbol_list.py +1291 -0
  150. sage/modular/modsym/modsym.py +400 -0
  151. sage/modular/modsym/modular_symbols.py +384 -0
  152. sage/modular/modsym/p1list_nf.py +1241 -0
  153. sage/modular/modsym/relation_matrix.py +591 -0
  154. sage/modular/modsym/relation_matrix_pyx.cpython-314t-darwin.so +0 -0
  155. sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
  156. sage/modular/modsym/space.py +2468 -0
  157. sage/modular/modsym/subspace.py +455 -0
  158. sage/modular/modsym/tests.py +376 -0
  159. sage/modular/multiple_zeta.py +2635 -0
  160. sage/modular/multiple_zeta_F_algebra.py +789 -0
  161. sage/modular/overconvergent/all.py +6 -0
  162. sage/modular/overconvergent/genus0.py +1879 -0
  163. sage/modular/overconvergent/hecke_series.py +1187 -0
  164. sage/modular/overconvergent/weightspace.py +776 -0
  165. sage/modular/pollack_stevens/all.py +4 -0
  166. sage/modular/pollack_stevens/distributions.py +874 -0
  167. sage/modular/pollack_stevens/fund_domain.py +1572 -0
  168. sage/modular/pollack_stevens/manin_map.py +856 -0
  169. sage/modular/pollack_stevens/modsym.py +1590 -0
  170. sage/modular/pollack_stevens/padic_lseries.py +417 -0
  171. sage/modular/pollack_stevens/sigma0.py +534 -0
  172. sage/modular/pollack_stevens/space.py +1078 -0
  173. sage/modular/quasimodform/all.py +3 -0
  174. sage/modular/quasimodform/element.py +846 -0
  175. sage/modular/quasimodform/ring.py +826 -0
  176. sage/modular/quatalg/all.py +3 -0
  177. sage/modular/quatalg/brandt.py +1642 -0
  178. sage/modular/ssmod/all.py +8 -0
  179. sage/modular/ssmod/ssmod.py +827 -0
  180. sage/rings/all__sagemath_schemes.py +1 -0
  181. sage/rings/polynomial/all__sagemath_schemes.py +1 -0
  182. sage/rings/polynomial/binary_form_reduce.py +585 -0
  183. sage/schemes/all.py +41 -0
  184. sage/schemes/berkovich/all.py +6 -0
  185. sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
  186. sage/schemes/berkovich/berkovich_space.py +700 -0
  187. sage/schemes/curves/affine_curve.py +2924 -0
  188. sage/schemes/curves/all.py +33 -0
  189. sage/schemes/curves/closed_point.py +434 -0
  190. sage/schemes/curves/constructor.py +397 -0
  191. sage/schemes/curves/curve.py +542 -0
  192. sage/schemes/curves/plane_curve_arrangement.py +1283 -0
  193. sage/schemes/curves/point.py +463 -0
  194. sage/schemes/curves/projective_curve.py +3203 -0
  195. sage/schemes/curves/weighted_projective_curve.py +106 -0
  196. sage/schemes/curves/zariski_vankampen.py +1931 -0
  197. sage/schemes/cyclic_covers/all.py +2 -0
  198. sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
  199. sage/schemes/cyclic_covers/constructor.py +137 -0
  200. sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
  201. sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
  202. sage/schemes/elliptic_curves/BSD.py +991 -0
  203. sage/schemes/elliptic_curves/Qcurves.py +592 -0
  204. sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
  205. sage/schemes/elliptic_curves/all.py +49 -0
  206. sage/schemes/elliptic_curves/cardinality.py +609 -0
  207. sage/schemes/elliptic_curves/cm.py +1103 -0
  208. sage/schemes/elliptic_curves/constructor.py +1530 -0
  209. sage/schemes/elliptic_curves/ec_database.py +175 -0
  210. sage/schemes/elliptic_curves/ell_curve_isogeny.py +3971 -0
  211. sage/schemes/elliptic_curves/ell_egros.py +457 -0
  212. sage/schemes/elliptic_curves/ell_field.py +2837 -0
  213. sage/schemes/elliptic_curves/ell_finite_field.py +3249 -0
  214. sage/schemes/elliptic_curves/ell_generic.py +3760 -0
  215. sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
  216. sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
  217. sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
  218. sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
  219. sage/schemes/elliptic_curves/ell_point.py +4944 -0
  220. sage/schemes/elliptic_curves/ell_rational_field.py +7184 -0
  221. sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
  222. sage/schemes/elliptic_curves/ell_torsion.py +436 -0
  223. sage/schemes/elliptic_curves/ell_wp.py +352 -0
  224. sage/schemes/elliptic_curves/formal_group.py +760 -0
  225. sage/schemes/elliptic_curves/gal_reps.py +1459 -0
  226. sage/schemes/elliptic_curves/gal_reps_number_field.py +1663 -0
  227. sage/schemes/elliptic_curves/gp_simon.py +152 -0
  228. sage/schemes/elliptic_curves/heegner.py +7328 -0
  229. sage/schemes/elliptic_curves/height.py +2108 -0
  230. sage/schemes/elliptic_curves/hom.py +1788 -0
  231. sage/schemes/elliptic_curves/hom_composite.py +1084 -0
  232. sage/schemes/elliptic_curves/hom_fractional.py +544 -0
  233. sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
  234. sage/schemes/elliptic_curves/hom_scalar.py +531 -0
  235. sage/schemes/elliptic_curves/hom_sum.py +681 -0
  236. sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
  237. sage/schemes/elliptic_curves/homset.py +271 -0
  238. sage/schemes/elliptic_curves/isogeny_class.py +1523 -0
  239. sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
  240. sage/schemes/elliptic_curves/jacobian.py +247 -0
  241. sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
  242. sage/schemes/elliptic_curves/kraus.py +1014 -0
  243. sage/schemes/elliptic_curves/lseries_ell.py +915 -0
  244. sage/schemes/elliptic_curves/mod5family.py +105 -0
  245. sage/schemes/elliptic_curves/mod_poly.py +197 -0
  246. sage/schemes/elliptic_curves/mod_sym_num.cpython-314t-darwin.so +0 -0
  247. sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
  248. sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
  249. sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
  250. sage/schemes/elliptic_curves/padics.py +1816 -0
  251. sage/schemes/elliptic_curves/period_lattice.py +2234 -0
  252. sage/schemes/elliptic_curves/period_lattice_region.cpython-314t-darwin.so +0 -0
  253. sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
  254. sage/schemes/elliptic_curves/saturation.py +716 -0
  255. sage/schemes/elliptic_curves/sha_tate.py +1158 -0
  256. sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
  257. sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
  258. sage/schemes/hyperelliptic_curves/all.py +6 -0
  259. sage/schemes/hyperelliptic_curves/constructor.py +369 -0
  260. sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1948 -0
  261. sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
  262. sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +936 -0
  263. sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
  264. sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
  265. sage/schemes/hyperelliptic_curves/invariants.py +410 -0
  266. sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +312 -0
  267. sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
  268. sage/schemes/hyperelliptic_curves/jacobian_generic.py +437 -0
  269. sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
  270. sage/schemes/hyperelliptic_curves/jacobian_morphism.py +878 -0
  271. sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
  272. sage/schemes/hyperelliptic_curves/mestre.py +302 -0
  273. sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3863 -0
  274. sage/schemes/jacobians/abstract_jacobian.py +277 -0
  275. sage/schemes/jacobians/all.py +2 -0
  276. sage/schemes/overview.py +161 -0
  277. sage/schemes/plane_conics/all.py +22 -0
  278. sage/schemes/plane_conics/con_field.py +1296 -0
  279. sage/schemes/plane_conics/con_finite_field.py +158 -0
  280. sage/schemes/plane_conics/con_number_field.py +456 -0
  281. sage/schemes/plane_conics/con_rational_field.py +406 -0
  282. sage/schemes/plane_conics/con_rational_function_field.py +581 -0
  283. sage/schemes/plane_conics/constructor.py +249 -0
  284. sage/schemes/plane_quartics/all.py +2 -0
  285. sage/schemes/plane_quartics/quartic_constructor.py +71 -0
  286. sage/schemes/plane_quartics/quartic_generic.py +53 -0
  287. sage/schemes/riemann_surfaces/all.py +1 -0
  288. sage/schemes/riemann_surfaces/riemann_surface.py +4177 -0
  289. sage_wheels/share/cremona/cremona_mini.db +0 -0
  290. sage_wheels/share/ellcurves/rank0 +30427 -0
  291. sage_wheels/share/ellcurves/rank1 +31871 -0
  292. sage_wheels/share/ellcurves/rank10 +6 -0
  293. sage_wheels/share/ellcurves/rank11 +6 -0
  294. sage_wheels/share/ellcurves/rank12 +1 -0
  295. sage_wheels/share/ellcurves/rank14 +1 -0
  296. sage_wheels/share/ellcurves/rank15 +1 -0
  297. sage_wheels/share/ellcurves/rank17 +1 -0
  298. sage_wheels/share/ellcurves/rank19 +1 -0
  299. sage_wheels/share/ellcurves/rank2 +2388 -0
  300. sage_wheels/share/ellcurves/rank20 +1 -0
  301. sage_wheels/share/ellcurves/rank21 +1 -0
  302. sage_wheels/share/ellcurves/rank22 +1 -0
  303. sage_wheels/share/ellcurves/rank23 +1 -0
  304. sage_wheels/share/ellcurves/rank24 +1 -0
  305. sage_wheels/share/ellcurves/rank28 +1 -0
  306. sage_wheels/share/ellcurves/rank3 +836 -0
  307. sage_wheels/share/ellcurves/rank4 +10 -0
  308. sage_wheels/share/ellcurves/rank5 +5 -0
  309. sage_wheels/share/ellcurves/rank6 +5 -0
  310. sage_wheels/share/ellcurves/rank7 +5 -0
  311. sage_wheels/share/ellcurves/rank8 +6 -0
  312. sage_wheels/share/ellcurves/rank9 +7 -0
@@ -0,0 +1,1426 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ # sage.doctest: needs sage.libs.gap
3
+ r"""
4
+ Hecke triangle groups
5
+
6
+ AUTHORS:
7
+
8
+ - Jonas Jermann (2013): initial version
9
+ """
10
+
11
+ # ****************************************************************************
12
+ # Copyright (C) 2013-2014 Jonas Jermann <jjermann2@gmail.com>
13
+ #
14
+ # Distributed under the terms of the GNU General Public License (GPL)
15
+ # as published by the Free Software Foundation; either version 2 of
16
+ # the License, or (at your option) any later version.
17
+ # https://www.gnu.org/licenses/
18
+ # ****************************************************************************
19
+
20
+ from sage.arith.misc import divisors
21
+ from sage.groups.matrix_gps.finitely_generated import FinitelyGeneratedMatrixGroup_generic
22
+ from sage.matrix.constructor import matrix
23
+ from sage.misc.cachefunc import cached_method
24
+ from sage.misc.latex import latex
25
+ from sage.misc.lazy_import import lazy_import
26
+ from sage.misc.misc_c import prod
27
+ from sage.rings.infinity import infinity
28
+ from sage.rings.integer_ring import ZZ
29
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
30
+ from sage.rings.rational_field import QQ
31
+ from sage.structure.unique_representation import UniqueRepresentation
32
+
33
+ lazy_import("sage.functions.log", "exp")
34
+ lazy_import("sage.functions.gamma", "psi1")
35
+ lazy_import("sage.functions.trig", "sec")
36
+ lazy_import("sage.rings.number_field.number_field", "NumberField")
37
+ lazy_import("sage.rings.qqbar", ["AA", "AlgebraicField"])
38
+ lazy_import("sage.rings.universal_cyclotomic_field", "E")
39
+ lazy_import("sage.symbolic.constants", "pi")
40
+
41
+ from .hecke_triangle_group_element import HeckeTriangleGroupElement, cyclic_representative, coerce_AA
42
+
43
+
44
+ class HeckeTriangleGroup(FinitelyGeneratedMatrixGroup_generic,
45
+ UniqueRepresentation):
46
+ r"""
47
+ Hecke triangle group `(2, n, \infty)`.
48
+ """
49
+
50
+ Element = HeckeTriangleGroupElement
51
+
52
+ @staticmethod
53
+ def __classcall__(cls, n=3):
54
+ r"""
55
+ Return a (cached) instance with canonical parameters.
56
+
57
+ EXAMPLES::
58
+
59
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
60
+ sage: HeckeTriangleGroup(QQ(3)) == HeckeTriangleGroup(int(3))
61
+ True
62
+ """
63
+ if n == infinity:
64
+ n = infinity
65
+ else:
66
+ n = ZZ(n)
67
+ if n < 3:
68
+ raise AttributeError("n has to be infinity or an Integer >= 3.")
69
+
70
+ return super().__classcall__(cls, n)
71
+
72
+ def __init__(self, n):
73
+ r"""
74
+ Hecke triangle group (2, n, infinity).
75
+
76
+ Namely the von Dyck group corresponding to the triangle group
77
+ with angles (pi/2, pi/n, 0).
78
+
79
+ INPUT:
80
+
81
+ - ``n`` -- ``infinity`` or an integer greater or equal to `3`
82
+
83
+ OUTPUT: the Hecke triangle group for the given parameter `n`
84
+
85
+ EXAMPLES::
86
+
87
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
88
+ sage: G = HeckeTriangleGroup(12)
89
+ sage: G
90
+ Hecke triangle group for n = 12
91
+ sage: G.category()
92
+ Category of groups
93
+ """
94
+
95
+ self._n = n
96
+ self.element_repr_method("default")
97
+
98
+ if n in [3, infinity]:
99
+ self._base_ring = ZZ
100
+ self._lam = ZZ.one() if n == 3 else ZZ(2)
101
+ else:
102
+ lam_symbolic = coerce_AA(E(2 * n) + ~E(2 * n))
103
+ K = NumberField(self.lam_minpoly(), 'lam',
104
+ embedding=lam_symbolic)
105
+ # self._base_ring = K.order(K.gens())
106
+ self._base_ring = K.maximal_order()
107
+ self._lam = self._base_ring.gen(1)
108
+
109
+ T = matrix(self._base_ring, [[1, self._lam], [0, 1]])
110
+ S = matrix(self._base_ring, [[0, -1], [1, 0]])
111
+
112
+ FinitelyGeneratedMatrixGroup_generic.__init__(self, ZZ(2), self._base_ring, [S, T])
113
+
114
+ def _repr_(self):
115
+ r"""
116
+ Return the string representation of ``self``.
117
+
118
+ EXAMPLES::
119
+
120
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
121
+ sage: HeckeTriangleGroup(10)
122
+ Hecke triangle group for n = 10
123
+ """
124
+ return f"Hecke triangle group for n = {self._n}"
125
+
126
+ def _latex_(self):
127
+ r"""
128
+ Return the LaTeX representation of ``self``.
129
+
130
+ EXAMPLES::
131
+
132
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
133
+ sage: a = HeckeTriangleGroup(5)
134
+ sage: latex(a)
135
+ \Gamma^{(5)}
136
+ """
137
+ return '\\Gamma^{(%s)}' % latex(self._n)
138
+
139
+ def element_repr_method(self, method=None):
140
+ r"""
141
+ Either return or set the representation method for elements of ``self``.
142
+
143
+ INPUT:
144
+
145
+ - ``method`` -- if ``method=None`` (default) the current default
146
+ representation method is returned. Otherwise the default method is
147
+ set to ``method``. If ``method`` is not available a
148
+ :exc:`ValueError` is raised. Possible methods are:
149
+
150
+ - ``default``: use the usual representation method for matrix group
151
+ elements
152
+
153
+ - ``basic``: the representation is given as a word in ``S`` and
154
+ powers of ``T``
155
+
156
+ - ``conj``: the conjugacy representative of the element is
157
+ represented as a word in powers of the basic blocks, together with
158
+ an unspecified conjugation matrix
159
+
160
+ - ``block``: same as ``conj`` but the conjugation matrix is
161
+ specified as well
162
+
163
+ EXAMPLES::
164
+
165
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
166
+ sage: G = HeckeTriangleGroup(5)
167
+ sage: G.element_repr_method()
168
+ 'default'
169
+ sage: G.element_repr_method("basic")
170
+ sage: G.element_repr_method()
171
+ 'basic'
172
+ """
173
+ if method is None:
174
+ return self._element_repr_method
175
+ elif method in ["default", "basic", "block", "conj"]:
176
+ self._element_repr_method = method
177
+ else:
178
+ raise ValueError(f"the specified method {method} is not supported")
179
+
180
+ def one(self):
181
+ r"""
182
+ Return the identity element/matrix for ``self``.
183
+
184
+ EXAMPLES::
185
+
186
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
187
+ sage: G = HeckeTriangleGroup(10)
188
+ sage: G(1) == G.one()
189
+ True
190
+ sage: G(1)
191
+ [1 0]
192
+ [0 1]
193
+
194
+ sage: G(1).parent()
195
+ Hecke triangle group for n = 10
196
+ """
197
+ return self.I()
198
+
199
+ def lam_minpoly(self):
200
+ r"""
201
+ Return the minimal polynomial of the corresponding lambda parameter of ``self``.
202
+
203
+ EXAMPLES::
204
+
205
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
206
+ sage: HeckeTriangleGroup(10).lam_minpoly()
207
+ x^4 - 5*x^2 + 5
208
+ sage: HeckeTriangleGroup(17).lam_minpoly()
209
+ x^8 - x^7 - 7*x^6 + 6*x^5 + 15*x^4 - 10*x^3 - 10*x^2 + 4*x + 1
210
+ sage: HeckeTriangleGroup(infinity).lam_minpoly()
211
+ x - 2
212
+ """
213
+ # TODO: Write an explicit (faster) implementation
214
+ n = self._n
215
+ if n == infinity:
216
+ lam_symbolic = QQ(2)
217
+ else:
218
+ lam_symbolic = E(2 * n) + ~E(2 * n)
219
+ return lam_symbolic.minpoly()
220
+
221
+ def base_ring(self):
222
+ r"""
223
+ Return the base ring of ``self``.
224
+
225
+ EXAMPLES::
226
+
227
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
228
+ sage: HeckeTriangleGroup(n=infinity).base_ring()
229
+ Integer Ring
230
+ sage: HeckeTriangleGroup(n=7).base_ring()
231
+ Maximal Order generated by lam in Number Field in lam with defining polynomial x^3 - x^2 - 2*x + 1 with lam = 1.801937735804839?
232
+ """
233
+ return self._base_ring
234
+
235
+ def base_field(self):
236
+ r"""
237
+ Return the base field of ``self``.
238
+
239
+ EXAMPLES::
240
+
241
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
242
+ sage: HeckeTriangleGroup(n=infinity).base_field()
243
+ Rational Field
244
+ sage: HeckeTriangleGroup(n=7).base_field()
245
+ Number Field in lam with defining polynomial x^3 - x^2 - 2*x + 1 with lam = 1.801937735804839?
246
+ """
247
+ if self._n in [3, infinity]:
248
+ return QQ
249
+ else:
250
+ return self._base_ring.number_field()
251
+
252
+ def n(self):
253
+ r"""
254
+ Return the parameter ``n`` of ``self``, where
255
+ ``pi/n`` is the angle at ``rho`` of the corresponding
256
+ basic hyperbolic triangle with vertices ``i``, ``rho``
257
+ and ``infinity``.
258
+
259
+ EXAMPLES::
260
+
261
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
262
+ sage: HeckeTriangleGroup(10).n()
263
+ 10
264
+ sage: HeckeTriangleGroup(infinity).n()
265
+ +Infinity
266
+ """
267
+ return self._n
268
+
269
+ def lam(self):
270
+ r"""
271
+ Return the parameter ``lambda`` of ``self``,
272
+ where ``lambda`` is twice the real part of ``rho``,
273
+ lying between ``1`` (when ``n=3``) and ``2`` (when ``n=infinity``).
274
+
275
+ EXAMPLES::
276
+
277
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
278
+ sage: HeckeTriangleGroup(3).lam()
279
+ 1
280
+ sage: HeckeTriangleGroup(4).lam()
281
+ lam
282
+ sage: HeckeTriangleGroup(4).lam()^2
283
+ 2
284
+ sage: HeckeTriangleGroup(6).lam()^2
285
+ 3
286
+ sage: AA(HeckeTriangleGroup(10).lam())
287
+ 1.9021130325903...?
288
+ sage: HeckeTriangleGroup(infinity).lam()
289
+ 2
290
+ """
291
+ return self._lam
292
+
293
+ def rho(self):
294
+ r"""
295
+ Return the vertex ``rho`` of the basic hyperbolic
296
+ triangle which describes ``self``. ``rho`` has
297
+ absolute value 1 and angle ``pi/n``.
298
+
299
+ EXAMPLES::
300
+
301
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
302
+ sage: HeckeTriangleGroup(3).rho() == QQbar(1/2 + sqrt(3)/2*i)
303
+ True
304
+ sage: HeckeTriangleGroup(4).rho() == QQbar(sqrt(2)/2*(1 + i))
305
+ True
306
+ sage: HeckeTriangleGroup(6).rho() == QQbar(sqrt(3)/2 + 1/2*i)
307
+ True
308
+ sage: HeckeTriangleGroup(10).rho()
309
+ 0.95105651629515...? + 0.30901699437494...?*I
310
+ sage: HeckeTriangleGroup(infinity).rho()
311
+ 1
312
+ """
313
+ # TODO: maybe rho should be replaced by -rhobar
314
+ # Also we could use NumberFields...
315
+ if self._n == infinity:
316
+ return AA.one()
317
+ else:
318
+ rho = AlgebraicField()(E(2 * self._n))
319
+ rho.simplify()
320
+ return rho
321
+
322
+ def alpha(self):
323
+ r"""
324
+ Return the parameter ``alpha`` of ``self``.
325
+
326
+ This is the first parameter of the hypergeometric series used
327
+ in the calculation of the Hauptmodul of ``self``.
328
+
329
+ EXAMPLES::
330
+
331
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
332
+ sage: HeckeTriangleGroup(3).alpha()
333
+ 1/12
334
+ sage: HeckeTriangleGroup(4).alpha()
335
+ 1/8
336
+ sage: HeckeTriangleGroup(5).alpha()
337
+ 3/20
338
+ sage: HeckeTriangleGroup(6).alpha()
339
+ 1/6
340
+ sage: HeckeTriangleGroup(10).alpha()
341
+ 1/5
342
+ sage: HeckeTriangleGroup(infinity).alpha()
343
+ 1/4
344
+ """
345
+ return QQ((1, 2)) * (QQ((1, 2)) - ZZ.one() / self._n)
346
+
347
+ def beta(self):
348
+ r"""
349
+ Return the parameter ``beta`` of ``self``.
350
+
351
+ This is the second parameter of the hypergeometric series used
352
+ in the calculation of the Hauptmodul of ``self``.
353
+
354
+ EXAMPLES::
355
+
356
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
357
+ sage: HeckeTriangleGroup(3).beta()
358
+ 5/12
359
+ sage: HeckeTriangleGroup(4).beta()
360
+ 3/8
361
+ sage: HeckeTriangleGroup(5).beta()
362
+ 7/20
363
+ sage: HeckeTriangleGroup(6).beta()
364
+ 1/3
365
+ sage: HeckeTriangleGroup(10).beta()
366
+ 3/10
367
+ sage: HeckeTriangleGroup(infinity).beta()
368
+ 1/4
369
+ """
370
+ return QQ((1, 2)) * (QQ((1, 2)) + ZZ.one() / self._n)
371
+
372
+ # We use cached method here to create unique instances of basic matrices
373
+ # (major performance gain)
374
+ @cached_method
375
+ def I(self):
376
+ r"""
377
+ Return the identity element/matrix for ``self``.
378
+
379
+ EXAMPLES::
380
+
381
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
382
+ sage: HeckeTriangleGroup(10).I()
383
+ [1 0]
384
+ [0 1]
385
+
386
+ sage: HeckeTriangleGroup(10).I().parent()
387
+ Hecke triangle group for n = 10
388
+ """
389
+ return self(matrix(self._base_ring, [[1, 0], [0, 1]]), check=False)
390
+
391
+ # We use cached method here to create unique instances of basic matrices
392
+ # (major performance gain)
393
+ @cached_method
394
+ def T(self, m=1):
395
+ r"""
396
+ Return the element in ``self`` corresponding to the translation by
397
+ ``m*self.lam()``.
398
+
399
+ INPUT:
400
+
401
+ - ``m`` -- integer (default: 1); namely the second generator of
402
+ ``self``
403
+
404
+ EXAMPLES::
405
+
406
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
407
+ sage: HeckeTriangleGroup(3).T()
408
+ [1 1]
409
+ [0 1]
410
+ sage: HeckeTriangleGroup(10).T(-4)
411
+ [ 1 -4*lam]
412
+ [ 0 1]
413
+ sage: HeckeTriangleGroup(10).T().parent()
414
+ Hecke triangle group for n = 10
415
+ """
416
+ return self(matrix(self._base_ring, [[1, self._lam * m], [0, 1]]),
417
+ check=False)
418
+
419
+ # We use cached method here to create unique instances of basic matrices
420
+ # (major performance gain)
421
+ @cached_method
422
+ def S(self):
423
+ r"""
424
+ Return the generator of ``self`` corresponding to the
425
+ conformal circle inversion.
426
+
427
+ EXAMPLES::
428
+
429
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
430
+ sage: HeckeTriangleGroup(3).S()
431
+ [ 0 -1]
432
+ [ 1 0]
433
+ sage: HeckeTriangleGroup(10).S()
434
+ [ 0 -1]
435
+ [ 1 0]
436
+ sage: HeckeTriangleGroup(10).S()^2 == -HeckeTriangleGroup(10).I()
437
+ True
438
+ sage: HeckeTriangleGroup(10).S()^4 == HeckeTriangleGroup(10).I()
439
+ True
440
+
441
+ sage: HeckeTriangleGroup(10).S().parent()
442
+ Hecke triangle group for n = 10
443
+ """
444
+ return self.gen(0)
445
+
446
+ # We use cached method here to create unique instances of basic matrices
447
+ # (major performance gain)
448
+ @cached_method
449
+ def U(self):
450
+ r"""
451
+ Return an alternative generator of ``self`` instead of ``T``.
452
+ ``U`` stabilizes ``rho`` and has order ``2*self.n()``.
453
+
454
+ If ``n=infinity`` then ``U`` is parabolic and has infinite order,
455
+ it then fixes the cusp ``[-1]``.
456
+
457
+ EXAMPLES::
458
+
459
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
460
+ sage: HeckeTriangleGroup(3).U()
461
+ [ 1 -1]
462
+ [ 1 0]
463
+ sage: HeckeTriangleGroup(3).U()^3 == -HeckeTriangleGroup(3).I()
464
+ True
465
+ sage: HeckeTriangleGroup(3).U()^6 == HeckeTriangleGroup(3).I()
466
+ True
467
+ sage: HeckeTriangleGroup(10).U()
468
+ [lam -1]
469
+ [ 1 0]
470
+ sage: HeckeTriangleGroup(10).U()^10 == -HeckeTriangleGroup(10).I()
471
+ True
472
+ sage: HeckeTriangleGroup(10).U()^20 == HeckeTriangleGroup(10).I()
473
+ True
474
+
475
+ sage: HeckeTriangleGroup(10).U().parent()
476
+ Hecke triangle group for n = 10
477
+ """
478
+ return self.T() * self.S()
479
+
480
+ def V(self, j):
481
+ r"""
482
+ Return the j'th generator for the usual representatives of
483
+ conjugacy classes of ``self``. It is given by ``V=U^(j-1)*T``.
484
+
485
+ INPUT:
486
+
487
+ - ``j`` --integer; to get the usual representatives
488
+ ``j`` should range from ``1`` to ``self.n()-1``
489
+
490
+ OUTPUT: the corresponding matrix/element
491
+
492
+ The matrix is parabolic if ``j`` is congruent to `\pm 1` modulo ``self.n()``.
493
+ It is elliptic if ``j`` is congruent to 0 modulo ``self.n()``.
494
+ It is hyperbolic otherwise.
495
+
496
+ EXAMPLES::
497
+
498
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
499
+ sage: G = HeckeTriangleGroup(3)
500
+ sage: G.V(0) == -G.S()
501
+ True
502
+ sage: G.V(1) == G.T()
503
+ True
504
+ sage: G.V(2)
505
+ [1 0]
506
+ [1 1]
507
+ sage: G.V(3) == G.S()
508
+ True
509
+
510
+ sage: G = HeckeTriangleGroup(5)
511
+ sage: G.element_repr_method("default")
512
+ sage: G.V(1)
513
+ [ 1 lam]
514
+ [ 0 1]
515
+ sage: G.V(2)
516
+ [lam lam]
517
+ [ 1 lam]
518
+ sage: G.V(3)
519
+ [lam 1]
520
+ [lam lam]
521
+ sage: G.V(4)
522
+ [ 1 0]
523
+ [lam 1]
524
+ sage: G.V(5) == G.S()
525
+ True
526
+ """
527
+ return self.U()**(j-1) * self.T()
528
+
529
+ def dvalue(self):
530
+ r"""
531
+ Return a symbolic expression (or an exact value in case n=3, 4, 6)
532
+ for the transfinite diameter (or capacity) of ``self``.
533
+
534
+ This is the first nontrivial Fourier coefficient of the Hauptmodul
535
+ for the Hecke triangle group in case it is normalized to ``J_inv(i)=1``.
536
+
537
+ EXAMPLES::
538
+
539
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
540
+ sage: HeckeTriangleGroup(3).dvalue()
541
+ 1/1728
542
+ sage: HeckeTriangleGroup(4).dvalue()
543
+ 1/256
544
+ sage: HeckeTriangleGroup(5).dvalue()
545
+ e^(2*euler_gamma - 4*pi/(sqrt(5) + 1) + psi(17/20) + psi(13/20))
546
+ sage: HeckeTriangleGroup(6).dvalue()
547
+ 1/108
548
+ sage: HeckeTriangleGroup(10).dvalue()
549
+ e^(2*euler_gamma - 4*pi/sqrt(2*sqrt(5) + 10) + psi(4/5) + psi(7/10))
550
+ sage: HeckeTriangleGroup(infinity).dvalue()
551
+ 1/64
552
+ """
553
+ n = self._n
554
+ if n == 3:
555
+ return 1 / ZZ(2**6*3**3)
556
+ if n == 4:
557
+ return 1 / ZZ(2**8)
558
+ if n == 6:
559
+ return 1 / ZZ(2**2*3**3)
560
+ if n == infinity:
561
+ return 1 / ZZ(2**6)
562
+ # reference for this formula ?
563
+ return exp(-ZZ(2)*psi1(ZZ.one()) + psi1(ZZ.one()-self.alpha())
564
+ + psi1(ZZ.one()-self.beta()) - pi*sec(pi/self._n))
565
+
566
+ def is_arithmetic(self) -> bool:
567
+ r"""
568
+ Return ``True`` if ``self`` is an arithmetic subgroup.
569
+
570
+ EXAMPLES::
571
+
572
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
573
+ sage: HeckeTriangleGroup(3).is_arithmetic()
574
+ True
575
+ sage: HeckeTriangleGroup(4).is_arithmetic()
576
+ True
577
+ sage: HeckeTriangleGroup(5).is_arithmetic()
578
+ False
579
+ sage: HeckeTriangleGroup(6).is_arithmetic()
580
+ True
581
+ sage: HeckeTriangleGroup(10).is_arithmetic()
582
+ False
583
+ sage: HeckeTriangleGroup(infinity).is_arithmetic()
584
+ True
585
+ """
586
+ return self._n in [ZZ(3), ZZ(4), ZZ(6), infinity]
587
+
588
+ def get_FD(self, z):
589
+ r"""
590
+ Return a tuple (A,w) which determines how to map ``z``
591
+ to the usual (strict) fundamental domain of ``self``.
592
+
593
+ INPUT:
594
+
595
+ - ``z`` -- a complex number or an element of AlgebraicField()
596
+
597
+ OUTPUT:
598
+
599
+ A tuple ``(A, w)``.
600
+
601
+ - ``A`` -- a matrix in ``self`` such that ``A.acton(w)==z``
602
+ (if ``z`` is exact at least)
603
+
604
+ - ``w`` -- a complex number or an element of AlgebraicField()
605
+ (depending on the type ``z``) which lies inside the (strict)
606
+ fundamental domain of ``self`` (``self.in_FD(w)==True``) and
607
+ which is equivalent to ``z`` (by the above property)
608
+
609
+ EXAMPLES::
610
+
611
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
612
+ sage: G = HeckeTriangleGroup(8)
613
+ sage: z = AlgebraicField()(1+i/2)
614
+ sage: A, w = G.get_FD(z)
615
+ sage: A
616
+ [-lam 1]
617
+ [ -1 0]
618
+ sage: A.acton(w) == z
619
+ True
620
+
621
+ sage: from sage.modular.modform_hecketriangle.space import ModularForms
622
+ sage: z = (134.12 + 0.22*i).n()
623
+ sage: A, w = G.get_FD(z)
624
+ sage: A
625
+ [-73*lam^3 + 74*lam 73*lam^2 - 1]
626
+ [ -lam^2 + 1 lam]
627
+ sage: w
628
+ 0.769070776942... + 0.779859114103...*I
629
+ sage: z
630
+ 134.120000000... + 0.220000000000...*I
631
+ sage: A.acton(w)
632
+ 134.1200000... + 0.2200000000...*I
633
+ """
634
+ ID = self.I()
635
+ T = self.T()
636
+ S = self.S()
637
+ TI = self.T(-1)
638
+
639
+ A = ID
640
+ w = z
641
+ while abs(w) < ZZ.one() or abs(w.real()) > self.lam() / ZZ(2):
642
+ if abs(w) < ZZ.one():
643
+ w = self.S().acton(w)
644
+ A = S*A
645
+ while w.real() >= self.lam() / ZZ(2):
646
+ w = TI.acton(w)
647
+ A = TI*A
648
+ while w.real() < -self.lam() / ZZ(2):
649
+ w = T.acton(w)
650
+ A = T*A
651
+ if w.real() == self.lam() / ZZ(2):
652
+ w = TI.acton(w)
653
+ A = TI*A
654
+ if abs(w) == ZZ.one() and w.real() > ZZ.zero():
655
+ w = S.acton(w)
656
+ A = S*A
657
+
658
+ AI = A.inverse()
659
+
660
+ return (AI, A.acton(z))
661
+
662
+ def in_FD(self, z) -> bool:
663
+ r"""
664
+ Return ``True`` if ``z`` lies in the (strict) fundamental
665
+ domain of ``self``.
666
+
667
+ EXAMPLES::
668
+
669
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
670
+ sage: HeckeTriangleGroup(5).in_FD(CC(1.5/2 + 0.9*i))
671
+ True
672
+ sage: HeckeTriangleGroup(4).in_FD(CC(1.5/2 + 0.9*i))
673
+ False
674
+ """
675
+ return self.get_FD(z)[0] == self.I()
676
+
677
+ def root_extension_field(self, D):
678
+ r"""
679
+ Return the quadratic extension field of the base field by
680
+ the square root of the given discriminant ``D``.
681
+
682
+ INPUT:
683
+
684
+ - ``D`` -- an element of the base ring of ``self``
685
+ corresponding to a discriminant
686
+
687
+ OUTPUT:
688
+
689
+ A relative (at most quadratic) extension to the base field
690
+ of ``self`` in the variable ``e`` which corresponds to ``sqrt(D)``.
691
+ If the extension degree is ``1`` then the base field is returned.
692
+
693
+ The correct embedding is the positive resp. positive imaginary one.
694
+ Unfortunately no default embedding can be specified for relative
695
+ number fields yet.
696
+
697
+ EXAMPLES::
698
+
699
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
700
+ sage: G = HeckeTriangleGroup(n=infinity)
701
+ sage: G.root_extension_field(32)
702
+ Number Field in e with defining polynomial x^2 - 32
703
+ sage: G.root_extension_field(-4)
704
+ Number Field in e with defining polynomial x^2 + 4
705
+ sage: G.root_extension_field(4) == G.base_field()
706
+ True
707
+
708
+ sage: G = HeckeTriangleGroup(n=7)
709
+ sage: lam = G.lam()
710
+ sage: D = 4*lam^2 + 4*lam - 4
711
+ sage: G.root_extension_field(D)
712
+ Number Field in e with defining polynomial x^2 - 4*lam^2 - 4*lam + 4 over its base field
713
+ sage: G.root_extension_field(4) == G.base_field()
714
+ True
715
+ sage: D = lam^2 - 4
716
+ sage: G.root_extension_field(D)
717
+ Number Field in e with defining polynomial x^2 - lam^2 + 4 over its base field
718
+ """
719
+ K = self.base_field()
720
+ x = PolynomialRing(K, 'x').gen()
721
+ D = self.base_ring()(D)
722
+
723
+ if D.is_square():
724
+ return K
725
+ else:
726
+ # unfortunately we can't set embeddings for relative extensions :-(
727
+ # return K.extension(x**2 - D, 'e', embedding=AA(D).sqrt())
728
+
729
+ L = K.extension(x**2 - D, 'e')
730
+
731
+ # e = AA(D).sqrt()
732
+ # emb = L.hom([e])
733
+ # L._unset_embedding()
734
+ # L.register_embedding(emb)
735
+
736
+ # return NumberField(L.absolute_polynomial(), 'e', structure=AbsoluteFromRelative(L), embedding=(???))
737
+ return L
738
+
739
+ # We cache this method for performance reasons (it is repeatedly reused)
740
+ @cached_method
741
+ def root_extension_embedding(self, D, K=None):
742
+ r"""
743
+ Return the correct embedding from the root extension field
744
+ of the given discriminant ``D`` to the field ``K``.
745
+
746
+ Also see the method ``root_extension_embedding(K)`` of
747
+ ``HeckeTriangleGroupElement`` for more examples.
748
+
749
+ INPUT:
750
+
751
+ - ``D`` -- an element of the base ring of ``self``
752
+ corresponding to a discriminant
753
+
754
+ - ``K`` -- a field to which we want the (correct) embedding;
755
+ if ``K=None`` (default) then ``AlgebraicField()`` is
756
+ used for positive ``D`` and ``AlgebraicRealField()``
757
+ otherwise
758
+
759
+ OUTPUT:
760
+
761
+ The corresponding embedding if it was found.
762
+ Otherwise a :exc:`ValueError` is raised.
763
+
764
+ EXAMPLES::
765
+
766
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
767
+ sage: G = HeckeTriangleGroup(n=infinity)
768
+ sage: G.root_extension_embedding(32)
769
+ Ring morphism:
770
+ From: Number Field in e with defining polynomial x^2 - 32
771
+ To: Algebraic Real Field
772
+ Defn: e |--> 5.656854249492...?
773
+ sage: G.root_extension_embedding(-4)
774
+ Ring morphism:
775
+ From: Number Field in e with defining polynomial x^2 + 4
776
+ To: Algebraic Field
777
+ Defn: e |--> 2*I
778
+ sage: G.root_extension_embedding(4)
779
+ Coercion map:
780
+ From: Rational Field
781
+ To: Algebraic Real Field
782
+
783
+ sage: G = HeckeTriangleGroup(n=7)
784
+ sage: lam = G.lam()
785
+ sage: D = 4*lam^2 + 4*lam - 4
786
+ sage: G.root_extension_embedding(D, CC)
787
+ Relative number field morphism:
788
+ From: Number Field in e with defining polynomial x^2 - 4*lam^2 - 4*lam + 4 over its base field
789
+ To: Complex Field with 53 bits of precision
790
+ Defn: e |--> 4.02438434522...
791
+ lam |--> 1.80193773580...
792
+ sage: D = lam^2 - 4
793
+ sage: G.root_extension_embedding(D)
794
+ Relative number field morphism:
795
+ From: Number Field in e with defining polynomial x^2 - lam^2 + 4 over its base field
796
+ To: Algebraic Field
797
+ Defn: e |--> 0.?... + 0.867767478235...?*I
798
+ lam |--> 1.801937735804...?
799
+ """
800
+ D = self.base_ring()(D)
801
+ F = self.root_extension_field(D)
802
+ if K is None:
803
+ if coerce_AA(D) > 0:
804
+ K = AA
805
+ else:
806
+ K = AlgebraicField()
807
+
808
+ L = list(F.embeddings(K))
809
+
810
+ # Three possibilities up to numerical artefacts:
811
+ # (1) emb = e, purely imaginary
812
+ # (2) emb = e or lam (can't distinguish), purely real
813
+ # (3) emb = (e,lam), e purely imaginary, lam purely real
814
+ # (4) emb = (e,lam), e purely real, lam purely real
815
+ # There always exists one emb with "e" positive resp. positive imaginary
816
+ # and if there is a lam there exists a positive one...
817
+ #
818
+ # Criteria to pick the correct "maximum":
819
+ # 1. First figure out if e resp. lam is purely real or imaginary
820
+ # (using "abs(e.imag()) > abs(e.real())")
821
+ # 2. In the purely imaginary case we don't want anything negative imaginary
822
+ # and we know the positive case is unique after sorting lam
823
+ # 3. For the remaining cases we want the biggest real part
824
+ # (and lam should get comparison priority)
825
+ def emb_key(emb):
826
+ L = []
827
+ gens_len = len(emb.im_gens())
828
+ for k in range(gens_len):
829
+ a = emb.im_gens()[k]
830
+ try:
831
+ a.simplify()
832
+ a.exactify()
833
+ except AttributeError:
834
+ pass
835
+ # If a is purely imaginary:
836
+ if abs(a.imag()) > abs(a.real()):
837
+ if a.imag() < 0:
838
+ a = -infinity
839
+ else:
840
+ a = ZZ(0)
841
+ else:
842
+ a = a.real()
843
+
844
+ L.append(a)
845
+
846
+ L.reverse()
847
+ return L
848
+
849
+ if len(L) > 1:
850
+ L.sort(key=emb_key)
851
+ return L[-1]
852
+
853
+ def _elliptic_conj_reps(self):
854
+ r"""
855
+ Store all elliptic conjugacy representatives in the
856
+ internal dictionary. This is a helper function
857
+ used by :meth:`_conjugacy_representatives`.
858
+
859
+ EXAMPLES::
860
+
861
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
862
+ sage: G = HeckeTriangleGroup(n=5)
863
+ sage: G.element_repr_method("conj")
864
+ sage: G._elliptic_conj_reps()
865
+ sage: sorted(G._conj_prim.items())
866
+ [(-4, [[S], [S]]), (lam - 3, [[U], [U]]), (0, [[V(4)]])]
867
+ sage: sorted(G._conj_nonprim.items())
868
+ [(-lam - 2, [[U^(-2)], [U^2], [U^(-2)], [U^2]]), (lam - 3, [[U^(-1)], [U^(-1)]])]
869
+ """
870
+ if not hasattr(self, "_max_block_length"):
871
+ self._conjugacy_representatives()
872
+ elif ZZ(-4) in self._conj_prim:
873
+ return
874
+
875
+ D = self.U().discriminant()
876
+ if D not in self._conj_prim:
877
+ self._conj_prim[D] = []
878
+ self._conj_prim[D].append(self.U())
879
+
880
+ D = self.S().discriminant()
881
+ if D not in self._conj_prim:
882
+ self._conj_prim[D] = []
883
+ self._conj_prim[D].append(self.S())
884
+
885
+ other_reps = [self.U()**k
886
+ for k in range(-((self.n() - 1) / 2).floor(),
887
+ self.n() // 2 + 1)
888
+ if k not in [0, 1]]
889
+
890
+ for v in other_reps:
891
+ D = v.discriminant()
892
+ if D not in self._conj_nonprim:
893
+ self._conj_nonprim[D] = []
894
+ self._conj_nonprim[D].append(v)
895
+
896
+ def _conjugacy_representatives(self, max_block_length=0, D=None):
897
+ r"""
898
+ Store conjugacy representatives up to block length
899
+ ``max_block_length`` (a nonnegative integer, default: 0)
900
+ in the internal dictionary. Previously calculated data is reused.
901
+ This is a helper function for e.g. :meth:`class_number`.
902
+
903
+ The set of all (hyperbolic) conjugacy types of block length
904
+ ``t`` is stored in ``self._conj_block[t]``.
905
+ The set of all primitive representatives (so far) with
906
+ discriminant ``D`` is stored in ``self._conj_prim[D]``.
907
+ The set of all non-primitive representatives (so far) with
908
+ discriminant ``D`` is stored in ``self._conj_nonprim[D]``.
909
+
910
+ The case of nonpositive discriminants is done manually.
911
+
912
+ INPUT:
913
+
914
+ - ``max_block_length`` -- nonnegative integer (default: `0`); the
915
+ maximal block length
916
+
917
+ - ``D`` -- an element/discriminant of the base ring or more generally
918
+ an upper bound for the involved discriminants. If ``D != None`` then
919
+ an upper bound for ``max_block_length`` is deduced from ``D``
920
+ (default: ``None``).
921
+
922
+ EXAMPLES::
923
+
924
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
925
+ sage: G = HeckeTriangleGroup(n=5)
926
+ sage: G.element_repr_method("conj")
927
+ sage: G._conjugacy_representatives(2)
928
+
929
+ sage: sorted(G._conj_block[2])
930
+ [((2, 1), (1, 1)),
931
+ ((2, 2),),
932
+ ((3, 1), (1, 1)),
933
+ ((3, 1), (2, 1)),
934
+ ((3, 2),),
935
+ ((4, 1), (1, 1)),
936
+ ((4, 1), (2, 1)),
937
+ ((4, 1), (3, 1))]
938
+
939
+ sage: [key for key in sorted(G._conj_prim)]
940
+ [-4, lam - 3, 0, 4*lam, 7*lam + 6, 9*lam + 5, 15*lam + 6, 33*lam + 21]
941
+ sage: for key in sorted(G._conj_prim):
942
+ ....: print(sorted(G._conj_prim[key]))
943
+ [[S], [S]]
944
+ [[U], [U]]
945
+ [[V(4)]]
946
+ [[V(3)], [V(2)]]
947
+ [[V(1)*V(4)]]
948
+ [[V(3)*V(4)], [V(1)*V(2)]]
949
+ [[V(2)*V(4)], [V(1)*V(3)]]
950
+ [[V(2)*V(3)]]
951
+ sage: [key for key in sorted(G._conj_nonprim)]
952
+ [-lam - 2, lam - 3, 32*lam + 16]
953
+
954
+ sage: for key in sorted(G._conj_nonprim):
955
+ ....: print(sorted(G._conj_nonprim[key]))
956
+ [[U^(-2)], [U^(-2)], [U^2], [U^2]]
957
+ [[U^(-1)], [U^(-1)]]
958
+ [[V(3)^2], [V(2)^2]]
959
+
960
+ sage: G.element_repr_method("default")
961
+ """
962
+ from sage.combinat.partition import OrderedPartitions
963
+ from sage.combinat.combinat import tuples
964
+
965
+ if D is not None:
966
+ max_block_length = max(AA.zero(),
967
+ coerce_AA((D + 4)/(self.lam()**2))).sqrt().floor()
968
+ else:
969
+ try:
970
+ max_block_length = ZZ(max_block_length)
971
+ if max_block_length < 0:
972
+ raise TypeError
973
+ except TypeError:
974
+ raise ValueError("max_block_length must be a nonnegative integer!")
975
+
976
+ if not hasattr(self, "_max_block_length"):
977
+ self._max_block_length = ZZ.zero()
978
+ self._conj_block = {}
979
+ self._conj_nonprim = {}
980
+ self._conj_prim = {}
981
+
982
+ # It is not clear how to define the class number for D=0:
983
+ # Conjugacy classes are V(n-1)^(+-k) for arbitrary k
984
+ # and the trivial class (what about self_conj_block[0]?).
985
+ #
986
+ # One way is to define it using the fixed points and in
987
+ # that case V(n-1) would be a good representative.
988
+ # The non-primitive case is unclear however...
989
+ #
990
+ # We set it here to ensure that 0 is enlisted as a discriminant...
991
+ #
992
+ self._conj_prim[ZZ.zero()] = []
993
+ self._conj_prim[ZZ.zero()].append(self.V(self.n()-1))
994
+
995
+ self._elliptic_conj_reps()
996
+
997
+ if max_block_length <= self._max_block_length:
998
+ return
999
+
1000
+ def is_cycle(seq) -> bool:
1001
+ length = len(seq)
1002
+ for n in divisors(length):
1003
+ if n < length and is_cycle_of_length(seq, n):
1004
+ return True
1005
+ return False
1006
+
1007
+ def is_cycle_of_length(seq, n) -> bool:
1008
+ return all(seq[j] == seq[j % n] for j in range(n, len(seq)))
1009
+
1010
+ j_list = range(1, self.n())
1011
+
1012
+ for t in range(self._max_block_length + 1, max_block_length + 1):
1013
+ t_ZZ = ZZ(t)
1014
+ if t_ZZ not in self._conj_block:
1015
+ self._conj_block[t_ZZ] = set()
1016
+
1017
+ partitions = OrderedPartitions(t).list()
1018
+ for par in partitions:
1019
+ len_par = len(par)
1020
+ exp_list = tuples(j_list, len_par)
1021
+ for ex in exp_list:
1022
+ keep = True
1023
+ if len_par > 1:
1024
+ for k in range(-1, len_par - 1):
1025
+ if ex[k] == ex[k + 1]:
1026
+ keep = False
1027
+ break
1028
+ # We don't want powers of V(1)
1029
+ elif ex[0] == 1:
1030
+ keep = False
1031
+ # But: Do we maybe want powers of V(n-1)??
1032
+ # For now we exclude the parabolic cases...
1033
+ elif ex[0] == self.n() - 1:
1034
+ keep = False
1035
+
1036
+ if keep:
1037
+ conj_type = cyclic_representative(tuple((ZZ(ex[k]), ZZ(par[k])) for k in range(len_par)))
1038
+ self._conj_block[t_ZZ].add(conj_type)
1039
+
1040
+ for el in self._conj_block[t_ZZ]:
1041
+ group_el = prod([self.V(el[k][0])**el[k][1] for k in range(len(el))])
1042
+
1043
+ D = group_el.discriminant()
1044
+ assert coerce_AA(D) > 0
1045
+
1046
+ # The primitive cases
1047
+ # if group_el.is_primitive():
1048
+ if not ((len(el) == 1 and el[0][1] > 1) or is_cycle(el)):
1049
+ if D not in self._conj_prim:
1050
+ self._conj_prim[D] = []
1051
+ self._conj_prim[D].append(group_el)
1052
+ # The remaining cases
1053
+ else:
1054
+ if D not in self._conj_nonprim:
1055
+ self._conj_nonprim[D] = []
1056
+ self._conj_nonprim[D].append(group_el)
1057
+
1058
+ self._max_block_length = max_block_length
1059
+
1060
+ def class_representatives(self, D, primitive=True):
1061
+ r"""
1062
+ Return a representative for each conjugacy class for the
1063
+ discriminant ``D`` (ignoring the sign).
1064
+
1065
+ If ``primitive=True`` only one representative for each
1066
+ fixed point is returned (ignoring sign).
1067
+
1068
+ INPUT:
1069
+
1070
+ - ``D`` -- an element of the base ring corresponding
1071
+ to a valid discriminant
1072
+
1073
+ - ``primitive`` -- if ``True`` (default) then only primitive
1074
+ representatives are considered
1075
+
1076
+ EXAMPLES::
1077
+
1078
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
1079
+ sage: G = HeckeTriangleGroup(n=4)
1080
+ sage: G.element_repr_method("conj")
1081
+
1082
+ sage: R = G.class_representatives(4)
1083
+ sage: R
1084
+ [[V(2)]]
1085
+ sage: [v.continued_fraction()[1] for v in R]
1086
+ [(2,)]
1087
+
1088
+ sage: R = G.class_representatives(0)
1089
+ sage: R
1090
+ [[V(3)]]
1091
+ sage: [v.continued_fraction()[1] for v in R]
1092
+ [(1, 2)]
1093
+
1094
+ sage: R = G.class_representatives(-4)
1095
+ sage: R
1096
+ [[S]]
1097
+ sage: R = G.class_representatives(-4, primitive=False)
1098
+ sage: R
1099
+ [[S], [U^2]]
1100
+
1101
+ sage: R = G.class_representatives(G.lam()^2 - 4)
1102
+ sage: R
1103
+ [[U]]
1104
+ sage: R = G.class_representatives(G.lam()^2 - 4, primitive=False)
1105
+ sage: R
1106
+ [[U], [U^(-1)]]
1107
+
1108
+ sage: R = G.class_representatives(14)
1109
+ sage: sorted(R)
1110
+ [[V(2)*V(3)], [V(1)*V(2)]]
1111
+ sage: sorted(v.continued_fraction()[1] for v in R)
1112
+ [(1, 2, 2), (3,)]
1113
+
1114
+ sage: R = G.class_representatives(32)
1115
+ sage: sorted(R)
1116
+ [[V(3)^2*V(1)], [V(1)^2*V(3)]]
1117
+ sage: [v.continued_fraction()[1] for v in sorted(R)]
1118
+ [(1, 2, 1, 3), (1, 4)]
1119
+
1120
+ sage: R = G.class_representatives(32, primitive=False)
1121
+ sage: sorted(R)
1122
+ [[V(3)^2*V(1)], [V(1)^2*V(3)], [V(2)^2]]
1123
+
1124
+ sage: G.element_repr_method("default")
1125
+ """
1126
+ if coerce_AA(D) == 0 and not primitive:
1127
+ raise ValueError("There are infinitely many non-primitive conjugacy classes of discriminant 0.")
1128
+
1129
+ self._conjugacy_representatives(D=D)
1130
+
1131
+ L = []
1132
+ if D in self._conj_prim:
1133
+ L += self._conj_prim[D]
1134
+ if not primitive and D in self._conj_nonprim:
1135
+ L += self._conj_nonprim[D]
1136
+
1137
+ if not L:
1138
+ raise ValueError("D = {} is not a{} discriminant for {}".format(D, " primitive" if primitive else "", self))
1139
+ else:
1140
+ return L
1141
+
1142
+ def class_number(self, D, primitive=True):
1143
+ r"""
1144
+ Return the class number of ``self`` for the discriminant ``D``.
1145
+
1146
+ This is the number of conjugacy classes of (primitive) elements
1147
+ of discriminant ``D``.
1148
+
1149
+ Note: Due to the 1-1 correspondence with hyperbolic fixed
1150
+ points resp. hyperbolic binary quadratic forms
1151
+ this also gives the class number in those cases.
1152
+
1153
+ INPUT:
1154
+
1155
+ - ``D`` -- an element of the base ring corresponding
1156
+ to a valid discriminant
1157
+
1158
+ - ``primitive`` -- if ``True`` (default) then only primitive
1159
+ elements are considered
1160
+
1161
+ EXAMPLES::
1162
+
1163
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
1164
+ sage: G = HeckeTriangleGroup(n=4)
1165
+
1166
+ sage: G.class_number(4)
1167
+ 1
1168
+ sage: G.class_number(4, primitive=False)
1169
+ 1
1170
+ sage: G.class_number(14)
1171
+ 2
1172
+ sage: G.class_number(32)
1173
+ 2
1174
+ sage: G.class_number(32, primitive=False)
1175
+ 3
1176
+ sage: G.class_number(68)
1177
+ 4
1178
+ """
1179
+
1180
+ if coerce_AA(D) <= 0:
1181
+ raise NotImplementedError
1182
+
1183
+ self._conjugacy_representatives(D=D)
1184
+
1185
+ num = ZZ(0)
1186
+ if D in self._conj_prim:
1187
+ num = len(self._conj_prim[D])
1188
+ if not primitive and D in self._conj_nonprim:
1189
+ num += len(self._conj_nonprim[D])
1190
+
1191
+ if num == 0:
1192
+ raise ValueError("D = {} is not a{} discriminant for {}".format(D, " primitive" if primitive else "", self))
1193
+ else:
1194
+ return num
1195
+
1196
+ def is_discriminant(self, D, primitive=True) -> bool:
1197
+ r"""
1198
+ Return whether ``D`` is a discriminant of an element of ``self``.
1199
+
1200
+ Note: Checking that something isn't a discriminant takes much
1201
+ longer than checking for valid discriminants.
1202
+
1203
+ INPUT:
1204
+
1205
+ - ``D`` -- an element of the base ring
1206
+
1207
+ - ``primitive`` -- if ``True`` (default) then only primitive
1208
+ elements are considered
1209
+
1210
+ OUTPUT:
1211
+
1212
+ ``True`` if ``D`` is a primitive discriminant (a discriminant of
1213
+ a primitive element) and ``False`` otherwise.
1214
+ If ``primitive=False`` then also non-primitive elements are considered.
1215
+
1216
+ EXAMPLES::
1217
+
1218
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
1219
+ sage: G = HeckeTriangleGroup(n=4)
1220
+
1221
+ sage: G.is_discriminant(68)
1222
+ True
1223
+ sage: G.is_discriminant(196, primitive=False) # long time
1224
+ True
1225
+ sage: G.is_discriminant(2)
1226
+ False
1227
+ """
1228
+ self._conjugacy_representatives(0)
1229
+ t_bound = max(AA.zero(),
1230
+ coerce_AA((D + 4) / (self.lam()**2))).sqrt().floor()
1231
+ for t in range(self._max_block_length + 1, t_bound + 1):
1232
+ self._conjugacy_representatives(t)
1233
+
1234
+ if D in self._conj_prim:
1235
+ return True
1236
+ if not primitive and D in self._conj_nonprim:
1237
+ return True
1238
+
1239
+ if D in self._conj_prim:
1240
+ return True
1241
+ return not primitive and D in self._conj_nonprim
1242
+
1243
+ def list_discriminants(self, D, primitive=True, hyperbolic=True, incomplete=False):
1244
+ r"""
1245
+ Return a list of all discriminants up to some upper bound ``D``.
1246
+
1247
+ INPUT:
1248
+
1249
+ - ``D`` -- an element/discriminant of the base ring or
1250
+ more generally an upper bound for the discriminant
1251
+
1252
+ - ``primitive`` -- if ``True`` (default) then only primitive
1253
+ discriminants are listed
1254
+
1255
+ - ``hyperbolic`` -- if ``True`` (default) then only positive
1256
+ discriminants are listed
1257
+
1258
+ - ``incomplete`` -- if ``True`` (default: ``False``) then all
1259
+ (also higher) discriminants which were gathered so far are listed
1260
+ (however there might be missing discriminants in between).
1261
+
1262
+ OUTPUT: list of discriminants less than or equal to ``D``
1263
+
1264
+ EXAMPLES::
1265
+
1266
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
1267
+ sage: G = HeckeTriangleGroup(n=4)
1268
+ sage: G.list_discriminants(D=68)
1269
+ [4, 12, 14, 28, 32, 46, 60, 68]
1270
+ sage: G.list_discriminants(D=0, hyperbolic=False, primitive=False)
1271
+ [-4, -2, 0]
1272
+
1273
+ sage: G = HeckeTriangleGroup(n=5)
1274
+ sage: G.list_discriminants(D=20)
1275
+ [4*lam, 7*lam + 6, 9*lam + 5]
1276
+ sage: G.list_discriminants(D=0, hyperbolic=False, primitive=False)
1277
+ [-4, -lam - 2, lam - 3, 0]
1278
+ """
1279
+
1280
+ self._conjugacy_representatives(D=D)
1281
+
1282
+ if incomplete:
1283
+ max_D = infinity
1284
+ else:
1285
+ max_D = coerce_AA(D)
1286
+
1287
+ if hyperbolic:
1288
+ L = [key for key in self._conj_prim if 0 < coerce_AA(key) <= max_D]
1289
+ else:
1290
+ L = [key for key in self._conj_prim if coerce_AA(key) <= max_D]
1291
+
1292
+ if not primitive:
1293
+ if hyperbolic:
1294
+ L += [key for key in self._conj_nonprim
1295
+ if 0 < coerce_AA(key) <= max_D and key not in L]
1296
+ else:
1297
+ L += [key for key in self._conj_nonprim
1298
+ if coerce_AA(key) <= max_D and key not in L]
1299
+
1300
+ return sorted(L, key=coerce_AA)
1301
+
1302
+ # TODO: non-primitive ones?
1303
+ def reduced_elements(self, D):
1304
+ r"""
1305
+ Return all reduced (primitive) elements of discriminant ``D``.
1306
+
1307
+ Also see the element method :meth:`is_reduced` for more information.
1308
+
1309
+ - ``D`` -- an element of the base ring corresponding
1310
+ to a valid discriminant
1311
+
1312
+ EXAMPLES::
1313
+
1314
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
1315
+ sage: G = HeckeTriangleGroup(n=4)
1316
+ sage: R = G.reduced_elements(D=12)
1317
+ sage: R
1318
+ [
1319
+ [ 5 -lam] [ 5 -3*lam]
1320
+ [3*lam -1], [ lam -1]
1321
+ ]
1322
+ sage: [v.continued_fraction() for v in R]
1323
+ [((), (1, 3)), ((), (3, 1))]
1324
+ sage: R = G.reduced_elements(D=14)
1325
+ sage: sorted(R)
1326
+ [
1327
+ [3*lam -1] [4*lam -3] [ 5*lam -7] [ 5*lam -3]
1328
+ [ 1 0], [ 3 -lam], [ 3 -2*lam], [ 7 -2*lam]
1329
+ ]
1330
+ sage: sorted(v.continued_fraction() for v in R)
1331
+ [((), (1, 2, 2)), ((), (2, 1, 2)), ((), (2, 2, 1)), ((), (3,))]
1332
+ """
1333
+ L = self.class_representatives(D=D, primitive=True)
1334
+ R = []
1335
+ for v in L:
1336
+ R += v.reduced_elements()
1337
+
1338
+ return R
1339
+
1340
+ def simple_elements(self, D):
1341
+ r"""
1342
+ Return all simple elements of discriminant ``D``.
1343
+
1344
+ Also see the element method ``is_simple()`` for more information.
1345
+
1346
+ - ``D`` -- an element of the base ring corresponding to a valid
1347
+ discriminant
1348
+
1349
+ EXAMPLES::
1350
+
1351
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
1352
+ sage: G = HeckeTriangleGroup(n=4)
1353
+ sage: sorted(G.simple_elements(D=12))
1354
+ [
1355
+ [ 1 lam] [ 3 lam]
1356
+ [lam 3], [lam 1]
1357
+ ]
1358
+ sage: sorted(G.simple_elements(D=14))
1359
+ [
1360
+ [ lam 1] [ lam 3] [2*lam 1] [2*lam 3]
1361
+ [ 3 2*lam], [ 1 2*lam], [ 3 lam], [ 1 lam]
1362
+ ]
1363
+ """
1364
+ L = self.class_representatives(D=D, primitive=True)
1365
+ R = []
1366
+ for v in L:
1367
+ R += v.simple_elements()
1368
+
1369
+ return R
1370
+
1371
+ def rational_period_functions(self, k, D):
1372
+ r"""
1373
+ Return a list of basic rational period functions of weight ``k`` for
1374
+ discriminant ``D``.
1375
+
1376
+ The list is expected to be a generating set for all rational
1377
+ period functions of the given weight and discriminant (unknown).
1378
+
1379
+ The method assumes that ``D > 0``.
1380
+
1381
+ Also see the element method ``rational_period_function`` for more information.
1382
+
1383
+ - ``k`` -- even integer, the desired weight of the rational period
1384
+ functions
1385
+
1386
+ - ``D`` -- an element of the base ring corresponding to a valid
1387
+ discriminant
1388
+
1389
+ EXAMPLES::
1390
+
1391
+ sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
1392
+ sage: G = HeckeTriangleGroup(n=4)
1393
+ sage: sorted(G.rational_period_functions(k=4, D=12))
1394
+ [(z^4 - 1)/z^4]
1395
+ sage: sorted(G.rational_period_functions(k=-2, D=12))
1396
+ [-z^2 + 1, 4*lam*z^2 - 4*lam]
1397
+ sage: sorted(G.rational_period_functions(k=2, D=14))
1398
+ [(24*z^6 - 120*z^4 + 120*z^2 - 24)/(9*z^8 - 80*z^6 + 146*z^4 - 80*z^2 + 9),
1399
+ (24*z^6 - 120*z^4 + 120*z^2 - 24)/(9*z^8 - 80*z^6 + 146*z^4 - 80*z^2 + 9),
1400
+ 1/z,
1401
+ (z^2 - 1)/z^2]
1402
+ sage: sorted(G.rational_period_functions(k=-4, D=14))
1403
+ [-16*z^4 + 16, -z^4 + 1, 16*z^4 - 16]
1404
+ """
1405
+ try:
1406
+ k = ZZ(k)
1407
+ if not ZZ(2).divides(k):
1408
+ raise TypeError
1409
+ except TypeError:
1410
+ raise ValueError(f"k={k} has to be an even integer!")
1411
+
1412
+ z = PolynomialRing(self.base_ring(), 'z').gen()
1413
+
1414
+ R = []
1415
+ if k != 0:
1416
+ R.append(ZZ(1) - z**(-k))
1417
+ if k == 2:
1418
+ R.append(z**(-1))
1419
+
1420
+ L = self.class_representatives(D=D, primitive=True)
1421
+ for v in L:
1422
+ rat = v.rational_period_function(k)
1423
+ if rat != 0:
1424
+ R.append(rat)
1425
+
1426
+ return R