passagemath-modules 10.6.31rc3__cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.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-modules might be problematic. Click here for more details.

Files changed (806) hide show
  1. passagemath_modules-10.6.31rc3.dist-info/METADATA +281 -0
  2. passagemath_modules-10.6.31rc3.dist-info/RECORD +806 -0
  3. passagemath_modules-10.6.31rc3.dist-info/WHEEL +6 -0
  4. passagemath_modules-10.6.31rc3.dist-info/top_level.txt +2 -0
  5. passagemath_modules.libs/libgfortran-e1b7dfc8.so.5.0.0 +0 -0
  6. passagemath_modules.libs/libgmp-93ebf16a.so.10.5.0 +0 -0
  7. passagemath_modules.libs/libgsl-e3525837.so.28.0.0 +0 -0
  8. passagemath_modules.libs/libmpc-c5c421e1.so.3.3.1 +0 -0
  9. passagemath_modules.libs/libmpfr-e0f11cf3.so.6.2.1 +0 -0
  10. passagemath_modules.libs/libopenblasp-r0-4c5b64b1.3.29.so +0 -0
  11. sage/algebras/all__sagemath_modules.py +20 -0
  12. sage/algebras/catalog.py +148 -0
  13. sage/algebras/clifford_algebra.py +3107 -0
  14. sage/algebras/clifford_algebra_element.cpython-314-aarch64-linux-gnu.so +0 -0
  15. sage/algebras/clifford_algebra_element.pxd +16 -0
  16. sage/algebras/clifford_algebra_element.pyx +997 -0
  17. sage/algebras/commutative_dga.py +4252 -0
  18. sage/algebras/exterior_algebra_groebner.cpython-314-aarch64-linux-gnu.so +0 -0
  19. sage/algebras/exterior_algebra_groebner.pxd +55 -0
  20. sage/algebras/exterior_algebra_groebner.pyx +727 -0
  21. sage/algebras/finite_dimensional_algebras/all.py +2 -0
  22. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra.py +1029 -0
  23. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.cpython-314-aarch64-linux-gnu.so +0 -0
  24. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pxd +12 -0
  25. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_element.pyx +706 -0
  26. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_ideal.py +196 -0
  27. sage/algebras/finite_dimensional_algebras/finite_dimensional_algebra_morphism.py +255 -0
  28. sage/algebras/finite_gca.py +528 -0
  29. sage/algebras/group_algebra.py +232 -0
  30. sage/algebras/lie_algebras/abelian.py +197 -0
  31. sage/algebras/lie_algebras/affine_lie_algebra.py +1213 -0
  32. sage/algebras/lie_algebras/all.py +25 -0
  33. sage/algebras/lie_algebras/all__sagemath_modules.py +1 -0
  34. sage/algebras/lie_algebras/bch.py +177 -0
  35. sage/algebras/lie_algebras/bgg_dual_module.py +1184 -0
  36. sage/algebras/lie_algebras/bgg_resolution.py +232 -0
  37. sage/algebras/lie_algebras/center_uea.py +767 -0
  38. sage/algebras/lie_algebras/classical_lie_algebra.py +2516 -0
  39. sage/algebras/lie_algebras/examples.py +683 -0
  40. sage/algebras/lie_algebras/free_lie_algebra.py +973 -0
  41. sage/algebras/lie_algebras/heisenberg.py +820 -0
  42. sage/algebras/lie_algebras/lie_algebra.py +1562 -0
  43. sage/algebras/lie_algebras/lie_algebra_element.cpython-314-aarch64-linux-gnu.so +0 -0
  44. sage/algebras/lie_algebras/lie_algebra_element.pxd +68 -0
  45. sage/algebras/lie_algebras/lie_algebra_element.pyx +2122 -0
  46. sage/algebras/lie_algebras/morphism.py +661 -0
  47. sage/algebras/lie_algebras/nilpotent_lie_algebra.py +457 -0
  48. sage/algebras/lie_algebras/onsager.py +1324 -0
  49. sage/algebras/lie_algebras/poincare_birkhoff_witt.py +816 -0
  50. sage/algebras/lie_algebras/quotient.py +462 -0
  51. sage/algebras/lie_algebras/rank_two_heisenberg_virasoro.py +355 -0
  52. sage/algebras/lie_algebras/representation.py +1040 -0
  53. sage/algebras/lie_algebras/structure_coefficients.py +459 -0
  54. sage/algebras/lie_algebras/subalgebra.py +967 -0
  55. sage/algebras/lie_algebras/symplectic_derivation.py +289 -0
  56. sage/algebras/lie_algebras/verma_module.py +1630 -0
  57. sage/algebras/lie_algebras/virasoro.py +1186 -0
  58. sage/algebras/octonion_algebra.cpython-314-aarch64-linux-gnu.so +0 -0
  59. sage/algebras/octonion_algebra.pxd +20 -0
  60. sage/algebras/octonion_algebra.pyx +987 -0
  61. sage/algebras/orlik_solomon.py +907 -0
  62. sage/algebras/orlik_terao.py +779 -0
  63. sage/algebras/steenrod/all.py +7 -0
  64. sage/algebras/steenrod/steenrod_algebra.py +4258 -0
  65. sage/algebras/steenrod/steenrod_algebra_bases.py +1179 -0
  66. sage/algebras/steenrod/steenrod_algebra_misc.py +1167 -0
  67. sage/algebras/steenrod/steenrod_algebra_mult.py +954 -0
  68. sage/algebras/weyl_algebra.py +1126 -0
  69. sage/all__sagemath_modules.py +62 -0
  70. sage/calculus/all__sagemath_modules.py +19 -0
  71. sage/calculus/expr.py +205 -0
  72. sage/calculus/integration.cpython-314-aarch64-linux-gnu.so +0 -0
  73. sage/calculus/integration.pyx +698 -0
  74. sage/calculus/interpolation.cpython-314-aarch64-linux-gnu.so +0 -0
  75. sage/calculus/interpolation.pxd +13 -0
  76. sage/calculus/interpolation.pyx +387 -0
  77. sage/calculus/interpolators.cpython-314-aarch64-linux-gnu.so +0 -0
  78. sage/calculus/interpolators.pyx +326 -0
  79. sage/calculus/ode.cpython-314-aarch64-linux-gnu.so +0 -0
  80. sage/calculus/ode.pxd +5 -0
  81. sage/calculus/ode.pyx +610 -0
  82. sage/calculus/riemann.cpython-314-aarch64-linux-gnu.so +0 -0
  83. sage/calculus/riemann.pyx +1521 -0
  84. sage/calculus/test_sympy.py +201 -0
  85. sage/calculus/transforms/all.py +7 -0
  86. sage/calculus/transforms/dft.py +844 -0
  87. sage/calculus/transforms/dwt.cpython-314-aarch64-linux-gnu.so +0 -0
  88. sage/calculus/transforms/dwt.pxd +7 -0
  89. sage/calculus/transforms/dwt.pyx +160 -0
  90. sage/calculus/transforms/fft.cpython-314-aarch64-linux-gnu.so +0 -0
  91. sage/calculus/transforms/fft.pxd +12 -0
  92. sage/calculus/transforms/fft.pyx +487 -0
  93. sage/calculus/wester.py +662 -0
  94. sage/coding/abstract_code.py +1108 -0
  95. sage/coding/ag_code.py +868 -0
  96. sage/coding/ag_code_decoders.cpython-314-aarch64-linux-gnu.so +0 -0
  97. sage/coding/ag_code_decoders.pyx +2639 -0
  98. sage/coding/all.py +15 -0
  99. sage/coding/bch_code.py +494 -0
  100. sage/coding/binary_code.cpython-314-aarch64-linux-gnu.so +0 -0
  101. sage/coding/binary_code.pxd +124 -0
  102. sage/coding/binary_code.pyx +4139 -0
  103. sage/coding/bounds_catalog.py +43 -0
  104. sage/coding/channel.py +819 -0
  105. sage/coding/channels_catalog.py +29 -0
  106. sage/coding/code_bounds.py +755 -0
  107. sage/coding/code_constructions.py +804 -0
  108. sage/coding/codes_catalog.py +111 -0
  109. sage/coding/cyclic_code.py +1329 -0
  110. sage/coding/databases.py +316 -0
  111. sage/coding/decoder.py +373 -0
  112. sage/coding/decoders_catalog.py +88 -0
  113. sage/coding/delsarte_bounds.py +709 -0
  114. sage/coding/encoder.py +390 -0
  115. sage/coding/encoders_catalog.py +64 -0
  116. sage/coding/extended_code.py +468 -0
  117. sage/coding/gabidulin_code.py +1058 -0
  118. sage/coding/golay_code.py +404 -0
  119. sage/coding/goppa_code.py +441 -0
  120. sage/coding/grs_code.py +2371 -0
  121. sage/coding/guava.py +107 -0
  122. sage/coding/guruswami_sudan/all.py +1 -0
  123. sage/coding/guruswami_sudan/gs_decoder.py +897 -0
  124. sage/coding/guruswami_sudan/interpolation.py +409 -0
  125. sage/coding/guruswami_sudan/utils.py +176 -0
  126. sage/coding/hamming_code.py +176 -0
  127. sage/coding/information_set_decoder.py +1032 -0
  128. sage/coding/kasami_codes.cpython-314-aarch64-linux-gnu.so +0 -0
  129. sage/coding/kasami_codes.pyx +351 -0
  130. sage/coding/linear_code.py +3067 -0
  131. sage/coding/linear_code_no_metric.py +1354 -0
  132. sage/coding/linear_rank_metric.py +961 -0
  133. sage/coding/parity_check_code.py +353 -0
  134. sage/coding/punctured_code.py +719 -0
  135. sage/coding/reed_muller_code.py +999 -0
  136. sage/coding/self_dual_codes.py +942 -0
  137. sage/coding/source_coding/all.py +2 -0
  138. sage/coding/source_coding/huffman.py +553 -0
  139. sage/coding/subfield_subcode.py +423 -0
  140. sage/coding/two_weight_db.py +399 -0
  141. sage/combinat/all__sagemath_modules.py +7 -0
  142. sage/combinat/cartesian_product.py +347 -0
  143. sage/combinat/family.py +11 -0
  144. sage/combinat/free_module.py +1977 -0
  145. sage/combinat/root_system/all.py +147 -0
  146. sage/combinat/root_system/ambient_space.py +527 -0
  147. sage/combinat/root_system/associahedron.py +471 -0
  148. sage/combinat/root_system/braid_move_calculator.py +143 -0
  149. sage/combinat/root_system/braid_orbit.cpython-314-aarch64-linux-gnu.so +0 -0
  150. sage/combinat/root_system/braid_orbit.pyx +144 -0
  151. sage/combinat/root_system/branching_rules.py +2301 -0
  152. sage/combinat/root_system/cartan_matrix.py +1245 -0
  153. sage/combinat/root_system/cartan_type.py +3069 -0
  154. sage/combinat/root_system/coxeter_group.py +162 -0
  155. sage/combinat/root_system/coxeter_matrix.py +1261 -0
  156. sage/combinat/root_system/coxeter_type.py +681 -0
  157. sage/combinat/root_system/dynkin_diagram.py +900 -0
  158. sage/combinat/root_system/extended_affine_weyl_group.py +2993 -0
  159. sage/combinat/root_system/fundamental_group.py +795 -0
  160. sage/combinat/root_system/hecke_algebra_representation.py +1203 -0
  161. sage/combinat/root_system/integrable_representations.py +1227 -0
  162. sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +1965 -0
  163. sage/combinat/root_system/pieri_factors.py +1147 -0
  164. sage/combinat/root_system/plot.py +1615 -0
  165. sage/combinat/root_system/root_lattice_realization_algebras.py +1214 -0
  166. sage/combinat/root_system/root_lattice_realizations.py +4628 -0
  167. sage/combinat/root_system/root_space.py +487 -0
  168. sage/combinat/root_system/root_system.py +882 -0
  169. sage/combinat/root_system/type_A.py +348 -0
  170. sage/combinat/root_system/type_A_affine.py +227 -0
  171. sage/combinat/root_system/type_A_infinity.py +241 -0
  172. sage/combinat/root_system/type_B.py +347 -0
  173. sage/combinat/root_system/type_BC_affine.py +287 -0
  174. sage/combinat/root_system/type_B_affine.py +216 -0
  175. sage/combinat/root_system/type_C.py +317 -0
  176. sage/combinat/root_system/type_C_affine.py +188 -0
  177. sage/combinat/root_system/type_D.py +357 -0
  178. sage/combinat/root_system/type_D_affine.py +208 -0
  179. sage/combinat/root_system/type_E.py +641 -0
  180. sage/combinat/root_system/type_E_affine.py +231 -0
  181. sage/combinat/root_system/type_F.py +387 -0
  182. sage/combinat/root_system/type_F_affine.py +137 -0
  183. sage/combinat/root_system/type_G.py +293 -0
  184. sage/combinat/root_system/type_G_affine.py +132 -0
  185. sage/combinat/root_system/type_H.py +105 -0
  186. sage/combinat/root_system/type_I.py +110 -0
  187. sage/combinat/root_system/type_Q.py +150 -0
  188. sage/combinat/root_system/type_affine.py +509 -0
  189. sage/combinat/root_system/type_dual.py +704 -0
  190. sage/combinat/root_system/type_folded.py +301 -0
  191. sage/combinat/root_system/type_marked.py +748 -0
  192. sage/combinat/root_system/type_reducible.py +601 -0
  193. sage/combinat/root_system/type_relabel.py +730 -0
  194. sage/combinat/root_system/type_super_A.py +837 -0
  195. sage/combinat/root_system/weight_lattice_realizations.py +1188 -0
  196. sage/combinat/root_system/weight_space.py +639 -0
  197. sage/combinat/root_system/weyl_characters.py +2238 -0
  198. sage/crypto/__init__.py +4 -0
  199. sage/crypto/all.py +28 -0
  200. sage/crypto/block_cipher/all.py +7 -0
  201. sage/crypto/block_cipher/des.py +1065 -0
  202. sage/crypto/block_cipher/miniaes.py +2171 -0
  203. sage/crypto/block_cipher/present.py +909 -0
  204. sage/crypto/block_cipher/sdes.py +1527 -0
  205. sage/crypto/boolean_function.cpython-314-aarch64-linux-gnu.so +0 -0
  206. sage/crypto/boolean_function.pxd +10 -0
  207. sage/crypto/boolean_function.pyx +1487 -0
  208. sage/crypto/cipher.py +78 -0
  209. sage/crypto/classical.py +3668 -0
  210. sage/crypto/classical_cipher.py +569 -0
  211. sage/crypto/cryptosystem.py +387 -0
  212. sage/crypto/key_exchange/all.py +7 -0
  213. sage/crypto/key_exchange/catalog.py +24 -0
  214. sage/crypto/key_exchange/diffie_hellman.py +323 -0
  215. sage/crypto/key_exchange/key_exchange_scheme.py +107 -0
  216. sage/crypto/lattice.py +312 -0
  217. sage/crypto/lfsr.py +295 -0
  218. sage/crypto/lwe.py +840 -0
  219. sage/crypto/mq/__init__.py +4 -0
  220. sage/crypto/mq/mpolynomialsystemgenerator.py +204 -0
  221. sage/crypto/mq/rijndael_gf.py +2345 -0
  222. sage/crypto/mq/sbox.py +7 -0
  223. sage/crypto/mq/sr.py +3344 -0
  224. sage/crypto/public_key/all.py +5 -0
  225. sage/crypto/public_key/blum_goldwasser.py +776 -0
  226. sage/crypto/sbox.cpython-314-aarch64-linux-gnu.so +0 -0
  227. sage/crypto/sbox.pyx +2090 -0
  228. sage/crypto/sboxes.py +2090 -0
  229. sage/crypto/stream.py +390 -0
  230. sage/crypto/stream_cipher.py +297 -0
  231. sage/crypto/util.py +519 -0
  232. sage/ext/all__sagemath_modules.py +1 -0
  233. sage/ext/interpreters/__init__.py +1 -0
  234. sage/ext/interpreters/all__sagemath_modules.py +2 -0
  235. sage/ext/interpreters/wrapper_cc.cpython-314-aarch64-linux-gnu.so +0 -0
  236. sage/ext/interpreters/wrapper_cc.pxd +30 -0
  237. sage/ext/interpreters/wrapper_cc.pyx +252 -0
  238. sage/ext/interpreters/wrapper_cdf.cpython-314-aarch64-linux-gnu.so +0 -0
  239. sage/ext/interpreters/wrapper_cdf.pxd +26 -0
  240. sage/ext/interpreters/wrapper_cdf.pyx +245 -0
  241. sage/ext/interpreters/wrapper_rdf.cpython-314-aarch64-linux-gnu.so +0 -0
  242. sage/ext/interpreters/wrapper_rdf.pxd +23 -0
  243. sage/ext/interpreters/wrapper_rdf.pyx +221 -0
  244. sage/ext/interpreters/wrapper_rr.cpython-314-aarch64-linux-gnu.so +0 -0
  245. sage/ext/interpreters/wrapper_rr.pxd +28 -0
  246. sage/ext/interpreters/wrapper_rr.pyx +335 -0
  247. sage/geometry/all__sagemath_modules.py +5 -0
  248. sage/geometry/toric_lattice.py +1745 -0
  249. sage/geometry/toric_lattice_element.cpython-314-aarch64-linux-gnu.so +0 -0
  250. sage/geometry/toric_lattice_element.pyx +432 -0
  251. sage/groups/abelian_gps/abelian_group.py +1925 -0
  252. sage/groups/abelian_gps/abelian_group_element.py +164 -0
  253. sage/groups/abelian_gps/all__sagemath_modules.py +5 -0
  254. sage/groups/abelian_gps/dual_abelian_group.py +421 -0
  255. sage/groups/abelian_gps/dual_abelian_group_element.py +179 -0
  256. sage/groups/abelian_gps/element_base.py +341 -0
  257. sage/groups/abelian_gps/values.py +488 -0
  258. sage/groups/additive_abelian/additive_abelian_group.py +476 -0
  259. sage/groups/additive_abelian/additive_abelian_wrapper.py +857 -0
  260. sage/groups/additive_abelian/all.py +4 -0
  261. sage/groups/additive_abelian/qmodnz.py +231 -0
  262. sage/groups/additive_abelian/qmodnz_element.py +349 -0
  263. sage/groups/affine_gps/affine_group.py +535 -0
  264. sage/groups/affine_gps/all.py +1 -0
  265. sage/groups/affine_gps/catalog.py +17 -0
  266. sage/groups/affine_gps/euclidean_group.py +246 -0
  267. sage/groups/affine_gps/group_element.py +562 -0
  268. sage/groups/all__sagemath_modules.py +12 -0
  269. sage/groups/galois_group.py +479 -0
  270. sage/groups/matrix_gps/all.py +4 -0
  271. sage/groups/matrix_gps/all__sagemath_modules.py +13 -0
  272. sage/groups/matrix_gps/catalog.py +26 -0
  273. sage/groups/matrix_gps/coxeter_group.py +927 -0
  274. sage/groups/matrix_gps/finitely_generated.py +487 -0
  275. sage/groups/matrix_gps/group_element.cpython-314-aarch64-linux-gnu.so +0 -0
  276. sage/groups/matrix_gps/group_element.pxd +11 -0
  277. sage/groups/matrix_gps/group_element.pyx +431 -0
  278. sage/groups/matrix_gps/linear.py +440 -0
  279. sage/groups/matrix_gps/matrix_group.py +617 -0
  280. sage/groups/matrix_gps/named_group.py +296 -0
  281. sage/groups/matrix_gps/orthogonal.py +544 -0
  282. sage/groups/matrix_gps/symplectic.py +251 -0
  283. sage/groups/matrix_gps/unitary.py +436 -0
  284. sage/groups/misc_gps/all__sagemath_modules.py +1 -0
  285. sage/groups/misc_gps/argument_groups.py +1905 -0
  286. sage/groups/misc_gps/imaginary_groups.py +479 -0
  287. sage/groups/perm_gps/all__sagemath_modules.py +1 -0
  288. sage/groups/perm_gps/partn_ref/all__sagemath_modules.py +1 -0
  289. sage/groups/perm_gps/partn_ref/refinement_binary.cpython-314-aarch64-linux-gnu.so +0 -0
  290. sage/groups/perm_gps/partn_ref/refinement_binary.pxd +41 -0
  291. sage/groups/perm_gps/partn_ref/refinement_binary.pyx +1167 -0
  292. sage/groups/perm_gps/partn_ref/refinement_matrices.cpython-314-aarch64-linux-gnu.so +0 -0
  293. sage/groups/perm_gps/partn_ref/refinement_matrices.pxd +31 -0
  294. sage/groups/perm_gps/partn_ref/refinement_matrices.pyx +385 -0
  295. sage/homology/algebraic_topological_model.py +595 -0
  296. sage/homology/all.py +2 -0
  297. sage/homology/all__sagemath_modules.py +8 -0
  298. sage/homology/chain_complex.py +2148 -0
  299. sage/homology/chain_complex_homspace.py +165 -0
  300. sage/homology/chain_complex_morphism.py +629 -0
  301. sage/homology/chain_homotopy.py +604 -0
  302. sage/homology/chains.py +653 -0
  303. sage/homology/free_resolution.py +923 -0
  304. sage/homology/graded_resolution.py +567 -0
  305. sage/homology/hochschild_complex.py +756 -0
  306. sage/homology/homology_group.py +188 -0
  307. sage/homology/homology_morphism.py +422 -0
  308. sage/homology/homology_vector_space_with_basis.py +1454 -0
  309. sage/homology/koszul_complex.py +169 -0
  310. sage/homology/matrix_utils.py +205 -0
  311. sage/libs/all__sagemath_modules.py +1 -0
  312. sage/libs/gsl/__init__.py +1 -0
  313. sage/libs/gsl/airy.pxd +56 -0
  314. sage/libs/gsl/all.pxd +66 -0
  315. sage/libs/gsl/array.cpython-314-aarch64-linux-gnu.so +0 -0
  316. sage/libs/gsl/array.pxd +5 -0
  317. sage/libs/gsl/array.pyx +102 -0
  318. sage/libs/gsl/bessel.pxd +208 -0
  319. sage/libs/gsl/blas.pxd +116 -0
  320. sage/libs/gsl/blas_types.pxd +34 -0
  321. sage/libs/gsl/block.pxd +52 -0
  322. sage/libs/gsl/chebyshev.pxd +37 -0
  323. sage/libs/gsl/clausen.pxd +12 -0
  324. sage/libs/gsl/combination.pxd +47 -0
  325. sage/libs/gsl/complex.pxd +151 -0
  326. sage/libs/gsl/coulomb.pxd +30 -0
  327. sage/libs/gsl/coupling.pxd +21 -0
  328. sage/libs/gsl/dawson.pxd +12 -0
  329. sage/libs/gsl/debye.pxd +24 -0
  330. sage/libs/gsl/dilog.pxd +14 -0
  331. sage/libs/gsl/eigen.pxd +46 -0
  332. sage/libs/gsl/elementary.pxd +12 -0
  333. sage/libs/gsl/ellint.pxd +48 -0
  334. sage/libs/gsl/elljac.pxd +8 -0
  335. sage/libs/gsl/erf.pxd +32 -0
  336. sage/libs/gsl/errno.pxd +26 -0
  337. sage/libs/gsl/exp.pxd +44 -0
  338. sage/libs/gsl/expint.pxd +44 -0
  339. sage/libs/gsl/fermi_dirac.pxd +44 -0
  340. sage/libs/gsl/fft.pxd +121 -0
  341. sage/libs/gsl/fit.pxd +50 -0
  342. sage/libs/gsl/gamma.pxd +94 -0
  343. sage/libs/gsl/gegenbauer.pxd +26 -0
  344. sage/libs/gsl/histogram.pxd +176 -0
  345. sage/libs/gsl/hyperg.pxd +52 -0
  346. sage/libs/gsl/integration.pxd +69 -0
  347. sage/libs/gsl/interp.pxd +109 -0
  348. sage/libs/gsl/laguerre.pxd +24 -0
  349. sage/libs/gsl/lambert.pxd +16 -0
  350. sage/libs/gsl/legendre.pxd +90 -0
  351. sage/libs/gsl/linalg.pxd +185 -0
  352. sage/libs/gsl/log.pxd +26 -0
  353. sage/libs/gsl/math.pxd +43 -0
  354. sage/libs/gsl/matrix.pxd +143 -0
  355. sage/libs/gsl/matrix_complex.pxd +130 -0
  356. sage/libs/gsl/min.pxd +67 -0
  357. sage/libs/gsl/monte.pxd +56 -0
  358. sage/libs/gsl/ntuple.pxd +32 -0
  359. sage/libs/gsl/odeiv.pxd +70 -0
  360. sage/libs/gsl/permutation.pxd +78 -0
  361. sage/libs/gsl/poly.pxd +40 -0
  362. sage/libs/gsl/pow_int.pxd +12 -0
  363. sage/libs/gsl/psi.pxd +28 -0
  364. sage/libs/gsl/qrng.pxd +29 -0
  365. sage/libs/gsl/random.pxd +257 -0
  366. sage/libs/gsl/rng.pxd +100 -0
  367. sage/libs/gsl/roots.pxd +72 -0
  368. sage/libs/gsl/sort.pxd +36 -0
  369. sage/libs/gsl/statistics.pxd +59 -0
  370. sage/libs/gsl/sum.pxd +55 -0
  371. sage/libs/gsl/synchrotron.pxd +16 -0
  372. sage/libs/gsl/transport.pxd +24 -0
  373. sage/libs/gsl/trig.pxd +58 -0
  374. sage/libs/gsl/types.pxd +137 -0
  375. sage/libs/gsl/vector.pxd +101 -0
  376. sage/libs/gsl/vector_complex.pxd +83 -0
  377. sage/libs/gsl/wavelet.pxd +49 -0
  378. sage/libs/gsl/zeta.pxd +28 -0
  379. sage/libs/mpc/__init__.pxd +114 -0
  380. sage/libs/mpc/types.pxd +28 -0
  381. sage/libs/mpfr/__init__.pxd +299 -0
  382. sage/libs/mpfr/types.pxd +26 -0
  383. sage/libs/mpmath/__init__.py +1 -0
  384. sage/libs/mpmath/all.py +27 -0
  385. sage/libs/mpmath/all__sagemath_modules.py +1 -0
  386. sage/libs/mpmath/utils.cpython-314-aarch64-linux-gnu.so +0 -0
  387. sage/libs/mpmath/utils.pxd +4 -0
  388. sage/libs/mpmath/utils.pyx +319 -0
  389. sage/matrix/action.cpython-314-aarch64-linux-gnu.so +0 -0
  390. sage/matrix/action.pxd +26 -0
  391. sage/matrix/action.pyx +596 -0
  392. sage/matrix/all.py +9 -0
  393. sage/matrix/args.cpython-314-aarch64-linux-gnu.so +0 -0
  394. sage/matrix/args.pxd +144 -0
  395. sage/matrix/args.pyx +1668 -0
  396. sage/matrix/benchmark.py +1258 -0
  397. sage/matrix/berlekamp_massey.py +95 -0
  398. sage/matrix/compute_J_ideal.py +926 -0
  399. sage/matrix/constructor.cpython-314-aarch64-linux-gnu.so +0 -0
  400. sage/matrix/constructor.pyx +750 -0
  401. sage/matrix/docs.py +430 -0
  402. sage/matrix/echelon_matrix.cpython-314-aarch64-linux-gnu.so +0 -0
  403. sage/matrix/echelon_matrix.pyx +155 -0
  404. sage/matrix/matrix.pxd +2 -0
  405. sage/matrix/matrix0.cpython-314-aarch64-linux-gnu.so +0 -0
  406. sage/matrix/matrix0.pxd +68 -0
  407. sage/matrix/matrix0.pyx +6324 -0
  408. sage/matrix/matrix1.cpython-314-aarch64-linux-gnu.so +0 -0
  409. sage/matrix/matrix1.pxd +8 -0
  410. sage/matrix/matrix1.pyx +2851 -0
  411. sage/matrix/matrix2.cpython-314-aarch64-linux-gnu.so +0 -0
  412. sage/matrix/matrix2.pxd +25 -0
  413. sage/matrix/matrix2.pyx +20181 -0
  414. sage/matrix/matrix_cdv.cpython-314-aarch64-linux-gnu.so +0 -0
  415. sage/matrix/matrix_cdv.pxd +4 -0
  416. sage/matrix/matrix_cdv.pyx +93 -0
  417. sage/matrix/matrix_complex_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  418. sage/matrix/matrix_complex_double_dense.pxd +5 -0
  419. sage/matrix/matrix_complex_double_dense.pyx +98 -0
  420. sage/matrix/matrix_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  421. sage/matrix/matrix_dense.pxd +5 -0
  422. sage/matrix/matrix_dense.pyx +343 -0
  423. sage/matrix/matrix_domain_dense.pxd +5 -0
  424. sage/matrix/matrix_domain_sparse.pxd +5 -0
  425. sage/matrix/matrix_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  426. sage/matrix/matrix_double_dense.pxd +7 -0
  427. sage/matrix/matrix_double_dense.pyx +3906 -0
  428. sage/matrix/matrix_double_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  429. sage/matrix/matrix_double_sparse.pxd +6 -0
  430. sage/matrix/matrix_double_sparse.pyx +248 -0
  431. sage/matrix/matrix_generic_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  432. sage/matrix/matrix_generic_dense.pxd +7 -0
  433. sage/matrix/matrix_generic_dense.pyx +354 -0
  434. sage/matrix/matrix_generic_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  435. sage/matrix/matrix_generic_sparse.pxd +7 -0
  436. sage/matrix/matrix_generic_sparse.pyx +461 -0
  437. sage/matrix/matrix_laurent_mpolynomial_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  438. sage/matrix/matrix_laurent_mpolynomial_dense.pxd +5 -0
  439. sage/matrix/matrix_laurent_mpolynomial_dense.pyx +115 -0
  440. sage/matrix/matrix_misc.py +313 -0
  441. sage/matrix/matrix_numpy_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  442. sage/matrix/matrix_numpy_dense.pxd +14 -0
  443. sage/matrix/matrix_numpy_dense.pyx +450 -0
  444. sage/matrix/matrix_numpy_integer_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  445. sage/matrix/matrix_numpy_integer_dense.pxd +7 -0
  446. sage/matrix/matrix_numpy_integer_dense.pyx +59 -0
  447. sage/matrix/matrix_polynomial_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  448. sage/matrix/matrix_polynomial_dense.pxd +5 -0
  449. sage/matrix/matrix_polynomial_dense.pyx +5341 -0
  450. sage/matrix/matrix_real_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  451. sage/matrix/matrix_real_double_dense.pxd +7 -0
  452. sage/matrix/matrix_real_double_dense.pyx +122 -0
  453. sage/matrix/matrix_space.py +2848 -0
  454. sage/matrix/matrix_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  455. sage/matrix/matrix_sparse.pxd +5 -0
  456. sage/matrix/matrix_sparse.pyx +1222 -0
  457. sage/matrix/matrix_window.cpython-314-aarch64-linux-gnu.so +0 -0
  458. sage/matrix/matrix_window.pxd +37 -0
  459. sage/matrix/matrix_window.pyx +242 -0
  460. sage/matrix/misc_mpfr.cpython-314-aarch64-linux-gnu.so +0 -0
  461. sage/matrix/misc_mpfr.pyx +80 -0
  462. sage/matrix/operation_table.py +1182 -0
  463. sage/matrix/special.py +3666 -0
  464. sage/matrix/strassen.cpython-314-aarch64-linux-gnu.so +0 -0
  465. sage/matrix/strassen.pyx +851 -0
  466. sage/matrix/symplectic_basis.py +541 -0
  467. sage/matrix/template.pxd +6 -0
  468. sage/matrix/tests.py +71 -0
  469. sage/matroids/advanced.py +77 -0
  470. sage/matroids/all.py +13 -0
  471. sage/matroids/basis_exchange_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  472. sage/matroids/basis_exchange_matroid.pxd +96 -0
  473. sage/matroids/basis_exchange_matroid.pyx +2344 -0
  474. sage/matroids/basis_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  475. sage/matroids/basis_matroid.pxd +45 -0
  476. sage/matroids/basis_matroid.pyx +1217 -0
  477. sage/matroids/catalog.py +44 -0
  478. sage/matroids/chow_ring.py +473 -0
  479. sage/matroids/chow_ring_ideal.py +849 -0
  480. sage/matroids/circuit_closures_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  481. sage/matroids/circuit_closures_matroid.pxd +16 -0
  482. sage/matroids/circuit_closures_matroid.pyx +559 -0
  483. sage/matroids/circuits_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  484. sage/matroids/circuits_matroid.pxd +38 -0
  485. sage/matroids/circuits_matroid.pyx +947 -0
  486. sage/matroids/constructor.py +1086 -0
  487. sage/matroids/database_collections.py +365 -0
  488. sage/matroids/database_matroids.py +5338 -0
  489. sage/matroids/dual_matroid.py +583 -0
  490. sage/matroids/extension.cpython-314-aarch64-linux-gnu.so +0 -0
  491. sage/matroids/extension.pxd +34 -0
  492. sage/matroids/extension.pyx +519 -0
  493. sage/matroids/flats_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  494. sage/matroids/flats_matroid.pxd +28 -0
  495. sage/matroids/flats_matroid.pyx +715 -0
  496. sage/matroids/gammoid.py +600 -0
  497. sage/matroids/graphic_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  498. sage/matroids/graphic_matroid.pxd +39 -0
  499. sage/matroids/graphic_matroid.pyx +2024 -0
  500. sage/matroids/lean_matrix.cpython-314-aarch64-linux-gnu.so +0 -0
  501. sage/matroids/lean_matrix.pxd +126 -0
  502. sage/matroids/lean_matrix.pyx +3667 -0
  503. sage/matroids/linear_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  504. sage/matroids/linear_matroid.pxd +180 -0
  505. sage/matroids/linear_matroid.pyx +6649 -0
  506. sage/matroids/matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  507. sage/matroids/matroid.pxd +243 -0
  508. sage/matroids/matroid.pyx +8759 -0
  509. sage/matroids/matroids_catalog.py +190 -0
  510. sage/matroids/matroids_plot_helpers.py +890 -0
  511. sage/matroids/minor_matroid.py +480 -0
  512. sage/matroids/minorfix.h +9 -0
  513. sage/matroids/named_matroids.py +5 -0
  514. sage/matroids/rank_matroid.py +268 -0
  515. sage/matroids/set_system.cpython-314-aarch64-linux-gnu.so +0 -0
  516. sage/matroids/set_system.pxd +38 -0
  517. sage/matroids/set_system.pyx +800 -0
  518. sage/matroids/transversal_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  519. sage/matroids/transversal_matroid.pxd +14 -0
  520. sage/matroids/transversal_matroid.pyx +893 -0
  521. sage/matroids/union_matroid.cpython-314-aarch64-linux-gnu.so +0 -0
  522. sage/matroids/union_matroid.pxd +20 -0
  523. sage/matroids/union_matroid.pyx +331 -0
  524. sage/matroids/unpickling.cpython-314-aarch64-linux-gnu.so +0 -0
  525. sage/matroids/unpickling.pyx +843 -0
  526. sage/matroids/utilities.py +809 -0
  527. sage/misc/all__sagemath_modules.py +20 -0
  528. sage/misc/c3.cpython-314-aarch64-linux-gnu.so +0 -0
  529. sage/misc/c3.pyx +238 -0
  530. sage/misc/compat.py +87 -0
  531. sage/misc/element_with_label.py +173 -0
  532. sage/misc/func_persist.py +79 -0
  533. sage/misc/pickle_old.cpython-314-aarch64-linux-gnu.so +0 -0
  534. sage/misc/pickle_old.pyx +19 -0
  535. sage/misc/proof.py +7 -0
  536. sage/misc/replace_dot_all.py +472 -0
  537. sage/misc/sagedoc_conf.py +168 -0
  538. sage/misc/sphinxify.py +167 -0
  539. sage/misc/test_class_pickling.py +85 -0
  540. sage/modules/all.py +42 -0
  541. sage/modules/complex_double_vector.py +25 -0
  542. sage/modules/diamond_cutting.py +380 -0
  543. sage/modules/fg_pid/all.py +1 -0
  544. sage/modules/fg_pid/fgp_element.py +456 -0
  545. sage/modules/fg_pid/fgp_module.py +2091 -0
  546. sage/modules/fg_pid/fgp_morphism.py +550 -0
  547. sage/modules/filtered_vector_space.py +1271 -0
  548. sage/modules/finite_submodule_iter.cpython-314-aarch64-linux-gnu.so +0 -0
  549. sage/modules/finite_submodule_iter.pxd +27 -0
  550. sage/modules/finite_submodule_iter.pyx +452 -0
  551. sage/modules/fp_graded/all.py +1 -0
  552. sage/modules/fp_graded/element.py +346 -0
  553. sage/modules/fp_graded/free_element.py +298 -0
  554. sage/modules/fp_graded/free_homspace.py +53 -0
  555. sage/modules/fp_graded/free_module.py +1060 -0
  556. sage/modules/fp_graded/free_morphism.py +217 -0
  557. sage/modules/fp_graded/homspace.py +563 -0
  558. sage/modules/fp_graded/module.py +1340 -0
  559. sage/modules/fp_graded/morphism.py +1990 -0
  560. sage/modules/fp_graded/steenrod/all.py +1 -0
  561. sage/modules/fp_graded/steenrod/homspace.py +65 -0
  562. sage/modules/fp_graded/steenrod/module.py +477 -0
  563. sage/modules/fp_graded/steenrod/morphism.py +404 -0
  564. sage/modules/fp_graded/steenrod/profile.py +241 -0
  565. sage/modules/free_module.py +8447 -0
  566. sage/modules/free_module_element.cpython-314-aarch64-linux-gnu.so +0 -0
  567. sage/modules/free_module_element.pxd +22 -0
  568. sage/modules/free_module_element.pyx +5445 -0
  569. sage/modules/free_module_homspace.py +369 -0
  570. sage/modules/free_module_integer.py +896 -0
  571. sage/modules/free_module_morphism.py +823 -0
  572. sage/modules/free_module_pseudohomspace.py +352 -0
  573. sage/modules/free_module_pseudomorphism.py +578 -0
  574. sage/modules/free_quadratic_module.py +1706 -0
  575. sage/modules/free_quadratic_module_integer_symmetric.py +1790 -0
  576. sage/modules/matrix_morphism.py +1745 -0
  577. sage/modules/misc.py +103 -0
  578. sage/modules/module_functors.py +192 -0
  579. sage/modules/multi_filtered_vector_space.py +719 -0
  580. sage/modules/ore_module.py +2208 -0
  581. sage/modules/ore_module_element.py +178 -0
  582. sage/modules/ore_module_homspace.py +147 -0
  583. sage/modules/ore_module_morphism.py +968 -0
  584. sage/modules/quotient_module.py +699 -0
  585. sage/modules/real_double_vector.py +22 -0
  586. sage/modules/submodule.py +255 -0
  587. sage/modules/tensor_operations.py +567 -0
  588. sage/modules/torsion_quadratic_module.py +1352 -0
  589. sage/modules/tutorial_free_modules.py +248 -0
  590. sage/modules/vector_complex_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  591. sage/modules/vector_complex_double_dense.pxd +6 -0
  592. sage/modules/vector_complex_double_dense.pyx +117 -0
  593. sage/modules/vector_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  594. sage/modules/vector_double_dense.pxd +6 -0
  595. sage/modules/vector_double_dense.pyx +604 -0
  596. sage/modules/vector_integer_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  597. sage/modules/vector_integer_dense.pxd +15 -0
  598. sage/modules/vector_integer_dense.pyx +361 -0
  599. sage/modules/vector_integer_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  600. sage/modules/vector_integer_sparse.pxd +29 -0
  601. sage/modules/vector_integer_sparse.pyx +406 -0
  602. sage/modules/vector_modn_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  603. sage/modules/vector_modn_dense.pxd +12 -0
  604. sage/modules/vector_modn_dense.pyx +394 -0
  605. sage/modules/vector_modn_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  606. sage/modules/vector_modn_sparse.pxd +21 -0
  607. sage/modules/vector_modn_sparse.pyx +298 -0
  608. sage/modules/vector_numpy_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  609. sage/modules/vector_numpy_dense.pxd +15 -0
  610. sage/modules/vector_numpy_dense.pyx +304 -0
  611. sage/modules/vector_numpy_integer_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  612. sage/modules/vector_numpy_integer_dense.pxd +7 -0
  613. sage/modules/vector_numpy_integer_dense.pyx +54 -0
  614. sage/modules/vector_rational_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  615. sage/modules/vector_rational_dense.pxd +15 -0
  616. sage/modules/vector_rational_dense.pyx +387 -0
  617. sage/modules/vector_rational_sparse.cpython-314-aarch64-linux-gnu.so +0 -0
  618. sage/modules/vector_rational_sparse.pxd +30 -0
  619. sage/modules/vector_rational_sparse.pyx +413 -0
  620. sage/modules/vector_real_double_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  621. sage/modules/vector_real_double_dense.pxd +6 -0
  622. sage/modules/vector_real_double_dense.pyx +126 -0
  623. sage/modules/vector_space_homspace.py +430 -0
  624. sage/modules/vector_space_morphism.py +989 -0
  625. sage/modules/with_basis/all.py +15 -0
  626. sage/modules/with_basis/cell_module.py +494 -0
  627. sage/modules/with_basis/indexed_element.cpython-314-aarch64-linux-gnu.so +0 -0
  628. sage/modules/with_basis/indexed_element.pxd +13 -0
  629. sage/modules/with_basis/indexed_element.pyx +1058 -0
  630. sage/modules/with_basis/invariant.py +1075 -0
  631. sage/modules/with_basis/morphism.py +1636 -0
  632. sage/modules/with_basis/representation.py +2939 -0
  633. sage/modules/with_basis/subquotient.py +685 -0
  634. sage/numerical/all__sagemath_modules.py +6 -0
  635. sage/numerical/gauss_legendre.cpython-314-aarch64-linux-gnu.so +0 -0
  636. sage/numerical/gauss_legendre.pyx +381 -0
  637. sage/numerical/optimize.py +910 -0
  638. sage/probability/all.py +10 -0
  639. sage/probability/probability_distribution.cpython-314-aarch64-linux-gnu.so +0 -0
  640. sage/probability/probability_distribution.pyx +1242 -0
  641. sage/probability/random_variable.py +411 -0
  642. sage/quadratic_forms/all.py +4 -0
  643. sage/quadratic_forms/all__sagemath_modules.py +15 -0
  644. sage/quadratic_forms/binary_qf.py +2042 -0
  645. sage/quadratic_forms/bqf_class_group.py +748 -0
  646. sage/quadratic_forms/constructions.py +93 -0
  647. sage/quadratic_forms/count_local_2.cpython-314-aarch64-linux-gnu.so +0 -0
  648. sage/quadratic_forms/count_local_2.pyx +365 -0
  649. sage/quadratic_forms/extras.py +195 -0
  650. sage/quadratic_forms/quadratic_form.py +1753 -0
  651. sage/quadratic_forms/quadratic_form__count_local_2.py +221 -0
  652. sage/quadratic_forms/quadratic_form__equivalence_testing.py +708 -0
  653. sage/quadratic_forms/quadratic_form__evaluate.cpython-314-aarch64-linux-gnu.so +0 -0
  654. sage/quadratic_forms/quadratic_form__evaluate.pyx +139 -0
  655. sage/quadratic_forms/quadratic_form__local_density_congruence.py +977 -0
  656. sage/quadratic_forms/quadratic_form__local_field_invariants.py +1072 -0
  657. sage/quadratic_forms/quadratic_form__neighbors.py +424 -0
  658. sage/quadratic_forms/quadratic_form__reduction_theory.py +488 -0
  659. sage/quadratic_forms/quadratic_form__split_local_covering.py +416 -0
  660. sage/quadratic_forms/quadratic_form__ternary_Tornaria.py +657 -0
  661. sage/quadratic_forms/quadratic_form__theta.py +352 -0
  662. sage/quadratic_forms/quadratic_form__variable_substitutions.py +370 -0
  663. sage/quadratic_forms/random_quadraticform.py +209 -0
  664. sage/quadratic_forms/ternary.cpython-314-aarch64-linux-gnu.so +0 -0
  665. sage/quadratic_forms/ternary.pyx +1154 -0
  666. sage/quadratic_forms/ternary_qf.py +2027 -0
  667. sage/rings/all__sagemath_modules.py +28 -0
  668. sage/rings/asymptotic/all__sagemath_modules.py +1 -0
  669. sage/rings/asymptotic/misc.py +1252 -0
  670. sage/rings/cc.py +4 -0
  671. sage/rings/cfinite_sequence.py +1306 -0
  672. sage/rings/complex_conversion.cpython-314-aarch64-linux-gnu.so +0 -0
  673. sage/rings/complex_conversion.pxd +8 -0
  674. sage/rings/complex_conversion.pyx +23 -0
  675. sage/rings/complex_double.cpython-314-aarch64-linux-gnu.so +0 -0
  676. sage/rings/complex_double.pxd +21 -0
  677. sage/rings/complex_double.pyx +2654 -0
  678. sage/rings/complex_mpc.cpython-314-aarch64-linux-gnu.so +0 -0
  679. sage/rings/complex_mpc.pxd +21 -0
  680. sage/rings/complex_mpc.pyx +2576 -0
  681. sage/rings/complex_mpfr.cpython-314-aarch64-linux-gnu.so +0 -0
  682. sage/rings/complex_mpfr.pxd +18 -0
  683. sage/rings/complex_mpfr.pyx +3602 -0
  684. sage/rings/derivation.py +2334 -0
  685. sage/rings/finite_rings/all__sagemath_modules.py +1 -0
  686. sage/rings/finite_rings/maps_finite_field.py +191 -0
  687. sage/rings/function_field/all__sagemath_modules.py +8 -0
  688. sage/rings/function_field/derivations.py +102 -0
  689. sage/rings/function_field/derivations_rational.py +132 -0
  690. sage/rings/function_field/differential.py +853 -0
  691. sage/rings/function_field/divisor.py +1107 -0
  692. sage/rings/function_field/drinfeld_modules/action.py +199 -0
  693. sage/rings/function_field/drinfeld_modules/all.py +1 -0
  694. sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +673 -0
  695. sage/rings/function_field/drinfeld_modules/drinfeld_module.py +2087 -0
  696. sage/rings/function_field/drinfeld_modules/finite_drinfeld_module.py +1131 -0
  697. sage/rings/function_field/drinfeld_modules/homset.py +420 -0
  698. sage/rings/function_field/drinfeld_modules/morphism.py +820 -0
  699. sage/rings/function_field/hermite_form_polynomial.cpython-314-aarch64-linux-gnu.so +0 -0
  700. sage/rings/function_field/hermite_form_polynomial.pyx +188 -0
  701. sage/rings/function_field/khuri_makdisi.cpython-314-aarch64-linux-gnu.so +0 -0
  702. sage/rings/function_field/khuri_makdisi.pyx +935 -0
  703. sage/rings/invariants/all.py +4 -0
  704. sage/rings/invariants/invariant_theory.py +4597 -0
  705. sage/rings/invariants/reconstruction.py +395 -0
  706. sage/rings/polynomial/all__sagemath_modules.py +17 -0
  707. sage/rings/polynomial/integer_valued_polynomials.py +1230 -0
  708. sage/rings/polynomial/laurent_polynomial_mpair.cpython-314-aarch64-linux-gnu.so +0 -0
  709. sage/rings/polynomial/laurent_polynomial_mpair.pxd +15 -0
  710. sage/rings/polynomial/laurent_polynomial_mpair.pyx +2023 -0
  711. sage/rings/polynomial/ore_function_element.py +952 -0
  712. sage/rings/polynomial/ore_function_field.py +1028 -0
  713. sage/rings/polynomial/ore_polynomial_element.cpython-314-aarch64-linux-gnu.so +0 -0
  714. sage/rings/polynomial/ore_polynomial_element.pxd +48 -0
  715. sage/rings/polynomial/ore_polynomial_element.pyx +3145 -0
  716. sage/rings/polynomial/ore_polynomial_ring.py +1334 -0
  717. sage/rings/polynomial/polynomial_real_mpfr_dense.cpython-314-aarch64-linux-gnu.so +0 -0
  718. sage/rings/polynomial/polynomial_real_mpfr_dense.pyx +788 -0
  719. sage/rings/polynomial/q_integer_valued_polynomials.py +1264 -0
  720. sage/rings/polynomial/skew_polynomial_element.cpython-314-aarch64-linux-gnu.so +0 -0
  721. sage/rings/polynomial/skew_polynomial_element.pxd +9 -0
  722. sage/rings/polynomial/skew_polynomial_element.pyx +684 -0
  723. sage/rings/polynomial/skew_polynomial_finite_field.cpython-314-aarch64-linux-gnu.so +0 -0
  724. sage/rings/polynomial/skew_polynomial_finite_field.pxd +19 -0
  725. sage/rings/polynomial/skew_polynomial_finite_field.pyx +1093 -0
  726. sage/rings/polynomial/skew_polynomial_finite_order.cpython-314-aarch64-linux-gnu.so +0 -0
  727. sage/rings/polynomial/skew_polynomial_finite_order.pxd +10 -0
  728. sage/rings/polynomial/skew_polynomial_finite_order.pyx +567 -0
  729. sage/rings/polynomial/skew_polynomial_ring.py +908 -0
  730. sage/rings/real_double_element_gsl.cpython-314-aarch64-linux-gnu.so +0 -0
  731. sage/rings/real_double_element_gsl.pxd +8 -0
  732. sage/rings/real_double_element_gsl.pyx +794 -0
  733. sage/rings/real_field.py +58 -0
  734. sage/rings/real_mpfr.cpython-314-aarch64-linux-gnu.so +0 -0
  735. sage/rings/real_mpfr.pxd +29 -0
  736. sage/rings/real_mpfr.pyx +6122 -0
  737. sage/rings/ring_extension.cpython-314-aarch64-linux-gnu.so +0 -0
  738. sage/rings/ring_extension.pxd +42 -0
  739. sage/rings/ring_extension.pyx +2779 -0
  740. sage/rings/ring_extension_conversion.cpython-314-aarch64-linux-gnu.so +0 -0
  741. sage/rings/ring_extension_conversion.pxd +16 -0
  742. sage/rings/ring_extension_conversion.pyx +462 -0
  743. sage/rings/ring_extension_element.cpython-314-aarch64-linux-gnu.so +0 -0
  744. sage/rings/ring_extension_element.pxd +21 -0
  745. sage/rings/ring_extension_element.pyx +1635 -0
  746. sage/rings/ring_extension_homset.py +64 -0
  747. sage/rings/ring_extension_morphism.cpython-314-aarch64-linux-gnu.so +0 -0
  748. sage/rings/ring_extension_morphism.pxd +35 -0
  749. sage/rings/ring_extension_morphism.pyx +920 -0
  750. sage/schemes/all__sagemath_modules.py +1 -0
  751. sage/schemes/projective/all__sagemath_modules.py +1 -0
  752. sage/schemes/projective/coherent_sheaf.py +300 -0
  753. sage/schemes/projective/cohomology.py +510 -0
  754. sage/stats/all.py +15 -0
  755. sage/stats/basic_stats.py +489 -0
  756. sage/stats/distributions/all.py +7 -0
  757. sage/stats/distributions/catalog.py +34 -0
  758. sage/stats/distributions/dgs.h +50 -0
  759. sage/stats/distributions/dgs.pxd +111 -0
  760. sage/stats/distributions/dgs_bern.h +400 -0
  761. sage/stats/distributions/dgs_gauss.h +614 -0
  762. sage/stats/distributions/dgs_misc.h +104 -0
  763. sage/stats/distributions/discrete_gaussian_integer.cpython-314-aarch64-linux-gnu.so +0 -0
  764. sage/stats/distributions/discrete_gaussian_integer.pxd +14 -0
  765. sage/stats/distributions/discrete_gaussian_integer.pyx +498 -0
  766. sage/stats/distributions/discrete_gaussian_lattice.py +908 -0
  767. sage/stats/distributions/discrete_gaussian_polynomial.py +141 -0
  768. sage/stats/hmm/all.py +15 -0
  769. sage/stats/hmm/chmm.cpython-314-aarch64-linux-gnu.so +0 -0
  770. sage/stats/hmm/chmm.pyx +1595 -0
  771. sage/stats/hmm/distributions.cpython-314-aarch64-linux-gnu.so +0 -0
  772. sage/stats/hmm/distributions.pxd +29 -0
  773. sage/stats/hmm/distributions.pyx +531 -0
  774. sage/stats/hmm/hmm.cpython-314-aarch64-linux-gnu.so +0 -0
  775. sage/stats/hmm/hmm.pxd +17 -0
  776. sage/stats/hmm/hmm.pyx +1388 -0
  777. sage/stats/hmm/util.cpython-314-aarch64-linux-gnu.so +0 -0
  778. sage/stats/hmm/util.pxd +7 -0
  779. sage/stats/hmm/util.pyx +165 -0
  780. sage/stats/intlist.cpython-314-aarch64-linux-gnu.so +0 -0
  781. sage/stats/intlist.pxd +14 -0
  782. sage/stats/intlist.pyx +588 -0
  783. sage/stats/r.py +49 -0
  784. sage/stats/time_series.cpython-314-aarch64-linux-gnu.so +0 -0
  785. sage/stats/time_series.pxd +6 -0
  786. sage/stats/time_series.pyx +2546 -0
  787. sage/tensor/all.py +2 -0
  788. sage/tensor/modules/all.py +8 -0
  789. sage/tensor/modules/alternating_contr_tensor.py +761 -0
  790. sage/tensor/modules/comp.py +5598 -0
  791. sage/tensor/modules/ext_pow_free_module.py +824 -0
  792. sage/tensor/modules/finite_rank_free_module.py +3589 -0
  793. sage/tensor/modules/format_utilities.py +333 -0
  794. sage/tensor/modules/free_module_alt_form.py +858 -0
  795. sage/tensor/modules/free_module_automorphism.py +1207 -0
  796. sage/tensor/modules/free_module_basis.py +1074 -0
  797. sage/tensor/modules/free_module_element.py +284 -0
  798. sage/tensor/modules/free_module_homset.py +652 -0
  799. sage/tensor/modules/free_module_linear_group.py +564 -0
  800. sage/tensor/modules/free_module_morphism.py +1581 -0
  801. sage/tensor/modules/free_module_tensor.py +3289 -0
  802. sage/tensor/modules/reflexive_module.py +386 -0
  803. sage/tensor/modules/tensor_free_module.py +780 -0
  804. sage/tensor/modules/tensor_free_submodule.py +538 -0
  805. sage/tensor/modules/tensor_free_submodule_basis.py +140 -0
  806. sage/tensor/modules/tensor_with_indices.py +1043 -0
