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,2042 @@
1
+ # sage_setup: distribution = sagemath-modules
2
+ """
3
+ Binary quadratic forms with integer coefficients
4
+
5
+ This module provides a specialized class for working with a binary quadratic
6
+ form `a x^2 + b x y + c y^2`, stored as a triple of integers `(a, b, c)`.
7
+
8
+ EXAMPLES::
9
+
10
+ sage: Q = BinaryQF([1, 2, 3])
11
+ sage: Q
12
+ x^2 + 2*x*y + 3*y^2
13
+ sage: Q.discriminant()
14
+ -8
15
+ sage: Q.reduced_form() # needs sage.libs.pari
16
+ x^2 + 2*y^2
17
+ sage: Q(1, 1)
18
+ 6
19
+
20
+ TESTS::
21
+
22
+ sage: Q == loads(dumps(Q))
23
+ True
24
+
25
+ AUTHORS:
26
+
27
+ - Jon Hanke (2006-08-08):
28
+
29
+ - Appended to add the methods :func:`BinaryQF_reduced_representatives`,
30
+ :meth:`~BinaryQF.is_reduced`, and ``__add__`` on 8-3-2006 for Coding Sprint
31
+ #2.
32
+
33
+ - Added Documentation and :meth:`~BinaryQF.complex_point` method on 8-8-2006.
34
+
35
+ - Nick Alexander: add doctests and clean code for Doc Days 2
36
+
37
+ - William Stein (2009-08-05): composition; some ReSTification.
38
+
39
+ - William Stein (2009-09-18): make immutable.
40
+
41
+ - Justin C. Walker (2011-02-06): Add support for indefinite forms.
42
+ """
43
+
44
+ # ****************************************************************************
45
+ # Copyright (C) 2006-2009 William Stein and Jon Hanke
46
+ #
47
+ # This program is free software: you can redistribute it and/or modify
48
+ # it under the terms of the GNU General Public License as published by
49
+ # the Free Software Foundation, either version 2 of the License, or
50
+ # (at your option) any later version.
51
+ # https://www.gnu.org/licenses/
52
+ # ****************************************************************************
53
+ from functools import total_ordering
54
+
55
+ from sage.rings.integer_ring import ZZ
56
+ from sage.arith.misc import gcd
57
+ from sage.structure.sage_object import SageObject
58
+ from sage.matrix.matrix_space import MatrixSpace
59
+ from sage.matrix.constructor import Matrix
60
+ from sage.misc.cachefunc import cached_method
61
+
62
+
63
+ try:
64
+ from sage.libs.pari import pari
65
+ from cypari2.gen import Gen as pari_gen
66
+ except ImportError:
67
+ pari_gen = ()
68
+
69
+
70
+ @total_ordering
71
+ class BinaryQF(SageObject):
72
+ r"""
73
+ A binary quadratic form over `\ZZ`.
74
+
75
+ INPUT:
76
+
77
+ One of the following:
78
+
79
+ - ``a`` -- either a 3-tuple of integers, or a quadratic
80
+ homogeneous polynomial in two variables with integer
81
+ coefficients
82
+
83
+ - ``a``, ``b``, ``c`` -- three integers
84
+
85
+ OUTPUT: the binary quadratic form `a x^2 + b xy + c y^2`
86
+
87
+ EXAMPLES::
88
+
89
+ sage: b = BinaryQF([1, 2, 3])
90
+ sage: b.discriminant()
91
+ -8
92
+ sage: b1 = BinaryQF(1, 2, 3)
93
+ sage: b1 == b
94
+ True
95
+ sage: R.<x, y> = ZZ[]
96
+ sage: BinaryQF(x^2 + 2*x*y + 3*y^2) == b
97
+ True
98
+ sage: BinaryQF(1, 0, 1)
99
+ x^2 + y^2
100
+ """
101
+ def __init__(self, a, b=None, c=None):
102
+ r"""
103
+ Create a binary quadratic form `ax^2 + bxy + cy^2`.
104
+
105
+ INPUT:
106
+
107
+ One of the following:
108
+
109
+ - ``a`` -- either a 3-tuple of integers, or a quadratic
110
+ homogeneous polynomial in two variables with integer
111
+ coefficients
112
+
113
+ - ``a``, ``b``, ``c`` -- three integers
114
+
115
+ EXAMPLES::
116
+
117
+ sage: Q = BinaryQF([1, 2, 3]); Q
118
+ x^2 + 2*x*y + 3*y^2
119
+ sage: Q = BinaryQF([1, 2])
120
+ Traceback (most recent call last):
121
+ ...
122
+ TypeError: binary quadratic form must be given by a quadratic homogeneous bivariate integer polynomial or its coefficients
123
+
124
+ sage: R.<x, y> = ZZ[]
125
+ sage: f = x^2 + 2*x*y + 3*y^2
126
+ sage: BinaryQF(f)
127
+ x^2 + 2*x*y + 3*y^2
128
+ sage: BinaryQF(f + x)
129
+ Traceback (most recent call last):
130
+ ...
131
+ TypeError: binary quadratic form must be given by a quadratic homogeneous bivariate integer polynomial or its coefficients
132
+
133
+ TESTS::
134
+
135
+ sage: BinaryQF(0)
136
+ 0
137
+ """
138
+ from sage.rings.polynomial.multi_polynomial import MPolynomial
139
+ if b is None and c is None:
140
+ if isinstance(a, (list, tuple)) and len(a) == 3:
141
+ a, b, c = a
142
+ elif a == 0:
143
+ a = b = c = 0
144
+ elif (isinstance(a, MPolynomial) and a.is_homogeneous() and a.base_ring() == ZZ
145
+ and a.degree() == 2 and a.parent().ngens() == 2):
146
+ x, y = a.parent().gens()
147
+ a, b, c = (a.monomial_coefficient(mon) for mon in [x**2, x*y, y**2])
148
+ elif isinstance(a, pari_gen) and a.type() in ('t_QFI', 't_QFR', 't_QFB'):
149
+ # a has 3 or 4 components
150
+ a, b, c = a[0], a[1], a[2]
151
+ try:
152
+ self._a = ZZ(a)
153
+ self._b = ZZ(b)
154
+ self._c = ZZ(c)
155
+ except TypeError:
156
+ raise TypeError('binary quadratic form must be given by a quadratic homogeneous bivariate integer polynomial or its coefficients')
157
+ self._poly = None
158
+
159
+ def _pari_init_(self):
160
+ """
161
+ Convert this quadratic form to PARI.
162
+
163
+ EXAMPLES::
164
+
165
+ sage: f = BinaryQF([2, 3, 4]); f
166
+ 2*x^2 + 3*x*y + 4*y^2
167
+ sage: f._pari_init_()
168
+ 'Qfb(2,3,4)'
169
+
170
+ sage: # needs sage.libs.pari
171
+ sage: pari(f)
172
+ Qfb(2, 3, 4)
173
+ sage: type(pari(f))
174
+ <... 'cypari2.gen.Gen'>
175
+ sage: gp(f)
176
+ Qfb(2, 3, 4)
177
+ sage: type(gp(f))
178
+ <class 'sage.interfaces.gp.GpElement'>
179
+ """
180
+ return f'Qfb({self._a},{self._b},{self._c})'
181
+
182
+ @staticmethod
183
+ def principal(D):
184
+ r"""
185
+ Return the principal binary quadratic form of the given discriminant.
186
+
187
+ EXAMPLES::
188
+
189
+ sage: BinaryQF.principal(8)
190
+ x^2 - 2*y^2
191
+ sage: BinaryQF.principal(5)
192
+ x^2 + x*y - y^2
193
+ sage: BinaryQF.principal(4)
194
+ x^2 - y^2
195
+ sage: BinaryQF.principal(1)
196
+ x^2 + x*y
197
+ sage: BinaryQF.principal(-3)
198
+ x^2 + x*y + y^2
199
+ sage: BinaryQF.principal(-4)
200
+ x^2 + y^2
201
+ sage: BinaryQF.principal(-7)
202
+ x^2 + x*y + 2*y^2
203
+ sage: BinaryQF.principal(-8)
204
+ x^2 + 2*y^2
205
+
206
+ TESTS:
207
+
208
+ Some randomized testing::
209
+
210
+ sage: D = 1
211
+ sage: while D.is_square():
212
+ ....: D = choice((-4,+4)) * randrange(9999) + randrange(2)
213
+ sage: Q = BinaryQF.principal(D)
214
+ sage: Q.discriminant() == D # correct discriminant
215
+ True
216
+ sage: (Q*Q).is_equivalent(Q) # idempotent (hence identity) # needs sage.libs.pari
217
+ True
218
+ """
219
+ D = ZZ(D)
220
+ D4 = D % 4
221
+ if D4 not in (0, 1):
222
+ raise ValueError('discriminant must be congruent to 0 or 1 modulo 4')
223
+ return BinaryQF([1, D4, (D4-D)//4])
224
+
225
+ def __mul__(self, right):
226
+ """
227
+ Gauss composition or right action by a 2x2 integer matrix.
228
+
229
+ The result need not be reduced.
230
+
231
+ EXAMPLES:
232
+
233
+ We explicitly compute in the group of classes of positive
234
+ definite binary quadratic forms of discriminant -23::
235
+
236
+ sage: # needs sage.libs.pari
237
+ sage: R = BinaryQF_reduced_representatives(-23, primitive_only=False); R
238
+ [x^2 + x*y + 6*y^2, 2*x^2 - x*y + 3*y^2, 2*x^2 + x*y + 3*y^2]
239
+ sage: R[0] * R[0]
240
+ x^2 + x*y + 6*y^2
241
+ sage: R[1] * R[1]
242
+ 4*x^2 + 3*x*y + 2*y^2
243
+ sage: (R[1] * R[1]).reduced_form()
244
+ 2*x^2 + x*y + 3*y^2
245
+ sage: (R[1] * R[1] * R[1]).reduced_form()
246
+ x^2 + x*y + 6*y^2
247
+
248
+ sage: q1 = BinaryQF(1, 1, 4)
249
+ sage: M = Matrix(ZZ, [[1, 3], [0, 1]])
250
+ sage: q1*M
251
+ x^2 + 7*x*y + 16*y^2
252
+ sage: q1.matrix_action_right(M)
253
+ x^2 + 7*x*y + 16*y^2
254
+ sage: N = Matrix(ZZ, [[1, 0], [1, 0]])
255
+ sage: q1*(M*N) == q1.matrix_action_right(M).matrix_action_right(N)
256
+ True
257
+ """
258
+ # Either a "right" action by
259
+ # ...or Gaussian composition
260
+ if isinstance(right, BinaryQF):
261
+ return BinaryQF(self.__pari__().qfbcompraw(right))
262
+ # ...or a 2x2 matrix...
263
+ if (isinstance(right.parent(), MatrixSpace)
264
+ and right.nrows() == right.ncols() == 2):
265
+ aa, bb, cc, dd = right.list()
266
+ A = self.polynomial()(aa, cc)
267
+ C = self.polynomial()(bb, dd)
268
+ B = self.polynomial()(aa + bb, cc + dd) - A - C
269
+ return BinaryQF(A, B, C)
270
+ raise TypeError("right operand must be a binary quadratic form or 2x2 matrix")
271
+
272
+ def __getitem__(self, n):
273
+ """
274
+ Return the `n`-th component of this quadratic form.
275
+
276
+ If this form is `a x^2 + b x y + c y^2`, the 0-th component is `a`,
277
+ the 1-st component is `b`, and `2`-nd component is `c`.
278
+
279
+ Indexing is like lists -- negative indices and slices are allowed.
280
+
281
+ EXAMPLES::
282
+
283
+ sage: Q = BinaryQF([2, 3, 4])
284
+ sage: Q[0]
285
+ 2
286
+ sage: Q[2]
287
+ 4
288
+ sage: Q[:2]
289
+ (2, 3)
290
+ sage: tuple(Q)
291
+ (2, 3, 4)
292
+ sage: list(Q)
293
+ [2, 3, 4]
294
+ """
295
+ return (self._a, self._b, self._c)[n]
296
+
297
+ def __call__(self, *args):
298
+ r"""
299
+ Evaluate this quadratic form at a point.
300
+
301
+ INPUT:
302
+
303
+ - ``args`` -- x and y values, as a pair x, y or a list, tuple, or
304
+ vector
305
+
306
+ EXAMPLES::
307
+
308
+ sage: Q = BinaryQF([2, 3, 4])
309
+ sage: Q(1, 2)
310
+ 24
311
+
312
+ TESTS::
313
+
314
+ sage: Q = BinaryQF([2, 3, 4])
315
+ sage: Q([1, 2])
316
+ 24
317
+ sage: Q((1, 2))
318
+ 24
319
+ sage: Q(vector([1, 2]))
320
+ 24
321
+ """
322
+ if len(args) == 1:
323
+ args = args[0]
324
+ x, y = args
325
+ return (self._a * x + self._b * y) * x + self._c * y**2
326
+
327
+ def __hash__(self):
328
+ r"""
329
+ TESTS::
330
+
331
+ sage: hash(BinaryQF([2, 2, 3]))
332
+ 802
333
+ sage: hash(BinaryQF([2, 3, 2]))
334
+ 562
335
+ sage: hash(BinaryQF([3, 2, 2]))
336
+ 547
337
+ """
338
+ return hash(self._a) ^ (hash(self._b) << 4) ^ (hash(self._c) << 8)
339
+
340
+ def __eq__(self, right):
341
+ """
342
+ Return ``True`` if ``self`` and ``right`` are identical.
343
+
344
+ This means that they have the same coefficients.
345
+
346
+ EXAMPLES::
347
+
348
+ sage: P = BinaryQF([2, 2, 3])
349
+ sage: Q = BinaryQF([2, 2, 3])
350
+ sage: R = BinaryQF([1, 2, 3])
351
+ sage: P == Q # indirect doctest
352
+ True
353
+ sage: P == R # indirect doctest
354
+ False
355
+
356
+ TESTS::
357
+
358
+ sage: P == P
359
+ True
360
+ sage: Q == P
361
+ True
362
+ sage: R == P
363
+ False
364
+ sage: P == 2
365
+ False
366
+ """
367
+ if not isinstance(right, BinaryQF):
368
+ return False
369
+ return (self._a, self._b, self._c) == (right._a, right._b, right._c)
370
+
371
+ def __ne__(self, right):
372
+ """
373
+ Return ``True`` if ``self`` and ``right`` are not identical.
374
+
375
+ This means that they have different coefficients.
376
+
377
+ EXAMPLES::
378
+
379
+ sage: P = BinaryQF([2, 2, 3])
380
+ sage: Q = BinaryQF([2, 2, 3])
381
+ sage: R = BinaryQF([1, 2, 3])
382
+ sage: P != Q # indirect doctest
383
+ False
384
+ sage: P != R # indirect doctest
385
+ True
386
+ """
387
+ return not (self == right)
388
+
389
+ def __lt__(self, right):
390
+ """
391
+ Compare the coefficients of ``self`` and ``right``.
392
+
393
+ This is done lexicographically.
394
+
395
+ EXAMPLES::
396
+
397
+ sage: P = BinaryQF([2, 2, 3])
398
+ sage: Q = BinaryQF([1, 2, 3])
399
+ sage: P < Q
400
+ False
401
+ sage: Q < P
402
+ True
403
+ sage: Q <= P
404
+ True
405
+ """
406
+ if not isinstance(right, BinaryQF):
407
+ return False
408
+ return (self._a, self._b, self._c) < (right._a, right._b, right._c)
409
+
410
+ def __add__(self, Q):
411
+ """
412
+ Return the component-wise sum of two forms.
413
+
414
+ Given `a_1 x^2 + b_1 x y + c_1 y^2` and `a_2 x^2 + b_2 x y +
415
+ c_2 y^2`, this returns the form `(a_1 + a_2) x^2 + (b_1 + b_2)
416
+ x y + (c_1 + c_2) y^2.`
417
+
418
+ EXAMPLES::
419
+
420
+ sage: P = BinaryQF([2, 2, 3]); P
421
+ 2*x^2 + 2*x*y + 3*y^2
422
+ sage: Q = BinaryQF([-1, 2, 2]); Q
423
+ -x^2 + 2*x*y + 2*y^2
424
+ sage: P + Q
425
+ x^2 + 4*x*y + 5*y^2
426
+ sage: P + Q == BinaryQF([1, 4, 5]) # indirect doctest
427
+ True
428
+
429
+ TESTS::
430
+
431
+ sage: Q + P == BinaryQF([1, 4, 5]) # indirect doctest
432
+ True
433
+ """
434
+ return BinaryQF([self._a + Q._a, self._b + Q._b, self._c + Q._c])
435
+
436
+ def __sub__(self, Q):
437
+ """
438
+ Return the component-wise difference of two forms.
439
+
440
+ Given two forms `a_1 x^2 + b_1 x y + c_1 y^2` and `a_2 x^2 +
441
+ b_2 x y + c_2 y^2`, this returns the form `(a_1 - a_2) x^2 +
442
+ (b_1 - b_2) x y + (c_1 - c_2) y^2.`
443
+
444
+ EXAMPLES::
445
+
446
+ sage: P = BinaryQF([2, 2, 3]); P
447
+ 2*x^2 + 2*x*y + 3*y^2
448
+ sage: Q = BinaryQF([-1, 2, 2]); Q
449
+ -x^2 + 2*x*y + 2*y^2
450
+ sage: P - Q
451
+ 3*x^2 + y^2
452
+ sage: P - Q == BinaryQF([3, 0, 1]) # indirect doctest
453
+ True
454
+
455
+ TESTS::
456
+
457
+ sage: Q - P == BinaryQF([3, 0, 1]) # indirect doctest
458
+ False
459
+ sage: Q - P != BinaryQF([3, 0, 1]) # indirect doctest
460
+ True
461
+ """
462
+ return BinaryQF([self._a - Q._a, self._b - Q._b, self._c - Q._c])
463
+
464
+ def __neg__(self):
465
+ r"""
466
+ Return the negative of this binary quadratic form.
467
+
468
+ EXAMPLES::
469
+
470
+ sage: Q = BinaryQF([1,-2,3])
471
+ sage: -Q
472
+ -x^2 + 2*x*y - 3*y^2
473
+ sage: -Q == BinaryQF([0,0,0]) - Q
474
+ True
475
+ """
476
+ return BinaryQF([-self._a, -self._b, -self._c])
477
+
478
+ def _repr_(self) -> str:
479
+ """
480
+ Display the quadratic form.
481
+
482
+ EXAMPLES::
483
+
484
+ sage: Q = BinaryQF([1, 2, 3]); Q # indirect doctest
485
+ x^2 + 2*x*y + 3*y^2
486
+
487
+ sage: Q = BinaryQF([-1, 2, 3]); Q
488
+ -x^2 + 2*x*y + 3*y^2
489
+
490
+ sage: Q = BinaryQF([0, 0, 0]); Q
491
+ 0
492
+ """
493
+ return repr(self.polynomial())
494
+
495
+ def _latex_(self) -> str:
496
+ """
497
+ Return latex representation of this binary quadratic form.
498
+
499
+ EXAMPLES::
500
+
501
+ sage: f = BinaryQF((778, 1115, 400)); f
502
+ 778*x^2 + 1115*x*y + 400*y^2
503
+ sage: latex(f) # indirect doctest
504
+ 778 x^{2} + 1115 x y + 400 y^{2}
505
+ """
506
+ return self.polynomial()._latex_()
507
+
508
+ @cached_method
509
+ def content(self):
510
+ r"""
511
+ Return the content of the form, i.e., the `\gcd` of the coefficients.
512
+
513
+ EXAMPLES::
514
+
515
+ sage: Q = BinaryQF(22, 14, 10)
516
+ sage: Q.content()
517
+ 2
518
+ sage: Q = BinaryQF(4, 4, -15)
519
+ sage: Q.content()
520
+ 1
521
+ """
522
+ return gcd([self._a, self._b, self._c])
523
+
524
+ def polynomial(self):
525
+ """
526
+ Return ``self`` as a homogeneous 2-variable polynomial.
527
+
528
+ EXAMPLES::
529
+
530
+ sage: Q = BinaryQF([1, 2, 3])
531
+ sage: Q.polynomial()
532
+ x^2 + 2*x*y + 3*y^2
533
+
534
+ sage: Q = BinaryQF([-1, -2, 3])
535
+ sage: Q.polynomial()
536
+ -x^2 - 2*x*y + 3*y^2
537
+
538
+ sage: Q = BinaryQF([0, 0, 0])
539
+ sage: Q.polynomial()
540
+ 0
541
+ """
542
+ # Note: Caching in _poly seems to give a very slight
543
+ # improvement (~0.2 usec) in 'timeit()' runs. Not sure it
544
+ # is worth the instance variable.
545
+ if self._poly is None:
546
+ self._poly = self(ZZ['x, y'].gens())
547
+ return self._poly
548
+
549
+ @staticmethod
550
+ def from_polynomial(poly):
551
+ r"""
552
+ Construct a :class:`BinaryQF` from a bivariate polynomial
553
+ with integer coefficients. Inverse of :meth:`polynomial`.
554
+
555
+ EXAMPLES::
556
+
557
+ sage: R.<u,v> = ZZ[]
558
+ sage: f = u^2 + 419*v^2
559
+ sage: Q = BinaryQF.from_polynomial(f); Q
560
+ x^2 + 419*y^2
561
+ sage: Q.polynomial()
562
+ x^2 + 419*y^2
563
+ sage: Q.polynomial()(R.gens()) == f
564
+ True
565
+
566
+ The method fails if the given polynomial is not a quadratic form::
567
+
568
+ sage: BinaryQF.from_polynomial(u^3 - 5*v)
569
+ Traceback (most recent call last):
570
+ ...
571
+ ValueError: polynomial has monomials of degree != 2
572
+
573
+ ...or if the coefficients aren't integers::
574
+
575
+ sage: BinaryQF.from_polynomial(u^2/7 + v^2)
576
+ Traceback (most recent call last):
577
+ ...
578
+ TypeError: no conversion of this rational to integer
579
+ """
580
+ R = poly.parent()
581
+ from sage.rings.polynomial.multi_polynomial_ring_base import MPolynomialRing_base
582
+ if not isinstance(R, MPolynomialRing_base) or R.ngens() != 2:
583
+ raise TypeError(f'not a bivariate polynomial ring: {R}')
584
+ if not all(mon.degree() == 2 for mon in poly.monomials()):
585
+ raise ValueError('polynomial has monomials of degree != 2')
586
+ x, y = R.gens()
587
+ coeffs = (poly.monomial_coefficient(mon) for mon in (x**2, x*y, y**2))
588
+ a, b, c = map(ZZ, coeffs)
589
+ return BinaryQF(a, b, c)
590
+
591
+ @cached_method
592
+ def discriminant(self):
593
+ """
594
+ Return the discriminant of ``self``.
595
+
596
+ Given a form `ax^2 + bxy + cy^2`, this returns `b^2 - 4ac`.
597
+
598
+ EXAMPLES::
599
+
600
+ sage: Q = BinaryQF([1, 2, 3])
601
+ sage: Q.discriminant()
602
+ -8
603
+ """
604
+ return self._b**2 - 4 * self._a * self._c
605
+
606
+ def determinant(self):
607
+ """
608
+ Return the determinant of the matrix associated to ``self``.
609
+
610
+ The determinant is used by Gauss and by Conway-Sloane, for
611
+ whom an integral quadratic form has coefficients `(a, 2b, c)`
612
+ with `a`, `b`, `c` integers.
613
+
614
+ OUTPUT: the determinant of the matrix::
615
+
616
+ [ a b/2]
617
+ [b/2 c]
618
+
619
+ as a rational.
620
+
621
+ REMARK:
622
+
623
+ This is just `-D/4` where `D` is the discriminant. The return
624
+ type is rational even if `b` (and hence `D`) is even.
625
+
626
+ EXAMPLES::
627
+
628
+ sage: q = BinaryQF(1, -1, 67)
629
+ sage: q.determinant()
630
+ 267/4
631
+ """
632
+ return -self.discriminant() / 4
633
+
634
+ # for consistency with general quadratic form code
635
+ det = determinant
636
+
637
+ @cached_method
638
+ def has_fundamental_discriminant(self) -> bool:
639
+ """
640
+ Return whether the discriminant `D` of this form is a
641
+ fundamental discriminant (i.e. `D` is the smallest element
642
+ of its squareclass with `D = 0` or `1` modulo `4`).
643
+
644
+ EXAMPLES::
645
+
646
+ sage: Q = BinaryQF([1, 0, 1])
647
+ sage: Q.discriminant()
648
+ -4
649
+ sage: Q.has_fundamental_discriminant() # needs sage.libs.pari
650
+ True
651
+
652
+ sage: Q = BinaryQF([2, 0, 2])
653
+ sage: Q.discriminant()
654
+ -16
655
+ sage: Q.has_fundamental_discriminant() # needs sage.libs.pari
656
+ False
657
+ """
658
+ return self.discriminant().is_fundamental_discriminant()
659
+
660
+ def is_primitive(self) -> bool:
661
+ r"""
662
+ Return whether the form `ax^2 + bxy + cy^2` satisfies
663
+ `\gcd(a, b, c) = 1`, i.e., is primitive.
664
+
665
+ EXAMPLES::
666
+
667
+ sage: Q = BinaryQF([6, 3, 9])
668
+ sage: Q.is_primitive()
669
+ False
670
+
671
+ sage: Q = BinaryQF([1, 1, 1])
672
+ sage: Q.is_primitive()
673
+ True
674
+
675
+ sage: Q = BinaryQF([2, 2, 2])
676
+ sage: Q.is_primitive()
677
+ False
678
+
679
+ sage: rqf = BinaryQF_reduced_representatives(-23*9, primitive_only=False)
680
+ sage: [qf.is_primitive() for qf in rqf]
681
+ [True, True, True, False, True, True, False, False, True]
682
+ sage: rqf
683
+ [x^2 + x*y + 52*y^2,
684
+ 2*x^2 - x*y + 26*y^2,
685
+ 2*x^2 + x*y + 26*y^2,
686
+ 3*x^2 + 3*x*y + 18*y^2,
687
+ 4*x^2 - x*y + 13*y^2,
688
+ 4*x^2 + x*y + 13*y^2,
689
+ 6*x^2 - 3*x*y + 9*y^2,
690
+ 6*x^2 + 3*x*y + 9*y^2,
691
+ 8*x^2 + 7*x*y + 8*y^2]
692
+ sage: [qf for qf in rqf if qf.is_primitive()]
693
+ [x^2 + x*y + 52*y^2,
694
+ 2*x^2 - x*y + 26*y^2,
695
+ 2*x^2 + x*y + 26*y^2,
696
+ 4*x^2 - x*y + 13*y^2,
697
+ 4*x^2 + x*y + 13*y^2,
698
+ 8*x^2 + 7*x*y + 8*y^2]
699
+
700
+ .. SEEALSO::
701
+
702
+ :meth:`content`
703
+ """
704
+ return self.content().is_one()
705
+
706
+ def is_zero(self) -> bool:
707
+ """
708
+ Return whether ``self`` is identically zero.
709
+
710
+ EXAMPLES::
711
+
712
+ sage: Q = BinaryQF(195751, 37615, 1807)
713
+ sage: Q.is_zero()
714
+ False
715
+ sage: Q = BinaryQF(0, 0, 0)
716
+ sage: Q.is_zero()
717
+ True
718
+ """
719
+ return self.content().is_zero()
720
+
721
+ @cached_method
722
+ def is_weakly_reduced(self) -> bool:
723
+ r"""
724
+ Check if the form `ax^2 + bxy + cy^2` satisfies
725
+ `|b| \leq a \leq c`, i.e., is weakly reduced.
726
+
727
+ EXAMPLES::
728
+
729
+ sage: Q = BinaryQF([1, 2, 3])
730
+ sage: Q.is_weakly_reduced()
731
+ False
732
+
733
+ sage: Q = BinaryQF([2, 1, 3])
734
+ sage: Q.is_weakly_reduced()
735
+ True
736
+
737
+ sage: Q = BinaryQF([1, -1, 1])
738
+ sage: Q.is_weakly_reduced()
739
+ True
740
+ """
741
+ if self.discriminant() >= 0:
742
+ raise ValueError("only defined for negative discriminant")
743
+ return (abs(self._b) <= self._a) and (self._a <= self._c)
744
+
745
+ @cached_method
746
+ def is_reducible(self) -> bool:
747
+ r"""
748
+ Return whether this form is reducible and cache the result.
749
+
750
+ A binary form `q` is called reducible if it is the product of
751
+ two linear forms `q = (a x + b y) (c x + d y)`, or
752
+ equivalently if its discriminant is a square.
753
+
754
+ EXAMPLES::
755
+
756
+ sage: q = BinaryQF([1, 0, -1])
757
+ sage: q.is_reducible()
758
+ True
759
+
760
+ .. WARNING::
761
+
762
+ Despite the similar name, this method is unrelated to
763
+ reduction of binary quadratic forms as implemented by
764
+ :meth:`reduced_form` and :meth:`is_reduced`.
765
+ """
766
+ return self.discriminant().is_square()
767
+
768
+ def _reduce_indef(self, transformation=False):
769
+ """
770
+ Reduce an indefinite, non-reduced form.
771
+
772
+ INPUT:
773
+
774
+ - ``transformation`` -- boolean (default: ``False``); if ``True``,
775
+ return both the reduced form and a matrix transforming ``self`` into
776
+ the reduced form
777
+
778
+ TESTS::
779
+
780
+ sage: f = BinaryQF(-1, 0, 3)
781
+ sage: f._reduce_indef(transformation=False)
782
+ -x^2 + 2*x*y + 2*y^2
783
+ sage: red, trans = f._reduce_indef(transformation=True)
784
+ sage: red
785
+ -x^2 + 2*x*y + 2*y^2
786
+ sage: trans
787
+ [-1 1]
788
+ [ 0 -1]
789
+ sage: red == f*trans
790
+ True
791
+
792
+ sage: f = BinaryQF(0, 5, 24)
793
+ sage: red, trans = f._reduce_indef(transformation=True)
794
+ sage: red == f*trans
795
+ True
796
+ """
797
+ if transformation:
798
+ U = Matrix(ZZ, 2, 2, [1, 0, 0, 1])
799
+ d = self.discriminant().sqrt(prec=53)
800
+ Q = self
801
+ while not Q.is_reduced():
802
+ a = Q._a
803
+ b = Q._b
804
+ c = Q._c
805
+ cabs = c.abs()
806
+ # rho(f) as defined in [BUVO2007]_ p. 112 equation (6.12)
807
+ if cabs != 0:
808
+ if cabs >= d:
809
+ s = c.sign() * ((cabs + b) / (2 * cabs)).floor()
810
+ else:
811
+ s = c.sign() * ((d + b) / (2 * cabs)).floor()
812
+ if transformation:
813
+ T = Matrix(ZZ, 2, 2, [0, -1, 1, s])
814
+ U = U * T
815
+ Q = BinaryQF(c, -b + 2*s*c, c*s*s - b*s + a)
816
+ else:
817
+ if b < 0:
818
+ Q = BinaryQF(a, -b, c)
819
+ if transformation:
820
+ T = Matrix(ZZ, 2, 2, [1, 0, 0, -1])
821
+ U = U * T
822
+ else:
823
+ q, r = a.quo_rem(b)
824
+ if 2*r > b:
825
+ q, r = a.quo_rem(-b)
826
+ q = -q
827
+ if transformation:
828
+ T = Matrix(ZZ, 2, 2, [1, 0, -q, 1])
829
+ U = U * T
830
+ Q = BinaryQF(r, b, c)
831
+ if transformation:
832
+ return Q, U
833
+ return Q
834
+
835
+ @cached_method
836
+ def reduced_form(self, transformation=False, algorithm='default'):
837
+ """
838
+ Return a reduced form equivalent to ``self``.
839
+
840
+ INPUT:
841
+
842
+ - ``self`` -- binary quadratic form of non-square discriminant
843
+
844
+ - ``transformation`` -- boolean (default: ``False``); if ``True``, return
845
+ both the reduced form and a matrix whose :meth:`matrix_action_right`
846
+ transforms ``self`` into the reduced form
847
+
848
+ - ``algorithm`` -- string; the algorithm to use. Valid options are:
849
+
850
+ * ``'default'`` -- let Sage pick an algorithm (default)
851
+ * ``'pari'`` -- use PARI (:pari:`qfbred` or :pari:`qfbredsl2`)
852
+ * ``'sage'`` -- use Sage
853
+
854
+ .. SEEALSO::
855
+
856
+ - :meth:`is_reduced`
857
+ - :meth:`is_equivalent`
858
+
859
+ EXAMPLES::
860
+
861
+ sage: a = BinaryQF([33, 11, 5])
862
+ sage: a.is_reduced()
863
+ False
864
+ sage: b = a.reduced_form(); b # needs sage.libs.pari
865
+ 5*x^2 - x*y + 27*y^2
866
+ sage: b.is_reduced() # needs sage.libs.pari
867
+ True
868
+
869
+ sage: a = BinaryQF([15, 0, 15])
870
+ sage: a.is_reduced()
871
+ True
872
+ sage: b = a.reduced_form(); b # needs sage.libs.pari
873
+ 15*x^2 + 15*y^2
874
+ sage: b.is_reduced() # needs sage.libs.pari
875
+ True
876
+
877
+ Examples of reducing indefinite forms::
878
+
879
+ sage: f = BinaryQF(1, 0, -3)
880
+ sage: f.is_reduced()
881
+ False
882
+ sage: g = f.reduced_form(); g # needs sage.libs.pari
883
+ x^2 + 2*x*y - 2*y^2
884
+ sage: g.is_reduced() # needs sage.libs.pari
885
+ True
886
+
887
+ sage: q = BinaryQF(1, 0, -1)
888
+ sage: q.reduced_form() # needs sage.libs.pari
889
+ x^2 + 2*x*y
890
+
891
+ sage: BinaryQF(1, 9, 4).reduced_form(transformation=True) # needs sage.libs.pari
892
+ (
893
+ [ 0 -1]
894
+ 4*x^2 + 7*x*y - y^2, [ 1 2]
895
+ )
896
+ sage: BinaryQF(3, 7, -2).reduced_form(transformation=True) # needs sage.libs.pari
897
+ (
898
+ [1 0]
899
+ 3*x^2 + 7*x*y - 2*y^2, [0 1]
900
+ )
901
+ sage: BinaryQF(-6, 6, -1).reduced_form(transformation=True) # needs sage.libs.pari
902
+ (
903
+ [ 0 -1]
904
+ -x^2 + 2*x*y + 2*y^2, [ 1 -4]
905
+ )
906
+
907
+ TESTS:
908
+
909
+ Check for :issue:`34229`::
910
+
911
+ sage: BinaryQF([1,2,3]).reduced_form(transformation=True) # needs sage.libs.pari
912
+ (
913
+ [ 1 -1]
914
+ x^2 + 2*y^2, [ 0 1]
915
+ )
916
+ sage: BinaryQF([-225, -743, -743]).reduced_form().is_reduced() # needs sage.libs.pari
917
+ True
918
+
919
+ Some randomized testing::
920
+
921
+ sage: # needs sage.libs.pari
922
+ sage: while True:
923
+ ....: f = BinaryQF([randrange(-10^3, 10^3) for _ in 'abc'])
924
+ ....: if not f.discriminant().is_square():
925
+ ....: break
926
+ sage: algos = ['default']
927
+ sage: assert pari; algos.append('pari')
928
+ sage: if f.discriminant() > 0:
929
+ ....: algos.append('sage')
930
+ sage: a = choice(algos)
931
+ sage: g = f.reduced_form(algorithm=a)
932
+ sage: g.is_reduced()
933
+ True
934
+ sage: g.is_equivalent(f)
935
+ True
936
+ sage: g,M = f.reduced_form(transformation=True, algorithm=a)
937
+ sage: g.is_reduced()
938
+ True
939
+ sage: g.is_equivalent(f)
940
+ True
941
+ sage: f * M == g
942
+ True
943
+ """
944
+ if self.is_reduced():
945
+ if transformation:
946
+ return self, Matrix.identity(2)
947
+ return self
948
+
949
+ if algorithm == "default":
950
+ algorithm = 'sage'
951
+ if not self.is_reducible():
952
+ try:
953
+ import sage.libs.pari
954
+ except ImportError:
955
+ pass
956
+ else:
957
+ algorithm = 'pari'
958
+
959
+ if algorithm == 'sage':
960
+ if self.discriminant() <= 0:
961
+ raise NotImplementedError('reduction of definite binary '
962
+ 'quadratic forms is not implemented '
963
+ 'in Sage')
964
+ return self._reduce_indef(transformation)
965
+
966
+ elif algorithm == 'pari':
967
+ # Negative definite forms are not supported by PARI. We can
968
+ # work around this by reducing [-a,b,-c] instead of [a,b,c].
969
+ if self.is_negative_definite():
970
+ M = Matrix.diagonal([-1, 1])
971
+ r = (-self*M).reduced_form(transformation=transformation, algorithm=algorithm)
972
+ if transformation:
973
+ return (-r[0]*M, M*r[1]*M)
974
+ return -r*M
975
+
976
+ if self.is_reducible():
977
+ raise NotImplementedError('reducible forms are not '
978
+ 'supported using PARI')
979
+
980
+ if transformation:
981
+ y, g = self.__pari__().qfbredsl2()
982
+ return BinaryQF(y), Matrix(ZZ, g)
983
+ return BinaryQF(self.__pari__().qfbred())
984
+
985
+ else:
986
+ raise ValueError('unknown implementation for binary quadratic form '
987
+ 'reduction: %s' % algorithm)
988
+
989
+ # Buchmann/Vollmer cycle algorithm
990
+ def _RhoTau(self):
991
+ """
992
+ Apply Rho and Tau operators to this form, returning a new form `Q`.
993
+
994
+ EXAMPLES::
995
+
996
+ sage: f = BinaryQF(1, 8, -3)
997
+ sage: f._RhoTau()
998
+ 3*x^2 + 4*x*y - 5*y^2
999
+ """
1000
+ d = self.discriminant().sqrt(prec=53)
1001
+ a = self._a
1002
+ b = self._b
1003
+ c = self._c
1004
+ cabs = c.abs()
1005
+ sign = c.sign()
1006
+ if cabs >= d:
1007
+ s = sign * ((cabs+b) / (2*cabs)).floor()
1008
+ else:
1009
+ s = sign * ((d+b) / (2*cabs)).floor()
1010
+ Q = BinaryQF(-c, -b + 2*s*c, -(a - b*s + c*s*s))
1011
+ return Q
1012
+
1013
+ def _Rho(self):
1014
+ """
1015
+ Apply the Rho operator to this form, returning a new form `Q`.
1016
+
1017
+ EXAMPLES::
1018
+
1019
+ sage: f = BinaryQF(1, 8, -3)
1020
+ sage: f._Rho()
1021
+ -3*x^2 + 4*x*y + 5*y^2
1022
+ """
1023
+ d = self.discriminant().sqrt(prec=53)
1024
+ a = self._a
1025
+ b = self._b
1026
+ c = self._c
1027
+ cabs = c.abs()
1028
+ sign = c.sign()
1029
+ if cabs >= d:
1030
+ s = sign * ((cabs+b) / (2*cabs)).floor()
1031
+ else:
1032
+ s = sign * ((d+b) / (2*cabs)).floor()
1033
+ Q = BinaryQF(c, -b + 2*s*c, a - b*s + c*s*s)
1034
+ return Q
1035
+
1036
+ def _Tau(self):
1037
+ """
1038
+ Apply the Tau operator to this form, returning a new form `Q`.
1039
+
1040
+ EXAMPLES::
1041
+
1042
+ sage: f = BinaryQF(1, 8, -3)
1043
+ sage: f._Tau()
1044
+ -x^2 + 8*x*y + 3*y^2
1045
+ """
1046
+ a = self._a
1047
+ b = self._b
1048
+ c = self._c
1049
+ Q = BinaryQF(-a, b, -c)
1050
+ return Q
1051
+
1052
+ def cycle(self, proper=False):
1053
+ """
1054
+ Return the cycle of reduced forms to which ``self`` belongs.
1055
+
1056
+ This is based on Algorithm 6.1 of [BUVO2007]_.
1057
+
1058
+ INPUT:
1059
+
1060
+ - ``self`` -- reduced, indefinite form of non-square discriminant
1061
+
1062
+ - ``proper`` -- boolean (default: ``False``); if ``True``, return the
1063
+ proper cycle
1064
+
1065
+ The proper cycle of a form `f` consists of all reduced forms that are
1066
+ properly equivalent to `f`. This is useful when testing for proper
1067
+ equivalence (or equivalence) between indefinite forms.
1068
+
1069
+ The cycle of `f` is a technical tool that is used when computing the proper
1070
+ cycle. Our definition of the cycle is slightly different from the one
1071
+ in [BUVO2007]_. In our definition, the cycle consists of all reduced
1072
+ forms `g`, such that the `a`-coefficient of `g` has the same sign as the
1073
+ `a`-coefficient of `f`, and `g` can be obtained from `f` by performing a
1074
+ change of variables, and then multiplying by the determinant of the
1075
+ change-of-variables matrix. It is important to note that `g` might not be
1076
+ equivalent to `f` (because of multiplying by the determinant). However,
1077
+ either `g` or `-g` must be equivalent to `f`. Also note that the cycle
1078
+ does contain `f`. (Under the definition in [BUVO2007]_, the cycle might
1079
+ not contain `f`, because all forms in the cycle are required to have
1080
+ positive `a`-coefficient, even if the `a`-coefficient of `f` is negative.)
1081
+
1082
+ EXAMPLES::
1083
+
1084
+ sage: Q = BinaryQF(14, 17, -2)
1085
+ sage: Q.cycle()
1086
+ [14*x^2 + 17*x*y - 2*y^2,
1087
+ 2*x^2 + 19*x*y - 5*y^2,
1088
+ 5*x^2 + 11*x*y - 14*y^2]
1089
+ sage: Q.cycle(proper=True)
1090
+ [14*x^2 + 17*x*y - 2*y^2,
1091
+ -2*x^2 + 19*x*y + 5*y^2,
1092
+ 5*x^2 + 11*x*y - 14*y^2,
1093
+ -14*x^2 + 17*x*y + 2*y^2,
1094
+ 2*x^2 + 19*x*y - 5*y^2,
1095
+ -5*x^2 + 11*x*y + 14*y^2]
1096
+
1097
+ sage: Q = BinaryQF(1, 8, -3)
1098
+ sage: Q.cycle()
1099
+ [x^2 + 8*x*y - 3*y^2,
1100
+ 3*x^2 + 4*x*y - 5*y^2,
1101
+ 5*x^2 + 6*x*y - 2*y^2,
1102
+ 2*x^2 + 6*x*y - 5*y^2,
1103
+ 5*x^2 + 4*x*y - 3*y^2,
1104
+ 3*x^2 + 8*x*y - y^2]
1105
+ sage: Q.cycle(proper=True)
1106
+ [x^2 + 8*x*y - 3*y^2,
1107
+ -3*x^2 + 4*x*y + 5*y^2,
1108
+ 5*x^2 + 6*x*y - 2*y^2,
1109
+ -2*x^2 + 6*x*y + 5*y^2,
1110
+ 5*x^2 + 4*x*y - 3*y^2,
1111
+ -3*x^2 + 8*x*y + y^2]
1112
+
1113
+ sage: Q = BinaryQF(1, 7, -6)
1114
+ sage: Q.cycle()
1115
+ [x^2 + 7*x*y - 6*y^2,
1116
+ 6*x^2 + 5*x*y - 2*y^2,
1117
+ 2*x^2 + 7*x*y - 3*y^2,
1118
+ 3*x^2 + 5*x*y - 4*y^2,
1119
+ 4*x^2 + 3*x*y - 4*y^2,
1120
+ 4*x^2 + 5*x*y - 3*y^2,
1121
+ 3*x^2 + 7*x*y - 2*y^2,
1122
+ 2*x^2 + 5*x*y - 6*y^2,
1123
+ 6*x^2 + 7*x*y - y^2]
1124
+
1125
+ TESTS:
1126
+
1127
+ Check an example in :issue:`28989`::
1128
+
1129
+ sage: Q = BinaryQF(1, 1, -1)
1130
+ sage: Q.cycle(proper=True)
1131
+ [x^2 + x*y - y^2, -x^2 + x*y + y^2]
1132
+
1133
+ This is Example 6.10.6 of [BUVO2007]_::
1134
+
1135
+ sage: Q = BinaryQF(1, 7, -6)
1136
+ sage: Q.cycle()
1137
+ [x^2 + 7*x*y - 6*y^2,
1138
+ 6*x^2 + 5*x*y - 2*y^2,
1139
+ 2*x^2 + 7*x*y - 3*y^2,
1140
+ 3*x^2 + 5*x*y - 4*y^2,
1141
+ 4*x^2 + 3*x*y - 4*y^2,
1142
+ 4*x^2 + 5*x*y - 3*y^2,
1143
+ 3*x^2 + 7*x*y - 2*y^2,
1144
+ 2*x^2 + 5*x*y - 6*y^2,
1145
+ 6*x^2 + 7*x*y - y^2]
1146
+ sage: Q.cycle(proper=True)
1147
+ [x^2 + 7*x*y - 6*y^2,
1148
+ -6*x^2 + 5*x*y + 2*y^2,
1149
+ 2*x^2 + 7*x*y - 3*y^2,
1150
+ -3*x^2 + 5*x*y + 4*y^2,
1151
+ 4*x^2 + 3*x*y - 4*y^2,
1152
+ -4*x^2 + 5*x*y + 3*y^2,
1153
+ 3*x^2 + 7*x*y - 2*y^2,
1154
+ -2*x^2 + 5*x*y + 6*y^2,
1155
+ 6*x^2 + 7*x*y - y^2,
1156
+ -x^2 + 7*x*y + 6*y^2,
1157
+ 6*x^2 + 5*x*y - 2*y^2,
1158
+ -2*x^2 + 7*x*y + 3*y^2,
1159
+ 3*x^2 + 5*x*y - 4*y^2,
1160
+ -4*x^2 + 3*x*y + 4*y^2,
1161
+ 4*x^2 + 5*x*y - 3*y^2,
1162
+ -3*x^2 + 7*x*y + 2*y^2,
1163
+ 2*x^2 + 5*x*y - 6*y^2,
1164
+ -6*x^2 + 7*x*y + y^2]
1165
+
1166
+ This is Example 6.10.7 of [BUVO2007]_::
1167
+
1168
+ sage: Q = BinaryQF(1, 8, -3)
1169
+ sage: Q.cycle()
1170
+ [x^2 + 8*x*y - 3*y^2,
1171
+ 3*x^2 + 4*x*y - 5*y^2,
1172
+ 5*x^2 + 6*x*y - 2*y^2,
1173
+ 2*x^2 + 6*x*y - 5*y^2,
1174
+ 5*x^2 + 4*x*y - 3*y^2,
1175
+ 3*x^2 + 8*x*y - y^2]
1176
+ sage: Q.cycle(proper=True)
1177
+ [x^2 + 8*x*y - 3*y^2,
1178
+ -3*x^2 + 4*x*y + 5*y^2,
1179
+ 5*x^2 + 6*x*y - 2*y^2,
1180
+ -2*x^2 + 6*x*y + 5*y^2,
1181
+ 5*x^2 + 4*x*y - 3*y^2,
1182
+ -3*x^2 + 8*x*y + y^2]
1183
+ sage: Q.cycle(proper=True) # should be the same as the previous one
1184
+ [x^2 + 8*x*y - 3*y^2,
1185
+ -3*x^2 + 4*x*y + 5*y^2,
1186
+ 5*x^2 + 6*x*y - 2*y^2,
1187
+ -2*x^2 + 6*x*y + 5*y^2,
1188
+ 5*x^2 + 4*x*y - 3*y^2,
1189
+ -3*x^2 + 8*x*y + y^2]
1190
+
1191
+ Try an example where a is negative::
1192
+
1193
+ sage: Q = BinaryQF(-1, 8, 3)
1194
+ sage: Q.cycle(proper=True)
1195
+ [-x^2 + 8*x*y + 3*y^2,
1196
+ 3*x^2 + 4*x*y - 5*y^2,
1197
+ -5*x^2 + 6*x*y + 2*y^2,
1198
+ 2*x^2 + 6*x*y - 5*y^2,
1199
+ -5*x^2 + 4*x*y + 3*y^2,
1200
+ 3*x^2 + 8*x*y - y^2]
1201
+ """
1202
+ if not (self.is_indef() and self.is_reduced()):
1203
+ raise ValueError("%s must be indefinite and reduced" % self)
1204
+ if self.discriminant().is_square():
1205
+ # Buchmann/Vollmer assume the discriminant to be non-square
1206
+ raise NotImplementedError('computation of cycles is only '
1207
+ 'implemented for non-square '
1208
+ 'discriminants')
1209
+ if proper:
1210
+ # Prop 6.10.5 in Buchmann Vollmer
1211
+ C = list(self.cycle(proper=False)) # make a copy that we can modify
1212
+ if len(C) % 2:
1213
+ C += C
1214
+ for i in range(len(C) // 2):
1215
+ C[2 * i + 1] = C[2 * i + 1]._Tau()
1216
+ return C
1217
+ if not hasattr(self, '_cycle_list'):
1218
+ C = [self]
1219
+ Q1 = self._RhoTau()
1220
+ while not self == Q1:
1221
+ C.append(Q1)
1222
+ Q1 = Q1._RhoTau()
1223
+ self._cycle_list = C
1224
+ return self._cycle_list
1225
+
1226
+ def is_positive_definite(self) -> bool:
1227
+ """
1228
+ Return ``True`` if ``self`` is positive definite, i.e., has
1229
+ negative discriminant with `a > 0`.
1230
+
1231
+ EXAMPLES::
1232
+
1233
+ sage: Q = BinaryQF(195751, 37615, 1807)
1234
+ sage: Q.is_positive_definite()
1235
+ True
1236
+ sage: Q = BinaryQF(195751, 1212121, -1876411)
1237
+ sage: Q.is_positive_definite()
1238
+ False
1239
+ """
1240
+ return self.discriminant() < 0 and self._a > 0
1241
+
1242
+ is_posdef = is_positive_definite
1243
+
1244
+ def is_negative_definite(self) -> bool:
1245
+ """
1246
+ Return ``True`` if ``self`` is negative definite, i.e., has
1247
+ negative discriminant with `a < 0`.
1248
+
1249
+ EXAMPLES::
1250
+
1251
+ sage: Q = BinaryQF(-1, 3, -5)
1252
+ sage: Q.is_positive_definite()
1253
+ False
1254
+ sage: Q.is_negative_definite()
1255
+ True
1256
+ """
1257
+ return self.discriminant() < 0 and self._a < 0
1258
+
1259
+ is_negdef = is_negative_definite
1260
+
1261
+ def is_indefinite(self) -> bool:
1262
+ """
1263
+ Return whether ``self`` is indefinite, i.e., has positive discriminant.
1264
+
1265
+ EXAMPLES::
1266
+
1267
+ sage: Q = BinaryQF(1, 3, -5)
1268
+ sage: Q.is_indef()
1269
+ True
1270
+ """
1271
+ return self.discriminant() > 0
1272
+
1273
+ is_indef = is_indefinite
1274
+
1275
+ def is_singular(self) -> bool:
1276
+ """
1277
+ Return whether ``self`` is singular, i.e., has zero discriminant.
1278
+
1279
+ EXAMPLES::
1280
+
1281
+ sage: Q = BinaryQF(1, 3, -5)
1282
+ sage: Q.is_singular()
1283
+ False
1284
+ sage: Q = BinaryQF(1, 2, 1)
1285
+ sage: Q.is_singular()
1286
+ True
1287
+ """
1288
+ return self.discriminant().is_zero()
1289
+
1290
+ def is_nonsingular(self) -> bool:
1291
+ """
1292
+ Return whether this form is nonsingular, i.e., has nonzero discriminant.
1293
+
1294
+ EXAMPLES::
1295
+
1296
+ sage: Q = BinaryQF(1, 3, -5)
1297
+ sage: Q.is_nonsingular()
1298
+ True
1299
+ sage: Q = BinaryQF(1, 2, 1)
1300
+ sage: Q.is_nonsingular()
1301
+ False
1302
+ """
1303
+ return not self.discriminant().is_zero()
1304
+
1305
+ def is_equivalent(self, other, proper=True) -> bool:
1306
+ """
1307
+ Return whether ``self`` is equivalent to ``other``.
1308
+
1309
+ INPUT:
1310
+
1311
+ - ``proper`` -- boolean (default: ``True``); if ``True`` use proper
1312
+ equivalence
1313
+ - ``other`` -- a binary quadratic form
1314
+
1315
+ EXAMPLES::
1316
+
1317
+ sage: # needs sage.libs.pari
1318
+ sage: Q3 = BinaryQF(4, 4, 15)
1319
+ sage: Q2 = BinaryQF(4, -4, 15)
1320
+ sage: Q2.is_equivalent(Q3)
1321
+ True
1322
+ sage: a = BinaryQF([33, 11, 5])
1323
+ sage: b = a.reduced_form(); b
1324
+ 5*x^2 - x*y + 27*y^2
1325
+ sage: a.is_equivalent(b)
1326
+ True
1327
+ sage: a.is_equivalent(BinaryQF((3, 4, 5)))
1328
+ False
1329
+
1330
+ Some indefinite examples::
1331
+
1332
+ sage: Q1 = BinaryQF(9, 8, -7)
1333
+ sage: Q2 = BinaryQF(9, -8, -7)
1334
+ sage: Q1.is_equivalent(Q2, proper=True) # needs sage.libs.pari
1335
+ False
1336
+ sage: Q1.is_equivalent(Q2, proper=False) # needs sage.libs.pari
1337
+ True
1338
+
1339
+ TESTS:
1340
+
1341
+ We check that :issue:`25888` is fixed::
1342
+
1343
+ sage: # needs sage.libs.pari
1344
+ sage: Q1 = BinaryQF(3, 4, -2)
1345
+ sage: Q2 = BinaryQF(-2, 4, 3)
1346
+ sage: Q1.is_equivalent(Q2) == Q2.is_equivalent(Q1)
1347
+ True
1348
+ sage: Q1.is_equivalent(Q2, proper=False) == Q2.is_equivalent(Q1, proper=False)
1349
+ True
1350
+ sage: Q1.is_equivalent(Q2, proper=True)
1351
+ True
1352
+
1353
+ We check that the first part of :issue:`29028` is fixed::
1354
+
1355
+ sage: Q = BinaryQF(0, 2, 0)
1356
+ sage: Q.discriminant()
1357
+ 4
1358
+ sage: Q.is_equivalent(Q, proper=True) # needs sage.libs.pari
1359
+ True
1360
+ sage: Q.is_equivalent(Q, proper=False) # needs sage.libs.pari
1361
+ True
1362
+
1363
+ A test for rational forms::
1364
+
1365
+ sage: Q1 = BinaryQF(0, 4, 2)
1366
+ sage: Q2 = BinaryQF(2, 4, 0)
1367
+ sage: Q1.is_equivalent(Q2, proper=False) # needs sage.libs.pari
1368
+ True
1369
+
1370
+ Test another part of :issue:`28989`::
1371
+
1372
+ sage: Q1, Q2 = BinaryQF(1, 1, -1), BinaryQF(-1, 1, 1)
1373
+ sage: Q1.is_equivalent(Q2, proper=True) # needs sage.libs.pari
1374
+ True
1375
+ """
1376
+ if not isinstance(other, BinaryQF):
1377
+ raise TypeError("%s is not a BinaryQF" % other)
1378
+ if self.discriminant() != other.discriminant():
1379
+ return False
1380
+ if self.is_indef():
1381
+ # First, reduce self and other
1382
+ selfred = self.reduced_form()
1383
+ otherred = other.reduced_form()
1384
+ if self.discriminant().is_square():
1385
+ # make sure we terminate in a form
1386
+ # with c = 0
1387
+ while selfred[2] != 0:
1388
+ selfred = selfred._Rho()
1389
+ while otherred[2] != 0:
1390
+ otherred = otherred._Rho()
1391
+ b = selfred._b
1392
+ a = selfred._a
1393
+ ao = otherred._a
1394
+ assert otherred._b == b
1395
+ # p. 359 of Conway-Sloane [CS1999]_
1396
+ # but `2b` in their notation is `b` in our notation
1397
+ is_properly_equiv = ((a-ao) % b == 0)
1398
+ if proper:
1399
+ return is_properly_equiv
1400
+ else:
1401
+ g = gcd(a, b)
1402
+ return is_properly_equiv or ((gcd(ao, b) == g) and ((a*ao - g**2) % (b*g) == 0))
1403
+
1404
+ proper_cycle = otherred.cycle(proper=True)
1405
+
1406
+ is_prop = selfred in proper_cycle
1407
+ if proper or is_prop:
1408
+ return is_prop
1409
+ # note that our definition of improper equivalence
1410
+ # differs from that of Buchmann and Vollmer
1411
+ # their action is det f * q(f(x, y))
1412
+ # ours is q(f(x, y))
1413
+
1414
+ # an improper equivalence in our convention
1415
+ selfred = BinaryQF(selfred._c, selfred._b, selfred._a)
1416
+ assert selfred.is_reduced()
1417
+
1418
+ return selfred in proper_cycle
1419
+
1420
+ # Else we're dealing with definite forms.
1421
+ if self.is_posdef() and not other.is_posdef():
1422
+ return False
1423
+ if self.is_negdef() and not other.is_negdef():
1424
+ return False
1425
+ Q1 = self.reduced_form()
1426
+ Q2 = other.reduced_form()
1427
+ if Q1 == Q2:
1428
+ return True
1429
+ if not proper:
1430
+ Q1e = BinaryQF(self._c, self._b, self._a).reduced_form()
1431
+ return Q1e == Q2
1432
+ return False
1433
+
1434
+ @cached_method
1435
+ def is_reduced(self) -> bool:
1436
+ r"""
1437
+ Return whether ``self`` is reduced.
1438
+
1439
+ Let `f = a x^2 + b xy + c y^2` be a binary quadratic form of
1440
+ discriminant `D`.
1441
+
1442
+ - If `f` is positive definite (`D < 0` and `a > 0`), then `f`
1443
+ is reduced if and only if `|b|\leq a \leq c`, and `b\geq 0`
1444
+ if either `a = b` or `a = c`.
1445
+
1446
+ - If `f` is negative definite (`D < 0` and `a < 0`), then `f`
1447
+ is reduced if and only if the positive definite form with
1448
+ coefficients `(-a, b, -c)` is reduced.
1449
+
1450
+ - If `f` is indefinite (`D > 0`), then `f` is reduced if and
1451
+ only if [`b > 0`, `ac < 0` and `(a-c)^2 < D`]
1452
+ (equivalently if `|\sqrt{D} - 2|a|| < b < \sqrt{D}`)
1453
+ or [`a = 0` and `-b < 2c \leq b`]
1454
+ or [`c = 0` and `-b < 2a \leq b`].
1455
+
1456
+ EXAMPLES::
1457
+
1458
+ sage: Q = BinaryQF([1, 2, 3])
1459
+ sage: Q.is_reduced()
1460
+ False
1461
+
1462
+ sage: Q = BinaryQF([2, 1, 3])
1463
+ sage: Q.is_reduced()
1464
+ True
1465
+
1466
+ sage: Q = BinaryQF([1, -1, 1])
1467
+ sage: Q.is_reduced()
1468
+ False
1469
+
1470
+ sage: Q = BinaryQF([1, 1, 1])
1471
+ sage: Q.is_reduced()
1472
+ True
1473
+
1474
+ Examples using indefinite forms::
1475
+
1476
+ sage: f = BinaryQF(-1, 2, 2)
1477
+ sage: f.is_reduced()
1478
+ True
1479
+ sage: BinaryQF(1, 9, 4).is_reduced()
1480
+ False
1481
+ sage: BinaryQF(1, 5, -1).is_reduced()
1482
+ True
1483
+
1484
+ TESTS:
1485
+
1486
+ We check that :issue:`37635` is fixed::
1487
+
1488
+ sage: list = range(0xa19ae44106b09bfffffffffff0, 0xa19ae44106b09c000000000010)
1489
+ sage: all(BinaryQF([1, 0, -x]).reduced_form().is_reduced() for x in list) # needs sage.libs.pari
1490
+ True
1491
+ """
1492
+ D = self.discriminant()
1493
+ if D.is_zero():
1494
+ raise ValueError('the quadratic form must be non-singular')
1495
+
1496
+ a = self._a
1497
+ b = self._b
1498
+ c = self._c
1499
+ if D < 0 and a > 0:
1500
+ return ((-a < b <= a < c)
1501
+ or (ZZ(0) <= b <= a == c))
1502
+ elif D < 0 and a < 0:
1503
+ return ((a < b <= -a < -c)
1504
+ or (ZZ(0) <= b <= -a == -c))
1505
+
1506
+ # Note that a = 0 implies D > 0 here
1507
+ else:
1508
+ return ((b > 0 and a*c < 0 and (a-c)**2 < D)
1509
+ or (0 == a and -b < 2*c <= b)
1510
+ or (0 == c and -b < 2*a <= b))
1511
+
1512
+ def complex_point(self):
1513
+ r"""
1514
+ Return the point in the complex upper half-plane associated to ``self``.
1515
+
1516
+ This form, `ax^2 + b xy + cy^2`, must be definite with
1517
+ negative discriminant `b^2 - 4 a c < 0`.
1518
+
1519
+ OUTPUT:
1520
+
1521
+ - the unique complex root of `a x^2 + b x + c` with positive
1522
+ imaginary part
1523
+
1524
+ EXAMPLES::
1525
+
1526
+ sage: Q = BinaryQF([1, 0, 1])
1527
+ sage: Q.complex_point() # needs sage.libs.pari
1528
+ 1.00000000000000*I
1529
+ """
1530
+ if self.discriminant() >= 0:
1531
+ raise ValueError("only defined for negative discriminant")
1532
+ Q1 = ZZ['x']([self._c, self._b, self._a])
1533
+ return [z for z in Q1.complex_roots() if z.imag() > 0][0]
1534
+
1535
+ def matrix_action_left(self, M):
1536
+ r"""
1537
+ Return the binary quadratic form resulting from the left action
1538
+ of the 2-by-2 matrix `M` on ``self``.
1539
+
1540
+ Here the action of the matrix `M = \begin{pmatrix} a & b \\ c & d
1541
+ \end{pmatrix}` on the form `Q(x, y)` produces the form `Q(ax+cy,
1542
+ bx+dy)`.
1543
+
1544
+ EXAMPLES::
1545
+
1546
+ sage: Q = BinaryQF([2, 1, 3]); Q
1547
+ 2*x^2 + x*y + 3*y^2
1548
+ sage: M = matrix(ZZ, [[1, 2], [3, 5]])
1549
+ sage: Q.matrix_action_left(M)
1550
+ 16*x^2 + 83*x*y + 108*y^2
1551
+ """
1552
+ v, w = M.rows()
1553
+ a1 = self(v)
1554
+ c1 = self(w)
1555
+ b1 = self(v + w) - a1 - c1
1556
+ return BinaryQF([a1, b1, c1])
1557
+
1558
+ def matrix_action_right(self, M):
1559
+ r"""
1560
+ Return the binary quadratic form resulting from the right action
1561
+ of the 2-by-2 matrix `M` on ``self``.
1562
+
1563
+ Here the action of the matrix `M = \begin{pmatrix} a & b \\ c & d
1564
+ \end{pmatrix}` on the form `Q(x, y)` produces the form `Q(ax+by,
1565
+ cx+dy)`.
1566
+
1567
+ EXAMPLES::
1568
+
1569
+ sage: Q = BinaryQF([2, 1, 3]); Q
1570
+ 2*x^2 + x*y + 3*y^2
1571
+ sage: M = matrix(ZZ, [[1, 2], [3, 5]])
1572
+ sage: Q.matrix_action_right(M)
1573
+ 32*x^2 + 109*x*y + 93*y^2
1574
+ """
1575
+ v, w = M.columns()
1576
+ a1 = self(v)
1577
+ c1 = self(w)
1578
+ b1 = self(v + w) - a1 - c1
1579
+ return BinaryQF([a1, b1, c1])
1580
+
1581
+ def small_prime_value(self, Bmax=1000):
1582
+ r"""
1583
+ Return a prime represented by this (primitive positive definite) binary form.
1584
+
1585
+ INPUT:
1586
+
1587
+ - ``Bmax`` -- a positive bound on the representing integers
1588
+
1589
+ OUTPUT: a prime number represented by the form
1590
+
1591
+ .. NOTE::
1592
+
1593
+ This is a very elementary implementation which just substitutes
1594
+ values until a prime is found.
1595
+
1596
+ EXAMPLES::
1597
+
1598
+ sage: [Q.small_prime_value() # needs sage.libs.pari
1599
+ ....: for Q in BinaryQF_reduced_representatives(-23, primitive_only=True)]
1600
+ [23, 2, 2]
1601
+ sage: [Q.small_prime_value() # needs sage.libs.pari
1602
+ ....: for Q in BinaryQF_reduced_representatives(-47, primitive_only=True)]
1603
+ [47, 2, 2, 3, 3]
1604
+ """
1605
+ from sage.sets.set import Set
1606
+ from sage.arith.srange import xsrange
1607
+ B = 10
1608
+ while True:
1609
+ llist = list(Set([self(x, y) for x in xsrange(-B, B) for y in xsrange(B)]))
1610
+ llist = sorted([l for l in llist if l.is_prime()])
1611
+ if llist:
1612
+ return llist[0]
1613
+ if B >= Bmax:
1614
+ raise ValueError("Unable to find a prime value of %s" % self)
1615
+ B += 10
1616
+
1617
+ def solve_integer(self, n, *, algorithm='general', _flag=2):
1618
+ r"""
1619
+ Solve `Q(x, y) = n` in integers `x` and `y` where `Q` is this
1620
+ quadratic form.
1621
+
1622
+ INPUT:
1623
+
1624
+ - ``n`` -- positive integer or a
1625
+ `:sage:`~sage.structure.factorization.Factorization` object
1626
+
1627
+ - ``algorithm`` -- ``'general'`` (default) or ``'cornacchia'``
1628
+
1629
+ - ``_flag`` -- ``1``, ``2`` (default) or ``3``; passed onto the pari
1630
+ function``qfbsolve``. For internal use only.
1631
+
1632
+ To use the Cornacchia algorithm, the quadratic form must have
1633
+ `a=1` and `b=0` and `c>0`, and ``n`` must be a prime or four
1634
+ times a prime (but this is not checked).
1635
+
1636
+ OUTPUT:
1637
+
1638
+ A tuple `(x, y)` of integers satisfying `Q(x, y) = n`, or ``None``
1639
+ if no solution exists.
1640
+
1641
+ ALGORITHM: :pari:`qfbsolve` or :pari:`qfbcornacchia`
1642
+
1643
+ TODO:: Replace ``_flag`` with human-readable parameters c.f. :issue:`37119`
1644
+
1645
+ EXAMPLES::
1646
+
1647
+ sage: Q = BinaryQF([1, 0, 419])
1648
+ sage: Q.solve_integer(773187972) # needs sage.libs.pari
1649
+ (4919, 1337)
1650
+
1651
+ If `Q` is of the form `[1,0,c]` as above and `n` is a prime
1652
+ (or four times a prime whenever `c \equiv 3 \pmod 4`), then
1653
+ Cornacchia's algorithm can be used, which is typically much
1654
+ faster than the general method::
1655
+
1656
+ sage: Q = BinaryQF([1, 0, 12345])
1657
+ sage: n = 2^99 + 5273
1658
+ sage: Q.solve_integer(n) # needs sage.libs.pari
1659
+ (67446480057659, 7139620553488)
1660
+ sage: Q.solve_integer(n, algorithm='cornacchia') # needs sage.libs.pari
1661
+ (67446480057659, 7139620553488)
1662
+ sage: timeit('Q.solve_integer(n)') # not tested
1663
+ 125 loops, best of 3: 3.13 ms per loop
1664
+ sage: timeit('Q.solve_integer(n, algorithm="cornacchia")') # not tested
1665
+ 625 loops, best of 3: 18.6 μs per loop
1666
+
1667
+ ::
1668
+
1669
+ sage: # needs sage.libs.pari
1670
+ sage: Qs = BinaryQF_reduced_representatives(-23, primitive_only=True)
1671
+ sage: Qs
1672
+ [x^2 + x*y + 6*y^2, 2*x^2 - x*y + 3*y^2, 2*x^2 + x*y + 3*y^2]
1673
+ sage: [Q.solve_integer(3) for Q in Qs]
1674
+ [None, (0, 1), (0, 1)]
1675
+ sage: [Q.solve_integer(5) for Q in Qs]
1676
+ [None, None, None]
1677
+ sage: [Q.solve_integer(6) for Q in Qs]
1678
+ [(1, -1), (1, -1), (-1, -1)]
1679
+
1680
+ ::
1681
+
1682
+ sage: # needs sage.libs.pari
1683
+ sage: n = factor(126)
1684
+ sage: Q = BinaryQF([1, 0, 5])
1685
+ sage: Q.solve_integer(n)
1686
+ (11, -1)
1687
+
1688
+ TESTS:
1689
+
1690
+ The returned solutions are correct (random inputs)::
1691
+
1692
+ sage: Q = BinaryQF([randrange(-10^3, 10^3) for _ in 'abc'])
1693
+ sage: n = randrange(-10^9, 10^9)
1694
+ sage: xy = Q.solve_integer(n) # needs sage.libs.pari
1695
+ sage: xy is None or Q(*xy) == n # needs sage.libs.pari
1696
+ True
1697
+
1698
+ Also when using the ``'cornacchia'`` algorithm::
1699
+
1700
+ sage: # needs sage.libs.pari
1701
+ sage: n = random_prime(10^9)
1702
+ sage: c = randrange(1, 10^3)
1703
+
1704
+ sage: # needs sage.libs.pari
1705
+ sage: Q1 = BinaryQF(1, 0, c)
1706
+ sage: xy = Q1.solve_integer(n, algorithm='cornacchia')
1707
+ sage: xy is None or Q1(*xy) == n
1708
+ True
1709
+ sage: (xy is None) == (Q1.solve_integer(n) is None)
1710
+ True
1711
+
1712
+ sage: # needs sage.libs.pari
1713
+ sage: Q3 = BinaryQF(1, 0, 4*c+3)
1714
+ sage: xy = Q3.solve_integer(n, algorithm='cornacchia')
1715
+ sage: xy is None or Q3(*xy) == n
1716
+ True
1717
+ sage: (xy is None) == (Q3.solve_integer(n) is None)
1718
+ True
1719
+
1720
+ sage: # needs sage.libs.pari
1721
+ sage: xy = Q3.solve_integer(4*n, algorithm='cornacchia')
1722
+ sage: xy is None or Q3(*xy) == 4*n
1723
+ True
1724
+ sage: (xy is None) == (Q3.solve_integer(4*n) is None)
1725
+ True
1726
+
1727
+ Test for square discriminants specifically (:issue:`33026`)::
1728
+
1729
+ sage: n = randrange(-10^3, 10^3)
1730
+ sage: Q = BinaryQF([n, randrange(-10^3, 10^3), 0][::(-1)**randrange(2)])
1731
+ sage: U = random_matrix(ZZ, 2, 2, 'unimodular')
1732
+ sage: U.rescale_row(0, choice((+1,-1)))
1733
+ sage: assert U.det() in (+1,-1)
1734
+ sage: Q = Q.matrix_action_right(U)
1735
+ sage: Q.discriminant().is_square()
1736
+ True
1737
+ sage: # needs sage.libs.pari
1738
+ sage: xy = Q.solve_integer(n)
1739
+ sage: Q(*xy) == n
1740
+ True
1741
+
1742
+ Also test the `n=0` special case separately::
1743
+
1744
+ sage: # needs sage.libs.pari
1745
+ sage: xy = Q.solve_integer(0)
1746
+ sage: Q(*xy)
1747
+ 0
1748
+
1749
+ Test for different ``_flag`` values::
1750
+
1751
+ sage: # needs sage.libs.pari
1752
+ sage: Q = BinaryQF([1, 0, 5])
1753
+ sage: Q.solve_integer(126, _flag=1)
1754
+ [(-11, -1), (-1, -5), (-1, 5), (11, -1)]
1755
+ sage: Q.solve_integer(126, _flag=2)
1756
+ (11, -1)
1757
+ sage: Q.solve_integer(126, _flag=3)
1758
+ [(-11, -1), (-9, -3), (-1, -5), (-1, 5), (9, -3), (11, -1)]
1759
+ """
1760
+ if self.is_negative_definite(): # not supported by PARI
1761
+ return (-self).solve_integer(-n)
1762
+
1763
+ if self.is_reducible(): # square discriminant; not supported by PARI
1764
+ from sage.structure.factorization import Factorization
1765
+ if isinstance(n, Factorization):
1766
+ n = ZZ(n.value())
1767
+ else:
1768
+ n = ZZ(n)
1769
+
1770
+ if self._a:
1771
+ # https://math.stackexchange.com/a/980075
1772
+ w = self.discriminant().sqrt()
1773
+ r = (-self._b + (w if w != self._b else -w)) / (2*self._a)
1774
+ p, q = r.as_integer_ratio()
1775
+ _, u, v = p.xgcd(q)
1776
+ M = Matrix(ZZ, [[v, p], [-u, q]])
1777
+ elif self._c:
1778
+ M = Matrix(ZZ, [[0, 1], [1, 0]])
1779
+ else:
1780
+ M = Matrix(ZZ, [[1, 0], [0, 1]])
1781
+ assert M.is_unit()
1782
+ Q = self.matrix_action_right(M)
1783
+ assert not Q._c
1784
+
1785
+ if not Q._b:
1786
+ # at this point, Q = a*x^2
1787
+ if Q._a.divides(n) and (n // Q._a).is_square():
1788
+ x = (n // Q._a).isqrt()
1789
+ return tuple(row[0] * x for row in M.rows())
1790
+ return None
1791
+
1792
+ # at this point, Q = a*x^2 + b*x*y
1793
+ if not n:
1794
+ return tuple(M.columns()[1])
1795
+ for x in n.divisors():
1796
+ y_num = n // x - Q._a * x
1797
+ if Q._b.divides(y_num):
1798
+ y = y_num // Q._b
1799
+ return tuple([row[0]*x + row[1]*y for row in M.rows()])
1800
+
1801
+ return None
1802
+
1803
+ if algorithm == 'cornacchia':
1804
+ if not (self._a.is_one() and self._b.is_zero() and self._c > 0):
1805
+ raise ValueError("Cornacchia's algorithm requires a=1 and b=0 and c>0")
1806
+ sol = pari.qfbcornacchia(self._c, n)
1807
+ return tuple(map(ZZ, sol)) if sol else None
1808
+
1809
+ if algorithm != 'general':
1810
+ raise ValueError(f'algorithm {algorithm!r} is not a valid algorithm')
1811
+
1812
+ sol = self.__pari__().qfbsolve(n, _flag)
1813
+ if _flag == 2:
1814
+ return tuple(map(ZZ, sol)) if sol else None
1815
+ return [tuple(map(ZZ, tup)) for tup in sol]
1816
+
1817
+ def form_class(self):
1818
+ r"""
1819
+ Return the class of this form modulo equivalence.
1820
+
1821
+ EXAMPLES::
1822
+
1823
+ sage: # needs sage.libs.pari
1824
+ sage: F = BinaryQF([3, -16, 161])
1825
+ sage: cl = F.form_class(); cl
1826
+ Class of 3*x^2 + 2*x*y + 140*y^2
1827
+ sage: cl.parent()
1828
+ Form Class Group of Discriminant -1676
1829
+ sage: cl.parent() is BQFClassGroup(-4*419)
1830
+ True
1831
+ """
1832
+ from sage.quadratic_forms.bqf_class_group import BQFClassGroup
1833
+ return BQFClassGroup(self.discriminant())(self)
1834
+
1835
+
1836
+ def BinaryQF_reduced_representatives(D, primitive_only=False, proper=True):
1837
+ r"""
1838
+ Return representatives for the classes of binary quadratic forms
1839
+ of discriminant `D`.
1840
+
1841
+ INPUT:
1842
+
1843
+ - ``D`` -- integer; a discriminant
1844
+
1845
+ - ``primitive_only`` -- boolean (default: ``True``); if ``True``, only
1846
+ return primitive forms
1847
+
1848
+ - ``proper`` -- boolean (default: ``True``)
1849
+
1850
+ OUTPUT:
1851
+
1852
+ (list) A lexicographically-ordered list of inequivalent reduced
1853
+ representatives for the (im)proper equivalence classes of binary quadratic
1854
+ forms of discriminant `D`. If ``primitive_only`` is ``True`` then
1855
+ imprimitive forms (which only exist when `D` is not fundamental) are
1856
+ omitted; otherwise they are included.
1857
+
1858
+ EXAMPLES::
1859
+
1860
+ sage: BinaryQF_reduced_representatives(-4)
1861
+ [x^2 + y^2]
1862
+
1863
+ sage: BinaryQF_reduced_representatives(-163)
1864
+ [x^2 + x*y + 41*y^2]
1865
+
1866
+ sage: BinaryQF_reduced_representatives(-12)
1867
+ [x^2 + 3*y^2, 2*x^2 + 2*x*y + 2*y^2]
1868
+
1869
+ sage: BinaryQF_reduced_representatives(-16)
1870
+ [x^2 + 4*y^2, 2*x^2 + 2*y^2]
1871
+
1872
+ sage: BinaryQF_reduced_representatives(-63)
1873
+ [x^2 + x*y + 16*y^2, 2*x^2 - x*y + 8*y^2, 2*x^2 + x*y + 8*y^2,
1874
+ 3*x^2 + 3*x*y + 6*y^2, 4*x^2 + x*y + 4*y^2]
1875
+
1876
+ The number of inequivalent reduced binary forms with a fixed negative
1877
+ fundamental discriminant `D` is the class number of the quadratic field
1878
+ `\QQ(\sqrt{D})`::
1879
+
1880
+ sage: len(BinaryQF_reduced_representatives(-13*4))
1881
+ 2
1882
+ sage: QuadraticField(-13*4, 'a').class_number() # needs sage.rings.number_field
1883
+ 2
1884
+
1885
+ sage: # needs sage.libs.pari
1886
+ sage: p = next_prime(2^20); p
1887
+ 1048583
1888
+ sage: len(BinaryQF_reduced_representatives(-p))
1889
+ 689
1890
+ sage: QuadraticField(-p, 'a').class_number() # needs sage.rings.number_field
1891
+ 689
1892
+ sage: BinaryQF_reduced_representatives(-23*9)
1893
+ [x^2 + x*y + 52*y^2,
1894
+ 2*x^2 - x*y + 26*y^2,
1895
+ 2*x^2 + x*y + 26*y^2,
1896
+ 3*x^2 + 3*x*y + 18*y^2,
1897
+ 4*x^2 - x*y + 13*y^2,
1898
+ 4*x^2 + x*y + 13*y^2,
1899
+ 6*x^2 - 3*x*y + 9*y^2,
1900
+ 6*x^2 + 3*x*y + 9*y^2,
1901
+ 8*x^2 + 7*x*y + 8*y^2]
1902
+ sage: BinaryQF_reduced_representatives(-23*9, primitive_only=True)
1903
+ [x^2 + x*y + 52*y^2,
1904
+ 2*x^2 - x*y + 26*y^2,
1905
+ 2*x^2 + x*y + 26*y^2,
1906
+ 4*x^2 - x*y + 13*y^2,
1907
+ 4*x^2 + x*y + 13*y^2,
1908
+ 8*x^2 + 7*x*y + 8*y^2]
1909
+
1910
+ TESTS::
1911
+
1912
+ sage: BinaryQF_reduced_representatives(73)
1913
+ [4*x^2 + 3*x*y - 4*y^2]
1914
+ sage: BinaryQF_reduced_representatives(76, primitive_only=True) # needs sage.libs.pari
1915
+ [-3*x^2 + 4*x*y + 5*y^2,
1916
+ 3*x^2 + 4*x*y - 5*y^2]
1917
+ sage: BinaryQF_reduced_representatives(136)
1918
+ [-5*x^2 + 4*x*y + 6*y^2,
1919
+ -2*x^2 + 8*x*y + 9*y^2,
1920
+ 2*x^2 + 8*x*y - 9*y^2,
1921
+ 5*x^2 + 4*x*y - 6*y^2]
1922
+ sage: BinaryQF_reduced_representatives(136, proper=False)
1923
+ [-2*x^2 + 8*x*y + 9*y^2, 2*x^2 + 8*x*y - 9*y^2, 5*x^2 + 4*x*y - 6*y^2]
1924
+
1925
+ Check that the primitive_only keyword does something::
1926
+
1927
+ sage: BinaryQF_reduced_representatives(148, proper=False, primitive_only=False)
1928
+ [x^2 + 12*x*y - y^2, 4*x^2 + 6*x*y - 7*y^2, 6*x^2 + 2*x*y - 6*y^2]
1929
+ sage: BinaryQF_reduced_representatives(148, proper=False, primitive_only=True) # needs sage.libs.pari
1930
+ [x^2 + 12*x*y - y^2, 4*x^2 + 6*x*y - 7*y^2]
1931
+ sage: BinaryQF_reduced_representatives(148, proper=True, primitive_only=True) # needs sage.libs.pari
1932
+ [-7*x^2 + 6*x*y + 4*y^2, x^2 + 12*x*y - y^2, 4*x^2 + 6*x*y - 7*y^2]
1933
+ sage: BinaryQF_reduced_representatives(148, proper=True, primitive_only=False)
1934
+ [-7*x^2 + 6*x*y + 4*y^2,
1935
+ x^2 + 12*x*y - y^2,
1936
+ 4*x^2 + 6*x*y - 7*y^2,
1937
+ 6*x^2 + 2*x*y - 6*y^2]
1938
+
1939
+ Test another part of :issue:`29028`::
1940
+
1941
+ sage: BinaryQF_reduced_representatives(10^2, proper=False, primitive_only=False)
1942
+ [-4*x^2 + 10*x*y,
1943
+ -3*x^2 + 10*x*y,
1944
+ -2*x^2 + 10*x*y,
1945
+ -x^2 + 10*x*y,
1946
+ 10*x*y,
1947
+ x^2 + 10*x*y,
1948
+ 2*x^2 + 10*x*y,
1949
+ 5*x^2 + 10*x*y]
1950
+ sage: BinaryQF_reduced_representatives(10^2, proper=False, primitive_only=True) # needs sage.libs.pari
1951
+ [-3*x^2 + 10*x*y, -x^2 + 10*x*y, x^2 + 10*x*y]
1952
+ sage: BinaryQF_reduced_representatives(10^2, proper=True, primitive_only=True) # needs sage.libs.pari
1953
+ [-3*x^2 + 10*x*y, -x^2 + 10*x*y, x^2 + 10*x*y, 3*x^2 + 10*x*y]
1954
+ sage: BinaryQF_reduced_representatives(10^2, proper=True, primitive_only=False)
1955
+ [-4*x^2 + 10*x*y,
1956
+ -3*x^2 + 10*x*y,
1957
+ -2*x^2 + 10*x*y,
1958
+ -x^2 + 10*x*y,
1959
+ 10*x*y,
1960
+ x^2 + 10*x*y,
1961
+ 2*x^2 + 10*x*y,
1962
+ 3*x^2 + 10*x*y,
1963
+ 4*x^2 + 10*x*y,
1964
+ 5*x^2 + 10*x*y]
1965
+ """
1966
+ D = ZZ(D)
1967
+
1968
+ # For a fundamental discriminant all forms are primitive so we need not check:
1969
+ if primitive_only:
1970
+ primitive_only = not D.is_fundamental_discriminant()
1971
+
1972
+ form_list = []
1973
+
1974
+ from sage.arith.srange import xsrange
1975
+
1976
+ D4 = D % 4
1977
+ if D4 == 2 or D4 == 3:
1978
+ raise ValueError("%s is not a discriminant" % D)
1979
+ if D > 0: # Indefinite
1980
+ if D.is_square():
1981
+ b = D.sqrt()
1982
+ c = ZZ.zero()
1983
+ # -b/2 < a <= b/2
1984
+ form_list.extend(BinaryQF(a, b, c)
1985
+ for a in xsrange((-b / 2).floor() + 1,
1986
+ (b / 2).floor() + 1)
1987
+ if not primitive_only or (gcd([a, b, c]) == 1))
1988
+
1989
+ # We follow the description of Buchmann/Vollmer 6.7.1. They
1990
+ # enumerate all reduced forms. We only want representatives.
1991
+ else:
1992
+ sqrt_d = D.sqrt(prec=53)
1993
+ for b in xsrange(1, sqrt_d.floor() + 1):
1994
+ if (D - b) % 2:
1995
+ continue
1996
+ A = (D - b**2) / 4
1997
+ Low_a = ((sqrt_d - b) / 2).ceil()
1998
+ High_a = (A.sqrt(prec=53)).floor()
1999
+ for a in xsrange(Low_a, High_a + 1):
2000
+ if a == 0:
2001
+ continue
2002
+ c = -A/a
2003
+ if c in ZZ:
2004
+ if (not primitive_only) or gcd([a, b, c]) == 1:
2005
+ Q = BinaryQF(a, b, c)
2006
+ Q1 = BinaryQF(-a, b, -c)
2007
+ form_list.append(Q)
2008
+ form_list.append(Q1)
2009
+ if a.abs() != c.abs():
2010
+ Q = BinaryQF(c, b, a)
2011
+ Q1 = BinaryQF(-c, b, -a)
2012
+ form_list.append(Q)
2013
+ form_list.append(Q1)
2014
+ else: # Definite
2015
+ # Only iterate over positive a and over b of the same
2016
+ # parity as D such that 4a^2 + D <= b^2 <= a^2
2017
+ for a in xsrange(1, 1+((-D)//3).isqrt()):
2018
+ a4 = 4*a
2019
+ s = D + a*a4
2020
+ w = 1+(s-1).isqrt() if s > 0 else 0
2021
+ if w % 2 != D % 2:
2022
+ w += 1
2023
+ for b in xsrange(w, a+1, 2):
2024
+ t = b*b-D
2025
+ if t % a4 == 0:
2026
+ c = t // a4
2027
+ if not primitive_only or gcd([a, b, c]) == 1:
2028
+ if c > a > b > 0:
2029
+ form_list.append(BinaryQF([a, -b, c]))
2030
+ form_list.append(BinaryQF([a, b, c]))
2031
+ if not proper or D > 0:
2032
+ # TODO:
2033
+ # instead of filtering, enumerate only improper classes to start with
2034
+ # filter for equivalence classes
2035
+ form_list_new = []
2036
+ for q in form_list:
2037
+ if not any(q.is_equivalent(q1, proper=proper) for q1 in form_list_new):
2038
+ form_list_new.append(q)
2039
+ form_list = form_list_new
2040
+
2041
+ form_list.sort()
2042
+ return form_list