passagemath-flint 10.6.1rc10__cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. passagemath_flint-10.6.1rc10.dist-info/METADATA +122 -0
  2. passagemath_flint-10.6.1rc10.dist-info/RECORD +361 -0
  3. passagemath_flint-10.6.1rc10.dist-info/WHEEL +6 -0
  4. passagemath_flint-10.6.1rc10.dist-info/top_level.txt +2 -0
  5. passagemath_flint.libs/libflint-aecb9cc5.so.21.0.0 +0 -0
  6. passagemath_flint.libs/libgf2x-a4cdec90.so.3.0.0 +0 -0
  7. passagemath_flint.libs/libgfortran-8f1e9814.so.5.0.0 +0 -0
  8. passagemath_flint.libs/libgmp-6e109695.so.10.5.0 +0 -0
  9. passagemath_flint.libs/libgsl-cda90e79.so.28.0.0 +0 -0
  10. passagemath_flint.libs/libmpfi-e3c25853.so.0.0.0 +0 -0
  11. passagemath_flint.libs/libmpfr-82690d50.so.6.2.1 +0 -0
  12. passagemath_flint.libs/libntl-74e7d9a3.so.44.0.1 +0 -0
  13. passagemath_flint.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
  14. passagemath_flint.libs/libquadmath-828275a7.so.0.0.0 +0 -0
  15. sage/all__sagemath_flint.py +29 -0
  16. sage/combinat/all__sagemath_flint.py +1 -0
  17. sage/combinat/posets/all__sagemath_flint.py +1 -0
  18. sage/combinat/posets/hasse_cython_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  19. sage/combinat/posets/hasse_cython_flint.pyx +194 -0
  20. sage/data_structures/all__sagemath_flint.py +1 -0
  21. sage/data_structures/bounded_integer_sequences.cpython-310-x86_64-linux-gnu.so +0 -0
  22. sage/data_structures/bounded_integer_sequences.pxd +62 -0
  23. sage/data_structures/bounded_integer_sequences.pyx +1418 -0
  24. sage/graphs/all__sagemath_flint.py +1 -0
  25. sage/graphs/chrompoly.cpython-310-x86_64-linux-gnu.so +0 -0
  26. sage/graphs/chrompoly.pyx +555 -0
  27. sage/graphs/matchpoly.cpython-310-x86_64-linux-gnu.so +0 -0
  28. sage/graphs/matchpoly.pyx +412 -0
  29. sage/libs/all__sagemath_flint.py +17 -0
  30. sage/libs/arb/__init__.py +1 -0
  31. sage/libs/arb/acb.pxd +154 -0
  32. sage/libs/arb/acb_calc.pxd +9 -0
  33. sage/libs/arb/acb_elliptic.pxd +25 -0
  34. sage/libs/arb/acb_hypgeom.pxd +74 -0
  35. sage/libs/arb/acb_mat.pxd +62 -0
  36. sage/libs/arb/acb_modular.pxd +17 -0
  37. sage/libs/arb/acb_poly.pxd +216 -0
  38. sage/libs/arb/arb.pxd +240 -0
  39. sage/libs/arb/arb_fmpz_poly.pxd +21 -0
  40. sage/libs/arb/arb_hypgeom.pxd +83 -0
  41. sage/libs/arb/arb_wrap.h +34 -0
  42. sage/libs/arb/arf.pxd +131 -0
  43. sage/libs/arb/arith.cpython-310-x86_64-linux-gnu.so +0 -0
  44. sage/libs/arb/arith.pyx +87 -0
  45. sage/libs/arb/bernoulli.pxd +6 -0
  46. sage/libs/arb/mag.pxd +77 -0
  47. sage/libs/arb/types.pxd +37 -0
  48. sage/libs/flint/__init__.py +1 -0
  49. sage/libs/flint/acb.pxd +270 -0
  50. sage/libs/flint/acb_calc.pxd +22 -0
  51. sage/libs/flint/acb_dft.pxd +51 -0
  52. sage/libs/flint/acb_dirichlet.pxd +112 -0
  53. sage/libs/flint/acb_elliptic.pxd +42 -0
  54. sage/libs/flint/acb_hypgeom.pxd +169 -0
  55. sage/libs/flint/acb_macros.pxd +9 -0
  56. sage/libs/flint/acb_mat.pxd +136 -0
  57. sage/libs/flint/acb_mat_macros.pxd +10 -0
  58. sage/libs/flint/acb_modular.pxd +62 -0
  59. sage/libs/flint/acb_poly.pxd +251 -0
  60. sage/libs/flint/acb_poly_macros.pxd +8 -0
  61. sage/libs/flint/acb_theta.pxd +124 -0
  62. sage/libs/flint/acf.pxd +32 -0
  63. sage/libs/flint/aprcl.pxd +84 -0
  64. sage/libs/flint/arb.pxd +382 -0
  65. sage/libs/flint/arb_calc.pxd +31 -0
  66. sage/libs/flint/arb_fmpz_poly.pxd +34 -0
  67. sage/libs/flint/arb_fpwrap.pxd +215 -0
  68. sage/libs/flint/arb_hypgeom.pxd +147 -0
  69. sage/libs/flint/arb_macros.pxd +9 -0
  70. sage/libs/flint/arb_mat.pxd +140 -0
  71. sage/libs/flint/arb_mat_macros.pxd +10 -0
  72. sage/libs/flint/arb_poly.pxd +237 -0
  73. sage/libs/flint/arf.pxd +167 -0
  74. sage/libs/flint/arith.cpython-310-x86_64-linux-gnu.so +0 -0
  75. sage/libs/flint/arith.pxd +76 -0
  76. sage/libs/flint/arith.pyx +77 -0
  77. sage/libs/flint/arith_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  78. sage/libs/flint/arith_sage.pyx +308 -0
  79. sage/libs/flint/bernoulli.pxd +28 -0
  80. sage/libs/flint/bool_mat.pxd +52 -0
  81. sage/libs/flint/ca.pxd +203 -0
  82. sage/libs/flint/ca_ext.pxd +34 -0
  83. sage/libs/flint/ca_field.pxd +32 -0
  84. sage/libs/flint/ca_mat.pxd +117 -0
  85. sage/libs/flint/ca_poly.pxd +104 -0
  86. sage/libs/flint/ca_vec.pxd +46 -0
  87. sage/libs/flint/calcium.pxd +27 -0
  88. sage/libs/flint/d_mat.pxd +39 -0
  89. sage/libs/flint/d_vec.pxd +32 -0
  90. sage/libs/flint/dirichlet.pxd +57 -0
  91. sage/libs/flint/dlog.pxd +53 -0
  92. sage/libs/flint/double_extras.pxd +24 -0
  93. sage/libs/flint/double_interval.pxd +36 -0
  94. sage/libs/flint/fexpr.pxd +104 -0
  95. sage/libs/flint/fexpr_builtin.pxd +20 -0
  96. sage/libs/flint/fft.pxd +66 -0
  97. sage/libs/flint/flint.pxd +36 -0
  98. sage/libs/flint/flint_ntl_wrap.h +35 -0
  99. sage/libs/flint/flint_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  100. sage/libs/flint/flint_sage.pyx +163 -0
  101. sage/libs/flint/flint_wrap.h +190 -0
  102. sage/libs/flint/fmpq.pxd +137 -0
  103. sage/libs/flint/fmpq_mat.pxd +105 -0
  104. sage/libs/flint/fmpq_mat_macros.pxd +10 -0
  105. sage/libs/flint/fmpq_mpoly.pxd +165 -0
  106. sage/libs/flint/fmpq_mpoly_factor.pxd +30 -0
  107. sage/libs/flint/fmpq_poly.pxd +241 -0
  108. sage/libs/flint/fmpq_poly_macros.pxd +9 -0
  109. sage/libs/flint/fmpq_poly_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  110. sage/libs/flint/fmpq_poly_sage.pxd +31 -0
  111. sage/libs/flint/fmpq_poly_sage.pyx +48 -0
  112. sage/libs/flint/fmpq_vec.pxd +27 -0
  113. sage/libs/flint/fmpz.pxd +256 -0
  114. sage/libs/flint/fmpz_extras.pxd +32 -0
  115. sage/libs/flint/fmpz_factor.pxd +42 -0
  116. sage/libs/flint/fmpz_factor_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  117. sage/libs/flint/fmpz_factor_sage.pxd +4 -0
  118. sage/libs/flint/fmpz_factor_sage.pyx +29 -0
  119. sage/libs/flint/fmpz_lll.pxd +49 -0
  120. sage/libs/flint/fmpz_macros.pxd +8 -0
  121. sage/libs/flint/fmpz_mat.pxd +184 -0
  122. sage/libs/flint/fmpz_mat_macros.pxd +10 -0
  123. sage/libs/flint/fmpz_mod.pxd +46 -0
  124. sage/libs/flint/fmpz_mod_mat.pxd +71 -0
  125. sage/libs/flint/fmpz_mod_mpoly.pxd +161 -0
  126. sage/libs/flint/fmpz_mod_mpoly_factor.pxd +28 -0
  127. sage/libs/flint/fmpz_mod_poly.pxd +249 -0
  128. sage/libs/flint/fmpz_mod_poly_factor.pxd +46 -0
  129. sage/libs/flint/fmpz_mod_vec.pxd +27 -0
  130. sage/libs/flint/fmpz_mpoly.pxd +224 -0
  131. sage/libs/flint/fmpz_mpoly_factor.pxd +29 -0
  132. sage/libs/flint/fmpz_mpoly_q.pxd +57 -0
  133. sage/libs/flint/fmpz_poly.cpython-310-x86_64-linux-gnu.so +0 -0
  134. sage/libs/flint/fmpz_poly.pxd +407 -0
  135. sage/libs/flint/fmpz_poly.pyx +19 -0
  136. sage/libs/flint/fmpz_poly_factor.pxd +33 -0
  137. sage/libs/flint/fmpz_poly_macros.pxd +8 -0
  138. sage/libs/flint/fmpz_poly_mat.pxd +71 -0
  139. sage/libs/flint/fmpz_poly_q.pxd +55 -0
  140. sage/libs/flint/fmpz_poly_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  141. sage/libs/flint/fmpz_poly_sage.pxd +20 -0
  142. sage/libs/flint/fmpz_poly_sage.pyx +500 -0
  143. sage/libs/flint/fmpz_vec.pxd +80 -0
  144. sage/libs/flint/fmpzi.pxd +52 -0
  145. sage/libs/flint/fq.pxd +97 -0
  146. sage/libs/flint/fq_default.pxd +84 -0
  147. sage/libs/flint/fq_default_mat.pxd +70 -0
  148. sage/libs/flint/fq_default_poly.pxd +97 -0
  149. sage/libs/flint/fq_default_poly_factor.pxd +39 -0
  150. sage/libs/flint/fq_embed.pxd +28 -0
  151. sage/libs/flint/fq_mat.pxd +83 -0
  152. sage/libs/flint/fq_nmod.pxd +95 -0
  153. sage/libs/flint/fq_nmod_embed.pxd +28 -0
  154. sage/libs/flint/fq_nmod_mat.pxd +83 -0
  155. sage/libs/flint/fq_nmod_mpoly.pxd +130 -0
  156. sage/libs/flint/fq_nmod_mpoly_factor.pxd +28 -0
  157. sage/libs/flint/fq_nmod_poly.pxd +202 -0
  158. sage/libs/flint/fq_nmod_poly_factor.pxd +47 -0
  159. sage/libs/flint/fq_nmod_vec.pxd +33 -0
  160. sage/libs/flint/fq_poly.pxd +204 -0
  161. sage/libs/flint/fq_poly_factor.pxd +47 -0
  162. sage/libs/flint/fq_vec.pxd +33 -0
  163. sage/libs/flint/fq_zech.pxd +99 -0
  164. sage/libs/flint/fq_zech_embed.pxd +28 -0
  165. sage/libs/flint/fq_zech_mat.pxd +78 -0
  166. sage/libs/flint/fq_zech_poly.pxd +198 -0
  167. sage/libs/flint/fq_zech_poly_factor.pxd +47 -0
  168. sage/libs/flint/fq_zech_vec.pxd +33 -0
  169. sage/libs/flint/gr.pxd +174 -0
  170. sage/libs/flint/gr_generic.pxd +215 -0
  171. sage/libs/flint/gr_mat.pxd +161 -0
  172. sage/libs/flint/gr_mpoly.pxd +68 -0
  173. sage/libs/flint/gr_poly.pxd +276 -0
  174. sage/libs/flint/gr_special.pxd +237 -0
  175. sage/libs/flint/gr_vec.pxd +120 -0
  176. sage/libs/flint/hypgeom.pxd +24 -0
  177. sage/libs/flint/long_extras.pxd +23 -0
  178. sage/libs/flint/mag.pxd +131 -0
  179. sage/libs/flint/mag_macros.pxd +8 -0
  180. sage/libs/flint/mpf_mat.pxd +36 -0
  181. sage/libs/flint/mpf_vec.pxd +34 -0
  182. sage/libs/flint/mpfr_mat.pxd +27 -0
  183. sage/libs/flint/mpfr_vec.pxd +25 -0
  184. sage/libs/flint/mpn_extras.pxd +41 -0
  185. sage/libs/flint/mpoly.pxd +72 -0
  186. sage/libs/flint/nf.pxd +19 -0
  187. sage/libs/flint/nf_elem.pxd +74 -0
  188. sage/libs/flint/nmod.pxd +35 -0
  189. sage/libs/flint/nmod_mat.pxd +104 -0
  190. sage/libs/flint/nmod_mpoly.pxd +144 -0
  191. sage/libs/flint/nmod_mpoly_factor.pxd +28 -0
  192. sage/libs/flint/nmod_poly.pxd +339 -0
  193. sage/libs/flint/nmod_poly_factor.pxd +44 -0
  194. sage/libs/flint/nmod_poly_linkage.pxi +710 -0
  195. sage/libs/flint/nmod_poly_mat.pxd +76 -0
  196. sage/libs/flint/nmod_vec.pxd +40 -0
  197. sage/libs/flint/ntl_interface.pxd +17 -0
  198. sage/libs/flint/padic.pxd +93 -0
  199. sage/libs/flint/padic_mat.pxd +64 -0
  200. sage/libs/flint/padic_poly.pxd +88 -0
  201. sage/libs/flint/partitions.pxd +23 -0
  202. sage/libs/flint/perm.pxd +26 -0
  203. sage/libs/flint/profiler.pxd +24 -0
  204. sage/libs/flint/qadic.pxd +77 -0
  205. sage/libs/flint/qfb.pxd +44 -0
  206. sage/libs/flint/qqbar.pxd +172 -0
  207. sage/libs/flint/qsieve.cpython-310-x86_64-linux-gnu.so +0 -0
  208. sage/libs/flint/qsieve.pxd +41 -0
  209. sage/libs/flint/qsieve.pyx +21 -0
  210. sage/libs/flint/qsieve_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  211. sage/libs/flint/qsieve_sage.pyx +67 -0
  212. sage/libs/flint/thread_pool.pxd +25 -0
  213. sage/libs/flint/types.pxd +2076 -0
  214. sage/libs/flint/ulong_extras.cpython-310-x86_64-linux-gnu.so +0 -0
  215. sage/libs/flint/ulong_extras.pxd +141 -0
  216. sage/libs/flint/ulong_extras.pyx +21 -0
  217. sage/libs/flint/ulong_extras_sage.cpython-310-x86_64-linux-gnu.so +0 -0
  218. sage/libs/flint/ulong_extras_sage.pyx +21 -0
  219. sage/matrix/all__sagemath_flint.py +1 -0
  220. sage/matrix/change_ring.cpython-310-x86_64-linux-gnu.so +0 -0
  221. sage/matrix/change_ring.pyx +43 -0
  222. sage/matrix/matrix_complex_ball_dense.cpython-310-x86_64-linux-gnu.so +0 -0
  223. sage/matrix/matrix_complex_ball_dense.pxd +14 -0
  224. sage/matrix/matrix_complex_ball_dense.pyx +973 -0
  225. sage/matrix/matrix_cyclo_dense.cpython-310-x86_64-linux-gnu.so +0 -0
  226. sage/matrix/matrix_cyclo_dense.pxd +16 -0
  227. sage/matrix/matrix_cyclo_dense.pyx +1761 -0
  228. sage/matrix/matrix_integer_dense.cpython-310-x86_64-linux-gnu.so +0 -0
  229. sage/matrix/matrix_integer_dense.pxd +32 -0
  230. sage/matrix/matrix_integer_dense.pyx +5801 -0
  231. sage/matrix/matrix_integer_dense_hnf.py +1294 -0
  232. sage/matrix/matrix_integer_dense_saturation.py +346 -0
  233. sage/matrix/matrix_integer_sparse.cpython-310-x86_64-linux-gnu.so +0 -0
  234. sage/matrix/matrix_integer_sparse.pxd +9 -0
  235. sage/matrix/matrix_integer_sparse.pyx +1090 -0
  236. sage/matrix/matrix_rational_dense.cpython-310-x86_64-linux-gnu.so +0 -0
  237. sage/matrix/matrix_rational_dense.pxd +23 -0
  238. sage/matrix/matrix_rational_dense.pyx +2995 -0
  239. sage/matrix/matrix_rational_sparse.cpython-310-x86_64-linux-gnu.so +0 -0
  240. sage/matrix/matrix_rational_sparse.pxd +11 -0
  241. sage/matrix/matrix_rational_sparse.pyx +789 -0
  242. sage/matrix/misc_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  243. sage/matrix/misc_flint.pyx +109 -0
  244. sage/modular/all__sagemath_flint.py +1 -0
  245. sage/modular/modform/all__sagemath_flint.py +1 -0
  246. sage/modular/modform/eis_series_cython.cpython-310-x86_64-linux-gnu.so +0 -0
  247. sage/modular/modform/eis_series_cython.pyx +226 -0
  248. sage/modular/modsym/all__sagemath_flint.py +1 -0
  249. sage/modular/modsym/apply.cpython-310-x86_64-linux-gnu.so +0 -0
  250. sage/modular/modsym/apply.pxd +6 -0
  251. sage/modular/modsym/apply.pyx +113 -0
  252. sage/modular/modsym/heilbronn.cpython-310-x86_64-linux-gnu.so +0 -0
  253. sage/modular/modsym/heilbronn.pyx +966 -0
  254. sage/modular/pollack_stevens/all__sagemath_flint.py +1 -0
  255. sage/modular/pollack_stevens/dist.cpython-310-x86_64-linux-gnu.so +0 -0
  256. sage/modular/pollack_stevens/dist.pxd +38 -0
  257. sage/modular/pollack_stevens/dist.pyx +1439 -0
  258. sage/quivers/algebra.py +691 -0
  259. sage/quivers/algebra_elements.cpython-310-x86_64-linux-gnu.so +0 -0
  260. sage/quivers/algebra_elements.pxd +97 -0
  261. sage/quivers/algebra_elements.pxi +1324 -0
  262. sage/quivers/algebra_elements.pyx +1424 -0
  263. sage/quivers/all.py +1 -0
  264. sage/quivers/ar_quiver.py +917 -0
  265. sage/quivers/homspace.py +640 -0
  266. sage/quivers/morphism.py +1282 -0
  267. sage/quivers/path_semigroup.py +1155 -0
  268. sage/quivers/paths.cpython-310-x86_64-linux-gnu.so +0 -0
  269. sage/quivers/paths.pxd +13 -0
  270. sage/quivers/paths.pyx +809 -0
  271. sage/quivers/representation.py +2975 -0
  272. sage/rings/all__sagemath_flint.py +37 -0
  273. sage/rings/cif.py +4 -0
  274. sage/rings/complex_arb.cpython-310-x86_64-linux-gnu.so +0 -0
  275. sage/rings/complex_arb.pxd +29 -0
  276. sage/rings/complex_arb.pyx +5176 -0
  277. sage/rings/complex_interval.cpython-310-x86_64-linux-gnu.so +0 -0
  278. sage/rings/complex_interval.pxd +30 -0
  279. sage/rings/complex_interval.pyx +2475 -0
  280. sage/rings/complex_interval_field.py +711 -0
  281. sage/rings/convert/all.py +1 -0
  282. sage/rings/convert/mpfi.cpython-310-x86_64-linux-gnu.so +0 -0
  283. sage/rings/convert/mpfi.pxd +6 -0
  284. sage/rings/convert/mpfi.pyx +576 -0
  285. sage/rings/factorint_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  286. sage/rings/factorint_flint.pyx +99 -0
  287. sage/rings/fraction_field_FpT.cpython-310-x86_64-linux-gnu.so +0 -0
  288. sage/rings/fraction_field_FpT.pxd +28 -0
  289. sage/rings/fraction_field_FpT.pyx +2043 -0
  290. sage/rings/imaginary_unit.py +5 -0
  291. sage/rings/monomials.py +73 -0
  292. sage/rings/number_field/S_unit_solver.py +2870 -0
  293. sage/rings/number_field/all__sagemath_flint.py +7 -0
  294. sage/rings/number_field/bdd_height.py +664 -0
  295. sage/rings/number_field/class_group.py +762 -0
  296. sage/rings/number_field/galois_group.py +1307 -0
  297. sage/rings/number_field/homset.py +612 -0
  298. sage/rings/number_field/maps.py +687 -0
  299. sage/rings/number_field/morphism.py +272 -0
  300. sage/rings/number_field/number_field.py +12820 -0
  301. sage/rings/number_field/number_field_element.cpython-310-x86_64-linux-gnu.so +0 -0
  302. sage/rings/number_field/number_field_element.pxd +59 -0
  303. sage/rings/number_field/number_field_element.pyx +5735 -0
  304. sage/rings/number_field/number_field_element_quadratic.cpython-310-x86_64-linux-gnu.so +0 -0
  305. sage/rings/number_field/number_field_element_quadratic.pxd +34 -0
  306. sage/rings/number_field/number_field_element_quadratic.pyx +3185 -0
  307. sage/rings/number_field/number_field_ideal_rel.py +925 -0
  308. sage/rings/number_field/number_field_morphisms.cpython-310-x86_64-linux-gnu.so +0 -0
  309. sage/rings/number_field/number_field_morphisms.pyx +781 -0
  310. sage/rings/number_field/number_field_rel.py +2734 -0
  311. sage/rings/number_field/order.py +2981 -0
  312. sage/rings/number_field/order_ideal.py +804 -0
  313. sage/rings/number_field/selmer_group.py +715 -0
  314. sage/rings/number_field/small_primes_of_degree_one.py +242 -0
  315. sage/rings/number_field/splitting_field.py +606 -0
  316. sage/rings/number_field/structure.py +380 -0
  317. sage/rings/number_field/unit_group.py +721 -0
  318. sage/rings/padics/all__sagemath_flint.py +3 -0
  319. sage/rings/polynomial/all__sagemath_flint.py +1 -0
  320. sage/rings/polynomial/complex_roots.py +312 -0
  321. sage/rings/polynomial/evaluation_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  322. sage/rings/polynomial/evaluation_flint.pxd +7 -0
  323. sage/rings/polynomial/evaluation_flint.pyx +68 -0
  324. sage/rings/polynomial/hilbert.cpython-310-x86_64-linux-gnu.so +0 -0
  325. sage/rings/polynomial/hilbert.pyx +602 -0
  326. sage/rings/polynomial/polynomial_complex_arb.cpython-310-x86_64-linux-gnu.so +0 -0
  327. sage/rings/polynomial/polynomial_complex_arb.pxd +7 -0
  328. sage/rings/polynomial/polynomial_complex_arb.pyx +963 -0
  329. sage/rings/polynomial/polynomial_integer_dense_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  330. sage/rings/polynomial/polynomial_integer_dense_flint.pxd +13 -0
  331. sage/rings/polynomial/polynomial_integer_dense_flint.pyx +1881 -0
  332. sage/rings/polynomial/polynomial_number_field.cpython-310-x86_64-linux-gnu.so +0 -0
  333. sage/rings/polynomial/polynomial_number_field.pyx +345 -0
  334. sage/rings/polynomial/polynomial_rational_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  335. sage/rings/polynomial/polynomial_rational_flint.pxd +20 -0
  336. sage/rings/polynomial/polynomial_rational_flint.pyx +2598 -0
  337. sage/rings/polynomial/polynomial_zmod_flint.cpython-310-x86_64-linux-gnu.so +0 -0
  338. sage/rings/polynomial/polynomial_zmod_flint.pxd +20 -0
  339. sage/rings/polynomial/polynomial_zmod_flint.pyx +1063 -0
  340. sage/rings/polynomial/real_roots.cpython-310-x86_64-linux-gnu.so +0 -0
  341. sage/rings/polynomial/real_roots.pxd +81 -0
  342. sage/rings/polynomial/real_roots.pyx +4704 -0
  343. sage/rings/polynomial/refine_root.cpython-310-x86_64-linux-gnu.so +0 -0
  344. sage/rings/polynomial/refine_root.pyx +142 -0
  345. sage/rings/polynomial/weil/all.py +4 -0
  346. sage/rings/polynomial/weil/power_sums.h +46 -0
  347. sage/rings/polynomial/weil/weil_polynomials.cpython-310-x86_64-linux-gnu.so +0 -0
  348. sage/rings/polynomial/weil/weil_polynomials.pyx +596 -0
  349. sage/rings/qqbar.py +9025 -0
  350. sage/rings/real_arb.cpython-310-x86_64-linux-gnu.so +0 -0
  351. sage/rings/real_arb.pxd +21 -0
  352. sage/rings/real_arb.pyx +4065 -0
  353. sage/rings/real_interval_absolute.cpython-310-x86_64-linux-gnu.so +0 -0
  354. sage/rings/real_interval_absolute.pyx +1073 -0
  355. sage/rings/real_mpfi.cpython-310-x86_64-linux-gnu.so +0 -0
  356. sage/rings/real_mpfi.pyx +5428 -0
  357. sage/schemes/all__sagemath_flint.py +1 -0
  358. sage/schemes/elliptic_curves/all__sagemath_flint.py +1 -0
  359. sage/schemes/elliptic_curves/descent_two_isogeny.cpython-310-x86_64-linux-gnu.so +0 -0
  360. sage/schemes/elliptic_curves/descent_two_isogeny.pyx +1387 -0
  361. sage/schemes/elliptic_curves/descent_two_isogeny_pari.pxd +5 -0