@@ -0,0 +1,2087 @@
1
+ # sage_setup: distribution = sagemath-modules
2
+ # sage.doctest: needs sage.rings.finite_rings
3
+ r"""
4
+ Drinfeld modules
5
+
6
+ This module provides the class
7
+ :class:`sage.rings.function_field.drinfeld_module.drinfeld_module.DrinfeldModule`.
8
+
9
+ For finite Drinfeld modules and their theory of complex multiplication, see
10
+ class
11
+ :class:`sage.rings.function_field.drinfeld_module.finite_drinfeld_module.DrinfeldModule`.
12
+
13
+ AUTHORS:
14
+
15
+ - Antoine Leudière (2022-04): initial version
16
+ - Xavier Caruso (2022-06): initial version
17
+ - David Ayotte (2023-03): added basic `j`-invariants
18
+ """
19
+
20
+ # *****************************************************************************
21
+ # Copyright (C) 2022 Antoine Leudière <antoine.leudiere@inria.fr>
22
+ #
23
+ # This program is free software: you can redistribute it and/or modify
24
+ # it under the terms of the GNU General Public License as published by
25
+ # the Free Software Foundation, either version 2 of the License, or
26
+ # (at your option) any later version.
27
+ # http://www.gnu.org/licenses/
28
+ # *****************************************************************************
29
+
30
+ from sage.arith.misc import gcd
31
+ from sage.categories.drinfeld_modules import DrinfeldModules
32
+ from sage.categories.homset import Hom
33
+ from sage.misc.latex import latex
34
+ from sage.misc.latex import latex_variable_name
35
+ from sage.misc.lazy_import import lazy_import
36
+ from sage.misc.lazy_string import _LazyString
37
+ from sage.misc.misc_c import prod
38
+ from sage.rings.integer import Integer
39
+ from sage.rings.integer_ring import ZZ
40
+ from sage.rings.fraction_field import FractionField_generic
41
+ from sage.rings.polynomial.ore_polynomial_element import OrePolynomial
42
+ from sage.rings.polynomial.polynomial_ring import PolynomialRing_generic
43
+ from sage.structure.parent import Parent
44
+ from sage.structure.sage_object import SageObject
45
+ from sage.structure.sequence import Sequence
46
+ from sage.structure.unique_representation import UniqueRepresentation
47
+
48
+ lazy_import('sage.rings.ring_extension', 'RingExtension_generic')
49
+ lazy_import('sage.geometry.polyhedron.constructor', 'Polyhedron')
50
+
51
+
52
+ class DrinfeldModule(Parent, UniqueRepresentation):
53
+ r"""
54
+ This class implements Drinfeld `\mathbb{F}_q[T]`-modules.
55
+
56
+ Let `\mathbb{F}_q[T]` be a polynomial ring with coefficients in a
57
+ finite field `\mathbb{F}_q` and let `K` be a field. Fix a ring
58
+ morphism `\gamma: \mathbb{F}_q[T] \to K`; we say that `K` is an
59
+ `\mathbb{F}_q[T]`-*field*. Let `K\{\tau\}` be the ring of Ore
60
+ polynomials with coefficients in `K`, whose multiplication is given
61
+ by the rule `\tau \lambda = \lambda^q \tau` for any `\lambda \in K`.
62
+
63
+ A Drinfeld `\mathbb{F}_q[T]`-module over the base
64
+ `\mathbb{F}_q[T]`-field `K` is an `\mathbb{F}_q`-algebra morphism
65
+ `\phi: \mathbb{F}_q[T] \to K\{\tau\}` such that `\mathrm{Im}(\phi)
66
+ \not\subset K` and `\phi` agrees with `\gamma` on `\mathbb{F}_q`.
67
+
68
+ For `a` in `\mathbb{F}_q[T]`, `\phi(a)` is denoted `\phi_a`.
69
+
70
+ The Drinfeld `\mathbb{F}_q[T]`-module `\phi` is uniquely determined
71
+ by the image `\phi_T` of `T`; this serves as input of the class.
72
+
73
+ .. NOTE::
74
+
75
+ See also :class:`sage.categories.drinfeld_modules`.
76
+
77
+ The *base morphism* is the morphism `\gamma: \mathbb{F}_q[T] \to K`.
78
+ The monic polynomial that generates the kernel of `\gamma` is called
79
+ the `\mathbb{F}_q[T]`-*characteristic*, or *function-field
80
+ characteristic*, of the base field. We say that `\mathbb{F}_q[T]` is
81
+ the *function ring* of `\phi`; `K\{\tau\}` is the *Ore polynomial
82
+ ring*. Further, the *generator* is `\phi_T` and the *constant
83
+ coefficient* is the constant coefficient of `\phi_T`.
84
+
85
+ A Drinfeld module is said to be *finite* if the field `K` is.
86
+ Despite an emphasis on this case, the base field can be any
87
+ extension of `\mathbb{F}_q`::
88
+
89
+ sage: Fq = GF(25)
90
+ sage: A.<T> = Fq[]
91
+ sage: K.<z> = Fq.extension(6)
92
+ sage: phi = DrinfeldModule(A, [z, 4, 1])
93
+ sage: phi
94
+ Drinfeld module defined by T |--> t^2 + 4*t + z
95
+
96
+ ::
97
+
98
+ sage: Fq = GF(49)
99
+ sage: A.<T> = Fq[]
100
+ sage: K = Frac(A)
101
+ sage: psi = DrinfeldModule(A, [K(T), T+1])
102
+ sage: psi
103
+ Drinfeld module defined by T |--> (T + 1)*t + T
104
+
105
+ .. NOTE::
106
+
107
+ Finite Drinfeld modules are implemented in the class
108
+ :class:`sage.rings.function_field.drinfeld_modules.finite_drinfeld_module`.
109
+
110
+ Classical references on Drinfeld modules include [Gos1998]_,
111
+ [Rosen2002]_, [VS06]_ and [Gek1991]_.
112
+
113
+ .. NOTE::
114
+
115
+ Drinfeld modules are defined in a larger setting, in which the
116
+ polynomial ring `\mathbb{F}_q[T]` is replaced by a more general
117
+ function ring: the ring of functions in `k` that are regular
118
+ outside `\infty`, where `k` is a function field over
119
+ `\mathbb{F}_q` with transcendence degree `1` and `\infty` is a
120
+ fixed place of `k`. This is out of the scope of this
121
+ implementation.
122
+
123
+ INPUT:
124
+
125
+ - ``function_ring`` -- a univariate polynomial ring whose base field
126
+ is a finite field
127
+
128
+ - ``gen`` -- the generator of the Drinfeld module; as a list of
129
+ coefficients or an Ore polynomial
130
+
131
+ - ``name`` -- (default: ``'t'``) the name of the Ore polynomial ring
132
+ generator
133
+
134
+ .. RUBRIC:: Construction
135
+
136
+ A Drinfeld module object is constructed by giving the function ring
137
+ and the generator::
138
+
139
+ sage: Fq.<z2> = GF(3^2)
140
+ sage: A.<T> = Fq[]
141
+ sage: K.<z> = Fq.extension(6)
142
+ sage: phi = DrinfeldModule(A, [z, 1, 1])
143
+ sage: phi
144
+ Drinfeld module defined by T |--> t^2 + t + z
145
+
146
+ .. NOTE::
147
+
148
+ Note that the definition of the base field is implicit; it is
149
+ automatically defined as the compositum of all the parents of
150
+ the coefficients.
151
+
152
+ The above Drinfeld module is finite; it can also be infinite::
153
+
154
+ sage: L = Frac(A)
155
+ sage: psi = DrinfeldModule(A, [L(T), 1, T^3 + T + 1])
156
+ sage: psi
157
+ Drinfeld module defined by T |--> (T^3 + T + 1)*t^2 + t + T
158
+
159
+ ::
160
+
161
+ sage: phi.is_finite()
162
+ True
163
+ sage: psi.is_finite()
164
+ False
165
+
166
+ In those examples, we used a list of coefficients (``[z, 1, 1]``) to
167
+ represent the generator `\phi_T = z + t + t^2`. One can also use
168
+ regular Ore polynomials::
169
+
170
+ sage: ore_polring = phi.ore_polring()
171
+ sage: t = ore_polring.gen()
172
+ sage: rho_T = z + t^3
173
+ sage: rho = DrinfeldModule(A, rho_T)
174
+ sage: rho
175
+ Drinfeld module defined by T |--> t^3 + z
176
+ sage: rho(T) == rho_T
177
+ True
178
+
179
+ Images under the Drinfeld module are computed by calling the
180
+ object::
181
+
182
+ sage: phi(T) # phi_T, the generator of the Drinfeld module
183
+ t^2 + t + z
184
+ sage: phi(T^3 + T + 1) # phi_(T^3 + T + 1)
185
+ t^6 + (z^11 + z^9 + 2*z^6 + 2*z^4 + 2*z + 1)*t^4
186
+ + (2*z^11 + 2*z^10 + z^9 + z^8 + 2*z^7 + 2*z^6 + z^5 + 2*z^3)*t^3
187
+ + (2*z^11 + z^10 + z^9 + 2*z^7 + 2*z^6 + z^5 + z^4 + 2*z^3 + 2*z + 2)*t^2
188
+ + (2*z^11 + 2*z^8 + 2*z^6 + z^5 + z^4 + 2*z^2)*t + z^3 + z + 1
189
+ sage: phi(1) # phi_1
190
+ 1
191
+
192
+ .. RUBRIC:: The category of Drinfeld modules
193
+
194
+ Drinfeld modules have their own category (see class
195
+ :class:`sage.categories.drinfeld_modules.DrinfeldModules`)::
196
+
197
+ sage: phi.category()
198
+ Category of Drinfeld modules over Finite Field in z of size 3^12 over its base
199
+ sage: phi.category() is psi.category()
200
+ False
201
+ sage: phi.category() is rho.category()
202
+ True
203
+
204
+ One can use the category to directly create new objects::
205
+
206
+ sage: cat = phi.category()
207
+ sage: cat.object([z, 0, 0, 1])
208
+ Drinfeld module defined by T |--> t^3 + z
209
+
210
+ .. RUBRIC:: The base field of a Drinfeld module
211
+
212
+ The base field of the Drinfeld module is retrieved using
213
+ :meth:`base`::
214
+
215
+ sage: phi.base()
216
+ Finite Field in z of size 3^12 over its base
217
+
218
+ The base morphism is retrieved using :meth:`base_morphism`::
219
+
220
+ sage: phi.base_morphism()
221
+ Ring morphism:
222
+ From: Univariate Polynomial Ring in T over Finite Field in z2 of size 3^2
223
+ To: Finite Field in z of size 3^12 over its base
224
+ Defn: T |--> z
225
+
226
+ Note that the base field is *not* the field `K`. Rather, it is a
227
+ ring extension
228
+ (see :class:`sage.rings.ring_extension.RingExtension`) whose
229
+ underlying ring is `K` and whose base is the base morphism::
230
+
231
+ sage: phi.base() is K
232
+ False
233
+
234
+ .. RUBRIC:: Getters
235
+
236
+ One can retrieve basic properties::
237
+
238
+ sage: phi.base_morphism()
239
+ Ring morphism:
240
+ From: Univariate Polynomial Ring in T over Finite Field in z2 of size 3^2
241
+ To: Finite Field in z of size 3^12 over its base
242
+ Defn: T |--> z
243
+
244
+ ::
245
+
246
+ sage: phi.ore_polring() # K{t}
247
+ Ore Polynomial Ring in t over Finite Field in z of size 3^12 over its base
248
+ twisted by Frob^2
249
+
250
+ ::
251
+
252
+ sage: phi.function_ring() # Fq[T]
253
+ Univariate Polynomial Ring in T over Finite Field in z2 of size 3^2
254
+
255
+ ::
256
+
257
+ sage: phi.gen() # phi_T
258
+ t^2 + t + z
259
+ sage: phi.gen() == phi(T)
260
+ True
261
+
262
+ ::
263
+
264
+ sage: phi.constant_coefficient() # Constant coefficient of phi_T
265
+ z
266
+
267
+ ::
268
+
269
+ sage: phi.morphism() # The Drinfeld module as a morphism
270
+ Ring morphism:
271
+ From: Univariate Polynomial Ring in T over Finite Field in z2 of size 3^2
272
+ To: Ore Polynomial Ring in t
273
+ over Finite Field in z of size 3^12 over its base
274
+ twisted by Frob^2
275
+ Defn: T |--> t^2 + t + z
276
+
277
+ One can compute the rank and height::
278
+
279
+ sage: phi.rank()
280
+ 2
281
+ sage: phi.height()
282
+ 1
283
+
284
+ As well as the j-invariant::
285
+
286
+ sage: phi.j_invariant() # j-invariant
287
+ 1
288
+
289
+ A Drinfeld `\mathbb{F}_q[T]`-module can be seen as an Ore polynomial
290
+ with positive degree and constant coefficient `\gamma(T)`, where
291
+ `\gamma` is the base morphism. This analogy is the motivation for
292
+ the following methods::
293
+
294
+ sage: phi.coefficients()
295
+ [z, 1, 1]
296
+
297
+ ::
298
+
299
+ sage: phi.coefficient(1)
300
+ 1
301
+
302
+
303
+ .. RUBRIC:: Morphisms and isogenies
304
+
305
+ A *morphism* of Drinfeld modules `\phi \to \psi` is an Ore
306
+ polynomial `f \in K\{\tau\}` such that `f \phi_a = \psi_a f` for
307
+ every `a` in the function ring. In our case, this is equivalent to
308
+ `f \phi_T = \psi_T f`. An *isogeny* is a nonzero morphism.
309
+
310
+ Use the ``in`` syntax to test if an Ore polynomial defines a
311
+ morphism::
312
+
313
+ sage: phi(T) in Hom(phi, phi)
314
+ True
315
+ sage: t^6 in Hom(phi, phi)
316
+ True
317
+ sage: t^5 + 2*t^3 + 1 in Hom(phi, phi)
318
+ False
319
+ sage: 1 in Hom(phi, rho)
320
+ False
321
+ sage: 1 in Hom(phi, phi)
322
+ True
323
+ sage: 0 in Hom(phi, rho)
324
+ True
325
+
326
+ To create a SageMath object representing the morphism, call the
327
+ homset (``hom``)::
328
+
329
+ sage: hom = Hom(phi, phi)
330
+ sage: frobenius_endomorphism = hom(t^6)
331
+ sage: identity_morphism = hom(1)
332
+ sage: zero_morphism = hom(0)
333
+ sage: frobenius_endomorphism
334
+ Endomorphism of Drinfeld module defined by T |--> t^2 + t + z
335
+ Defn: t^6
336
+ sage: identity_morphism
337
+ Identity morphism of Drinfeld module defined by T |--> t^2 + t + z
338
+ sage: zero_morphism
339
+ Endomorphism of Drinfeld module defined by T |--> t^2 + t + z
340
+ Defn: 0
341
+
342
+ The underlying Ore polynomial is retrieved with the method
343
+ :meth:`ore_polynomial`::
344
+
345
+ sage: frobenius_endomorphism.ore_polynomial()
346
+ t^6
347
+ sage: identity_morphism.ore_polynomial()
348
+ 1
349
+
350
+ One checks if a morphism is an isogeny, endomorphism or
351
+ isomorphism::
352
+
353
+ sage: frobenius_endomorphism.is_isogeny()
354
+ True
355
+ sage: identity_morphism.is_isogeny()
356
+ True
357
+ sage: zero_morphism.is_isogeny()
358
+ False
359
+ sage: frobenius_endomorphism.is_isomorphism()
360
+ False
361
+ sage: identity_morphism.is_isomorphism()
362
+ True
363
+ sage: zero_morphism.is_isomorphism()
364
+ False
365
+
366
+ .. RUBRIC:: The Vélu formula
367
+
368
+ Let ``P`` be a nonzero Ore polynomial. We can decide if ``P``
369
+ defines an isogeny with a given domain and, if it does, find
370
+ the codomain::
371
+
372
+ sage: P = (2*z^6 + z^3 + 2*z^2 + z + 2)*t + z^11 + 2*z^10 + 2*z^9 + 2*z^8 + z^7 + 2*z^6 + z^5 + z^3 + z^2 + z
373
+ sage: psi = phi.velu(P)
374
+ sage: psi
375
+ Drinfeld module defined by T |--> (2*z^11 + 2*z^9 + z^6 + 2*z^5 + 2*z^4 + 2*z^2 + 1)*t^2
376
+ + (2*z^11 + 2*z^10 + 2*z^9 + z^8 + 2*z^7 + 2*z^6 + z^5 + 2*z^4 + 2*z^2 + 2*z)*t + z
377
+ sage: P in Hom(phi, psi)
378
+ True
379
+ sage: P * phi(T) == psi(T) * P
380
+ True
381
+
382
+ If the input does not define an isogeny, an exception is raised::
383
+
384
+ sage: phi.velu(0)
385
+ Traceback (most recent call last):
386
+ ...
387
+ ValueError: the input does not define an isogeny
388
+ sage: phi.velu(t)
389
+ Traceback (most recent call last):
390
+ ...
391
+ ValueError: the input does not define an isogeny
392
+
393
+ .. RUBRIC:: The action of a Drinfeld module
394
+
395
+ The `\mathbb{F}_q[T]`-Drinfeld module `\phi` induces a special left
396
+ `\mathbb{F}_q[T]`-module structure on any field extension `L/K`. Let
397
+ `x \in L` and `a` be in the function ring; the action is defined as
398
+ `(a, x) \mapsto \phi_a(x)`. The method :meth:`action` returns a
399
+ :class:`sage.rings.function_field.drinfeld_modules.action.Action`
400
+ object representing the Drinfeld module action.
401
+
402
+ .. NOTE::
403
+
404
+ In this implementation, `L` is `K`::
405
+
406
+ sage: action = phi.action()
407
+ sage: action
408
+ Action on Finite Field in z of size 3^12 over its base
409
+ induced by Drinfeld module defined by T |--> t^2 + t + z
410
+
411
+ The action on elements is computed by calling the action object::
412
+
413
+ sage: P = T + 1
414
+ sage: a = z
415
+ sage: action(P, a)
416
+ ...
417
+ z^9 + 2*z^8 + 2*z^7 + 2*z^6 + 2*z^3 + z^2
418
+ sage: action(0, K.random_element())
419
+ 0
420
+ sage: action(A.random_element(), 0)
421
+ 0
422
+
423
+ .. WARNING::
424
+
425
+ The class ``DrinfeldModuleAction`` may be replaced later on. See
426
+ issues #34833 and #34834.
427
+
428
+ TESTS:
429
+
430
+ The generator must have positive degree::
431
+
432
+ sage: Fq = GF(2)
433
+ sage: K.<z> = Fq.extension(2)
434
+ sage: A.<T> = Fq[]
435
+ sage: DrinfeldModule(A, [K(1)])
436
+ Traceback (most recent call last):
437
+ ...
438
+ ValueError: generator must have positive degree
439
+
440
+ The constant coefficient must be nonzero::
441
+
442
+ sage: Fq = GF(2)
443
+ sage: K.<z> = Fq.extension(2)
444
+ sage: A.<T> = Fq[]
445
+ sage: DrinfeldModule(A, [K(0), K(1)])
446
+ Traceback (most recent call last):
447
+ ...
448
+ ValueError: constant coefficient must be nonzero
449
+
450
+ The coefficients of the generator must lie in an
451
+ `\mathbb{F}_q[T]`-field, where `\mathbb{F}_q[T]` is the function
452
+ ring of the Drinfeld module::
453
+
454
+ sage: Fq = GF(2)
455
+ sage: K.<z> = Fq.extension(2)
456
+ sage: A.<T> = Fq[]
457
+ sage: DrinfeldModule(A, [z, QQ(1)])
458
+ Traceback (most recent call last):
459
+ ...
460
+ ValueError: function ring base must coerce into base field
461
+
462
+ ::
463
+
464
+ sage: Fq = GF(2)
465
+ sage: K.<z> = Fq.extension(2)
466
+ sage: A.<T> = Fq[]
467
+ sage: DrinfeldModule(A, [1, QQ(1)])
468
+ Traceback (most recent call last):
469
+ ...
470
+ ValueError: function ring base must coerce into base field
471
+
472
+ The function ring must be an univariate polynomial ring whose
473
+ base is a finite field::
474
+
475
+ sage: Fq = GF(2)
476
+ sage: K.<z> = Fq.extension(2)
477
+ sage: A.<T> = Fq[]
478
+ sage: DrinfeldModule(K, [z, 1, 1])
479
+ Traceback (most recent call last):
480
+ ...
481
+ NotImplementedError: function ring must be a polynomial ring
482
+
483
+ ::
484
+
485
+ sage: Fq = GF(2)
486
+ sage: K.<z> = Fq.extension(2)
487
+ sage: A.<T> = Fq[]
488
+ sage: AY.<Y> = A[]
489
+ sage: DrinfeldModule(AY, [z, 1, 1])
490
+ Traceback (most recent call last):
491
+ ...
492
+ TypeError: function ring base must be a finite field
493
+
494
+ If you already defined a category of Drinfeld modules, and you
495
+ create a Drinfeld module through this category, you must ensure that
496
+ the constant coefficient is that of the category::
497
+
498
+ sage: Fq = GF(2)
499
+ sage: K.<z> = Fq.extension(2)
500
+ sage: A.<T> = Fq[]
501
+ sage: phi = DrinfeldModule(A, [z, 1])
502
+ sage: phi.category().object([1, 1, K(1)])
503
+ Traceback (most recent call last):
504
+ ...
505
+ ValueError: constant coefficient must equal that of the category
506
+
507
+ ::
508
+
509
+ sage: Fq = K = GF(2)
510
+ sage: A.<T> = Fq[]
511
+ sage: phi = DrinfeldModule(A, [1, 1])
512
+ Traceback (most recent call last):
513
+ ...
514
+ ValueError: function ring base must coerce into base field
515
+
516
+ ::
517
+
518
+ sage: Fq = K = GF(2)
519
+ sage: A.<T> = Fq[]
520
+ sage: phi = DrinfeldModule(A, [K(1), 1])
521
+ sage: isinstance(phi.ore_polring(), OrePolynomialRing)
522
+ True
523
+ """
524
+
525
+ @staticmethod
526
+ def __classcall_private__(cls, function_ring, gen, name='t'):
527
+ """
528
+ Check input validity and return a ``DrinfeldModule`` or
529
+ ``DrinfeldModule_finite`` object accordingly.
530
+
531
+ INPUT:
532
+
533
+ - ``function_ring`` -- a univariate polynomial ring whose base
534
+ is a finite field
535
+
536
+ - ``gen`` -- the generator of the Drinfeld module; as a list of
537
+ coefficients or an Ore polynomial
538
+
539
+ - ``name`` -- (default: ``'t'``) the name of the Ore polynomial
540
+ ring gen
541
+
542
+ OUTPUT: a DrinfeldModule or DrinfeldModule_finite
543
+
544
+ TESTS::
545
+
546
+ sage: from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import DrinfeldModule_finite
547
+ sage: Fq = GF(25)
548
+ sage: A.<T> = Fq[]
549
+ sage: K.<z12> = Fq.extension(6)
550
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
551
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
552
+ sage: isinstance(phi, DrinfeldModule_finite)
553
+ True
554
+
555
+ ::
556
+
557
+ sage: K = Frac(A)
558
+ sage: phi = DrinfeldModule(A, [K(T), 1])
559
+ sage: isinstance(psi, DrinfeldModule_finite)
560
+ False
561
+ """
562
+
563
+ # FIXME: function_ring must be checked before calling base_ring
564
+ # on it. But then it is checked twice: firstly here, secondly in
565
+ # the category. Another problem is that those lines are
566
+ # duplicate. As a general comment, there are sanity checks both
567
+ # here and in the category constructor, which is not ideal.
568
+ # Check domain is Fq[T]
569
+ if not isinstance(function_ring, PolynomialRing_generic):
570
+ raise NotImplementedError('function ring must be a polynomial '
571
+ 'ring')
572
+ function_ring_base = function_ring.base_ring()
573
+ if not function_ring_base.is_field() \
574
+ or not function_ring_base.is_finite():
575
+ raise TypeError('function ring base must be a finite field')
576
+
577
+ # Check all possible input types for gen
578
+ # `gen` is an Ore polynomial:
579
+ if isinstance(gen, OrePolynomial):
580
+ ore_polring = gen.parent()
581
+ # Base ring without morphism structure:
582
+ base_field_noext = ore_polring.base()
583
+ name = ore_polring.variable_name()
584
+ # `gen` is a list of coefficients (function_ring = Fq[T]):
585
+ elif isinstance(gen, (list, tuple)):
586
+ ore_polring = None
587
+ # Base ring without morphism structure:
588
+ base_field_noext = Sequence(gen).universe()
589
+ else:
590
+ raise TypeError('generator must be list of coefficients or Ore '
591
+ 'polynomial')
592
+ # Constant coefficient must be nonzero:
593
+ if gen[0].is_zero():
594
+ raise ValueError('constant coefficient must be nonzero')
595
+ # The coefficients are in a base field that has coercion from Fq:
596
+ if not (hasattr(base_field_noext, 'has_coerce_map_from') and
597
+ base_field_noext.has_coerce_map_from(function_ring.base_ring())):
598
+ raise ValueError('function ring base must coerce into base field')
599
+
600
+ # Build the category
601
+ T = function_ring.gen()
602
+ if isinstance(base_field_noext, RingExtension_generic):
603
+ base_field = base_field_noext
604
+ elif base_field_noext.has_coerce_map_from(function_ring) \
605
+ and T == gen[0]:
606
+ base_morphism = base_field_noext.coerce_map_from(function_ring)
607
+ base_field = base_field_noext.over(base_morphism)
608
+ else:
609
+ base_morphism = Hom(function_ring, base_field_noext)(gen[0])
610
+ base_field = base_field_noext.over(base_morphism)
611
+
612
+ # This test is also done in the category. We put it here also
613
+ # to have a friendlier error message
614
+ if not base_field.is_field():
615
+ raise ValueError('generator coefficients must live in a field')
616
+
617
+ category = DrinfeldModules(base_field, name=name)
618
+
619
+ # Check gen as Ore polynomial
620
+ ore_polring = category.ore_polring() # Sanity cast
621
+ gen = ore_polring(gen)
622
+ if gen.degree() <= 0:
623
+ raise ValueError('generator must have positive degree')
624
+
625
+ # Instantiate the appropriate class:
626
+ backend = base_field.backend(force=True)
627
+ if backend.is_finite():
628
+ from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import DrinfeldModule_finite
629
+ return DrinfeldModule_finite(gen, category)
630
+ if isinstance(backend, FractionField_generic):
631
+ ring = backend.ring()
632
+ if (isinstance(ring, PolynomialRing_generic)
633
+ and ring.base_ring() is function_ring_base
634
+ and base_morphism(T) == ring.gen()):
635
+ from .charzero_drinfeld_module import DrinfeldModule_rational
636
+ return DrinfeldModule_rational(gen, category)
637
+ if not category._characteristic:
638
+ from .charzero_drinfeld_module import DrinfeldModule_charzero
639
+ return DrinfeldModule_charzero(gen, category)
640
+ return cls.__classcall__(cls, gen, category)
641
+
642
+ def __init__(self, gen, category):
643
+ """
644
+ Initialize ``self``.
645
+
646
+ Validity of the input is checked in meth:`__classcall_private__`.
647
+ The meth:`__init__` just saves attributes.
648
+
649
+ INPUT:
650
+
651
+ - ``function_ring`` -- a univariate polynomial ring whose base
652
+ is a finite field
653
+
654
+ - ``gen`` -- the generator of the Drinfeld module; as a list of
655
+ coefficients or an Ore polynomial
656
+
657
+ - ``name`` -- (default: ``'t'``) the name of the Ore polynomial
658
+ ring gen
659
+
660
+ TESTS::
661
+
662
+ sage: Fq = GF(25)
663
+ sage: A.<T> = Fq[]
664
+ sage: K.<z12> = Fq.extension(6)
665
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
666
+ sage: gen = [p_root, z12^3, z12^5]
667
+ sage: phi = DrinfeldModule(A, gen)
668
+ sage: ore_polring = phi.ore_polring()
669
+ sage: phi._base == phi.category().base()
670
+ True
671
+ sage: phi._function_ring == A
672
+ True
673
+ sage: phi._gen == ore_polring(gen)
674
+ True
675
+ sage: phi._ore_polring == ore_polring
676
+ True
677
+ sage: phi._morphism == Hom(A, ore_polring)(phi._gen)
678
+ True
679
+
680
+ ::
681
+
682
+ sage: TestSuite(phi).run()
683
+ """
684
+ self._base = category.base()
685
+ self._function_ring = category.function_ring()
686
+ self._gen = gen
687
+ self._morphism = category._function_ring.hom([gen])
688
+ self._ore_polring = gen.parent()
689
+ self._Fq = self._function_ring.base_ring() # Must be last
690
+ super().__init__(base=self._base, category=category)
691
+
692
+ def __call__(self, a):
693
+ r"""
694
+ Return the image of input ``a`` by the morphism that defines the
695
+ Drinfeld module; i.e. `\phi_a` if the Drinfeld module is denoted
696
+ `phi`.
697
+
698
+ INPUT:
699
+
700
+ - ``a`` -- a function ring element
701
+
702
+ OUTPUT: an element in the base codomain
703
+
704
+ TESTS::
705
+
706
+ sage: Fq = GF(25)
707
+ sage: A.<T> = Fq[]
708
+ sage: K.<z12> = Fq.extension(6)
709
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
710
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
711
+
712
+ ::
713
+ sage: a = T^3 + 4*T + 2
714
+ sage: phi(a) == phi(T)^3 + 4*phi(T) + 2
715
+ True
716
+ sage: phi(a)[0] == p_root^3 + 4*p_root + 2
717
+ True
718
+
719
+ ::
720
+
721
+ sage: phi(0)
722
+ 0
723
+ sage: phi(1)
724
+ 1
725
+ sage: phi(T) == phi._gen
726
+ True
727
+
728
+ ::
729
+
730
+ sage: a = A.random_element(5)
731
+ sage: phi(a)[0] == phi.category().base()(a)
732
+ True
733
+ """
734
+ return self._morphism(a)
735
+
736
+ def _Hom_(self, other, category):
737
+ r"""
738
+ Return the set of morphisms from ``self`` to ``other``.
739
+
740
+ Validity of the input is checked at the instantiation of
741
+ ``DrinfeldModuleHomset``; ``self`` and ``other`` only need be in
742
+ the same category.
743
+
744
+ INPUT:
745
+
746
+ - ``other`` -- the codomain of the homset
747
+
748
+ - ``category`` -- the category in which we consider the
749
+ morphisms, usually ``self.category()``
750
+
751
+ EXAMPLES::
752
+
753
+ sage: Fq = GF(25)
754
+ sage: A.<T> = Fq[]
755
+ sage: K.<z12> = Fq.extension(6)
756
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
757
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
758
+ sage: t = phi.ore_polring().gen()
759
+ sage: isog = t + 2*z12^11 + 4*z12^9 + 2*z12^8 + 2*z12^6 + 3*z12^5 + z12^4 + 2*z12^3 + 4*z12^2 + 4*z12 + 4
760
+ sage: psi = phi.velu(isog)
761
+ sage: hom = phi._Hom_(psi, category=phi.category())
762
+ sage: hom is Hom(phi, psi) # known bug
763
+ True
764
+ sage: from sage.rings.function_field.drinfeld_modules.homset import DrinfeldModuleHomset
765
+ sage: isinstance(hom, DrinfeldModuleHomset)
766
+ True
767
+ """
768
+ from sage.rings.function_field.drinfeld_modules.homset import DrinfeldModuleHomset
769
+ return DrinfeldModuleHomset(self, other, category)
770
+
771
+ def _latex_(self):
772
+ r"""
773
+ Return a LaTeX representation of the Drinfeld module.
774
+
775
+ If a representation name is given with meth:`rename`, it is
776
+ taken into account for LaTeX representation.
777
+
778
+ EXAMPLES::
779
+
780
+ sage: Fq = GF(25)
781
+ sage: A.<T> = Fq[]
782
+ sage: K.<z12> = Fq.extension(6)
783
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
784
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
785
+ sage: latex(phi)
786
+ \phi: T \mapsto z_{12}^{5} t^{2} + z_{12}^{3} t + 2 z_{12}^{11} + 2 z_{12}^{10} + z_{12}^{9} + 3 z_{12}^{8} + z_{12}^{7} + 2 z_{12}^{5} + 2 z_{12}^{4} + 3 z_{12}^{3} + z_{12}^{2} + 2 z_{12}
787
+
788
+ ::
789
+
790
+ sage: phi.rename('phi')
791
+ sage: latex(phi)
792
+ \phi
793
+ sage: phi.reset_name()
794
+ """
795
+ if self.get_custom_name() is not None:
796
+ return latex_variable_name(self.get_custom_name())
797
+ else:
798
+ return f'\\phi: {latex(self._function_ring.gen())} \\mapsto ' \
799
+ f'{latex(self._gen)}'
800
+
801
+ def _repr_(self):
802
+ r"""
803
+ Return a string representation of this Drinfeld module.
804
+
805
+ EXAMPLES::
806
+
807
+ sage: Fq = GF(25)
808
+ sage: A.<T> = Fq[]
809
+ sage: K.<z12> = Fq.extension(6)
810
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
811
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
812
+ sage: phi
813
+ Drinfeld module defined by T |--> z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
814
+ """
815
+ return f'Drinfeld module defined by {self._function_ring.gen()} ' \
816
+ f'|--> {self._gen}'
817
+
818
+ def _test_category(self, **options):
819
+ """
820
+ Run generic tests on the method :meth:`.category`.
821
+
822
+ EXAMPLES::
823
+
824
+ sage: Fq = GF(25)
825
+ sage: A.<T> = Fq[]
826
+ sage: K.<z12> = Fq.extension(6)
827
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
828
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
829
+ sage: phi._test_category()
830
+
831
+ .. NOTE::
832
+
833
+ We reimplemented this method because Drinfeld modules are
834
+ parents, and
835
+ meth:`sage.structure.parent.Parent._test_category` requires
836
+ parents' categories to be subcategories of ``Sets()``.
837
+ """
838
+ tester = self._tester(**options)
839
+ SageObject._test_category(self, tester=tester)
840
+ category = self.category()
841
+ # Tests that self inherits methods from the categories
842
+ tester.assertTrue(isinstance(self, category.parent_class),
843
+ _LazyString("category of %s improperly initialized", (self,), {}))
844
+
845
+ def __hash__(self):
846
+ r"""
847
+ Return a hash of ``self``.
848
+
849
+ EXAMPLES::
850
+
851
+ sage: Fq = GF(25)
852
+ sage: A.<T> = Fq[]
853
+ sage: K.<z12> = Fq.extension(6)
854
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
855
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
856
+ sage: hash(phi) # random
857
+ -6894299335185957188
858
+ """
859
+ return hash((self.base(), self._gen))
860
+
861
+ def action(self):
862
+ r"""
863
+ Return the action object
864
+ (:class:`sage.rings.function_field.drinfeld_modules.action.Action`)
865
+ that represents the module action, on the base codomain, that is
866
+ induced by the Drinfeld module.
867
+
868
+ OUTPUT: a Drinfeld module action object
869
+
870
+ EXAMPLES::
871
+
872
+ sage: Fq = GF(25)
873
+ sage: A.<T> = Fq[]
874
+ sage: K.<z12> = Fq.extension(6)
875
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
876
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
877
+ sage: action = phi.action()
878
+ sage: action
879
+ Action on Finite Field in z12 of size 5^12 over its base
880
+ induced by Drinfeld module defined by T |--> z12^5*t^2 + z12^3*t + 2*z12^11
881
+ + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
882
+
883
+ The action on elements is computed as follows::
884
+
885
+ sage: P = T^2 + T + 1
886
+ sage: a = z12 + 1
887
+ sage: action(P, a)
888
+ 3*z12^11 + 2*z12^10 + 3*z12^9 + 3*z12^7 + 4*z12^5 + z12^4 + z12^3 + 2*z12 + 1
889
+ sage: action(0, a)
890
+ 0
891
+ sage: action(P, 0)
892
+ 0
893
+ """
894
+ from sage.rings.function_field.drinfeld_modules.action import DrinfeldModuleAction
895
+ return DrinfeldModuleAction(self)
896
+
897
+ def basic_j_invariant_parameters(self, coeff_indices=None, nonzero=False):
898
+ r"""
899
+ Return the list of basic `j`-invariant parameters.
900
+
901
+ See the method :meth:`j_invariant` for definitions.
902
+
903
+ INPUT:
904
+
905
+ - ``coeff_indices`` -- list or tuple, or NoneType (default:
906
+ ``None``); indices of the Drinfeld module generator
907
+ coefficients to be considered in the computation. If the
908
+ parameter is ``None`` (default), all the coefficients are
909
+ involved.
910
+
911
+ - ``nonzero``-- boolean (default: ``False``); if this flag
912
+ is set to ``True``, then only the parameters for which the
913
+ corresponding basic `j`-invariant is nonzero are returned
914
+
915
+ .. WARNING::
916
+
917
+ The usage of this method can be computationally
918
+ expensive e.g. if the rank is greater than four,
919
+ or if `q` is large. Setting the ``nonzero`` flag to ``True``
920
+ can speed up the computation considerably if the Drinfeld
921
+ module generator possesses multiple zero coefficients.
922
+
923
+ EXAMPLES::
924
+
925
+ sage: A = GF(5)['T']
926
+ sage: K.<T> = Frac(A)
927
+ sage: phi = DrinfeldModule(A, [T, 0, T+1, T^2 + 1])
928
+ sage: phi.basic_j_invariant_parameters() # needs sage.geometry.polyhedron
929
+ [((1,), (31, 1)),
930
+ ((1, 2), (1, 5, 1)),
931
+ ((1, 2), (7, 4, 1)),
932
+ ((1, 2), (8, 9, 2)),
933
+ ((1, 2), (9, 14, 3)),
934
+ ((1, 2), (10, 19, 4)),
935
+ ((1, 2), (11, 24, 5)),
936
+ ((1, 2), (12, 29, 6)),
937
+ ((1, 2), (13, 3, 1)),
938
+ ((1, 2), (15, 13, 3)),
939
+ ((1, 2), (17, 23, 5)),
940
+ ((1, 2), (19, 2, 1)),
941
+ ((1, 2), (20, 7, 2)),
942
+ ((1, 2), (22, 17, 4)),
943
+ ((1, 2), (23, 22, 5)),
944
+ ((1, 2), (25, 1, 1)),
945
+ ((1, 2), (27, 11, 3)),
946
+ ((1, 2), (29, 21, 5)),
947
+ ((1, 2), (31, 31, 7)),
948
+ ((2,), (31, 6))]
949
+
950
+ Use the ``nonzero=True`` flag to display only the parameters
951
+ whose `j`-invariant value is nonzero::
952
+
953
+ sage: phi.basic_j_invariant_parameters(nonzero=True) # needs sage.geometry.polyhedron
954
+ [((2,), (31, 6))]
955
+
956
+
957
+ One can specify the list of coefficients indices to be
958
+ considered in the computation::
959
+
960
+ sage: A = GF(2)['T']
961
+ sage: K.<T> = Frac(A)
962
+ sage: phi = DrinfeldModule(A, [T, T, 1, T])
963
+ sage: phi.basic_j_invariant_parameters([1, 2]) # needs sage.geometry.polyhedron
964
+ [((1,), (7, 1)),
965
+ ((1, 2), (1, 2, 1)),
966
+ ((1, 2), (4, 1, 1)),
967
+ ((1, 2), (5, 3, 2)),
968
+ ((1, 2), (6, 5, 3)),
969
+ ((1, 2), (7, 7, 4)),
970
+ ((2,), (7, 3))]
971
+
972
+ TESTS::
973
+
974
+ sage: A = GF(5)['T']
975
+ sage: K.<T> = Frac(A)
976
+ sage: phi = DrinfeldModule(A, [T, 0, T+1, T^2 + 1])
977
+ sage: phi.basic_j_invariant_parameters([1, 'x']) # needs sage.geometry.polyhedron
978
+ Traceback (most recent call last):
979
+ ...
980
+ TypeError: coefficients indices must be integers
981
+
982
+ ::
983
+
984
+ sage: phi.basic_j_invariant_parameters([1, 10]) # needs sage.geometry.polyhedron
985
+ Traceback (most recent call last):
986
+ ...
987
+ ValueError: indices must be > 0 and < 3
988
+
989
+ ::
990
+
991
+ sage: phi.basic_j_invariant_parameters([1, 1]) # needs sage.geometry.polyhedron
992
+ Traceback (most recent call last):
993
+ ...
994
+ ValueError: indices must be distinct and sorted
995
+
996
+ ::
997
+
998
+ sage: phi.basic_j_invariant_parameters([2, 1]) # needs sage.geometry.polyhedron
999
+ Traceback (most recent call last):
1000
+ ...
1001
+ ValueError: indices must be distinct and sorted
1002
+
1003
+ ::
1004
+
1005
+ sage: phi.basic_j_invariant_parameters('x') # needs sage.geometry.polyhedron
1006
+ Traceback (most recent call last):
1007
+ ...
1008
+ TypeError: indices must be None, a tuple or a list
1009
+ """
1010
+ r = self._gen.degree()
1011
+ if coeff_indices is None:
1012
+ if nonzero:
1013
+ coeff_indices = [k for k, g in enumerate(
1014
+ self.coefficients(sparse=False)[1:-1], start=1) if g]
1015
+ else:
1016
+ coeff_indices = list(range(1, r))
1017
+ # Check if coeff_indices is valid:
1018
+ elif isinstance(coeff_indices, (tuple, list)):
1019
+ coeff_indices = list(coeff_indices)
1020
+ if not all(isinstance(k, (int, Integer)) for k in coeff_indices):
1021
+ raise TypeError('coefficients indices must be integers')
1022
+ if max(coeff_indices) >= r or min(coeff_indices) <= 0:
1023
+ raise ValueError(f'indices must be > 0 and < {r}')
1024
+ if not all(coeff_indices[i] < coeff_indices[i+1] for i in
1025
+ range(len(coeff_indices) - 1)):
1026
+ raise ValueError('indices must be distinct and sorted')
1027
+ if nonzero:
1028
+ coeff_indices = [k for k in coeff_indices if self._gen[k]]
1029
+ else:
1030
+ raise TypeError('indices must be None, a tuple or a list')
1031
+ # Create the equation and inequalities for the polyhedron:
1032
+ q = self._Fq.order()
1033
+ equation = [0]
1034
+ inequalities = []
1035
+ # Create the equation:
1036
+ # d_1 (q - 1) + ... + d_{r-1} (q^{r-1} - 1)
1037
+ # = d_r (q^r - 1)
1038
+ for idx, i in enumerate(coeff_indices):
1039
+ equation.append(q**i - 1)
1040
+ # Create inequalities of the form 0 <= delta_i
1041
+ lower_bounds = [0] * (len(coeff_indices) + 2)
1042
+ lower_bounds[idx + 1] = 1
1043
+ # Create inequalities of the form
1044
+ # delta_i <= (q^r - 1)/(q^{gcd(i,r)} - 1)
1045
+ upper_bounds = [Integer((q**r - 1) / (q**(gcd(i, r)) - 1))]\
1046
+ + [0]*(len(coeff_indices) + 1)
1047
+ upper_bounds[idx + 1] = -1
1048
+ inequalities.extend((lower_bounds, upper_bounds))
1049
+ equation.append(1 - q**r)
1050
+ # Create the polyhedron defined by the equation and the
1051
+ # inequalities.
1052
+ polyhedron = Polyhedron(ieqs=inequalities, eqns=[equation])
1053
+ # Compute its integral points
1054
+ integral_points = polyhedron.integral_points()
1055
+ # Format the result
1056
+ parameters = []
1057
+ for p in integral_points:
1058
+ if gcd(p) != 1:
1059
+ continue
1060
+ ks = list(coeff_indices)
1061
+ ds = p.list()
1062
+ i = 0
1063
+ while i < len(ks):
1064
+ if ds[i] == 0:
1065
+ del ds[i]
1066
+ del ks[i]
1067
+ else:
1068
+ i += 1
1069
+ parameters.append((tuple(ks), tuple(ds)))
1070
+ parameters.sort()
1071
+ return parameters
1072
+
1073
+ def basic_j_invariants(self, nonzero=False):
1074
+ r"""
1075
+ Return a dictionary whose keys are all the basic `j`-invariants
1076
+ parameters and values are the corresponding `j`-invariant.
1077
+
1078
+ See the method :meth:`j_invariant` for definitions.
1079
+
1080
+ INPUT:
1081
+
1082
+ - ``nonzero``-- boolean (default: ``False``); if this flag
1083
+ is set to ``True``, then only the parameters for which the
1084
+ corresponding basic `j`-invariant is nonzero are returned
1085
+
1086
+ .. WARNING::
1087
+
1088
+ The usage of this method can be computationally
1089
+ expensive e.g. if the rank is greater than four,
1090
+ or if `q` is large. Setting the ``nonzero`` flag to ``True``
1091
+ can speed up the computation considerably if the Drinfeld
1092
+ module generator possesses multiple zero coefficients.
1093
+
1094
+ EXAMPLES::
1095
+
1096
+ sage: Fq = GF(25)
1097
+ sage: A.<T> = Fq[]
1098
+ sage: K.<z12> = Fq.extension(6)
1099
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1100
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
1101
+ sage: phi.basic_j_invariants() # needs sage.geometry.polyhedron
1102
+ {((1,), (26, 1)): z12^10 + 4*z12^9 + 3*z12^8 + 2*z12^7 + 3*z12^6 + z12^5 + z12^3 + 4*z12^2 + z12 + 2}
1103
+
1104
+ ::
1105
+
1106
+ sage: phi = DrinfeldModule(A, [p_root, 0, 1, z12])
1107
+ sage: phi.basic_j_invariants(nonzero=True) # needs sage.geometry.polyhedron
1108
+ {((2,), (651, 26)): z12^11 + 3*z12^10 + 4*z12^9 + 3*z12^8 + z12^7 + 2*z12^6 + 3*z12^4 + 2*z12^3 + z12^2 + 4*z12}
1109
+
1110
+ ::
1111
+
1112
+ sage: A = GF(5)['T']
1113
+ sage: K.<T> = Frac(A)
1114
+ sage: phi = DrinfeldModule(A, [T, T + 2, T+1, 1])
1115
+ sage: J_phi = phi.basic_j_invariants(); J_phi # needs sage.geometry.polyhedron
1116
+ {((1,), (31, 1)): T^31 + 2*T^30 + 2*T^26 + 4*T^25 + 2*T^6 + 4*T^5 + 4*T + 3,
1117
+ ((1, 2), (1, 5, 1)): T^6 + 2*T^5 + T + 2,
1118
+ ((1, 2), (7, 4, 1)): T^11 + 3*T^10 + T^9 + 4*T^8 + T^7 + 2*T^6 + 2*T^4 + 3*T^3 + 2*T^2 + 3,
1119
+ ((1, 2), (8, 9, 2)): T^17 + 2*T^15 + T^14 + 4*T^13 + 4*T^11 + 4*T^10 + 3*T^9 + 2*T^8 + 3*T^7 + 2*T^6 + 3*T^5 + 2*T^4 + 3*T^3 + 4*T^2 + 3*T + 1,
1120
+ ((1, 2), (9, 14, 3)): T^23 + 2*T^22 + 2*T^21 + T^19 + 4*T^18 + T^17 + 4*T^16 + T^15 + 4*T^14 + 2*T^12 + 4*T^11 + 4*T^10 + 2*T^8 + 4*T^7 + 4*T^6 + 2*T^4 + T^2 + 2*T + 2,
1121
+ ((1, 2), (10, 19, 4)): T^29 + 4*T^28 + T^27 + 4*T^26 + T^25 + 2*T^24 + 3*T^23 + 2*T^22 + 3*T^21 + 2*T^20 + 4*T^19 + T^18 + 4*T^17 + T^16 + 4*T^15 + T^9 + 4*T^8 + T^7 + 4*T^6 + T^5 + 4*T^4 + T^3 + 4*T^2 + T + 4,
1122
+ ...
1123
+ ((2,), (31, 6)): T^31 + T^30 + T^26 + T^25 + T^6 + T^5 + T + 1}
1124
+ sage: J_phi[((1, 2), (7, 4, 1))] # needs sage.geometry.polyhedron
1125
+ T^11 + 3*T^10 + T^9 + 4*T^8 + T^7 + 2*T^6 + 2*T^4 + 3*T^3 + 2*T^2 + 3
1126
+ """
1127
+ return {parameter: self.j_invariant(parameter, check=False)
1128
+ for parameter in self.basic_j_invariant_parameters(nonzero=nonzero)}
1129
+
1130
+ def coefficient(self, n):
1131
+ r"""
1132
+ Return the `n`-th coefficient of the generator.
1133
+
1134
+ INPUT:
1135
+
1136
+ - ``n`` -- nonnegative integer
1137
+
1138
+ OUTPUT: an element in the base codomain
1139
+
1140
+ EXAMPLES::
1141
+
1142
+ sage: Fq = GF(25)
1143
+ sage: A.<T> = Fq[]
1144
+ sage: K.<z12> = Fq.extension(6)
1145
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1146
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
1147
+ sage: phi.coefficient(0)
1148
+ 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5
1149
+ + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1150
+ sage: phi.coefficient(0) == p_root
1151
+ True
1152
+ sage: phi.coefficient(1)
1153
+ z12^3
1154
+ sage: phi.coefficient(2)
1155
+ z12^5
1156
+ sage: phi.coefficient(5)
1157
+ Traceback (most recent call last):
1158
+ ...
1159
+ ValueError: input must be >= 0 and <= rank
1160
+ """
1161
+ n = Integer(n)
1162
+ if not 0 <= n <= self.rank():
1163
+ raise ValueError('input must be >= 0 and <= rank')
1164
+ return self.coefficients(sparse=False)[n]
1165
+
1166
+ def coefficients(self, sparse=True):
1167
+ r"""
1168
+ Return the coefficients of the generator, as a list.
1169
+
1170
+ If the flag ``sparse`` is ``True`` (default), only return the
1171
+ nonzero coefficients; otherwise, return all of them.
1172
+
1173
+ INPUT:
1174
+
1175
+ - ``sparse`` -- boolean
1176
+
1177
+ EXAMPLES::
1178
+
1179
+ sage: Fq = GF(25)
1180
+ sage: A.<T> = Fq[]
1181
+ sage: K.<z12> = Fq.extension(6)
1182
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1183
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
1184
+ sage: phi.coefficients()
1185
+ [2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7
1186
+ + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12,
1187
+ z12^3,
1188
+ z12^5]
1189
+
1190
+ Careful, the method only returns the nonzero coefficients,
1191
+ unless otherwise specified::
1192
+
1193
+ sage: rho = DrinfeldModule(A, [p_root, 0, 0, 0, 1])
1194
+ sage: rho.coefficients()
1195
+ [2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7
1196
+ + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12,
1197
+ 1]
1198
+ sage: rho.coefficients(sparse=False)
1199
+ [2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7
1200
+ + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12,
1201
+ 0,
1202
+ 0,
1203
+ 0,
1204
+ 1]
1205
+ """
1206
+ return self._gen.coefficients(sparse=sparse)
1207
+
1208
+ def gen(self):
1209
+ r"""
1210
+ Return the generator of the Drinfeld module.
1211
+
1212
+ EXAMPLES::
1213
+
1214
+ sage: Fq = GF(25)
1215
+ sage: A.<T> = Fq[]
1216
+ sage: K.<z12> = Fq.extension(6)
1217
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1218
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
1219
+ sage: phi.gen() == phi(T)
1220
+ True
1221
+ """
1222
+ return self._gen
1223
+
1224
+ def height(self):
1225
+ r"""
1226
+ Return the height of the Drinfeld module if the function field
1227
+ characteristic is a prime ideal; raise :exc:`ValueError` otherwise.
1228
+
1229
+ The height of a Drinfeld module is defined when the function
1230
+ field characteristic is a prime ideal. In our case, this ideal
1231
+ is even generated by a monic polynomial `\mathfrak{p}` in the
1232
+ function field. Write `\phi_\mathfrak{p} = a_s \tau^s + \dots +
1233
+ \tau^{r*\deg(\mathfrak{p})}`. The height of the Drinfeld module
1234
+ is the well-defined positive integer `h =
1235
+ \frac{s}{\deg(\mathfrak{p})}`.
1236
+
1237
+ .. NOTE::
1238
+
1239
+ See [Gos1998]_, Definition 4.5.8 for the general definition.
1240
+
1241
+ EXAMPLES::
1242
+
1243
+ sage: Fq = GF(25)
1244
+ sage: A.<T> = Fq[]
1245
+ sage: K.<z12> = Fq.extension(6)
1246
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1247
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
1248
+ sage: phi.height() == 1
1249
+ True
1250
+ sage: phi.is_ordinary()
1251
+ True
1252
+
1253
+ ::
1254
+
1255
+ sage: Fq = GF(343)
1256
+ sage: A.<T> = Fq[]
1257
+ sage: K.<z6> = Fq.extension(2)
1258
+ sage: phi = DrinfeldModule(A, [1, 0, z6])
1259
+ sage: phi.height()
1260
+ 2
1261
+ sage: phi.is_supersingular()
1262
+ True
1263
+
1264
+ In characteristic zero, height is not defined::
1265
+
1266
+ sage: L = A.fraction_field()
1267
+ sage: phi = DrinfeldModule(A, [L(T), L(1)])
1268
+ sage: phi.height()
1269
+ Traceback (most recent call last):
1270
+ ...
1271
+ ValueError: height is only defined for prime function field characteristic
1272
+
1273
+ TESTS:
1274
+
1275
+ In the following case, sage is unable to determine the
1276
+ characteristic; that is why an error is raised::
1277
+
1278
+ sage: B.<Y> = Fq[]
1279
+ sage: L = Frac(B)
1280
+ sage: phi = DrinfeldModule(A, [L(2), L(1)])
1281
+ sage: phi.height()
1282
+ Traceback (most recent call last):
1283
+ ...
1284
+ NotImplementedError: height not implemented in this case
1285
+ """
1286
+ try:
1287
+ if self.characteristic().is_zero():
1288
+ raise ValueError('height is only defined for prime '
1289
+ 'function field characteristic')
1290
+ else:
1291
+ p = self.characteristic()
1292
+ return Integer(self(p).valuation() // p.degree())
1293
+ except NotImplementedError:
1294
+ raise NotImplementedError('height not implemented in this case')
1295
+
1296
+ def is_isomorphic(self, other, absolutely=False):
1297
+ r"""
1298
+ Return ``True`` if this Drinfeld module is isomorphic to ``other``;
1299
+ return ``False`` otherwise.
1300
+
1301
+ INPUT:
1302
+
1303
+ - ``absolutely`` -- a boolean (default: ``False``); if ``False``,
1304
+ check the existence of an isomorphism defined on the base
1305
+ field. If ``True``, check over an algebraic closure.
1306
+
1307
+ EXAMPLES::
1308
+
1309
+ sage: Fq = GF(5)
1310
+ sage: A.<T> = Fq[]
1311
+ sage: K.<z> = Fq.extension(3)
1312
+ sage: phi = DrinfeldModule(A, [z, 0, 1, z])
1313
+ sage: t = phi.ore_variable()
1314
+
1315
+ We create a second Drinfeld module, which is isomorphic to `\phi`
1316
+ and then check that they are indeed isomorphic::
1317
+
1318
+ sage: psi = phi.velu(z)
1319
+ sage: phi.is_isomorphic(psi)
1320
+ True
1321
+
1322
+ In the example below, `\phi` and `\psi` are isogenous but not
1323
+ isomorphic::
1324
+
1325
+ sage: psi = phi.velu(t + 1)
1326
+ sage: phi.is_isomorphic(psi)
1327
+ False
1328
+
1329
+ Here is an example of two Drinfeld modules which are isomorphic
1330
+ on an algebraic closure but not on the base field::
1331
+
1332
+ sage: phi = DrinfeldModule(A, [z, 1])
1333
+ sage: psi = DrinfeldModule(A, [z, z])
1334
+ sage: phi.is_isomorphic(psi)
1335
+ False
1336
+ sage: phi.is_isomorphic(psi, absolutely=True)
1337
+ True
1338
+
1339
+ In particular, two Drinfeld modules may have the same
1340
+ `j`-invariant, while not being isomorphic on the base field::
1341
+
1342
+ sage: phi = DrinfeldModule(A, [z, 0, 1])
1343
+ sage: psi = DrinfeldModule(A, [z, 0, z])
1344
+ sage: phi.j_invariant() == psi.j_invariant()
1345
+ True
1346
+ sage: phi.is_isomorphic(psi)
1347
+ False
1348
+ sage: phi.is_isomorphic(psi, absolutely=True)
1349
+ True
1350
+
1351
+ On certain fields, testing isomorphisms over the base field may
1352
+ fail::
1353
+
1354
+ sage: L = A.fraction_field()
1355
+ sage: T = L.gen()
1356
+ sage: phi = DrinfeldModule(A, [T, 0, 1])
1357
+ sage: psi = DrinfeldModule(A, [T, 0, T])
1358
+ sage: psi.is_isomorphic(phi)
1359
+ Traceback (most recent call last):
1360
+ ...
1361
+ NotImplementedError: cannot solve the equation u^24 == T
1362
+
1363
+ However, it never fails over the algebraic closure::
1364
+
1365
+ sage: psi.is_isomorphic(phi, absolutely=True)
1366
+ True
1367
+
1368
+ Note finally that when the constant coefficients of `\phi_T` and
1369
+ `\psi_T` differ, `\phi` and `\psi` do not belong to the same category
1370
+ and checking whether they are isomorphic does not make sense; in this
1371
+ case, an error is raised::
1372
+
1373
+ sage: phi = DrinfeldModule(A, [z, 0, 1])
1374
+ sage: psi = DrinfeldModule(A, [z^2, 0, 1])
1375
+ sage: phi.is_isomorphic(psi)
1376
+ Traceback (most recent call last):
1377
+ ...
1378
+ ValueError: Drinfeld modules are not in the same category
1379
+
1380
+ TESTS:
1381
+
1382
+ A Drinfeld module is always isomorphic to itself::
1383
+
1384
+ sage: phi = DrinfeldModule(A, [z] + [K.random_element() for _ in range(3)] + [1])
1385
+ sage: phi.is_isomorphic(phi)
1386
+ True
1387
+
1388
+ Two Drinfeld modules of different ranks are never isomorphic::
1389
+
1390
+ sage: psi = DrinfeldModule(A, [z] + [K.random_element() for _ in range(5)] + [1])
1391
+ sage: phi.is_isomorphic(psi)
1392
+ False
1393
+
1394
+ Two Drinfeld modules which are not patterned-alike are also not
1395
+ isomorphic::
1396
+
1397
+ sage: phi = DrinfeldModule(A, [T, 1, 0, 1])
1398
+ sage: psi = DrinfeldModule(A, [T, 1, 1, 1])
1399
+ sage: phi.is_isomorphic(psi)
1400
+ False
1401
+ """
1402
+ # Trivial cases
1403
+ if self.category() is not other.category():
1404
+ raise ValueError("Drinfeld modules are not in the same category")
1405
+ if self is other:
1406
+ return True
1407
+ r = self.rank()
1408
+ if other.rank() != r:
1409
+ return False
1410
+ # Check if there exists u such that u*self_X = other_X*u:
1411
+ # if self_X = a_0 + a_1*t + ... + a_r*t^r
1412
+ # and other_x = b_0 + b_1*t + ... + b_r*t^r
1413
+ # this reduces to find a solution of the system:
1414
+ # b_i * u^(q^i - 1) = a_i (0 <= i <= r)
1415
+ # which, using gcds, can be reduced to a unique equation
1416
+ # of the form u^e = ue.
1417
+ q = self._Fq.cardinality()
1418
+ A = self.gen()
1419
+ B = other.gen()
1420
+ e = Integer(0)
1421
+ ue = self._base(1)
1422
+ for i in range(1, r+1):
1423
+ ai = A[i]
1424
+ bi = B[i]
1425
+ if ai == 0 and bi == 0:
1426
+ continue
1427
+ if ai == 0 or bi == 0:
1428
+ return False
1429
+ if e != q - 1:
1430
+ # u^e = ue
1431
+ # u^(q^i - 1) = ai/bi
1432
+ e, s, t = e.xgcd(q**i - 1)
1433
+ ue = ue**s * (ai/bi)**t
1434
+ for i in range(1, r+1):
1435
+ if A[i]:
1436
+ f = (q**i - 1) // e
1437
+ if A[i] != B[i] * ue**f:
1438
+ return False
1439
+ # Solve the equation u^e = ue
1440
+ # - when absolutely=True, over the algebraic closure (then a
1441
+ # solution always exists)
1442
+ # - when absolutely=False, over the ground field.
1443
+ if absolutely:
1444
+ return True
1445
+ else:
1446
+ ue = ue.backend(force=True)
1447
+ try:
1448
+ _ = ue.nth_root(e)
1449
+ except ValueError:
1450
+ return False
1451
+ except (AttributeError, NotImplementedError):
1452
+ raise NotImplementedError(f"cannot solve the equation u^{e} == {ue}")
1453
+ return True
1454
+
1455
+ def is_finite(self) -> bool:
1456
+ r"""
1457
+ Return ``True`` if this Drinfeld module is finite,
1458
+ ``False`` otherwise.
1459
+
1460
+ EXAMPLES::
1461
+
1462
+ sage: Fq = GF(25)
1463
+ sage: A.<T> = Fq[]
1464
+ sage: K.<z12> = Fq.extension(6)
1465
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1466
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
1467
+ sage: phi.is_finite()
1468
+ True
1469
+ sage: B.<Y> = Fq[]
1470
+ sage: L = Frac(B)
1471
+ sage: psi = DrinfeldModule(A, [L(2), L(1)])
1472
+ sage: psi.is_finite()
1473
+ False
1474
+ """
1475
+ from sage.rings.function_field.drinfeld_modules.finite_drinfeld_module import DrinfeldModule_finite
1476
+ return isinstance(self, DrinfeldModule_finite)
1477
+
1478
+ def j_invariant(self, parameter=None, check=True):
1479
+ r"""
1480
+ Return the `j`-invariant of the Drinfeld
1481
+ `\mathbb{F}_q[T]`-module for the given parameter.
1482
+
1483
+ Suppose that `\phi_T = g_0 + g_1\tau + \cdots + g_r \tau^r` with
1484
+ `g_r \neq 0`. Then the
1485
+ `((k_1, \ldots, k_n), (d_1, \ldots, d_n, d_r))`-`j`-*invariant*
1486
+ of `\phi` is defined by
1487
+
1488
+ .. MATH::
1489
+
1490
+ j_{k_1, \ldots, k_n}^{d_1, \ldots, d_n, d_r}(\phi)
1491
+ := \frac{1}{g_r^{d_r}}\prod_{i = 1}^n g_{k_i}^{d_i}
1492
+
1493
+ where `1\leqslant k_1 < k_2 < \ldots < k_n \leqslant r - 1` and
1494
+ the integers `d_i` satisfy the *weight-0 condition*:
1495
+
1496
+ .. MATH::
1497
+
1498
+ d_1 (q^{k_1} - 1) + d_2 (q^{k_2} - 1)
1499
+ + \cdots + d_{n} (q^{k_n} - 1) = d_r (q^r - 1).
1500
+
1501
+ Furthermore, if `\gcd(d_1,\ldots, d_n, d_r) = 1` and
1502
+
1503
+ .. MATH::
1504
+
1505
+ 0 \leq d_i \leq (q^r - 1)/(q^{\gcd(i, r)} - 1),
1506
+ \quad 1 \leq i \leq n,
1507
+
1508
+ then the `j`-invariant is called *basic*. See the method
1509
+ :meth:`basic_j_invariant_parameters` for computing the list of
1510
+ all basic `j`-invariant parameters.
1511
+
1512
+ .. NOTE::
1513
+
1514
+ In [Pap2023]_, Papikian follows a slightly different
1515
+ convention:
1516
+
1517
+ - His `j`-invariants (see Definition 3.8.7) correspond to
1518
+ our basic `j`-invariants, as defined above.
1519
+ - His *basic* `j`-invariant (see Example 3.8.10) correspond
1520
+ to our `j_k`-invariants, as implemented in
1521
+ :meth:`jk_invariants`.
1522
+
1523
+ We chose to follow Potemine's convention, as he introduced
1524
+ those objects in [Pot1998]_. Theorem 2.2 of [Pot1998]_ or
1525
+ Theorem 3.8.11 of [Pap2023]_ assert that two Drinfeld
1526
+ `\mathbb F_q[T]`-modules over `K` are isomorphic over the
1527
+ separable closure of `K` if and only if their basic
1528
+ `j`-invariants (as implemented here) coincide for any
1529
+ well-defined couple of tuples `((k_1, k_2, \ldots, k_n),
1530
+ (d_1, d_2, \ldots, d_n, d_r))`, .
1531
+
1532
+ INPUT:
1533
+
1534
+ - ``parameter`` -- tuple or list, integer or NoneType (default:
1535
+ ``None``); the `j`-invariant parameter:
1536
+
1537
+ - If ``parameter`` is a list or a tuple, then it must be of
1538
+ the form:
1539
+ `((k_1, k_2, \ldots, k_n), (d_1, d_2, \ldots, d_n, d_r))`,
1540
+ where the `k_i` and `d_i` are integers satisfying the
1541
+ weight-0 condition described above.
1542
+
1543
+ - If ``parameter`` is an integer `k` then the method returns
1544
+ the ``j``-invariant associated to the parameter
1545
+ `((k,), (d_k, d_r))`;
1546
+
1547
+ - If ``parameter`` is ``None`` and the rank of the Drinfeld
1548
+ module is 2, then the method returns its usual
1549
+ `j`-invariant, that is the `j`-invariant for the parameter
1550
+ `((1,), (q+1, 1))`.
1551
+
1552
+ - ``check`` -- boolean (default: ``True``); if this flag is set to
1553
+ ``False`` then the code will not check if the given parameter
1554
+ is valid and satisfy the weight-0 condition.
1555
+
1556
+ OUTPUT: the `j`-invariant of ``self`` for the given parameter
1557
+
1558
+ EXAMPLES::
1559
+
1560
+ sage: Fq = GF(25)
1561
+ sage: A.<T> = Fq[]
1562
+ sage: K.<z12> = Fq.extension(6)
1563
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1564
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
1565
+ sage: phi.j_invariant()
1566
+ z12^10 + 4*z12^9 + 3*z12^8 + 2*z12^7 + 3*z12^6 + z12^5 + z12^3 + 4*z12^2 + z12 + 2
1567
+ sage: psi = DrinfeldModule(A, [p_root, 1, 1])
1568
+ sage: psi.j_invariant()
1569
+ 1
1570
+ sage: rho = DrinfeldModule(A, [p_root, 0, 1])
1571
+ sage: rho.j_invariant()
1572
+ 0
1573
+
1574
+ ::
1575
+
1576
+ sage: A = GF(5)['T']
1577
+ sage: K.<T> = Frac(A)
1578
+ sage: phi = DrinfeldModule(A, [T, T^2, 1, T + 1, T^3])
1579
+ sage: phi.j_invariant(1)
1580
+ T^309
1581
+ sage: phi.j_invariant(2)
1582
+ 1/T^3
1583
+ sage: phi.j_invariant(3)
1584
+ (T^156 + T^155 + T^151 + T^150 + T^131 + T^130 + T^126 + T^125 + T^31 + T^30 + T^26 + T^25 + T^6 + T^5 + T + 1)/T^93
1585
+
1586
+ The parameter can either be a tuple or a list::
1587
+
1588
+ sage: Fq.<a> = GF(7)
1589
+ sage: A.<T> = Fq[]
1590
+ sage: phi = DrinfeldModule(A, [a, a^2 + a, 0, 3*a, a^2+1])
1591
+ sage: J = phi.j_invariant(((1, 3), (267, 269, 39))); J
1592
+ 5
1593
+ sage: J == (phi.coefficient(1)**267)*(phi.coefficient(3)**269)/(phi.coefficient(4)**39)
1594
+ True
1595
+ sage: phi.j_invariant([[3], [400, 57]])
1596
+ 4
1597
+ sage: phi.j_invariant([[3], [400, 57]]) == phi.j_invariant(3)
1598
+ True
1599
+
1600
+ The list of all basic `j`-invariant parameters can be retrieved
1601
+ using the method :meth:`basic_j_invariant_parameters`::
1602
+
1603
+ sage: A = GF(3)['T']
1604
+ sage: K.<T> = Frac(A)
1605
+ sage: phi = DrinfeldModule(A, [T, T^2 + T + 1, 0, T^4 + 1, T - 1])
1606
+ sage: param = phi.basic_j_invariant_parameters(nonzero=True) # needs sage.geometry.polyhedron
1607
+ sage: phi.j_invariant(param[1]) # needs sage.geometry.polyhedron
1608
+ T^13 + 2*T^12 + T + 2
1609
+ sage: phi.j_invariant(param[2]) # needs sage.geometry.polyhedron
1610
+ T^35 + 2*T^31 + T^27 + 2*T^8 + T^4 + 2
1611
+
1612
+ TESTS::
1613
+
1614
+ sage: A = GF(5)['T']
1615
+ sage: K.<T> = Frac(A)
1616
+ sage: phi = DrinfeldModule(A, [T, T^2, 1, T + 1, T^3])
1617
+ sage: phi.j_invariant()
1618
+ Traceback (most recent call last):
1619
+ ...
1620
+ TypeError: parameter must not be None if the rank is greater than 2
1621
+
1622
+ ::
1623
+
1624
+ sage: phi.j_invariant(-1)
1625
+ Traceback (most recent call last):
1626
+ ...
1627
+ ValueError: integer parameter must be >= 1 and < the rank (=4)
1628
+
1629
+ ::
1630
+
1631
+ sage: phi.j_invariant('x')
1632
+ Traceback (most recent call last):
1633
+ ...
1634
+ TypeError: parameter must be a tuple or a list of length 2 or an integer
1635
+
1636
+ ::
1637
+
1638
+ sage: phi.j_invariant((1, 2, 3))
1639
+ Traceback (most recent call last):
1640
+ ...
1641
+ ValueError: list or tuple parameter must be of length 2
1642
+
1643
+ ::
1644
+
1645
+ sage: phi.j_invariant(('x', (1, 2, 3)))
1646
+ Traceback (most recent call last):
1647
+ ...
1648
+ TypeError: list or tuple parameter must contain tuples or lists
1649
+
1650
+ ::
1651
+
1652
+ sage: phi.j_invariant(((1, 2), 'x'))
1653
+ Traceback (most recent call last):
1654
+ ...
1655
+ TypeError: list or tuple parameter must contain tuples or lists
1656
+
1657
+ ::
1658
+
1659
+ sage: phi.j_invariant(((1, 2, 3, 4, 5), (2, 1)))
1660
+ Traceback (most recent call last):
1661
+ ...
1662
+ ValueError: components of tuple or list parameter have incorrect length
1663
+
1664
+ ::
1665
+
1666
+ sage: phi.j_invariant(((1, 'x'), (2, 3, 8)))
1667
+ Traceback (most recent call last):
1668
+ ...
1669
+ TypeError: components of tuple or list parameter must contain only integers
1670
+
1671
+ ::
1672
+
1673
+ sage: phi.j_invariant(((1, 2), (2, 3, 'x')))
1674
+ Traceback (most recent call last):
1675
+ ...
1676
+ TypeError: components of tuple or list parameter must contain only integers
1677
+
1678
+ ::
1679
+
1680
+ sage: phi.j_invariant(((1, 2), (4, 3, 7)))
1681
+ Traceback (most recent call last):
1682
+ ...
1683
+ ValueError: parameter does not satisfy the weight-0 condition
1684
+
1685
+ ::
1686
+
1687
+ sage: phi.j_invariant(((1, 2), (4, 3, 7)), check=False)
1688
+ 1/T^13
1689
+ """
1690
+ r = self._gen.degree()
1691
+ q = self._Fq.order()
1692
+ if parameter is None:
1693
+ if r != 2:
1694
+ raise TypeError("parameter must not be None "
1695
+ "if the rank is greater than 2")
1696
+ return self._gen[1]**(q+1)/self._gen[2]
1697
+ if parameter in ZZ:
1698
+ parameter = ZZ(parameter)
1699
+ if parameter <= 0 or parameter >= r:
1700
+ raise ValueError("integer parameter must be >= 1 and < the "
1701
+ f"rank (={r})")
1702
+ dk = Integer((q**r - 1)/(q**gcd(parameter, r) - 1))
1703
+ dr = Integer((q**parameter - 1)/(q**gcd(parameter, r) - 1))
1704
+ return self._gen[parameter]**dk / self._gen[-1]**dr
1705
+ elif isinstance(parameter, (tuple, list)):
1706
+ if len(parameter) != 2:
1707
+ raise ValueError("list or tuple parameter must be of length 2")
1708
+ if not isinstance(parameter[0], (tuple, list)) \
1709
+ or not isinstance(parameter[1], (tuple, list)):
1710
+ raise TypeError("list or tuple parameter must contain tuples "
1711
+ "or lists")
1712
+ if not len(parameter[0]) < r or\
1713
+ not len(parameter[1]) == len(parameter[0]) + 1:
1714
+ raise ValueError("components of tuple or list parameter have "
1715
+ "incorrect length")
1716
+ try: # Check parameter's type
1717
+ parameter_0 = [ZZ(p) for p in parameter[0]]
1718
+ parameter_1 = [ZZ(p) for p in parameter[1]]
1719
+ except TypeError:
1720
+ raise TypeError("components of tuple or list parameter must "
1721
+ "contain only integers")
1722
+ # Check that the weight-0 condition is satisfied:
1723
+ # d_1 (q - 1) + ... + d_{r-1} (q^{r-1} - 1)
1724
+ # = d_r (q^r - 1)
1725
+ if check:
1726
+ right = parameter_1[-1]*(q**r - 1)
1727
+ left = sum(parameter_1[i]*(q**(parameter_0[i]) - 1) for i in
1728
+ range(len(parameter_0)))
1729
+ if left != right:
1730
+ raise ValueError("parameter does not satisfy the "
1731
+ "weight-0 condition")
1732
+ else:
1733
+ raise TypeError("parameter must be a tuple or a list of "
1734
+ "length 2 or an integer")
1735
+ num = prod(self._gen[k]**d
1736
+ for k, d in zip(parameter_0, parameter_1[:-1]))
1737
+ return num / (self._gen[-1]**parameter_1[-1])
1738
+
1739
+ def jk_invariants(self):
1740
+ r"""
1741
+ Return a dictionary whose keys are all the integers
1742
+ `1 \leqslant k \leqslant r-1` and the values are the
1743
+ corresponding `j_k`-invariants
1744
+
1745
+ Recall that the `j_k`-invariant of ``self`` is defined by:
1746
+
1747
+ .. MATH::
1748
+
1749
+ j_k := \frac{g_k^{(q^r - 1)/(\mathrm{gcd}(k, r) - 1)}}{g_r^{(q^k - 1)/(\mathrm{gcd}(k, r) - 1)}}
1750
+
1751
+ where `g_i` is the `i`-th coefficient of the generator of ``self``.
1752
+
1753
+ EXAMPLES::
1754
+
1755
+ sage: A = GF(3)['T']
1756
+ sage: K.<T> = Frac(A)
1757
+ sage: phi = DrinfeldModule(A, [T, 1, T+1, T^3, T^6])
1758
+ sage: jk_inv = phi.jk_invariants(); jk_inv
1759
+ {1: 1/T^6, 2: (T^10 + T^9 + T + 1)/T^6, 3: T^42}
1760
+ sage: jk_inv[2]
1761
+ (T^10 + T^9 + T + 1)/T^6
1762
+
1763
+ ::
1764
+
1765
+ sage: F = GF(7**2)
1766
+ sage: A = F['T']
1767
+ sage: E.<z> = F.extension(4)
1768
+ sage: phi = DrinfeldModule(A, [z^2, 1, z+1, z^2, z, z+1])
1769
+ sage: phi.jk_invariants()
1770
+ {1: 5*z^7 + 2*z^6 + 5*z^5 + 2*z^4 + 5*z^3 + z^2 + z + 2,
1771
+ 2: 3*z^7 + 4*z^6 + 5*z^5 + 6*z^4 + 4*z,
1772
+ 3: 5*z^7 + 6*z^6 + 6*z^5 + 4*z^3 + z^2 + 2*z + 1,
1773
+ 4: 3*z^6 + 2*z^5 + 4*z^4 + 2*z^3 + 4*z^2 + 6*z + 2}
1774
+ """
1775
+ r = self._gen.degree() # rank of self
1776
+ return {k: self.j_invariant(k) for k in range(1, r)}
1777
+
1778
+ def morphism(self):
1779
+ r"""
1780
+ Return the morphism object that defines the Drinfeld module.
1781
+
1782
+ OUTPUT: a ring morphism from the function ring to the Ore
1783
+ polynomial ring
1784
+
1785
+ EXAMPLES::
1786
+
1787
+ sage: Fq = GF(25)
1788
+ sage: A.<T> = Fq[]
1789
+ sage: K.<z12> = Fq.extension(6)
1790
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1791
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
1792
+ sage: phi.morphism()
1793
+ Ring morphism:
1794
+ From: Univariate Polynomial Ring in T over Finite Field in z2 of size 5^2
1795
+ To: Ore Polynomial Ring in t over Finite Field in z12 of size 5^12
1796
+ over its base twisted by Frob^2
1797
+ Defn: T |--> z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8
1798
+ + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1799
+ sage: from sage.rings.morphism import RingHomomorphism
1800
+ sage: isinstance(phi.morphism(), RingHomomorphism)
1801
+ True
1802
+
1803
+ Actually, the ``DrinfeldModule`` method :meth:`__call__` simply
1804
+ class the ``__call__`` method of this morphism::
1805
+
1806
+ sage: phi.morphism()(T) == phi(T)
1807
+ True
1808
+ sage: a = A.random_element()
1809
+ sage: phi.morphism()(a) == phi(a)
1810
+ True
1811
+
1812
+ And many methods of the Drinfeld module have a counterpart in
1813
+ the morphism object::
1814
+
1815
+ sage: m = phi.morphism()
1816
+ sage: m.domain() is phi.function_ring()
1817
+ True
1818
+ sage: m.codomain() is phi.ore_polring()
1819
+ True
1820
+ sage: m.im_gens()
1821
+ [z12^5*t^2 + z12^3*t + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8
1822
+ + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12]
1823
+ sage: phi(T) == m.im_gens()[0]
1824
+ True
1825
+ """
1826
+ return self._morphism
1827
+
1828
+ def rank(self):
1829
+ r"""
1830
+ Return the rank of the Drinfeld module.
1831
+
1832
+ In our case, the rank is the degree of the generator.
1833
+
1834
+ OUTPUT: integer
1835
+
1836
+ EXAMPLES::
1837
+
1838
+ sage: Fq = GF(25)
1839
+ sage: A.<T> = Fq[]
1840
+ sage: K.<z12> = Fq.extension(6)
1841
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1842
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
1843
+ sage: phi.rank()
1844
+ 2
1845
+ sage: psi = DrinfeldModule(A, [p_root, 2])
1846
+ sage: psi.rank()
1847
+ 1
1848
+ sage: rho = DrinfeldModule(A, [p_root, 0, 0, 0, 1])
1849
+ sage: rho.rank()
1850
+ 4
1851
+
1852
+ TESTS:
1853
+
1854
+ The rank must be an ``Integer`` (see PR #35519)::
1855
+
1856
+ sage: Fq = GF(25)
1857
+ sage: A.<T> = Fq[]
1858
+ sage: K.<z12> = Fq.extension(6)
1859
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1860
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
1861
+ sage: isinstance(phi.rank(), Integer)
1862
+ True
1863
+ """
1864
+ return self._gen.degree()
1865
+
1866
+ def velu(self, isog):
1867
+ r"""
1868
+ Return a new Drinfeld module such that ``isog`` defines an
1869
+ isogeny to this module with domain ``self``; if no such isogeny
1870
+ exists, raise an exception.
1871
+
1872
+ INPUT:
1873
+
1874
+ - ``isog`` -- the Ore polynomial that defines the isogeny
1875
+
1876
+ OUTPUT: a Drinfeld module
1877
+
1878
+ ALGORITHM:
1879
+
1880
+ The input defines an isogeny if only if:
1881
+
1882
+ 1. The degree of the characteristic divides the height of
1883
+ the input. (The height of an Ore polynomial `P(\tau)` is the
1884
+ maximum `n` such that `\tau^n` right-divides `P(\tau)`.)
1885
+
1886
+ 2. The input right-divides the generator, which can
1887
+ be tested with Euclidean division.
1888
+
1889
+ We test if the input is an isogeny, and, if it is, we
1890
+ return the quotient of the Euclidean division.
1891
+
1892
+ Height and Euclidean division of Ore polynomials are
1893
+ implemented as methods of class
1894
+ :class:`sage.rings.polynomial.ore_polynomial_element.OrePolynomial`.
1895
+
1896
+ Another possible algorithm is to recursively solve a system,
1897
+ see :arxiv:`2203.06970`, Eq. 1.1.
1898
+
1899
+ EXAMPLES::
1900
+
1901
+ sage: Fq = GF(25)
1902
+ sage: A.<T> = Fq[]
1903
+ sage: K.<z12> = Fq.extension(6)
1904
+ sage: p_root = 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1905
+ sage: phi = DrinfeldModule(A, [p_root, z12^3, z12^5])
1906
+ sage: t = phi.ore_polring().gen()
1907
+ sage: isog = t + 2*z12^11 + 4*z12^9 + 2*z12^8 + 2*z12^6 + 3*z12^5 + z12^4 + 2*z12^3 + 4*z12^2 + 4*z12 + 4
1908
+ sage: psi = phi.velu(isog)
1909
+ sage: psi
1910
+ Drinfeld module defined by T |-->
1911
+ (z12^11 + 3*z12^10 + z12^9 + z12^7 + z12^5 + 4*z12^4 + 4*z12^3 + z12^2 + 1)*t^2
1912
+ + (2*z12^11 + 4*z12^10 + 2*z12^8 + z12^6 + 3*z12^5 + z12^4 + 2*z12^3 + z12^2 + z12 + 4)*t
1913
+ + 2*z12^11 + 2*z12^10 + z12^9 + 3*z12^8 + z12^7 + 2*z12^5 + 2*z12^4 + 3*z12^3 + z12^2 + 2*z12
1914
+ sage: isog in Hom(phi, psi)
1915
+ True
1916
+
1917
+ This method works for endomorphisms as well::
1918
+
1919
+ sage: phi.velu(phi(T)) is phi
1920
+ True
1921
+ sage: phi.velu(t^6) is phi
1922
+ True
1923
+
1924
+ The following inputs do not define isogenies, and the method
1925
+ returns ``None``::
1926
+
1927
+ sage: phi.velu(0)
1928
+ Traceback (most recent call last):
1929
+ ...
1930
+ ValueError: the input does not define an isogeny
1931
+ sage: phi.velu(t)
1932
+ Traceback (most recent call last):
1933
+ ...
1934
+ ValueError: the input does not define an isogeny
1935
+ sage: phi.velu(t^3 + t + 2)
1936
+ Traceback (most recent call last):
1937
+ ...
1938
+ ValueError: the input does not define an isogeny
1939
+ """
1940
+ if isog not in self.ore_polring():
1941
+ raise TypeError('input must be an Ore polynomial')
1942
+ e = ValueError('the input does not define an isogeny')
1943
+ if isog == 0:
1944
+ raise e
1945
+ quo, rem = (isog * self.gen()).right_quo_rem(isog)
1946
+ if rem.is_zero() and quo[0] == self.gen()[0]:
1947
+ return self.category().object(quo)
1948
+ else:
1949
+ raise e
1950
+
1951
+ def hom(self, x, codomain=None):
1952
+ r"""
1953
+ Return the homomorphism defined by ``x`` having this Drinfeld
1954
+ module as domain.
1955
+
1956
+ We recall that a homomorphism `f : \phi \to \psi` between
1957
+ two Drinfeld modules is defined by an Ore polynomial `u`,
1958
+ which is subject to the relation `phi_T u = u \psi_T`.
1959
+
1960
+ INPUT:
1961
+
1962
+ - ``x`` -- an element of the ring of functions, or an
1963
+ Ore polynomial
1964
+
1965
+ - ``codomain`` -- a Drinfeld module or ``None`` (default:
1966
+ ``None``)
1967
+
1968
+ EXAMPLES::
1969
+
1970
+ sage: Fq = GF(5)
1971
+ sage: A.<T> = Fq[]
1972
+ sage: K.<z> = Fq.extension(3)
1973
+ sage: phi = DrinfeldModule(A, [z, 0, 1, z])
1974
+ sage: phi
1975
+ Drinfeld module defined by T |--> z*t^3 + t^2 + z
1976
+
1977
+ An important class of endomorphisms of a Drinfeld module
1978
+ `\phi` is given by scalar multiplications, that are endomorphisms
1979
+ corresponding to the Ore polynomials `\phi_a` with `a` in the function
1980
+ ring `A`. We construct them as follows::
1981
+
1982
+ sage: phi.hom(T)
1983
+ Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z
1984
+ Defn: z*t^3 + t^2 + z
1985
+
1986
+ ::
1987
+
1988
+ sage: phi.hom(T^2 + 1)
1989
+ Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z
1990
+ Defn: z^2*t^6 + (3*z^2 + z + 1)*t^5 + t^4 + 2*z^2*t^3 + (3*z^2 + z + 1)*t^2 + z^2 + 1
1991
+
1992
+ We can also define a morphism by passing in the Ore polynomial
1993
+ defining it.
1994
+ For example, below, we construct the Frobenius endomorphism
1995
+ of `\phi`::
1996
+
1997
+ sage: t = phi.ore_variable()
1998
+ sage: phi.hom(t^3)
1999
+ Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z
2000
+ Defn: t^3
2001
+
2002
+ If the input Ore polynomial defines a morphism to another
2003
+ Drinfeld module, the latter is determined automatically::
2004
+
2005
+ sage: phi.hom(t + 1)
2006
+ Drinfeld Module morphism:
2007
+ From: Drinfeld module defined by T |--> z*t^3 + t^2 + z
2008
+ To: Drinfeld module defined by T |--> (2*z^2 + 4*z + 4)*t^3 + (3*z^2 + 2*z + 2)*t^2 + (2*z^2 + 3*z + 4)*t + z
2009
+ Defn: t + 1
2010
+
2011
+ TESTS::
2012
+
2013
+ sage: phi.hom(t)
2014
+ Traceback (most recent call last):
2015
+ ...
2016
+ ValueError: the input does not define an isogeny
2017
+
2018
+ ::
2019
+
2020
+ sage: phi.hom(T + z)
2021
+ Traceback (most recent call last):
2022
+ ...
2023
+ ValueError: the input does not define an isogeny
2024
+
2025
+ ::
2026
+
2027
+ sage: phi.hom(t + 1, codomain=phi)
2028
+ Traceback (most recent call last):
2029
+ ...
2030
+ ValueError: Ore polynomial does not define a morphism
2031
+
2032
+ Check that x = 0 (without specified codomain) gives the zero endomorphism::
2033
+
2034
+ sage: phi.hom(K.zero())
2035
+ Endomorphism of Drinfeld module defined by ...
2036
+ Defn: 0
2037
+ """
2038
+ # When `x` is in the function ring (or something that coerces to it):
2039
+ if self.function_ring().has_coerce_map_from(x.parent()):
2040
+ return self.Hom(self)(x)
2041
+ if codomain is None:
2042
+ if x.is_zero():
2043
+ return self.Hom(self)(0)
2044
+ try:
2045
+ codomain = self.velu(x)
2046
+ except TypeError:
2047
+ raise ValueError("the input does not define an isogeny")
2048
+ H = self.Hom(codomain)
2049
+ return H(x)
2050
+
2051
+ # TODO: implement the method `moh`, the analogue of `hom`
2052
+ # with fixed codomain.
2053
+ # It's not straightforward because `left_divides` does not
2054
+ # work currently because Sage does not know how to invert the
2055
+ # Frobenius endomorphism; this is due to the RingExtension stuff.
2056
+
2057
+ def scalar_multiplication(self, x):
2058
+ r"""
2059
+ Return the endomorphism of this Drinfeld module, which is
2060
+ the multiplication by `x`, i.e. the isogeny defined by the
2061
+ Ore polynomial `\phi_x`.
2062
+
2063
+ INPUT:
2064
+
2065
+ - ``x`` -- an element in the ring of functions
2066
+
2067
+ EXAMPLES::
2068
+
2069
+ sage: Fq = GF(5)
2070
+ sage: A.<T> = Fq[]
2071
+ sage: K.<z> = Fq.extension(3)
2072
+ sage: phi = DrinfeldModule(A, [z, 0, 1, z])
2073
+ sage: phi
2074
+ Drinfeld module defined by T |--> z*t^3 + t^2 + z
2075
+ sage: phi.hom(T) # indirect doctest
2076
+ Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z
2077
+ Defn: z*t^3 + t^2 + z
2078
+
2079
+ ::
2080
+
2081
+ sage: phi.hom(T^2 + 1)
2082
+ Endomorphism of Drinfeld module defined by T |--> z*t^3 + t^2 + z
2083
+ Defn: z^2*t^6 + (3*z^2 + z + 1)*t^5 + t^4 + 2*z^2*t^3 + (3*z^2 + z + 1)*t^2 + z^2 + 1
2084
+ """
2085
+ if not self.function_ring().has_coerce_map_from(x.parent()):
2086
+ raise ValueError("%s is not element of the function ring" % x)
2087
+ return self.Hom(self)(x)