@@ -0,0 +1,1324 @@
1
+ # sage_setup: distribution = sagemath-flint
2
+ # sage.doctest: needs sage.graphs
3
+ """
4
+ Boilerplate functions for a cython implementation of elements of path algebras
5
+
6
+ AUTHORS:
7
+
8
+ - Simon King (2015-08)
9
+ """
10
+
11
+ # ****************************************************************************
12
+ # Copyright (C) 2015 Simon King <simon.king@uni-jena.de>
13
+ #
14
+ # Distributed under the terms of the GNU General Public License (GPL)
15
+ # as published by the Free Software Foundation; either version 2 of
16
+ # the License, or (at your option) any later version.
17
+ # https://www.gnu.org/licenses/
18
+ # ****************************************************************************
19
+
20
+ from cysignals.memory cimport check_malloc, check_allocarray, sig_free
21
+ from cysignals.signals cimport sig_check, sig_on, sig_off
22
+
23
+ from cpython.ref cimport *
24
+ from cython.operator cimport predecrement as predec, postincrement as postinc
25
+
26
+ from sage.data_structures.bitset_base cimport *
27
+ from sage.structure.richcmp cimport richcmp_not_equal, rich_to_bool
28
+ from sage.libs.gmp.mpn cimport mpn_cmp
29
+ from libc.stdlib cimport free
30
+
31
+ cdef extern from *: # Defined by Cython
32
+ int unlikely(int) nogil
33
+ int likely(int) nogil
34
+
35
+ ########################################
36
+ #
37
+ # Allocation and Deallocation of monomials
38
+ #
39
+ # Monomials are expensive, hence, copying will just be done by increasing a
40
+ # reference counter.
41
+
42
+ # Create a monomial by copying the given bounded integer sequence
43
+ cdef bint mon_create(path_mon_t out, biseq_t Mon, long Pos, mp_size_t L_len, mp_size_t S_len) except -1:
44
+ biseq_init_copy(out.path, Mon)
45
+ out.pos = Pos
46
+ out.l_len = L_len
47
+ out.s_len = S_len
48
+
49
+ # The following is only used in the free-list for terms.
50
+ # It changes an existing monomial in-place (which should NEVER
51
+ # be done on a monomial that is in use), re-allocating memory
52
+ # and filling it with a copy of the given bounded integer sequence.
53
+ cdef bint mon_realloc(path_mon_t out, biseq_t Mon, long Pos, mp_size_t L_len, mp_size_t S_len) except -1:
54
+ biseq_dealloc(out.path)
55
+ sig_check()
56
+ biseq_init_copy(out.path, Mon)
57
+ out.pos = Pos
58
+ out.l_len = L_len
59
+ out.s_len = S_len
60
+
61
+ # Create a monomial without copying the given bounded integer sequence
62
+ cdef bint mon_create_keep(path_mon_t out, biseq_t Mon, long Pos, mp_size_t L_len, mp_size_t S_len) except -1:
63
+ out.path[0] = Mon[0]
64
+ out.pos = Pos
65
+ out.l_len = L_len
66
+ out.s_len = S_len
67
+
68
+ # The following is only used in the free-list for terms.
69
+ # It changes an existing monomial in-place (which should NEVER
70
+ # be done on a monomial that is in use), re-allocating memory
71
+ # and filling it with the given bounded integer sequence (not a copy).
72
+ cdef bint mon_realloc_keep(path_mon_t out, biseq_t Mon, long Pos, mp_size_t L_len, mp_size_t S_len) noexcept:
73
+ biseq_dealloc(out.path)
74
+ out.path[0] = Mon[0]
75
+ out.pos = Pos
76
+ out.l_len = L_len
77
+ out.s_len = S_len
78
+ return True
79
+
80
+ cdef inline bint mon_copy(path_mon_t out, path_mon_t M) except -1:
81
+ out.pos = M.pos
82
+ out.l_len = M.l_len
83
+ out.s_len = M.s_len
84
+ biseq_init_copy(out.path, M.path)
85
+
86
+ # Deallocate the monomial, which means to decrease the reference count,
87
+ # or to actually deallocate the data if there is no reference left.
88
+ cdef inline void mon_free(path_mon_t M) noexcept:
89
+ biseq_dealloc(M.path)
90
+
91
+ # Linearisation
92
+ cdef inline tuple mon_pickle(path_mon_t M):
93
+ return (bitset_pickle(M.path.data) if M.path.length>0 else (),
94
+ M.path.itembitsize, M.path.length, M.pos, M.l_len, M.s_len)
95
+
96
+ # De-linearisation
97
+ cdef bint mon_unpickle(path_mon_t out, tuple data) except -1:
98
+ cdef tuple bitset_data
99
+ cdef mp_bitcnt_t itembitsize
100
+ cdef mp_size_t length
101
+ cdef long Pos
102
+ cdef mp_size_t L_len
103
+ cdef mp_size_t S_len
104
+ bitset_data, itembitsize, length, Pos, L_len, S_len = data
105
+ out.path.itembitsize = itembitsize
106
+ out.path.mask_item = limb_lower_bits_up(itembitsize)
107
+ out.path.length = length
108
+
109
+ # bitset_unpickle assumes that out.path.data is initialised.
110
+ bitset_init(out.path.data, GMP_LIMB_BITS)
111
+ if bitset_data:
112
+ sig_on()
113
+ bitset_unpickle(out.path.data, bitset_data)
114
+ sig_off()
115
+ out.pos = Pos
116
+ out.l_len = L_len
117
+ out.s_len = S_len
118
+
119
+
120
+ ########################################
121
+ #
122
+ # Monomial orders---we only use degree orders
123
+
124
+ # Negative degree reverse lexicographic ordering
125
+ cdef int negdegrevlex(path_mon_t M1, path_mon_t M2) except -2:
126
+ # a*s_i*b<c*s_j*d <=>
127
+ # 1. deg(a*b) > deg(c*d), otherwise
128
+ # 2. deg(a) > deg(c) (note that one of them may be -1), otherwise
129
+ # 3. deg(s_i) < deg(s_j), otherwise
130
+ # 4. a*s_i*b <_revlex c*s_j*d, otherwise
131
+ # 5. i<j
132
+ cdef mp_size_t l1 = M1.path.length + M2.s_len # sic!
133
+ cdef mp_size_t l2 = M2.path.length + M1.s_len
134
+ if l1 != l2:
135
+ if l2 < l1:
136
+ return -1
137
+ return 1
138
+ if M2.l_len != M1.l_len:
139
+ if M2.l_len < M1.l_len:
140
+ return -1
141
+ return 1
142
+ if M1.s_len != M2.s_len:
143
+ if M1.s_len < M2.s_len:
144
+ return -1
145
+ return 1
146
+ # mpn_cmp does comparison of long integers. If the two long integers have
147
+ # the same number of digits (this is the case her), it is the same as
148
+ # lexicographic comparison of the numbers. The highest digit corresponds
149
+ # to the right-most item in the path. Hence, it becomes
150
+ # reverse-lexicographic order.
151
+ sig_on()
152
+ cdef int c = mpn_cmp(M1.path.data.bits, M2.path.data.bits, M1.path.data.limbs)
153
+ sig_off()
154
+ if c!=0:
155
+ return c
156
+ if M1.pos != M2.pos:
157
+ if M1.pos < M2.pos:
158
+ return -1
159
+ return 1
160
+ return 0
161
+
162
+ # Degree reverse lexicographic ordering
163
+ cdef int degrevlex(path_mon_t M1, path_mon_t M2) except -2:
164
+ # a*s_i*b<c*s_j*d <=>
165
+ # 1. deg(a*b) < deg(c*d), otherwise
166
+ # 2. deg(a) < deg(c) (note that one of them may be -1), otherwise
167
+ # 3. deg(s_i) > deg(s_j), otherwise
168
+ # 4. a*s_i*b <_revlex c*s_j*d, otherwise
169
+ # 5. i<j
170
+ cdef mp_size_t l1 = M1.path.length + M2.s_len # sic!
171
+ cdef mp_size_t l2 = M2.path.length + M1.s_len
172
+ if l2 != l1:
173
+ if l2 < l1:
174
+ return 1
175
+ return -1
176
+ if M2.l_len != M1.l_len:
177
+ if M2.l_len < M1.l_len:
178
+ return 1
179
+ return -1
180
+ if M1.s_len != M2.s_len:
181
+ if M1.s_len < M2.s_len:
182
+ return 1
183
+ return -1
184
+ # mpn_cmp does comparison of long integers. If the two long integers have
185
+ # the same number of digits (this is the case her), it is the same as
186
+ # lexicographic comparison of the numbers. The highest digit corresponds
187
+ # to the right-most item in the path. Hence, it becomes
188
+ # reverse-lexicographic order.
189
+ sig_on()
190
+ cdef int c = mpn_cmp(M1.path.data.bits, M2.path.data.bits, M1.path.data.limbs)
191
+ sig_off()
192
+ if c!=0:
193
+ return c
194
+ if M1.pos != M2.pos:
195
+ if M1.pos < M2.pos:
196
+ return -1
197
+ return 1
198
+ return 0
199
+
200
+ # Negative degree lexicographic ordering
201
+ cdef int negdeglex(path_mon_t M1, path_mon_t M2) except -2:
202
+ # a*s_i*b<c*s_j*d <=>
203
+ # 1. deg(a*b) > deg(c*d), otherwise
204
+ # 2. deg(a) > deg(c) (note that one of them may be -1), otherwise
205
+ # 3. deg(s_i) < deg(s_j), otherwise
206
+ # 4. a*s_i*b <_lex c*s_j*d, otherwise
207
+ # 5. i<j
208
+ cdef mp_size_t l1 = M1.path.length + M2.s_len # sic!
209
+ cdef mp_size_t l2 = M2.path.length + M1.s_len
210
+ cdef size_t item1, item2
211
+ if l2 != l1:
212
+ if l2 < l1:
213
+ return -1
214
+ return 1
215
+ if M2.l_len != M1.l_len:
216
+ if M2.l_len < M1.l_len:
217
+ return -1
218
+ return 1
219
+ if M1.s_len != M2.s_len:
220
+ if M1.s_len < M2.s_len:
221
+ return -1
222
+ return 1
223
+ for index in range(M1.path.length):
224
+ item1 = biseq_getitem(M1.path, index)
225
+ item2 = biseq_getitem(M2.path, index)
226
+ sig_check()
227
+ if item1 != item2:
228
+ if item1 < item2:
229
+ return -1
230
+ return 1
231
+ if M1.pos != M2.pos:
232
+ if M1.pos < M2.pos:
233
+ return -1
234
+ return 1
235
+ return 0
236
+
237
+ # Degree lexicographic ordering
238
+ cdef int deglex(path_mon_t M1, path_mon_t M2) except -2:
239
+ # a*s_i*b<c*s_j*d <=>
240
+ # 1. deg(a*b) < deg(c*d), otherwise
241
+ # 2. deg(a) < deg(c) (note that one of them may be -1), otherwise
242
+ # 3. deg(s_i) > deg(s_j), otherwise
243
+ # 4. a*s_i*b <_lex c*s_j*d, otherwise
244
+ # 5. i<j
245
+ cdef mp_size_t l1 = M1.path.length + M2.s_len # sic!
246
+ cdef mp_size_t l2 = M2.path.length + M1.s_len
247
+ cdef size_t item1, item2
248
+ if l2 != l1:
249
+ if l2 < l1:
250
+ return 1
251
+ return -1
252
+ if M2.l_len != M1.l_len:
253
+ if M2.l_len < M1.l_len:
254
+ return 1
255
+ return -1
256
+ if M1.s_len != M2.s_len:
257
+ if M1.s_len < M2.s_len:
258
+ return 1
259
+ return -1
260
+ for index in range(M1.path.length):
261
+ item1 = biseq_getitem(M1.path, index)
262
+ item2 = biseq_getitem(M2.path, index)
263
+ sig_check()
264
+ if item1 != item2:
265
+ if item1 < item2:
266
+ return -1
267
+ return 1
268
+ if M1.pos != M2.pos:
269
+ if M1.pos < M2.pos:
270
+ return -1
271
+ return 1
272
+ return 0
273
+
274
+ ########################################
275
+ #
276
+ # Allocation and Deallocation of terms
277
+ ###########################
278
+ # We use a freelist for terms
279
+
280
+ cdef struct freelist_t:
281
+ path_term_t **pool
282
+ size_t used
283
+ cdef size_t poolsize = 5000 # The freelist contains at most that many terms.
284
+
285
+ cdef freelist_t *freelist = <freelist_t*>check_malloc(sizeof(freelist_t))
286
+ freelist.used = 0
287
+ freelist.pool = <path_term_t**>check_allocarray(poolsize, sizeof(path_term_t*))
288
+
289
+ # Deallocate the term, and return the pointer .nxt, without using kill list
290
+ cdef inline path_term_t *term_free_force(path_term_t *T) noexcept:
291
+ mon_free(T.mon)
292
+ cdef path_term_t *out = T.nxt
293
+ sig_free(T)
294
+ return out
295
+
296
+ cdef class _FreeListProtector:
297
+ """
298
+ The purpose of this class is to deallocate our freelist
299
+ of path algebra terms. When its only instance is deleted (which
300
+ should only happen when a SageMath session ends), then the
301
+ freelist is cleared.
302
+ """
303
+ def __dealloc__(self):
304
+ """
305
+ TESTS::
306
+
307
+ sage: s = Sage()
308
+ sage: s.eval("P = DiGraph({1:{1:['x','y','z']}}).path_semigroup().algebra(GF(25,'t'))")
309
+ ''
310
+ sage: s.eval("P.inject_variables()")
311
+ 'Defining e_1, x, y, z'
312
+ sage: s.eval("x*y+y*z*x")
313
+ 'x*y + y*z*x'
314
+ sage: s.quit() # indirect doctest
315
+ """
316
+ cdef size_t i
317
+ for i in range(freelist.used):
318
+ term_free_force(freelist.pool[i])
319
+ sig_check()
320
+ sig_free(freelist.pool)
321
+ sig_free(freelist)
322
+
323
+ _freelist_protector = _FreeListProtector()
324
+
325
+ # Put the term on the freelist (unless the list is full),
326
+ # and return the pointer .nxt
327
+ cdef inline path_term_t *term_free(path_term_t *T) noexcept:
328
+ if T.coef!=NULL:
329
+ Py_XDECREF(T.coef)
330
+ if likely(freelist.used < poolsize):
331
+ freelist.pool[postinc(freelist.used)] = T
332
+ return T.nxt
333
+ return term_free_force(T)
334
+
335
+ # Create a term by copying the given bounded integer sequence,
336
+ # with the given coefficient
337
+ cdef path_term_t *term_create(object coef, biseq_t Mon, long Pos, mp_size_t L_len, mp_size_t S_len) except NULL:
338
+ cdef path_term_t *out
339
+ if likely(freelist.used > 0):
340
+ out = freelist.pool[predec(freelist.used)]
341
+ mon_realloc(out.mon, Mon, Pos, L_len, S_len)
342
+ else:
343
+ out = <path_term_t*>check_malloc(sizeof(path_term_t))
344
+ mon_create(out.mon, Mon, Pos, L_len, S_len)
345
+ Py_INCREF(coef)
346
+ out.coef = <PyObject*>coef
347
+ out.nxt = NULL
348
+ return out
349
+
350
+ # Create a term without copying the given bounded integer sequence
351
+ cdef path_term_t *term_create_keep(object coef, biseq_t Mon, long Pos, mp_size_t L_len, mp_size_t S_len) except NULL:
352
+ cdef path_term_t *out
353
+ if likely(freelist.used) > 0:
354
+ out = freelist.pool[predec(freelist.used)]
355
+ mon_realloc_keep(out.mon, Mon, Pos, L_len, S_len)
356
+ else:
357
+ out = <path_term_t*>check_malloc(sizeof(path_term_t))
358
+ mon_create_keep(out.mon, Mon, Pos, L_len, S_len)
359
+ Py_INCREF(coef)
360
+ out.coef = <PyObject*>coef
361
+ # out.nxt = NULL # to be taken care of externally
362
+ return out
363
+
364
+ # Create a term with a given coefficient, but empty monomial
365
+ cdef path_term_t *term_create_blank(object coef) except NULL:
366
+ cdef path_term_t *out
367
+ if likely(freelist.used > 0):
368
+ out = freelist.pool[predec(freelist.used)]
369
+ mon_free(out.mon)
370
+ else:
371
+ out = <path_term_t*>check_malloc(sizeof(path_term_t))
372
+ Py_INCREF(coef)
373
+ out.coef = <PyObject*>coef
374
+ # out.nxt = NULL # to be taken care of externally
375
+ return out
376
+
377
+ ######################################################################
378
+ ######################################################################
379
+
380
+ # Copy a term; recall that copying the underlying monomial
381
+ # just means to increase its reference count. However,
382
+ # the copied TERM is new.
383
+ # The .nxt attribute is NOT defined on the copy of the term.
384
+ cdef path_term_t *term_copy(path_term_t *T) except NULL:
385
+ cdef path_term_t *out
386
+ if likely(freelist.used > 0):
387
+ out = freelist.pool[predec(freelist.used)]
388
+ mon_free(out.mon)
389
+ else:
390
+ out = <path_term_t*>check_malloc(sizeof(path_term_t))
391
+ sig_on()
392
+ mon_copy(out.mon, T.mon)
393
+ sig_off()
394
+ Py_XINCREF(T.coef)
395
+ out.coef = T.coef
396
+ # out.nxt is supposed to be taken care of externally
397
+ return out
398
+
399
+ # Create a copy of T and recursively of T.nxt
400
+ cdef path_term_t *term_copy_recursive(path_term_t *T) except NULL:
401
+ cdef path_term_t *out = term_copy(T)
402
+ cdef path_term_t *first = out
403
+ T = T.nxt
404
+ while T!=NULL:
405
+ out.nxt = term_copy(T)
406
+ out = out.nxt
407
+ T = T.nxt
408
+ out.nxt = NULL
409
+ return first
410
+
411
+ # Hash of a term; probably not a good one.
412
+ cdef inline long term_hash(path_term_t *T) noexcept:
413
+ return (<long>hash(<object>T.coef)+(T.mon.l_len<<5)+(T.mon.pos<<10))^bitset_hash(T.mon.path.data)
414
+
415
+ # Recall that a monomial a*I*b (with I a generator of a free module)
416
+ # is encoded by a path a*s*b for some monomial s that refers to a
417
+ # so-called Schreyer ordering. The total degree of a*I*b is the length
418
+ # of a plus the length of b.
419
+ cdef inline mp_size_t term_total_degree(path_term_t *T) noexcept:
420
+ return T.mon.path.length-T.mon.s_len
421
+
422
+ # Linearisation
423
+ cdef inline tuple term_pickle(path_term_t *T):
424
+ return (<object>T.coef, mon_pickle(T.mon))
425
+
426
+ # De-linearisation
427
+ cdef inline path_term_t *term_unpickle(object coef, tuple mon_data) except NULL:
428
+ cdef path_term_t *out = term_create_blank(coef)
429
+ mon_unpickle(out.mon, mon_data)
430
+ return out
431
+
432
+ ########################################
433
+ #
434
+ # Multiplication of monomials
435
+
436
+ # Return T*p, for a path p and a monomial T.
437
+ cdef bint mon_mul_path(path_mon_t out, path_mon_t T, biseq_t p) except -1:
438
+ if unlikely(p.length == 0):
439
+ return mon_copy(out, T)
440
+ biseq_init_concat(out.path, T.path, p)
441
+ out.pos = T.pos
442
+ out.l_len = T.l_len
443
+ out.s_len = T.s_len
444
+
445
+ # Return p*T, for a path p and a monomial T.
446
+ cdef bint path_mul_mon(path_mon_t out, biseq_t p, path_mon_t T) except -1:
447
+ if unlikely(p.length == 0):
448
+ return mon_copy(out, T)
449
+ biseq_init_concat(out.path, p, T.path)
450
+ out.pos = T.pos
451
+ out.l_len = 0 if T.pos==-1 else T.l_len+p.length
452
+ out.s_len = T.s_len
453
+
454
+ # Return p*T*q, for paths p,q and a monomial T.
455
+ cdef bint path_mul_mon_mul_path(path_mon_t out, biseq_t p, path_mon_t T, biseq_t q) except -1:
456
+ # .l_len and .s_len are taken care of externally!
457
+ if unlikely(p.length==0 and q.length==0):
458
+ return mon_copy(out, T)
459
+ if unlikely(p.length == 0):
460
+ return mon_mul_path(out, T, q)
461
+ if unlikely(q.length == 0):
462
+ return path_mul_mon(out, p, T)
463
+ out.pos = T.pos
464
+ if unlikely(T.path.length == 0):
465
+ biseq_init_concat(out.path, p, q)
466
+ return True
467
+ cdef mp_size_t pTlength = p.length + T.path.length
468
+ cdef mp_size_t res_length = pTlength + q.length
469
+ biseq_init(out.path, res_length, p.itembitsize)
470
+ if res_length == 0:
471
+ return False
472
+ cdef mp_bitcnt_t pTsize = p.data.size+T.path.data.size
473
+ sig_on()
474
+ bitset_lshift(out.path.data, q.data, pTsize)
475
+ cdef mp_bitcnt_t p_offset = p.data.size % GMP_LIMB_BITS
476
+ # p_limbs gives the index of the limb that will store the first bit of the
477
+ # shifted version of T.
478
+ cdef mp_bitcnt_t p_limbs = (p.data.limbs - 1) if p_offset>0 else p.data.limbs
479
+
480
+ # pT_limbs gives the index of the last limb used to store p+T
481
+ cdef mp_bitcnt_t pT_limbs = (pTsize-1)//GMP_LIMB_BITS
482
+ if ((T.path.data.size-1) % GMP_LIMB_BITS) + p_offset >= GMP_LIMB_BITS:
483
+ # We shift all limbs of T. The highest bits of the highest limbs are
484
+ # pushed out and returned by mpn_lshift. We need to assign them to the
485
+ # beginning of the last limb that is (partially) occupied by p+T
486
+ out.path.data.bits[pT_limbs] |= mpn_lshift(out.path.data.bits+p_limbs,
487
+ T.path.data.bits,
488
+ T.path.data.limbs, p_offset)
489
+ else:
490
+ if T.path.data.limbs>1:
491
+ # If we would move all limbs of T, then the result would override
492
+ # the lowest limb of the shifted copy of q. We thus only move all
493
+ # but the last limb of T, assigning to the beginning of the last
494
+ # limb of p+T the bits that have been pushed out.
495
+ out.path.data.bits[pT_limbs] |= mpn_lshift(out.path.data.bits+p_limbs,
496
+ T.path.data.bits,
497
+ T.path.data.limbs-1,
498
+ p_offset)
499
+ # Last, we need to move the last limb of T (which is only
500
+ # partially occupied), namely into the spot between the previously
501
+ # moved parts of T and the beginning of the shifted copy of q.
502
+ out.path.data.bits[pT_limbs] |= (T.path.data.bits[T.path.data.limbs-1]<<p_offset)
503
+ else:
504
+ out.path.data.bits[p_limbs] |= (T.path.data.bits[T.path.data.limbs-1]<<p_offset)
505
+ bitset_or(out.path.data, out.path.data, p.data)
506
+ sig_off()
507
+
508
+ ########################################
509
+ # Addition and scaling of terms
510
+
511
+ # Return -T
512
+ cdef path_term_t *term_neg(path_term_t *T) except NULL:
513
+ cdef path_term_t *out
514
+ if likely(freelist.used > 0):
515
+ out = freelist.pool[predec(freelist.used)]
516
+ mon_free(out.mon)
517
+ else:
518
+ out = <path_term_t*>check_malloc(sizeof(path_term_t))
519
+ cdef object coef = -<object>T.coef
520
+ out.coef = <PyObject*>coef
521
+ Py_INCREF(coef)
522
+ mon_copy(out.mon, T.mon)
523
+ # out.nxt is supposed to be taken care of externally
524
+ return out
525
+
526
+ # Return -T, and recurse over T.nxt
527
+ cdef path_term_t *term_neg_recursive(path_term_t *T) except NULL:
528
+ cdef path_term_t *out = term_neg(T)
529
+ cdef path_term_t *first = out
530
+ T = T.nxt
531
+ while T!=NULL:
532
+ sig_check()
533
+ out.nxt = term_neg(T)
534
+ out = out.nxt
535
+ T = T.nxt
536
+ out.nxt = NULL
537
+ return first
538
+
539
+ # Return coef*T
540
+ cdef path_term_t *term_scale(path_term_t *T, object coef) except NULL:
541
+ cdef path_term_t *out
542
+ if likely(freelist.used > 0):
543
+ out = freelist.pool[predec(freelist.used)]
544
+ mon_free(out.mon)
545
+ else:
546
+ out = <path_term_t*>check_malloc(sizeof(path_term_t))
547
+ cdef object new_coef = coef*<object>T.coef
548
+ if new_coef:
549
+ out.coef = <PyObject*>new_coef
550
+ Py_INCREF(new_coef)
551
+ mon_copy(out.mon, T.mon)
552
+ else:
553
+ out.coef = NULL
554
+ # out.nxt is supposed to be taken care of externally
555
+ return out
556
+
557
+ # Return coef*T and recurse over T.nxt
558
+ cdef path_term_t *term_scale_recursive(path_term_t *T, object coef) except NULL:
559
+ cdef path_term_t *out = term_scale(T, coef)
560
+ cdef path_term_t *first = out
561
+ T = T.nxt
562
+ while T!=NULL:
563
+ sig_check()
564
+ out.nxt = term_scale(T, coef)
565
+ if out.nxt.coef == NULL:
566
+ term_free(out.nxt)
567
+ out.nxt = NULL
568
+ else:
569
+ out = out.nxt
570
+ T = T.nxt
571
+ out.nxt = NULL
572
+ return first
573
+
574
+ # Return T1*T2.
575
+ # An error is raised if both T1 and T2 belong to a free module over a
576
+ # path algebra (but not to the path algebra itself). Hence, this function
577
+ # implements multiplication of a term in a path algebra, and the action
578
+ # of a term of a path algebra on a term in a free module.
579
+ cdef path_term_t *term_mul_term(path_term_t *T1, path_term_t *T2) except NULL:
580
+ cdef mp_size_t new_l_len
581
+ cdef long new_pos
582
+ cdef mp_size_t new_s_len
583
+ if T1.mon.pos!=-1:
584
+ if T2.mon.pos!=-1:
585
+ raise ValueError("we cannot multiply two module elements")
586
+ new_l_len = T1.mon.l_len
587
+ new_pos = T1.mon.pos
588
+ new_s_len = T1.mon.s_len
589
+ elif T2.mon.pos!=-1:
590
+ new_l_len = T2.mon.l_len+T1.mon.path.length
591
+ new_pos = T2.mon.pos
592
+ new_s_len = T2.mon.s_len
593
+ else:
594
+ new_l_len = 0
595
+ new_pos = -1
596
+ new_s_len = 0
597
+ cdef object new_coef = (<object>T1.coef)*(<object>T2.coef)
598
+
599
+ cdef path_term_t *out
600
+ if likely(freelist.used > 0):
601
+ out = freelist.pool[predec(freelist.used)]
602
+ if new_coef:
603
+ out.coef = <PyObject*>(new_coef)
604
+ Py_INCREF(new_coef)
605
+ biseq_dealloc(out.mon.path)
606
+ biseq_init_concat(out.mon.path, T1.mon.path, T2.mon.path)
607
+ else:
608
+ out.coef = NULL
609
+ else:
610
+ out = <path_term_t*>check_malloc(sizeof(path_term_t))
611
+ if new_coef:
612
+ out.coef = <PyObject*>(new_coef)
613
+ Py_INCREF(new_coef)
614
+ biseq_init_concat(out.mon.path, T1.mon.path, T2.mon.path)
615
+ else:
616
+ out.coef = NULL
617
+ out.mon.pos = new_pos
618
+ out.mon.l_len = new_l_len
619
+ out.mon.s_len = new_s_len
620
+ out.nxt = NULL
621
+ return out
622
+
623
+ ########################################
624
+ #
625
+ # Basics for polynomials
626
+
627
+ # Create an empty polynomial
628
+ cdef inline path_poly_t *poly_create() except NULL:
629
+ cdef path_poly_t *out = <path_poly_t*>check_malloc(sizeof(path_poly_t))
630
+ out.lead = NULL
631
+ out.nterms = 0
632
+ return out
633
+
634
+ # Deallocate all terms of the polynomial, but NOT the polynomial itself
635
+ cdef inline void poly_dealloc(path_poly_t *P) noexcept:
636
+ cdef path_term_t *T = P.lead
637
+ while T!=NULL:
638
+ T = term_free(T)
639
+
640
+ # Deallocate all terms of the polynomial, and free the chunk of memory
641
+ # used by the polynomial.
642
+ cdef inline void poly_free(path_poly_t *P) noexcept:
643
+ poly_dealloc(P)
644
+ sig_free(P)
645
+
646
+ # Fill "out" with a copy of the terms of P. Note that previous contents
647
+ # of "out" will NOT be freed---this function should thus only be called
648
+ # when "out" is empty.
649
+ cdef inline bint poly_icopy(path_poly_t *out, path_poly_t *P) except -1:
650
+ cdef path_term_t *T = P.lead
651
+ out.nterms = P.nterms
652
+ out.lead = term_copy_recursive(T)
653
+ return True
654
+
655
+ # Fill "out" with a copy of the terms of -P. Note that previous contents
656
+ # of "out" will NOT be freed---this function should thus only be called
657
+ # when "out" is empty.
658
+ cdef inline bint poly_icopy_neg(path_poly_t *out, path_poly_t *P) except -1:
659
+ cdef path_term_t *T = P.lead
660
+ out.nterms = P.nterms
661
+ out.lead = term_neg_recursive(T)
662
+ return True
663
+
664
+ # Fill "out" with a copy of the terms of coef*P. Note that previous contents
665
+ # of "out" will NOT be freed---this function should thus only be called
666
+ # when "out" is empty.
667
+ cdef bint poly_icopy_scale(path_poly_t *out, path_poly_t *P, object coef) except -1:
668
+ cdef path_term_t *T = P.lead
669
+ cdef path_term_t *res = term_scale(T, coef)
670
+ out.nterms = 0
671
+ out.lead = NULL
672
+ while res.coef == NULL:
673
+ sig_check()
674
+ sig_free(res)
675
+ T = T.nxt
676
+ if T == NULL:
677
+ return True
678
+ res = term_scale(T, coef)
679
+ out.lead = res
680
+ out.nterms += 1
681
+ T = T.nxt
682
+ while T != NULL:
683
+ sig_check()
684
+ res.nxt = term_scale(T, coef)
685
+ if res.nxt.coef == NULL:
686
+ sig_free(res.nxt)
687
+ else:
688
+ res = res.nxt
689
+ out.nterms += 1
690
+ T = T.nxt
691
+ if res != NULL:
692
+ res.nxt = NULL
693
+ return True
694
+
695
+ # Linearisation of a path polynomials
696
+ cdef list poly_pickle(path_poly_t *P):
697
+ cdef list L = []
698
+ cdef path_term_t *T = P.lead
699
+ while T != NULL:
700
+ L.append(term_pickle(T))
701
+ T = T.nxt
702
+ return L
703
+
704
+ # De-linearisation
705
+ cdef bint poly_inplace_unpickle(path_poly_t *P, list data) except -1:
706
+ cdef tuple term_data
707
+ cdef object coef
708
+ cdef path_term_t *T
709
+ if not data:
710
+ P.nterms = 0
711
+ P.lead = NULL
712
+ return True
713
+ P.nterms = len(data)
714
+ coef, term_data = data.pop(0)
715
+ P.lead = term_unpickle(coef, term_data)
716
+ T = P.lead
717
+ for coef, term_data in data:
718
+ T.nxt = term_unpickle(coef, term_data)
719
+ T = T.nxt
720
+ T.nxt = NULL
721
+ return True
722
+
723
+ ############################################
724
+ #
725
+ # Polynomial arithmetics
726
+
727
+ # Rich comparison of P1 and P2, using the given monomial ordering cmp_terms.
728
+ # Return a boolean.
729
+ cdef bint poly_richcmp(path_poly_t *P1, path_poly_t *P2, path_order_t cmp_terms, int op) noexcept:
730
+ cdef path_term_t *T1 = P1.lead
731
+ cdef path_term_t *T2 = P2.lead
732
+ cdef int c
733
+ cdef object t1
734
+ cdef object t2
735
+ while T1 != NULL and T2 != NULL:
736
+ sig_check()
737
+ c = cmp_terms(T1.mon, T2.mon)
738
+ if c:
739
+ return rich_to_bool(op, c)
740
+
741
+ t1 = <object>T1.coef
742
+ t2 = <object>T2.coef
743
+ if t1 != t2:
744
+ return richcmp_not_equal(t1, t2, op)
745
+ T1 = T1.nxt
746
+ T2 = T2.nxt
747
+ if T1 == NULL:
748
+ if T2 == NULL:
749
+ return rich_to_bool(op, 0)
750
+ return rich_to_bool(op, -1)
751
+ return rich_to_bool(op, 1)
752
+
753
+ # Hash of a polynomial. Probably not a very strong hash.
754
+ cdef inline long poly_hash(path_poly_t *P) noexcept:
755
+ cdef path_term_t *T = P.lead
756
+ cdef long out = 0
757
+ while T != NULL:
758
+ out = out<<7 | (out>>(sizeof(long)-7))
759
+ out += term_hash(T)
760
+ T = T.nxt
761
+ return out
762
+
763
+ # Change T1 inplace to T1+T2.coeff*T1. If the new coefficient is zero,
764
+ # then T1.coef becomes NULL
765
+ cdef inline void term_iadd(path_term_t *T1, path_term_t *T2) noexcept:
766
+ cdef object coef = <object>(T1.coef) + <object>(T2.coef)
767
+ Py_XDECREF(T1.coef)
768
+ if coef:
769
+ Py_INCREF(coef)
770
+ T1.coef = <PyObject*>coef
771
+ else:
772
+ T1.coef = NULL
773
+
774
+ # Change P inplace to P+T. It is assumed that initially the terms of P are
775
+ # decreasingly sorted wrt. cmp_terms, and then it is guaranteed that they
776
+ # are decreasingly sorted wrt. cmp_terms after adding T.
777
+ # The addition is "destructive" for T, which means that one MUST NOT
778
+ # call term_free(T) after the addition!
779
+ cdef bint poly_iadd_term_d(path_poly_t *P, path_term_t *T, path_order_t cmp_terms) except -1:
780
+ if P.lead == NULL:
781
+ P.nterms += 1
782
+ T.nxt = NULL
783
+ P.lead = T
784
+ return True
785
+ cdef path_term_t *tmp = P.lead
786
+ cdef int c
787
+ cdef object coef
788
+ c = cmp_terms(tmp.mon, T.mon)
789
+ if c==-1:
790
+ # The poly's lead term is smaller than T. Hence, we need to prepend
791
+ # it.
792
+ P.nterms += 1
793
+ T.nxt = tmp
794
+ P.lead = T
795
+ return True
796
+ elif c==0:
797
+ sig_on()
798
+ term_iadd(tmp, T)
799
+ term_free(T)
800
+ if tmp.coef==NULL:
801
+ P.nterms -= 1
802
+ P.lead = term_free(tmp)
803
+ elif <object>(tmp.coef)==0:
804
+ sig_off()
805
+ raise RuntimeError("this should never happen")
806
+ sig_off()
807
+ return True
808
+ while True:
809
+ # At this point, we have tmp>T.
810
+ #
811
+ # We need to append the term, or continue until we can
812
+ # insert/append
813
+ sig_check()
814
+ if tmp.nxt == NULL:
815
+ P.nterms += 1
816
+ T.nxt = NULL
817
+ tmp.nxt = T
818
+ return True
819
+ c = cmp_terms(tmp.nxt.mon, T.mon)
820
+ if c==-1:
821
+ P.nterms += 1
822
+ T.nxt = tmp.nxt
823
+ tmp.nxt = T
824
+ return True
825
+ elif c==0:
826
+ term_iadd(tmp.nxt, T)
827
+ term_free(T)
828
+ if tmp.nxt.coef==NULL:
829
+ P.nterms -= 1
830
+ tmp.nxt = term_free(tmp.nxt)
831
+ elif <object>(tmp.coef)==0:
832
+ raise RuntimeError("this should never happen")
833
+ return True
834
+ # otherwise, tmp is still larger than T. Hence, move to the next term
835
+ # of P.
836
+ tmp = tmp.nxt
837
+
838
+ # Change P1 inplace to P1+P2. It is assumed that both P1's and P2's terms
839
+ # are decreasingly sorted wrt. cmp_terms, and after the operation P1's terms
840
+ # will still be decreasingly sorted. After the operation, one MUST NOT
841
+ # call poly_free(P2)!
842
+ cdef bint poly_iadd_d(path_poly_t *P1, path_poly_t *P2, path_order_t cmp_terms) except -1:
843
+ # Terms of P2 will be moved to P1, so that deallocation of P2 will not be
844
+ # needed.
845
+ if P1.lead == NULL:
846
+ P1.lead = P2.lead
847
+ P1.nterms = P2.nterms
848
+ P2.nterms = 0
849
+ P2.lead = NULL
850
+ return 1
851
+ if P2.lead == NULL:
852
+ return 1
853
+ cdef path_term_t *T1 = P1.lead
854
+ cdef path_term_t *T2 = P2.lead
855
+ cdef path_term_t *prev = NULL
856
+ cdef int c
857
+ cdef object new_coef
858
+ while True:
859
+ # Is one of the summands consumed already? Then we can use an easier
860
+ # method.
861
+ sig_check()
862
+ if T1 == NULL:
863
+ if prev==NULL:
864
+ P1.lead = T2
865
+ else:
866
+ prev.nxt = T2
867
+ P1.nterms += P2.nterms
868
+ P2.nterms = 0
869
+ P2.lead = NULL
870
+ return 1
871
+ elif T2 == NULL:
872
+ if P2.nterms != 0:
873
+ print("term counting of second summand was wrong! " +
874
+ str(P2.nterms))
875
+ P2.lead = NULL
876
+ return 1
877
+ c = cmp_terms(T1.mon, T2.mon)
878
+ if c == 0:
879
+ # T1==T2 --- We need to add
880
+ new_coef = <object>(T1.coef)+<object>(T2.coef)
881
+ if new_coef:
882
+ Py_INCREF(new_coef)
883
+ Py_XDECREF(T1.coef)
884
+ T1.coef = <PyObject*>new_coef
885
+ prev = T1
886
+ T1 = T1.nxt
887
+ else:
888
+ T1 = term_free(T1)
889
+ if prev==NULL:
890
+ P1.lead = T1
891
+ else:
892
+ prev.nxt = T1
893
+ P1.nterms -= 1
894
+ P2.nterms -= 1
895
+ T2 = term_free(T2)
896
+ elif c == 1:
897
+ # We move the prev/T1 through P1, until prev>T2>=T1. But now,
898
+ # T1>T2. So, we move prev/T1 further down.
899
+ prev = T1
900
+ T1 = T1.nxt
901
+ else:
902
+ # prev > T2 > T1. Hence, we insert T2, without copying
903
+ if prev==NULL:
904
+ P1.lead = T2
905
+ T2 = T2.nxt
906
+ prev = P1.lead
907
+ else:
908
+ prev.nxt = T2
909
+ T2 = T2.nxt
910
+ prev = prev.nxt
911
+ prev.nxt = T1
912
+ P1.nterms += 1
913
+ P2.nterms -= 1
914
+
915
+ # Return P1+P2 (a new polynomial, and after the operation it is still safe
916
+ # to call poly_free(P2)). Both P1's and P2's terms are supposed to be
917
+ # decreasingly sorted wrt. cmp_terms, and so will be the terms of P1+P2.
918
+ cdef path_poly_t *poly_add(path_poly_t *P1, path_poly_t *P2, path_order_t cmp_terms) except NULL:
919
+ cdef path_poly_t *out = poly_create()
920
+ cdef path_term_t *T1 = P1.lead
921
+ cdef path_term_t *T2 = P2.lead
922
+ cdef path_term_t *T = NULL
923
+ cdef path_term_t *res
924
+ cdef size_t count1, count2 # How many terms of P1/P2 have been considered?
925
+ count1 = 0
926
+ count2 = 0
927
+ cdef object coef
928
+ cdef int c
929
+ while True:
930
+ sig_check()
931
+ if T1 == NULL:
932
+ out.nterms += (P2.nterms-count2)
933
+ if T == NULL:
934
+ if T2 == NULL:
935
+ out.lead = NULL
936
+ else:
937
+ out.lead = term_copy_recursive(T2)
938
+ else:
939
+ if T2 == NULL:
940
+ T.nxt = NULL
941
+ else:
942
+ T.nxt = term_copy_recursive(T2)
943
+ return out
944
+ if T2 == NULL:
945
+ out.nterms += (P1.nterms-count1)
946
+ if T == NULL:
947
+ out.lead = term_copy_recursive(T1)
948
+ else:
949
+ T.nxt = term_copy_recursive(T1)
950
+ return out
951
+
952
+ c = cmp_terms(T1.mon, T2.mon)
953
+ if c == 1:
954
+ if T == NULL:
955
+ out.lead = term_copy(T1)
956
+ T = out.lead
957
+ else:
958
+ T.nxt = term_copy(T1)
959
+ T = T.nxt
960
+ T1 = T1.nxt
961
+ count1 += 1
962
+ out.nterms += 1
963
+ elif c == -1:
964
+ if T == NULL:
965
+ out.lead = term_copy(T2)
966
+ T = out.lead
967
+ else:
968
+ T.nxt = term_copy(T2)
969
+ T = T.nxt
970
+ T2 = T2.nxt
971
+ count2 += 1
972
+ out.nterms += 1
973
+ else:
974
+ coef = (<object>T1.coef)+(<object>T2.coef)
975
+ if coef:
976
+ out.nterms += 1
977
+ if T == NULL:
978
+ out.lead = term_create(coef, T1.mon.path, T1.mon.pos, T1.mon.l_len, T1.mon.s_len)
979
+ T = out.lead
980
+ else:
981
+ T.nxt = term_create(coef, T1.mon.path, T1.mon.pos, T1.mon.l_len, T1.mon.s_len)
982
+ T = T.nxt
983
+ count1 += 1
984
+ count2 += 1
985
+ T1 = T1.nxt
986
+ T2 = T2.nxt
987
+
988
+ # Return P1-P2 (a new polynomial, and after the operation it is still safe
989
+ # to call poly_free(P2)). Both P1's and P2's terms are supposed to be
990
+ # decreasingly sorted wrt. cmp_terms, and so will be the terms of P1-P2.
991
+ cdef path_poly_t *poly_sub(path_poly_t *P1, path_poly_t *P2, path_order_t cmp_terms) except NULL:
992
+ cdef path_poly_t *out = poly_create()
993
+ cdef path_term_t *T1 = P1.lead
994
+ cdef path_term_t *T2 = P2.lead
995
+ cdef path_term_t *T = NULL
996
+ cdef path_term_t *res
997
+ cdef size_t count1, count2 # How many terms of P1/P2 have been considered?
998
+ count1 = 0
999
+ count2 = 0
1000
+ cdef object coef
1001
+ cdef int c
1002
+ while True:
1003
+ sig_check()
1004
+ if T1 == NULL:
1005
+ out.nterms += (P2.nterms-count2)
1006
+ if T == NULL:
1007
+ if T2 == NULL:
1008
+ out.lead = NULL
1009
+ else:
1010
+ out.lead = term_neg_recursive(T2)
1011
+ else:
1012
+ if T2 == NULL:
1013
+ T.nxt = NULL
1014
+ else:
1015
+ T.nxt = term_neg_recursive(T2)
1016
+ return out
1017
+ if T2 == NULL:
1018
+ out.nterms += (P1.nterms-count1)
1019
+ if T == NULL:
1020
+ out.lead = term_copy_recursive(T1)
1021
+ else:
1022
+ T.nxt = term_copy_recursive(T1)
1023
+ return out
1024
+
1025
+ c = cmp_terms(T1.mon, T2.mon)
1026
+ if c == 1:
1027
+ if T == NULL:
1028
+ out.lead = term_copy(T1)
1029
+ T = out.lead
1030
+ else:
1031
+ T.nxt = term_copy(T1)
1032
+ T = T.nxt
1033
+ T1 = T1.nxt
1034
+ count1 += 1
1035
+ out.nterms += 1
1036
+ elif c == -1:
1037
+ if T == NULL:
1038
+ out.lead = term_neg(T2)
1039
+ T = out.lead
1040
+ else:
1041
+ T.nxt = term_neg(T2)
1042
+ T = T.nxt
1043
+ T2 = T2.nxt
1044
+ count2 += 1
1045
+ out.nterms += 1
1046
+ else:
1047
+ coef = (<object>T1.coef)-(<object>T2.coef)
1048
+ if coef:
1049
+ out.nterms += 1
1050
+ if T == NULL:
1051
+ out.lead = term_create(coef, T1.mon.path, T1.mon.pos, T1.mon.l_len, T1.mon.s_len)
1052
+ T = out.lead
1053
+ else:
1054
+ T.nxt = term_create(coef, T1.mon.path, T1.mon.pos, T1.mon.l_len, T1.mon.s_len)
1055
+ T = T.nxt
1056
+ count1 += 1
1057
+ count2 += 1
1058
+ T1 = T1.nxt
1059
+ T2 = T2.nxt
1060
+
1061
+ #
1062
+ # In-place addition of a multiple of a polynomial
1063
+ # Replace P1 by P1+coef*P2*R. Return a pointer to the first term of P1
1064
+ # that may be involved in a change when calling the function again with
1065
+ # P1, P2 and a cofactor that is smaller than R wrt. cmp_terms.
1066
+ # The return value should then be provided as argument "P1start" of the
1067
+ # next function call.
1068
+ #
1069
+ # We return P1start if P2.lead is NULL. Otherwise, if P1.lead becomes NULL
1070
+ # during addition, then we return P2.lead.
1071
+ #
1072
+ # Let m be a monomial of P2. If it is of module-type (i.e., m.pos!=-1),
1073
+ # then it is clear what m2=m*R is (m2.l_len and m2.s_len are obtained from
1074
+ # m.l_len and m.s_len). Otherwise, however, it could be that we
1075
+ # want m2=m*R to denote a module-type monomial. In that case, "m2.l_len"
1076
+ # and "m2.s_len" are given by the respective arguments.
1077
+
1078
+ cdef path_term_t *poly_iadd_lmul(path_poly_t *P1, object coef, path_poly_t *P2, biseq_t R, path_order_t cmp_terms, long pos, mp_size_t l_len, mp_size_t s_len, path_term_t *P1start) except NULL:
1079
+ if not coef or P2.lead==NULL:
1080
+ return P1start
1081
+ cdef path_mon_t new_mon
1082
+ cdef object new_coef
1083
+ cdef path_term_t *prev = NULL
1084
+ cdef path_term_t *T1
1085
+ if P1start == NULL:
1086
+ T1 = P1.lead
1087
+ else:
1088
+ T1 = P1start
1089
+ cdef path_term_t *T2 = P2.lead
1090
+ cdef int c
1091
+ cdef path_term_t *out = P1start
1092
+ while T2!=NULL:
1093
+ sig_check()
1094
+ new_coef = coef*<object>(T2.coef)
1095
+ if not new_coef:
1096
+ T2 = T2.nxt
1097
+ continue
1098
+
1099
+ if T2.mon.pos!=-1:
1100
+ mon_mul_path(new_mon, T2.mon, R)
1101
+ new_mon.pos = T2.mon.pos
1102
+ new_mon.l_len = T2.mon.l_len
1103
+ new_mon.s_len = T2.mon.s_len
1104
+ else:
1105
+ mon_mul_path(new_mon, T2.mon, R)
1106
+ new_mon.pos = pos
1107
+ new_mon.l_len = l_len
1108
+ new_mon.s_len = s_len
1109
+ # Now new_term is T2*R
1110
+ # We go down in P1 until we may append, insert or add
1111
+ while T1!=NULL:
1112
+ sig_check()
1113
+ c = cmp_terms(T1.mon, new_mon)
1114
+ if c!=1:
1115
+ break
1116
+ prev = T1
1117
+ T1 = prev.nxt
1118
+ if T1==NULL:
1119
+ # We need to append to P1
1120
+ if prev==NULL:
1121
+ P1.lead = term_create_blank(new_coef)
1122
+ P1.lead.mon[0] = new_mon[0]
1123
+ prev = P1.lead
1124
+ else:
1125
+ prev.nxt = term_create_blank(new_coef)
1126
+ prev.nxt.mon[0] = new_mon[0]
1127
+ prev = prev.nxt
1128
+ if T2 == P2.lead:
1129
+ out = prev
1130
+ prev.nxt = NULL
1131
+ P1.nterms += 1
1132
+ elif c==-1:
1133
+ # We need to insert between prev and T1
1134
+ if prev==NULL:
1135
+ P1.lead = term_create_blank(new_coef)
1136
+ P1.lead.mon[0] = new_mon[0]
1137
+ prev = P1.lead
1138
+ else:
1139
+ prev.nxt = term_create_blank(new_coef)
1140
+ prev.nxt.mon[0] = new_mon[0]
1141
+ prev = prev.nxt
1142
+ if T2 == P2.lead:
1143
+ out = prev
1144
+ prev.nxt = T1
1145
+ P1.nterms += 1
1146
+ else:
1147
+ # we add the coefficients and see what happens
1148
+ new_coef+=<object>(T1.coef)
1149
+ mon_free(new_mon)
1150
+ if new_coef:
1151
+ Py_INCREF(new_coef)
1152
+ Py_XDECREF(T1.coef)
1153
+ T1.coef = <PyObject*>new_coef
1154
+ if T2 == P2.lead:
1155
+ out = T1
1156
+ prev = T1
1157
+ T1 = T1.nxt
1158
+ else:
1159
+ P1.nterms -= 1
1160
+ T1 = term_free(T1)
1161
+ if prev==NULL:
1162
+ P1.lead = T1
1163
+ else:
1164
+ prev.nxt = T1
1165
+ if T2 == P2.lead:
1166
+ out = prev
1167
+ T2 = T2.nxt
1168
+ if out == NULL:
1169
+ return P2.lead
1170
+ return out
1171
+
1172
+ ########################################
1173
+ #
1174
+ # Basics for homogeneous polynomials
1175
+
1176
+ # Create an empty polynomial whose to-be-inserted terms
1177
+ # have start- and end-points of the given integer labels
1178
+ # start and end.
1179
+ cdef path_homog_poly_t *homog_poly_create(int start, int end) except NULL:
1180
+ cdef path_homog_poly_t *out = <path_homog_poly_t*>check_malloc(sizeof(path_homog_poly_t))
1181
+ out.poly = poly_create()
1182
+ out.start = start
1183
+ out.end = end
1184
+ out.nxt = NULL
1185
+ return out
1186
+
1187
+ # Create a new homogeneous polynomial from a given polynomial P.
1188
+ # It is assumed that all terms of P have start- and end-points
1189
+ # with integer labels start and end. This assumption is NOT checked!
1190
+ # P is inserted, not copied.
1191
+ cdef path_homog_poly_t *homog_poly_init_poly(int start, int end, path_poly_t *P) except NULL:
1192
+ cdef path_homog_poly_t *out = <path_homog_poly_t*>check_malloc(sizeof(path_homog_poly_t))
1193
+ out.poly = P
1194
+ out.start = start
1195
+ out.end = end
1196
+ out.nxt = NULL
1197
+ return out
1198
+
1199
+ # L provides a list of pairs (P,coef), where P is a path
1200
+ # and coef the coefficient of the corresponding term.
1201
+ # With this function, one can create elements of a path algebra (pos==-1),
1202
+ # or elements of free modules over a path algebra in summand pos.
1203
+ # In either case, the length of left cofactors of each monomial will
1204
+ # be zero, and also the length of Schreyer monomials will be zero.
1205
+ cdef path_homog_poly_t *homog_poly_init_list(int start, int end, list L, path_order_t cmp_terms, long pos) except NULL:
1206
+ cdef path_homog_poly_t * out = homog_poly_create(start, end)
1207
+ cdef QuiverPath P
1208
+ for P, coef in L:
1209
+ poly_iadd_term_d(out.poly, term_create(coef, P._path, pos, 0, 0), cmp_terms)
1210
+ return out
1211
+
1212
+ cdef void homog_poly_free(path_homog_poly_t *P) noexcept:
1213
+ cdef path_homog_poly_t *nxt
1214
+ while P!=NULL:
1215
+ nxt = P.nxt
1216
+ poly_free(P.poly)
1217
+ sig_free(P)
1218
+ P = nxt
1219
+
1220
+ # Return a copy of H
1221
+ cdef path_homog_poly_t *homog_poly_copy(path_homog_poly_t *H) except NULL:
1222
+ cdef path_homog_poly_t *out
1223
+ cdef path_homog_poly_t *tmp
1224
+ if H == NULL:
1225
+ raise ValueError("the polynomial to be copied is the NULL pointer")
1226
+ out = homog_poly_create(H.start, H.end)
1227
+ poly_icopy(out.poly, H.poly)
1228
+ tmp = out
1229
+ H = H.nxt
1230
+ while H != NULL:
1231
+ sig_check()
1232
+ tmp.nxt = homog_poly_create(H.start, H.end)
1233
+ tmp = tmp.nxt
1234
+ poly_icopy(tmp.poly, H.poly)
1235
+ H = H.nxt
1236
+ return out
1237
+
1238
+ # Linearisation
1239
+ cdef list homog_poly_pickle(path_homog_poly_t *H):
1240
+ cdef list L = []
1241
+ while H != NULL:
1242
+ L.append((H.start, H.end, poly_pickle(H.poly)))
1243
+ H = H.nxt
1244
+ return L
1245
+
1246
+ # De-linearisation
1247
+ cdef path_homog_poly_t *homog_poly_unpickle(list data) except NULL:
1248
+ # ASSUMPTION: data is not empty
1249
+ cdef int start, end
1250
+ cdef list poly_data
1251
+ cdef path_homog_poly_t *out
1252
+ start, end, poly_data = data.pop(0)
1253
+ out = homog_poly_create(start, end)
1254
+ poly_inplace_unpickle(out.poly, poly_data)
1255
+ cdef path_homog_poly_t *tmp = out
1256
+ for start, end, poly_data in data:
1257
+ sig_check()
1258
+ tmp.nxt = homog_poly_create(start, end)
1259
+ tmp = tmp.nxt
1260
+ poly_inplace_unpickle(tmp.poly, poly_data)
1261
+ return out
1262
+
1263
+ # Return -H
1264
+ cdef path_homog_poly_t *homog_poly_neg(path_homog_poly_t *H) except NULL:
1265
+ cdef path_homog_poly_t *out
1266
+ cdef path_homog_poly_t *tmp
1267
+ if H == NULL:
1268
+ raise ValueError("the polynomial to be copied is the NULL pointer")
1269
+ out = homog_poly_create(H.start, H.end)
1270
+ poly_icopy_neg(out.poly, H.poly)
1271
+ tmp = out
1272
+ H = H.nxt
1273
+ while H != NULL:
1274
+ sig_check()
1275
+ tmp.nxt = homog_poly_create(H.start, H.end)
1276
+ tmp = tmp.nxt
1277
+ poly_icopy_neg(tmp.poly, H.poly)
1278
+ H = H.nxt
1279
+ return out
1280
+
1281
+ # Return coef*H
1282
+ cdef path_homog_poly_t *homog_poly_scale(path_homog_poly_t *H, object coef) except NULL:
1283
+ # The first component may be zero, all other zero components are removed.
1284
+ cdef path_homog_poly_t *out
1285
+ cdef path_homog_poly_t *tmp
1286
+ if H == NULL:
1287
+ raise ValueError("the polynomial to be copied is the NULL pointer")
1288
+ out = homog_poly_create(H.start, H.end)
1289
+ poly_icopy_scale(out.poly, H.poly, coef)
1290
+ tmp = out
1291
+ H = H.nxt
1292
+ while H != NULL:
1293
+ sig_check()
1294
+ tmp.nxt = homog_poly_create(H.start, H.end)
1295
+ poly_icopy_scale(tmp.nxt.poly, H.poly, coef)
1296
+ if tmp.nxt.poly.nterms == 0:
1297
+ homog_poly_free(tmp.nxt)
1298
+ tmp.nxt = NULL
1299
+ else:
1300
+ tmp = tmp.nxt
1301
+ H = H.nxt
1302
+ return out
1303
+
1304
+ cdef path_homog_poly_t *homog_poly_get_predecessor_of_component(path_homog_poly_t *H, int s, int e) noexcept:
1305
+ # Search through H.nxt.nxt... and return the pointer C to a component of H
1306
+ # such that either C.nxt.start==s and C.nxt.end==e, or the component for
1307
+ # (s,e) should be inserted between C and C.nxt. Return NULL if H==NULL or
1308
+ # (s,e) should be inserted in front of H.
1309
+ if H == NULL:
1310
+ return NULL
1311
+ if H.start > s:
1312
+ return NULL
1313
+ elif H.start == s and H.end >= e:
1314
+ return NULL
1315
+ while True:
1316
+ sig_check()
1317
+ if H.nxt == NULL:
1318
+ return H
1319
+ if H.nxt.start == s:
1320
+ if H.nxt.end >= e:
1321
+ return H
1322
+ elif H.nxt.start > s:
1323
+ return H
1324
+ H = H.nxt