passagemath-categories 10.6.32__cp314-cp314t-musllinux_1_2_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.
Files changed (719) hide show
  1. passagemath_categories-10.6.32.dist-info/METADATA +156 -0
  2. passagemath_categories-10.6.32.dist-info/RECORD +719 -0
  3. passagemath_categories-10.6.32.dist-info/WHEEL +5 -0
  4. passagemath_categories-10.6.32.dist-info/top_level.txt +2 -0
  5. passagemath_categories.libs/libgcc_s-2d945d6c.so.1 +0 -0
  6. passagemath_categories.libs/libgmp-28992bcb.so.10.5.0 +0 -0
  7. passagemath_categories.libs/libstdc++-85f2cd6d.so.6.0.33 +0 -0
  8. sage/all__sagemath_categories.py +28 -0
  9. sage/arith/all.py +38 -0
  10. sage/arith/constants.pxd +27 -0
  11. sage/arith/functions.cpython-314t-aarch64-linux-musl.so +0 -0
  12. sage/arith/functions.pxd +4 -0
  13. sage/arith/functions.pyx +221 -0
  14. sage/arith/misc.py +6552 -0
  15. sage/arith/multi_modular.cpython-314t-aarch64-linux-musl.so +0 -0
  16. sage/arith/multi_modular.pxd +39 -0
  17. sage/arith/multi_modular.pyx +994 -0
  18. sage/arith/rational_reconstruction.cpython-314t-aarch64-linux-musl.so +0 -0
  19. sage/arith/rational_reconstruction.pxd +4 -0
  20. sage/arith/rational_reconstruction.pyx +115 -0
  21. sage/arith/srange.cpython-314t-aarch64-linux-musl.so +0 -0
  22. sage/arith/srange.pyx +571 -0
  23. sage/calculus/all__sagemath_categories.py +2 -0
  24. sage/calculus/functional.py +481 -0
  25. sage/calculus/functions.py +151 -0
  26. sage/categories/additive_groups.py +73 -0
  27. sage/categories/additive_magmas.py +1044 -0
  28. sage/categories/additive_monoids.py +114 -0
  29. sage/categories/additive_semigroups.py +184 -0
  30. sage/categories/affine_weyl_groups.py +238 -0
  31. sage/categories/algebra_ideals.py +95 -0
  32. sage/categories/algebra_modules.py +96 -0
  33. sage/categories/algebras.py +349 -0
  34. sage/categories/algebras_with_basis.py +377 -0
  35. sage/categories/all.py +160 -0
  36. sage/categories/aperiodic_semigroups.py +29 -0
  37. sage/categories/associative_algebras.py +47 -0
  38. sage/categories/bialgebras.py +101 -0
  39. sage/categories/bialgebras_with_basis.py +414 -0
  40. sage/categories/bimodules.py +206 -0
  41. sage/categories/chain_complexes.py +268 -0
  42. sage/categories/classical_crystals.py +480 -0
  43. sage/categories/coalgebras.py +405 -0
  44. sage/categories/coalgebras_with_basis.py +232 -0
  45. sage/categories/coercion_methods.cpython-314t-aarch64-linux-musl.so +0 -0
  46. sage/categories/coercion_methods.pyx +52 -0
  47. sage/categories/commutative_additive_groups.py +104 -0
  48. sage/categories/commutative_additive_monoids.py +45 -0
  49. sage/categories/commutative_additive_semigroups.py +48 -0
  50. sage/categories/commutative_algebra_ideals.py +87 -0
  51. sage/categories/commutative_algebras.py +94 -0
  52. sage/categories/commutative_ring_ideals.py +58 -0
  53. sage/categories/commutative_rings.py +736 -0
  54. sage/categories/complete_discrete_valuation.py +293 -0
  55. sage/categories/complex_reflection_groups.py +145 -0
  56. sage/categories/complex_reflection_or_generalized_coxeter_groups.py +1249 -0
  57. sage/categories/coxeter_group_algebras.py +186 -0
  58. sage/categories/coxeter_groups.py +3402 -0
  59. sage/categories/crystals.py +2628 -0
  60. sage/categories/cw_complexes.py +216 -0
  61. sage/categories/dedekind_domains.py +137 -0
  62. sage/categories/discrete_valuation.py +325 -0
  63. sage/categories/distributive_magmas_and_additive_magmas.py +100 -0
  64. sage/categories/division_rings.py +114 -0
  65. sage/categories/domains.py +95 -0
  66. sage/categories/drinfeld_modules.py +789 -0
  67. sage/categories/dual.py +42 -0
  68. sage/categories/enumerated_sets.py +1146 -0
  69. sage/categories/euclidean_domains.py +271 -0
  70. sage/categories/examples/algebras_with_basis.py +102 -0
  71. sage/categories/examples/all.py +1 -0
  72. sage/categories/examples/commutative_additive_monoids.py +130 -0
  73. sage/categories/examples/commutative_additive_semigroups.py +199 -0
  74. sage/categories/examples/coxeter_groups.py +8 -0
  75. sage/categories/examples/crystals.py +236 -0
  76. sage/categories/examples/cw_complexes.py +163 -0
  77. sage/categories/examples/facade_sets.py +187 -0
  78. sage/categories/examples/filtered_algebras_with_basis.py +204 -0
  79. sage/categories/examples/filtered_modules_with_basis.py +154 -0
  80. sage/categories/examples/finite_coxeter_groups.py +252 -0
  81. sage/categories/examples/finite_dimensional_algebras_with_basis.py +148 -0
  82. sage/categories/examples/finite_dimensional_lie_algebras_with_basis.py +495 -0
  83. sage/categories/examples/finite_enumerated_sets.py +208 -0
  84. sage/categories/examples/finite_monoids.py +150 -0
  85. sage/categories/examples/finite_semigroups.py +190 -0
  86. sage/categories/examples/finite_weyl_groups.py +191 -0
  87. sage/categories/examples/graded_connected_hopf_algebras_with_basis.py +152 -0
  88. sage/categories/examples/graded_modules_with_basis.py +168 -0
  89. sage/categories/examples/graphs.py +122 -0
  90. sage/categories/examples/hopf_algebras_with_basis.py +145 -0
  91. sage/categories/examples/infinite_enumerated_sets.py +190 -0
  92. sage/categories/examples/lie_algebras.py +352 -0
  93. sage/categories/examples/lie_algebras_with_basis.py +196 -0
  94. sage/categories/examples/magmas.py +162 -0
  95. sage/categories/examples/manifolds.py +94 -0
  96. sage/categories/examples/monoids.py +144 -0
  97. sage/categories/examples/posets.py +178 -0
  98. sage/categories/examples/semigroups.py +580 -0
  99. sage/categories/examples/semigroups_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  100. sage/categories/examples/semigroups_cython.pyx +221 -0
  101. sage/categories/examples/semirings.py +249 -0
  102. sage/categories/examples/sets_cat.py +706 -0
  103. sage/categories/examples/sets_with_grading.py +101 -0
  104. sage/categories/examples/with_realizations.py +542 -0
  105. sage/categories/fields.py +991 -0
  106. sage/categories/filtered_algebras.py +63 -0
  107. sage/categories/filtered_algebras_with_basis.py +548 -0
  108. sage/categories/filtered_hopf_algebras_with_basis.py +138 -0
  109. sage/categories/filtered_modules.py +210 -0
  110. sage/categories/filtered_modules_with_basis.py +1209 -0
  111. sage/categories/finite_complex_reflection_groups.py +1506 -0
  112. sage/categories/finite_coxeter_groups.py +1138 -0
  113. sage/categories/finite_crystals.py +103 -0
  114. sage/categories/finite_dimensional_algebras_with_basis.py +1860 -0
  115. sage/categories/finite_dimensional_bialgebras_with_basis.py +33 -0
  116. sage/categories/finite_dimensional_coalgebras_with_basis.py +33 -0
  117. sage/categories/finite_dimensional_graded_lie_algebras_with_basis.py +231 -0
  118. sage/categories/finite_dimensional_hopf_algebras_with_basis.py +38 -0
  119. sage/categories/finite_dimensional_lie_algebras_with_basis.py +2774 -0
  120. sage/categories/finite_dimensional_modules_with_basis.py +1407 -0
  121. sage/categories/finite_dimensional_nilpotent_lie_algebras_with_basis.py +167 -0
  122. sage/categories/finite_dimensional_semisimple_algebras_with_basis.py +270 -0
  123. sage/categories/finite_enumerated_sets.py +769 -0
  124. sage/categories/finite_fields.py +252 -0
  125. sage/categories/finite_groups.py +256 -0
  126. sage/categories/finite_lattice_posets.py +242 -0
  127. sage/categories/finite_monoids.py +316 -0
  128. sage/categories/finite_permutation_groups.py +339 -0
  129. sage/categories/finite_posets.py +1994 -0
  130. sage/categories/finite_semigroups.py +136 -0
  131. sage/categories/finite_sets.py +93 -0
  132. sage/categories/finite_weyl_groups.py +39 -0
  133. sage/categories/finitely_generated_lambda_bracket_algebras.py +112 -0
  134. sage/categories/finitely_generated_lie_conformal_algebras.py +114 -0
  135. sage/categories/finitely_generated_magmas.py +57 -0
  136. sage/categories/finitely_generated_semigroups.py +214 -0
  137. sage/categories/function_fields.py +76 -0
  138. sage/categories/g_sets.py +77 -0
  139. sage/categories/gcd_domains.py +65 -0
  140. sage/categories/generalized_coxeter_groups.py +94 -0
  141. sage/categories/graded_algebras.py +85 -0
  142. sage/categories/graded_algebras_with_basis.py +258 -0
  143. sage/categories/graded_bialgebras.py +32 -0
  144. sage/categories/graded_bialgebras_with_basis.py +32 -0
  145. sage/categories/graded_coalgebras.py +65 -0
  146. sage/categories/graded_coalgebras_with_basis.py +51 -0
  147. sage/categories/graded_hopf_algebras.py +41 -0
  148. sage/categories/graded_hopf_algebras_with_basis.py +169 -0
  149. sage/categories/graded_lie_algebras.py +91 -0
  150. sage/categories/graded_lie_algebras_with_basis.py +44 -0
  151. sage/categories/graded_lie_conformal_algebras.py +74 -0
  152. sage/categories/graded_modules.py +133 -0
  153. sage/categories/graded_modules_with_basis.py +329 -0
  154. sage/categories/graphs.py +138 -0
  155. sage/categories/group_algebras.py +430 -0
  156. sage/categories/groupoid.py +94 -0
  157. sage/categories/groups.py +667 -0
  158. sage/categories/h_trivial_semigroups.py +64 -0
  159. sage/categories/hecke_modules.py +185 -0
  160. sage/categories/highest_weight_crystals.py +980 -0
  161. sage/categories/hopf_algebras.py +219 -0
  162. sage/categories/hopf_algebras_with_basis.py +309 -0
  163. sage/categories/infinite_enumerated_sets.py +115 -0
  164. sage/categories/integral_domains.py +203 -0
  165. sage/categories/j_trivial_semigroups.py +29 -0
  166. sage/categories/kac_moody_algebras.py +82 -0
  167. sage/categories/kahler_algebras.py +203 -0
  168. sage/categories/l_trivial_semigroups.py +63 -0
  169. sage/categories/lambda_bracket_algebras.py +280 -0
  170. sage/categories/lambda_bracket_algebras_with_basis.py +107 -0
  171. sage/categories/lattice_posets.py +89 -0
  172. sage/categories/left_modules.py +49 -0
  173. sage/categories/lie_algebras.py +1070 -0
  174. sage/categories/lie_algebras_with_basis.py +261 -0
  175. sage/categories/lie_conformal_algebras.py +350 -0
  176. sage/categories/lie_conformal_algebras_with_basis.py +147 -0
  177. sage/categories/lie_groups.py +73 -0
  178. sage/categories/loop_crystals.py +1290 -0
  179. sage/categories/magmas.py +1189 -0
  180. sage/categories/magmas_and_additive_magmas.py +149 -0
  181. sage/categories/magmatic_algebras.py +365 -0
  182. sage/categories/manifolds.py +352 -0
  183. sage/categories/matrix_algebras.py +40 -0
  184. sage/categories/metric_spaces.py +387 -0
  185. sage/categories/modular_abelian_varieties.py +78 -0
  186. sage/categories/modules.py +989 -0
  187. sage/categories/modules_with_basis.py +2794 -0
  188. sage/categories/monoid_algebras.py +38 -0
  189. sage/categories/monoids.py +739 -0
  190. sage/categories/noetherian_rings.py +87 -0
  191. sage/categories/number_fields.py +242 -0
  192. sage/categories/ore_modules.py +189 -0
  193. sage/categories/partially_ordered_monoids.py +49 -0
  194. sage/categories/permutation_groups.py +63 -0
  195. sage/categories/pointed_sets.py +42 -0
  196. sage/categories/polyhedra.py +74 -0
  197. sage/categories/poor_man_map.py +270 -0
  198. sage/categories/posets.py +722 -0
  199. sage/categories/principal_ideal_domains.py +270 -0
  200. sage/categories/quantum_group_representations.py +543 -0
  201. sage/categories/quotient_fields.py +728 -0
  202. sage/categories/r_trivial_semigroups.py +45 -0
  203. sage/categories/regular_crystals.py +898 -0
  204. sage/categories/regular_supercrystals.py +170 -0
  205. sage/categories/right_modules.py +49 -0
  206. sage/categories/ring_ideals.py +74 -0
  207. sage/categories/rings.py +1904 -0
  208. sage/categories/rngs.py +175 -0
  209. sage/categories/schemes.py +393 -0
  210. sage/categories/semigroups.py +1060 -0
  211. sage/categories/semirings.py +71 -0
  212. sage/categories/semisimple_algebras.py +114 -0
  213. sage/categories/sets_with_grading.py +235 -0
  214. sage/categories/shephard_groups.py +43 -0
  215. sage/categories/signed_tensor.py +120 -0
  216. sage/categories/simplicial_complexes.py +134 -0
  217. sage/categories/simplicial_sets.py +1206 -0
  218. sage/categories/super_algebras.py +149 -0
  219. sage/categories/super_algebras_with_basis.py +144 -0
  220. sage/categories/super_hopf_algebras_with_basis.py +126 -0
  221. sage/categories/super_lie_conformal_algebras.py +193 -0
  222. sage/categories/super_modules.py +229 -0
  223. sage/categories/super_modules_with_basis.py +193 -0
  224. sage/categories/supercommutative_algebras.py +99 -0
  225. sage/categories/supercrystals.py +406 -0
  226. sage/categories/tensor.py +110 -0
  227. sage/categories/topological_spaces.py +170 -0
  228. sage/categories/triangular_kac_moody_algebras.py +439 -0
  229. sage/categories/tutorial.py +58 -0
  230. sage/categories/unique_factorization_domains.py +318 -0
  231. sage/categories/unital_algebras.py +426 -0
  232. sage/categories/vector_bundles.py +159 -0
  233. sage/categories/vector_spaces.py +357 -0
  234. sage/categories/weyl_groups.py +853 -0
  235. sage/combinat/all__sagemath_categories.py +34 -0
  236. sage/combinat/backtrack.py +180 -0
  237. sage/combinat/combinat.py +2269 -0
  238. sage/combinat/combinat_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  239. sage/combinat/combinat_cython.pxd +6 -0
  240. sage/combinat/combinat_cython.pyx +390 -0
  241. sage/combinat/combination.py +796 -0
  242. sage/combinat/combinatorial_map.py +416 -0
  243. sage/combinat/composition.py +2192 -0
  244. sage/combinat/dlx.py +510 -0
  245. sage/combinat/integer_lists/__init__.py +7 -0
  246. sage/combinat/integer_lists/base.cpython-314t-aarch64-linux-musl.so +0 -0
  247. sage/combinat/integer_lists/base.pxd +16 -0
  248. sage/combinat/integer_lists/base.pyx +713 -0
  249. sage/combinat/integer_lists/invlex.cpython-314t-aarch64-linux-musl.so +0 -0
  250. sage/combinat/integer_lists/invlex.pxd +4 -0
  251. sage/combinat/integer_lists/invlex.pyx +1650 -0
  252. sage/combinat/integer_lists/lists.py +328 -0
  253. sage/combinat/integer_lists/nn.py +48 -0
  254. sage/combinat/integer_vector.py +1818 -0
  255. sage/combinat/integer_vector_weighted.py +413 -0
  256. sage/combinat/matrices/all__sagemath_categories.py +5 -0
  257. sage/combinat/matrices/dancing_links.cpython-314t-aarch64-linux-musl.so +0 -0
  258. sage/combinat/matrices/dancing_links.pyx +1159 -0
  259. sage/combinat/matrices/dancing_links_c.h +380 -0
  260. sage/combinat/matrices/dlxcpp.py +136 -0
  261. sage/combinat/partition.py +10070 -0
  262. sage/combinat/partitions.cpython-314t-aarch64-linux-musl.so +0 -0
  263. sage/combinat/partitions.pyx +743 -0
  264. sage/combinat/permutation.py +10168 -0
  265. sage/combinat/permutation_cython.cpython-314t-aarch64-linux-musl.so +0 -0
  266. sage/combinat/permutation_cython.pxd +11 -0
  267. sage/combinat/permutation_cython.pyx +407 -0
  268. sage/combinat/q_analogues.py +1090 -0
  269. sage/combinat/ranker.py +268 -0
  270. sage/combinat/subset.py +1561 -0
  271. sage/combinat/subsets_hereditary.py +202 -0
  272. sage/combinat/subsets_pairwise.py +184 -0
  273. sage/combinat/tools.py +63 -0
  274. sage/combinat/tuple.py +348 -0
  275. sage/data_structures/all.py +2 -0
  276. sage/data_structures/all__sagemath_categories.py +2 -0
  277. sage/data_structures/binary_matrix.pxd +138 -0
  278. sage/data_structures/binary_search.cpython-314t-aarch64-linux-musl.so +0 -0
  279. sage/data_structures/binary_search.pxd +3 -0
  280. sage/data_structures/binary_search.pyx +66 -0
  281. sage/data_structures/bitset.cpython-314t-aarch64-linux-musl.so +0 -0
  282. sage/data_structures/bitset.pxd +40 -0
  283. sage/data_structures/bitset.pyx +2385 -0
  284. sage/data_structures/bitset_base.cpython-314t-aarch64-linux-musl.so +0 -0
  285. sage/data_structures/bitset_base.pxd +926 -0
  286. sage/data_structures/bitset_base.pyx +117 -0
  287. sage/data_structures/bitset_intrinsics.h +487 -0
  288. sage/data_structures/blas_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  289. sage/data_structures/blas_dict.pxd +12 -0
  290. sage/data_structures/blas_dict.pyx +469 -0
  291. sage/data_structures/list_of_pairs.cpython-314t-aarch64-linux-musl.so +0 -0
  292. sage/data_structures/list_of_pairs.pxd +16 -0
  293. sage/data_structures/list_of_pairs.pyx +122 -0
  294. sage/data_structures/mutable_poset.py +3312 -0
  295. sage/data_structures/pairing_heap.cpython-314t-aarch64-linux-musl.so +0 -0
  296. sage/data_structures/pairing_heap.h +346 -0
  297. sage/data_structures/pairing_heap.pxd +88 -0
  298. sage/data_structures/pairing_heap.pyx +1464 -0
  299. sage/data_structures/sparse_bitset.pxd +62 -0
  300. sage/data_structures/stream.py +5070 -0
  301. sage/databases/all__sagemath_categories.py +7 -0
  302. sage/databases/sql_db.py +2236 -0
  303. sage/ext/all__sagemath_categories.py +3 -0
  304. sage/ext/fast_callable.cpython-314t-aarch64-linux-musl.so +0 -0
  305. sage/ext/fast_callable.pxd +4 -0
  306. sage/ext/fast_callable.pyx +2746 -0
  307. sage/ext/fast_eval.cpython-314t-aarch64-linux-musl.so +0 -0
  308. sage/ext/fast_eval.pxd +1 -0
  309. sage/ext/fast_eval.pyx +102 -0
  310. sage/ext/interpreters/__init__.py +1 -0
  311. sage/ext/interpreters/all__sagemath_categories.py +2 -0
  312. sage/ext/interpreters/wrapper_el.cpython-314t-aarch64-linux-musl.so +0 -0
  313. sage/ext/interpreters/wrapper_el.pxd +18 -0
  314. sage/ext/interpreters/wrapper_el.pyx +148 -0
  315. sage/ext/interpreters/wrapper_py.cpython-314t-aarch64-linux-musl.so +0 -0
  316. sage/ext/interpreters/wrapper_py.pxd +17 -0
  317. sage/ext/interpreters/wrapper_py.pyx +133 -0
  318. sage/functions/airy.py +937 -0
  319. sage/functions/all.py +97 -0
  320. sage/functions/bessel.py +2102 -0
  321. sage/functions/error.py +784 -0
  322. sage/functions/exp_integral.py +1529 -0
  323. sage/functions/gamma.py +1087 -0
  324. sage/functions/generalized.py +672 -0
  325. sage/functions/hyperbolic.py +747 -0
  326. sage/functions/hypergeometric.py +1156 -0
  327. sage/functions/jacobi.py +1705 -0
  328. sage/functions/log.py +1402 -0
  329. sage/functions/min_max.py +338 -0
  330. sage/functions/orthogonal_polys.py +3106 -0
  331. sage/functions/other.py +2303 -0
  332. sage/functions/piecewise.py +1505 -0
  333. sage/functions/prime_pi.cpython-314t-aarch64-linux-musl.so +0 -0
  334. sage/functions/prime_pi.pyx +262 -0
  335. sage/functions/special.py +1212 -0
  336. sage/functions/spike_function.py +278 -0
  337. sage/functions/transcendental.py +690 -0
  338. sage/functions/trig.py +1062 -0
  339. sage/functions/wigner.py +726 -0
  340. sage/geometry/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  341. sage/geometry/abc.pyx +82 -0
  342. sage/geometry/all__sagemath_categories.py +1 -0
  343. sage/groups/all__sagemath_categories.py +11 -0
  344. sage/groups/generic.py +1733 -0
  345. sage/groups/groups_catalog.py +113 -0
  346. sage/groups/perm_gps/all__sagemath_categories.py +1 -0
  347. sage/groups/perm_gps/partn_ref/all.py +1 -0
  348. sage/groups/perm_gps/partn_ref/all__sagemath_categories.py +1 -0
  349. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.cpython-314t-aarch64-linux-musl.so +0 -0
  350. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pxd +52 -0
  351. sage/groups/perm_gps/partn_ref/automorphism_group_canonical_label.pyx +906 -0
  352. sage/groups/perm_gps/partn_ref/canonical_augmentation.cpython-314t-aarch64-linux-musl.so +0 -0
  353. sage/groups/perm_gps/partn_ref/canonical_augmentation.pxd +85 -0
  354. sage/groups/perm_gps/partn_ref/canonical_augmentation.pyx +534 -0
  355. sage/groups/perm_gps/partn_ref/data_structures.cpython-314t-aarch64-linux-musl.so +0 -0
  356. sage/groups/perm_gps/partn_ref/data_structures.pxd +576 -0
  357. sage/groups/perm_gps/partn_ref/data_structures.pyx +1792 -0
  358. sage/groups/perm_gps/partn_ref/double_coset.cpython-314t-aarch64-linux-musl.so +0 -0
  359. sage/groups/perm_gps/partn_ref/double_coset.pxd +45 -0
  360. sage/groups/perm_gps/partn_ref/double_coset.pyx +739 -0
  361. sage/groups/perm_gps/partn_ref/refinement_lists.cpython-314t-aarch64-linux-musl.so +0 -0
  362. sage/groups/perm_gps/partn_ref/refinement_lists.pxd +18 -0
  363. sage/groups/perm_gps/partn_ref/refinement_lists.pyx +82 -0
  364. sage/groups/perm_gps/partn_ref/refinement_python.cpython-314t-aarch64-linux-musl.so +0 -0
  365. sage/groups/perm_gps/partn_ref/refinement_python.pxd +16 -0
  366. sage/groups/perm_gps/partn_ref/refinement_python.pyx +564 -0
  367. sage/groups/perm_gps/partn_ref/refinement_sets.cpython-314t-aarch64-linux-musl.so +0 -0
  368. sage/groups/perm_gps/partn_ref/refinement_sets.pxd +60 -0
  369. sage/groups/perm_gps/partn_ref/refinement_sets.pyx +858 -0
  370. sage/interfaces/abc.py +140 -0
  371. sage/interfaces/all.py +58 -0
  372. sage/interfaces/all__sagemath_categories.py +1 -0
  373. sage/interfaces/expect.py +1643 -0
  374. sage/interfaces/interface.py +1682 -0
  375. sage/interfaces/process.cpython-314t-aarch64-linux-musl.so +0 -0
  376. sage/interfaces/process.pxd +5 -0
  377. sage/interfaces/process.pyx +288 -0
  378. sage/interfaces/quit.py +167 -0
  379. sage/interfaces/sage0.py +604 -0
  380. sage/interfaces/sagespawn.cpython-314t-aarch64-linux-musl.so +0 -0
  381. sage/interfaces/sagespawn.pyx +308 -0
  382. sage/interfaces/tab_completion.py +101 -0
  383. sage/misc/all__sagemath_categories.py +78 -0
  384. sage/misc/allocator.cpython-314t-aarch64-linux-musl.so +0 -0
  385. sage/misc/allocator.pxd +6 -0
  386. sage/misc/allocator.pyx +47 -0
  387. sage/misc/binary_tree.cpython-314t-aarch64-linux-musl.so +0 -0
  388. sage/misc/binary_tree.pxd +29 -0
  389. sage/misc/binary_tree.pyx +537 -0
  390. sage/misc/callable_dict.cpython-314t-aarch64-linux-musl.so +0 -0
  391. sage/misc/callable_dict.pyx +89 -0
  392. sage/misc/citation.cpython-314t-aarch64-linux-musl.so +0 -0
  393. sage/misc/citation.pyx +159 -0
  394. sage/misc/converting_dict.py +293 -0
  395. sage/misc/defaults.py +129 -0
  396. sage/misc/derivative.cpython-314t-aarch64-linux-musl.so +0 -0
  397. sage/misc/derivative.pyx +223 -0
  398. sage/misc/functional.py +2005 -0
  399. sage/misc/html.py +589 -0
  400. sage/misc/latex.py +2673 -0
  401. sage/misc/latex_macros.py +236 -0
  402. sage/misc/latex_standalone.py +1833 -0
  403. sage/misc/map_threaded.py +38 -0
  404. sage/misc/mathml.py +76 -0
  405. sage/misc/method_decorator.py +88 -0
  406. sage/misc/mrange.py +755 -0
  407. sage/misc/multireplace.py +41 -0
  408. sage/misc/object_multiplexer.py +92 -0
  409. sage/misc/parser.cpython-314t-aarch64-linux-musl.so +0 -0
  410. sage/misc/parser.pyx +1107 -0
  411. sage/misc/random_testing.py +264 -0
  412. sage/misc/rest_index_of_methods.py +377 -0
  413. sage/misc/search.cpython-314t-aarch64-linux-musl.so +0 -0
  414. sage/misc/search.pxd +2 -0
  415. sage/misc/search.pyx +68 -0
  416. sage/misc/stopgap.cpython-314t-aarch64-linux-musl.so +0 -0
  417. sage/misc/stopgap.pyx +95 -0
  418. sage/misc/table.py +853 -0
  419. sage/monoids/all__sagemath_categories.py +1 -0
  420. sage/monoids/indexed_free_monoid.py +1071 -0
  421. sage/monoids/monoid.py +82 -0
  422. sage/numerical/all__sagemath_categories.py +1 -0
  423. sage/numerical/backends/all__sagemath_categories.py +1 -0
  424. sage/numerical/backends/generic_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  425. sage/numerical/backends/generic_backend.pxd +61 -0
  426. sage/numerical/backends/generic_backend.pyx +1893 -0
  427. sage/numerical/backends/generic_sdp_backend.cpython-314t-aarch64-linux-musl.so +0 -0
  428. sage/numerical/backends/generic_sdp_backend.pxd +38 -0
  429. sage/numerical/backends/generic_sdp_backend.pyx +755 -0
  430. sage/parallel/all.py +6 -0
  431. sage/parallel/decorate.py +575 -0
  432. sage/parallel/map_reduce.py +1997 -0
  433. sage/parallel/multiprocessing_sage.py +76 -0
  434. sage/parallel/ncpus.py +35 -0
  435. sage/parallel/parallelism.py +364 -0
  436. sage/parallel/reference.py +47 -0
  437. sage/parallel/use_fork.py +333 -0
  438. sage/rings/abc.cpython-314t-aarch64-linux-musl.so +0 -0
  439. sage/rings/abc.pxd +31 -0
  440. sage/rings/abc.pyx +526 -0
  441. sage/rings/algebraic_closure_finite_field.py +1154 -0
  442. sage/rings/all__sagemath_categories.py +91 -0
  443. sage/rings/big_oh.py +227 -0
  444. sage/rings/continued_fraction.py +2754 -0
  445. sage/rings/continued_fraction_gosper.py +220 -0
  446. sage/rings/factorint.cpython-314t-aarch64-linux-musl.so +0 -0
  447. sage/rings/factorint.pyx +295 -0
  448. sage/rings/fast_arith.cpython-314t-aarch64-linux-musl.so +0 -0
  449. sage/rings/fast_arith.pxd +21 -0
  450. sage/rings/fast_arith.pyx +535 -0
  451. sage/rings/finite_rings/all__sagemath_categories.py +9 -0
  452. sage/rings/finite_rings/conway_polynomials.py +542 -0
  453. sage/rings/finite_rings/element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  454. sage/rings/finite_rings/element_base.pxd +12 -0
  455. sage/rings/finite_rings/element_base.pyx +1176 -0
  456. sage/rings/finite_rings/finite_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  457. sage/rings/finite_rings/finite_field_base.pxd +7 -0
  458. sage/rings/finite_rings/finite_field_base.pyx +2171 -0
  459. sage/rings/finite_rings/finite_field_constructor.py +827 -0
  460. sage/rings/finite_rings/finite_field_prime_modn.py +372 -0
  461. sage/rings/finite_rings/galois_group.py +154 -0
  462. sage/rings/finite_rings/hom_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  463. sage/rings/finite_rings/hom_finite_field.pxd +23 -0
  464. sage/rings/finite_rings/hom_finite_field.pyx +856 -0
  465. sage/rings/finite_rings/hom_prime_finite_field.cpython-314t-aarch64-linux-musl.so +0 -0
  466. sage/rings/finite_rings/hom_prime_finite_field.pxd +15 -0
  467. sage/rings/finite_rings/hom_prime_finite_field.pyx +164 -0
  468. sage/rings/finite_rings/homset.py +357 -0
  469. sage/rings/finite_rings/integer_mod.cpython-314t-aarch64-linux-musl.so +0 -0
  470. sage/rings/finite_rings/integer_mod.pxd +56 -0
  471. sage/rings/finite_rings/integer_mod.pyx +4586 -0
  472. sage/rings/finite_rings/integer_mod_limits.h +11 -0
  473. sage/rings/finite_rings/integer_mod_ring.py +2044 -0
  474. sage/rings/finite_rings/residue_field.cpython-314t-aarch64-linux-musl.so +0 -0
  475. sage/rings/finite_rings/residue_field.pxd +30 -0
  476. sage/rings/finite_rings/residue_field.pyx +1811 -0
  477. sage/rings/finite_rings/stdint.pxd +19 -0
  478. sage/rings/fraction_field.py +1452 -0
  479. sage/rings/fraction_field_element.cpython-314t-aarch64-linux-musl.so +0 -0
  480. sage/rings/fraction_field_element.pyx +1357 -0
  481. sage/rings/function_field/all.py +7 -0
  482. sage/rings/function_field/all__sagemath_categories.py +2 -0
  483. sage/rings/function_field/constructor.py +218 -0
  484. sage/rings/function_field/element.cpython-314t-aarch64-linux-musl.so +0 -0
  485. sage/rings/function_field/element.pxd +11 -0
  486. sage/rings/function_field/element.pyx +1008 -0
  487. sage/rings/function_field/element_rational.cpython-314t-aarch64-linux-musl.so +0 -0
  488. sage/rings/function_field/element_rational.pyx +513 -0
  489. sage/rings/function_field/extensions.py +230 -0
  490. sage/rings/function_field/function_field.py +1468 -0
  491. sage/rings/function_field/function_field_rational.py +1005 -0
  492. sage/rings/function_field/ideal.py +1155 -0
  493. sage/rings/function_field/ideal_rational.py +629 -0
  494. sage/rings/function_field/jacobian_base.py +826 -0
  495. sage/rings/function_field/jacobian_hess.py +1053 -0
  496. sage/rings/function_field/jacobian_khuri_makdisi.py +1027 -0
  497. sage/rings/function_field/maps.py +1039 -0
  498. sage/rings/function_field/order.py +281 -0
  499. sage/rings/function_field/order_basis.py +586 -0
  500. sage/rings/function_field/order_rational.py +576 -0
  501. sage/rings/function_field/place.py +426 -0
  502. sage/rings/function_field/place_rational.py +181 -0
  503. sage/rings/generic.py +320 -0
  504. sage/rings/homset.py +332 -0
  505. sage/rings/ideal.py +1885 -0
  506. sage/rings/ideal_monoid.py +215 -0
  507. sage/rings/infinity.py +1890 -0
  508. sage/rings/integer.cpython-314t-aarch64-linux-musl.so +0 -0
  509. sage/rings/integer.pxd +45 -0
  510. sage/rings/integer.pyx +7874 -0
  511. sage/rings/integer_ring.cpython-314t-aarch64-linux-musl.so +0 -0
  512. sage/rings/integer_ring.pxd +8 -0
  513. sage/rings/integer_ring.pyx +1693 -0
  514. sage/rings/laurent_series_ring.py +931 -0
  515. sage/rings/laurent_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  516. sage/rings/laurent_series_ring_element.pxd +11 -0
  517. sage/rings/laurent_series_ring_element.pyx +1927 -0
  518. sage/rings/lazy_series.py +7815 -0
  519. sage/rings/lazy_series_ring.py +4356 -0
  520. sage/rings/localization.py +1043 -0
  521. sage/rings/morphism.cpython-314t-aarch64-linux-musl.so +0 -0
  522. sage/rings/morphism.pxd +39 -0
  523. sage/rings/morphism.pyx +3299 -0
  524. sage/rings/multi_power_series_ring.py +1145 -0
  525. sage/rings/multi_power_series_ring_element.py +2184 -0
  526. sage/rings/noncommutative_ideals.cpython-314t-aarch64-linux-musl.so +0 -0
  527. sage/rings/noncommutative_ideals.pyx +423 -0
  528. sage/rings/number_field/all__sagemath_categories.py +1 -0
  529. sage/rings/number_field/number_field_base.cpython-314t-aarch64-linux-musl.so +0 -0
  530. sage/rings/number_field/number_field_base.pxd +8 -0
  531. sage/rings/number_field/number_field_base.pyx +507 -0
  532. sage/rings/number_field/number_field_element_base.cpython-314t-aarch64-linux-musl.so +0 -0
  533. sage/rings/number_field/number_field_element_base.pxd +6 -0
  534. sage/rings/number_field/number_field_element_base.pyx +36 -0
  535. sage/rings/number_field/number_field_ideal.py +3550 -0
  536. sage/rings/padics/all__sagemath_categories.py +4 -0
  537. sage/rings/padics/local_generic.py +1670 -0
  538. sage/rings/padics/local_generic_element.cpython-314t-aarch64-linux-musl.so +0 -0
  539. sage/rings/padics/local_generic_element.pxd +5 -0
  540. sage/rings/padics/local_generic_element.pyx +1017 -0
  541. sage/rings/padics/misc.py +256 -0
  542. sage/rings/padics/padic_generic.py +1911 -0
  543. sage/rings/padics/pow_computer.cpython-314t-aarch64-linux-musl.so +0 -0
  544. sage/rings/padics/pow_computer.pxd +38 -0
  545. sage/rings/padics/pow_computer.pyx +671 -0
  546. sage/rings/padics/precision_error.py +24 -0
  547. sage/rings/polynomial/all__sagemath_categories.py +25 -0
  548. sage/rings/polynomial/commutative_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  549. sage/rings/polynomial/commutative_polynomial.pxd +6 -0
  550. sage/rings/polynomial/commutative_polynomial.pyx +24 -0
  551. sage/rings/polynomial/cyclotomic.cpython-314t-aarch64-linux-musl.so +0 -0
  552. sage/rings/polynomial/cyclotomic.pyx +404 -0
  553. sage/rings/polynomial/flatten.py +711 -0
  554. sage/rings/polynomial/ideal.py +102 -0
  555. sage/rings/polynomial/infinite_polynomial_element.py +1768 -0
  556. sage/rings/polynomial/infinite_polynomial_ring.py +1653 -0
  557. sage/rings/polynomial/laurent_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  558. sage/rings/polynomial/laurent_polynomial.pxd +18 -0
  559. sage/rings/polynomial/laurent_polynomial.pyx +2190 -0
  560. sage/rings/polynomial/laurent_polynomial_ideal.py +590 -0
  561. sage/rings/polynomial/laurent_polynomial_ring.py +832 -0
  562. sage/rings/polynomial/laurent_polynomial_ring_base.py +708 -0
  563. sage/rings/polynomial/multi_polynomial.cpython-314t-aarch64-linux-musl.so +0 -0
  564. sage/rings/polynomial/multi_polynomial.pxd +12 -0
  565. sage/rings/polynomial/multi_polynomial.pyx +3082 -0
  566. sage/rings/polynomial/multi_polynomial_element.py +2570 -0
  567. sage/rings/polynomial/multi_polynomial_ideal.py +5771 -0
  568. sage/rings/polynomial/multi_polynomial_ring.py +947 -0
  569. sage/rings/polynomial/multi_polynomial_ring_base.cpython-314t-aarch64-linux-musl.so +0 -0
  570. sage/rings/polynomial/multi_polynomial_ring_base.pxd +15 -0
  571. sage/rings/polynomial/multi_polynomial_ring_base.pyx +1855 -0
  572. sage/rings/polynomial/multi_polynomial_sequence.py +2204 -0
  573. sage/rings/polynomial/polydict.cpython-314t-aarch64-linux-musl.so +0 -0
  574. sage/rings/polynomial/polydict.pxd +45 -0
  575. sage/rings/polynomial/polydict.pyx +2701 -0
  576. sage/rings/polynomial/polynomial_compiled.cpython-314t-aarch64-linux-musl.so +0 -0
  577. sage/rings/polynomial/polynomial_compiled.pxd +59 -0
  578. sage/rings/polynomial/polynomial_compiled.pyx +509 -0
  579. sage/rings/polynomial/polynomial_element.cpython-314t-aarch64-linux-musl.so +0 -0
  580. sage/rings/polynomial/polynomial_element.pxd +64 -0
  581. sage/rings/polynomial/polynomial_element.pyx +13255 -0
  582. sage/rings/polynomial/polynomial_element_generic.py +1637 -0
  583. sage/rings/polynomial/polynomial_fateman.py +97 -0
  584. sage/rings/polynomial/polynomial_quotient_ring.py +2465 -0
  585. sage/rings/polynomial/polynomial_quotient_ring_element.py +779 -0
  586. sage/rings/polynomial/polynomial_ring.py +3784 -0
  587. sage/rings/polynomial/polynomial_ring_constructor.py +1051 -0
  588. sage/rings/polynomial/polynomial_ring_homomorphism.cpython-314t-aarch64-linux-musl.so +0 -0
  589. sage/rings/polynomial/polynomial_ring_homomorphism.pxd +5 -0
  590. sage/rings/polynomial/polynomial_ring_homomorphism.pyx +121 -0
  591. sage/rings/polynomial/polynomial_singular_interface.py +549 -0
  592. sage/rings/polynomial/symmetric_ideal.py +989 -0
  593. sage/rings/polynomial/symmetric_reduction.cpython-314t-aarch64-linux-musl.so +0 -0
  594. sage/rings/polynomial/symmetric_reduction.pxd +8 -0
  595. sage/rings/polynomial/symmetric_reduction.pyx +669 -0
  596. sage/rings/polynomial/term_order.py +2279 -0
  597. sage/rings/polynomial/toy_buchberger.py +449 -0
  598. sage/rings/polynomial/toy_d_basis.py +387 -0
  599. sage/rings/polynomial/toy_variety.py +362 -0
  600. sage/rings/power_series_mpoly.cpython-314t-aarch64-linux-musl.so +0 -0
  601. sage/rings/power_series_mpoly.pxd +9 -0
  602. sage/rings/power_series_mpoly.pyx +161 -0
  603. sage/rings/power_series_poly.cpython-314t-aarch64-linux-musl.so +0 -0
  604. sage/rings/power_series_poly.pxd +10 -0
  605. sage/rings/power_series_poly.pyx +1317 -0
  606. sage/rings/power_series_ring.py +1441 -0
  607. sage/rings/power_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  608. sage/rings/power_series_ring_element.pxd +12 -0
  609. sage/rings/power_series_ring_element.pyx +3028 -0
  610. sage/rings/puiseux_series_ring.py +487 -0
  611. sage/rings/puiseux_series_ring_element.cpython-314t-aarch64-linux-musl.so +0 -0
  612. sage/rings/puiseux_series_ring_element.pxd +7 -0
  613. sage/rings/puiseux_series_ring_element.pyx +1055 -0
  614. sage/rings/qqbar_decorators.py +167 -0
  615. sage/rings/quotient_ring.py +1598 -0
  616. sage/rings/quotient_ring_element.py +979 -0
  617. sage/rings/rational.cpython-314t-aarch64-linux-musl.so +0 -0
  618. sage/rings/rational.pxd +20 -0
  619. sage/rings/rational.pyx +4284 -0
  620. sage/rings/rational_field.py +1730 -0
  621. sage/rings/real_double.cpython-314t-aarch64-linux-musl.so +0 -0
  622. sage/rings/real_double.pxd +16 -0
  623. sage/rings/real_double.pyx +2218 -0
  624. sage/rings/real_lazy.cpython-314t-aarch64-linux-musl.so +0 -0
  625. sage/rings/real_lazy.pxd +30 -0
  626. sage/rings/real_lazy.pyx +1773 -0
  627. sage/rings/ring.cpython-314t-aarch64-linux-musl.so +0 -0
  628. sage/rings/ring.pxd +30 -0
  629. sage/rings/ring.pyx +850 -0
  630. sage/rings/semirings/all.py +3 -0
  631. sage/rings/semirings/non_negative_integer_semiring.py +107 -0
  632. sage/rings/semirings/tropical_mpolynomial.py +972 -0
  633. sage/rings/semirings/tropical_polynomial.py +997 -0
  634. sage/rings/semirings/tropical_semiring.cpython-314t-aarch64-linux-musl.so +0 -0
  635. sage/rings/semirings/tropical_semiring.pyx +676 -0
  636. sage/rings/semirings/tropical_variety.py +1701 -0
  637. sage/rings/sum_of_squares.cpython-314t-aarch64-linux-musl.so +0 -0
  638. sage/rings/sum_of_squares.pxd +3 -0
  639. sage/rings/sum_of_squares.pyx +336 -0
  640. sage/rings/tests.py +504 -0
  641. sage/schemes/affine/affine_homset.py +508 -0
  642. sage/schemes/affine/affine_morphism.py +1574 -0
  643. sage/schemes/affine/affine_point.py +460 -0
  644. sage/schemes/affine/affine_rational_point.py +308 -0
  645. sage/schemes/affine/affine_space.py +1264 -0
  646. sage/schemes/affine/affine_subscheme.py +592 -0
  647. sage/schemes/affine/all.py +25 -0
  648. sage/schemes/all__sagemath_categories.py +5 -0
  649. sage/schemes/generic/algebraic_scheme.py +2092 -0
  650. sage/schemes/generic/all.py +5 -0
  651. sage/schemes/generic/ambient_space.py +400 -0
  652. sage/schemes/generic/divisor.py +465 -0
  653. sage/schemes/generic/divisor_group.py +313 -0
  654. sage/schemes/generic/glue.py +84 -0
  655. sage/schemes/generic/homset.py +820 -0
  656. sage/schemes/generic/hypersurface.py +234 -0
  657. sage/schemes/generic/morphism.py +2107 -0
  658. sage/schemes/generic/point.py +237 -0
  659. sage/schemes/generic/scheme.py +1190 -0
  660. sage/schemes/generic/spec.py +199 -0
  661. sage/schemes/product_projective/all.py +6 -0
  662. sage/schemes/product_projective/homset.py +236 -0
  663. sage/schemes/product_projective/morphism.py +517 -0
  664. sage/schemes/product_projective/point.py +568 -0
  665. sage/schemes/product_projective/rational_point.py +550 -0
  666. sage/schemes/product_projective/space.py +1301 -0
  667. sage/schemes/product_projective/subscheme.py +466 -0
  668. sage/schemes/projective/all.py +24 -0
  669. sage/schemes/projective/proj_bdd_height.py +453 -0
  670. sage/schemes/projective/projective_homset.py +718 -0
  671. sage/schemes/projective/projective_morphism.py +2792 -0
  672. sage/schemes/projective/projective_point.py +1484 -0
  673. sage/schemes/projective/projective_rational_point.py +569 -0
  674. sage/schemes/projective/projective_space.py +2571 -0
  675. sage/schemes/projective/projective_subscheme.py +1574 -0
  676. sage/sets/all.py +17 -0
  677. sage/sets/cartesian_product.py +376 -0
  678. sage/sets/condition_set.py +525 -0
  679. sage/sets/disjoint_set.cpython-314t-aarch64-linux-musl.so +0 -0
  680. sage/sets/disjoint_set.pxd +36 -0
  681. sage/sets/disjoint_set.pyx +998 -0
  682. sage/sets/disjoint_union_enumerated_sets.py +625 -0
  683. sage/sets/family.cpython-314t-aarch64-linux-musl.so +0 -0
  684. sage/sets/family.pxd +12 -0
  685. sage/sets/family.pyx +1556 -0
  686. sage/sets/finite_enumerated_set.py +406 -0
  687. sage/sets/finite_set_map_cy.cpython-314t-aarch64-linux-musl.so +0 -0
  688. sage/sets/finite_set_map_cy.pxd +34 -0
  689. sage/sets/finite_set_map_cy.pyx +708 -0
  690. sage/sets/finite_set_maps.py +591 -0
  691. sage/sets/image_set.py +448 -0
  692. sage/sets/integer_range.py +829 -0
  693. sage/sets/non_negative_integers.py +241 -0
  694. sage/sets/positive_integers.py +93 -0
  695. sage/sets/primes.py +188 -0
  696. sage/sets/real_set.py +2760 -0
  697. sage/sets/recursively_enumerated_set.cpython-314t-aarch64-linux-musl.so +0 -0
  698. sage/sets/recursively_enumerated_set.pxd +31 -0
  699. sage/sets/recursively_enumerated_set.pyx +2082 -0
  700. sage/sets/set.py +2083 -0
  701. sage/sets/set_from_iterator.py +1021 -0
  702. sage/sets/totally_ordered_finite_set.py +329 -0
  703. sage/symbolic/all__sagemath_categories.py +1 -0
  704. sage/symbolic/function.cpython-314t-aarch64-linux-musl.so +0 -0
  705. sage/symbolic/function.pxd +29 -0
  706. sage/symbolic/function.pyx +1488 -0
  707. sage/symbolic/symbols.py +56 -0
  708. sage/tests/all__sagemath_categories.py +1 -0
  709. sage/tests/cython.cpython-314t-aarch64-linux-musl.so +0 -0
  710. sage/tests/cython.pyx +37 -0
  711. sage/tests/stl_vector.cpython-314t-aarch64-linux-musl.so +0 -0
  712. sage/tests/stl_vector.pyx +171 -0
  713. sage/typeset/all.py +6 -0
  714. sage/typeset/ascii_art.py +295 -0
  715. sage/typeset/character_art.py +789 -0
  716. sage/typeset/character_art_factory.py +572 -0
  717. sage/typeset/symbols.py +334 -0
  718. sage/typeset/unicode_art.py +183 -0
  719. sage/typeset/unicode_characters.py +101 -0
@@ -0,0 +1,1792 @@
1
+ # sage_setup: distribution = sagemath-categories
2
+ r"""
3
+ Data structures
4
+
5
+ This module implements basic data structures essential to the rest of the
6
+ partn_ref module.
7
+
8
+ REFERENCES:
9
+
10
+ [1] McKay, Brendan D. Practical Graph Isomorphism. Congressus Numerantium,
11
+ Vol. 30 (1981), pp. 45-87.
12
+ [2] Fredman, M. and Saks, M. The cell probe complexity of dynamic data
13
+ structures. Proceedings of the Twenty-First Annual ACM Symposium on
14
+ Theory of Computing, pp. 345–354. May 1989.
15
+ [3] Seress, Akos. Permutation Group Algorithms. Cambridge University Press,
16
+ 2003.
17
+ """
18
+
19
+ #*****************************************************************************
20
+ # Copyright (C) 2006 - 2011 Robert L. Miller <rlmillster@gmail.com>
21
+ #
22
+ # This program is free software: you can redistribute it and/or modify
23
+ # it under the terms of the GNU General Public License as published by
24
+ # the Free Software Foundation, either version 2 of the License, or
25
+ # (at your option) any later version.
26
+ # https://www.gnu.org/licenses/
27
+ #*****************************************************************************
28
+
29
+ from libc.math cimport log, ceil
30
+ from libc.string cimport memcpy, memset
31
+ from libc.stdlib cimport rand
32
+ from cysignals.memory cimport sig_malloc, sig_calloc, sig_realloc, sig_free
33
+
34
+ from sage.data_structures.bitset_base cimport *
35
+ from sage.rings.integer cimport Integer
36
+ # from sage.libs.flint.ulong_extras cimport n_is_prime
37
+ # -- avoid modularization obstruction -- function is only used for a doctest helper
38
+ from sage.arith.misc import is_prime as n_is_prime
39
+
40
+
41
+ # OrbitPartition (OP)
42
+
43
+ cdef inline OrbitPartition *OP_new(int n) noexcept:
44
+ """
45
+ Allocate and return a pointer to a new OrbitPartition of degree n. Return a
46
+ null pointer in the case of an allocation failure.
47
+ """
48
+ cdef OrbitPartition *OP = <OrbitPartition *> \
49
+ sig_malloc(sizeof(OrbitPartition))
50
+ if OP is NULL:
51
+ return NULL
52
+ OP.parent = <int *> sig_malloc(n * sizeof(int))
53
+ OP.rank = <int *> sig_malloc(n * sizeof(int))
54
+ OP.mcr = <int *> sig_malloc(n * sizeof(int))
55
+ OP.size = <int *> sig_malloc(n * sizeof(int))
56
+ if OP.parent is NULL or OP.rank is NULL or OP.mcr is NULL or OP.size is NULL:
57
+ sig_free(OP.parent)
58
+ sig_free(OP.rank)
59
+ sig_free(OP.mcr)
60
+ sig_free(OP.size)
61
+ sig_free(OP)
62
+ return NULL
63
+ OP.degree = n
64
+ OP.num_cells = n
65
+ OP_clear(OP)
66
+ return OP
67
+
68
+
69
+ cdef inline void OP_dealloc(OrbitPartition *OP) noexcept:
70
+ if OP is not NULL:
71
+ sig_free(OP.parent)
72
+ sig_free(OP.rank)
73
+ sig_free(OP.mcr)
74
+ sig_free(OP.size)
75
+ sig_free(OP)
76
+
77
+
78
+ cdef OP_string(OrbitPartition *OP):
79
+ """
80
+ Return a string representation of the OrbitPartition.
81
+ """
82
+ cdef i,j
83
+ s = ""
84
+ for i in range(OP.degree):
85
+ s += " "
86
+ j = OP_find(OP, i)
87
+ s += "%d -> %d" % (i, j)
88
+ return s
89
+
90
+
91
+ cdef inline void OP_make_set(OrbitPartition *OP) noexcept:
92
+ """
93
+ Increase the degree of the input partition by one.
94
+
95
+ An error is raised in case of memory allocation failure.
96
+ """
97
+ cdef int n = OP.degree
98
+
99
+ OP.parent = <int *> sig_realloc(OP.parent, (n + 1) * sizeof(int))
100
+ OP.rank = <int *> sig_realloc(OP.rank, (n + 1) * sizeof(int))
101
+ OP.mcr = <int *> sig_realloc(OP.mcr, (n + 1) * sizeof(int))
102
+ OP.size = <int *> sig_realloc(OP.size, (n + 1) * sizeof(int))
103
+ if OP.parent is NULL or OP.rank is NULL or OP.mcr is NULL or OP.size is NULL:
104
+ sig_free(OP.parent)
105
+ sig_free(OP.rank)
106
+ sig_free(OP.mcr)
107
+ sig_free(OP.size)
108
+ raise MemoryError("unable to reallocate memory in OP_make_set method")
109
+ OP.degree = n + 1
110
+ OP.num_cells = OP.num_cells + 1
111
+
112
+ OP.parent[n] = n
113
+ OP.rank[n] = 0
114
+ OP.mcr[n] = n
115
+ OP.size[n] = 1
116
+
117
+
118
+ def OP_represent(int n, merges, perm):
119
+ """
120
+ Demonstration and testing.
121
+
122
+ TESTS::
123
+
124
+ sage: from sage.groups.perm_gps.partn_ref.data_structures import OP_represent
125
+ sage: OP_represent(9, [(0,1),(2,3),(3,4)], [1,2,0,4,3,6,7,5,8])
126
+ Allocating OrbitPartition...
127
+ Allocation passed.
128
+ Checking that each element reports itself as its root.
129
+ Each element reports itself as its root.
130
+ Merging:
131
+ Merged 0 and 1.
132
+ Merged 2 and 3.
133
+ Merged 3 and 4.
134
+ Done merging.
135
+ Finding:
136
+ 0 -> 0, root: size=2, mcr=0, rank=1
137
+ 1 -> 0
138
+ 2 -> 2, root: size=3, mcr=2, rank=1
139
+ 3 -> 2
140
+ 4 -> 2
141
+ 5 -> 5, root: size=1, mcr=5, rank=0
142
+ 6 -> 6, root: size=1, mcr=6, rank=0
143
+ 7 -> 7, root: size=1, mcr=7, rank=0
144
+ 8 -> 8, root: size=1, mcr=8, rank=0
145
+ Allocating array to test merge_perm.
146
+ Allocation passed.
147
+ Merging permutation: [1, 2, 0, 4, 3, 6, 7, 5, 8]
148
+ Done merging.
149
+ Finding:
150
+ 0 -> 0, root: size=5, mcr=0, rank=2
151
+ 1 -> 0
152
+ 2 -> 0
153
+ 3 -> 0
154
+ 4 -> 0
155
+ 5 -> 5, root: size=3, mcr=5, rank=1
156
+ 6 -> 5
157
+ 7 -> 5
158
+ 8 -> 8, root: size=1, mcr=8, rank=0
159
+ Deallocating OrbitPartition.
160
+ Done.
161
+ """
162
+ cdef int i
163
+ print("Allocating OrbitPartition...")
164
+ cdef OrbitPartition *OP = OP_new(n)
165
+ if OP is NULL:
166
+ print("Allocation failed!")
167
+ return
168
+ print("Allocation passed.")
169
+ print("Checking that each element reports itself as its root.")
170
+ good = True
171
+ for i in range(n):
172
+ if not OP_find(OP, i) == i:
173
+ print("Failed at i = %d!" % i)
174
+ good = False
175
+ if good:
176
+ print("Each element reports itself as its root.")
177
+ print("Merging:")
178
+ for i,j in merges:
179
+ OP_join(OP, i, j)
180
+ print("Merged %d and %d." % (i, j))
181
+ print("Done merging.")
182
+ print("Finding:")
183
+ for i in range(n):
184
+ j = OP_find(OP, i)
185
+ s = "%d -> %d" % (i, j)
186
+ if i == j:
187
+ s += ", root: size=%d, mcr=%d, rank=%d" % \
188
+ (OP.size[i], OP.mcr[i], OP.rank[i])
189
+ print(s)
190
+ print("Allocating array to test merge_perm.")
191
+ cdef int *gamma = <int *> sig_malloc( n * sizeof(int) )
192
+ if gamma is NULL:
193
+ print("Allocation failed!")
194
+ OP_dealloc(OP)
195
+ return
196
+ print("Allocation passed.")
197
+ for i in range(n):
198
+ gamma[i] = perm[i]
199
+ print("Merging permutation: %s" % perm)
200
+ OP_merge_list_perm(OP, gamma)
201
+ print("Done merging.")
202
+ print("Finding:")
203
+ for i in range(n):
204
+ j = OP_find(OP, i)
205
+ s = "%d -> %d" % (i, j)
206
+ if i == j:
207
+ s += ", root: size=%d, mcr=%d, rank=%d" % \
208
+ (OP.size[i], OP.mcr[i], OP.rank[i])
209
+ print(s)
210
+ print("Deallocating OrbitPartition.")
211
+ sig_free(gamma)
212
+ OP_dealloc(OP)
213
+ print("Done.")
214
+
215
+
216
+ # PartitionStack (PS)
217
+
218
+ cdef inline PartitionStack *PS_new(int n, bint unit_partition) noexcept:
219
+ """
220
+ Allocate and return a pointer to a new PartitionStack of degree n. Return a
221
+ null pointer in the case of an allocation failure.
222
+ """
223
+ cdef PartitionStack *PS = <PartitionStack *> \
224
+ sig_malloc(sizeof(PartitionStack))
225
+ cdef int *int_array = <int *> sig_malloc( 2*n * sizeof(int) )
226
+ if PS is NULL or int_array is NULL:
227
+ sig_free(PS)
228
+ sig_free(int_array)
229
+ return NULL
230
+ PS.entries = int_array
231
+ PS.levels = int_array + n
232
+ PS.depth = 0
233
+ PS.degree = n
234
+ if unit_partition:
235
+ PS_unit_partition(PS)
236
+ return PS
237
+
238
+
239
+ cdef void PS_unit_partition(PartitionStack *PS) noexcept:
240
+ """
241
+ Set partition stack to a single partition with a single cell.
242
+ """
243
+ cdef int i, n = PS.degree
244
+ PS.depth = 0
245
+ for i in range(n - 1):
246
+ PS.entries[i] = i
247
+ PS.levels[i] = n
248
+ PS.entries[n-1] = n - 1
249
+ PS.levels[n-1] = -1
250
+
251
+
252
+ cdef inline PartitionStack *PS_copy(PartitionStack *PS) noexcept:
253
+ """
254
+ Allocate and return a pointer to a copy of PartitionStack PS. Return a null
255
+ pointer in the case of an allocation failure.
256
+ """
257
+ cdef int n = PS.degree
258
+
259
+ cdef PartitionStack *PS2 = <PartitionStack *> \
260
+ sig_malloc(sizeof(PartitionStack))
261
+ cdef int *int_array = <int *> sig_malloc( 2*n * sizeof(int) )
262
+ if PS2 is NULL or int_array is NULL:
263
+ sig_free(PS2)
264
+ sig_free(int_array)
265
+ return NULL
266
+ PS2.entries = int_array
267
+ PS2.levels = int_array + n
268
+ PS_copy_from_to(PS, PS2)
269
+ return PS2
270
+
271
+
272
+ cdef inline void PS_dealloc(PartitionStack *PS) noexcept:
273
+ if PS is not NULL:
274
+ sig_free(PS.entries)
275
+ sig_free(PS)
276
+
277
+
278
+ cdef PartitionStack *PS_from_list(list L) noexcept:
279
+ """
280
+ Allocate and return a pointer to a PartitionStack representing L. Return a
281
+ null pointer in the case of an allocation failure.
282
+ """
283
+ cdef int cell, i, num_cells = len(L), cur_start = 0, cur_len, n = 0
284
+ for cell in range(num_cells):
285
+ n += len(L[cell])
286
+ cdef PartitionStack *PS = PS_new(n, 0)
287
+ if PS is NULL:
288
+ return NULL
289
+ for cell in range(num_cells):
290
+ cur_len = len(L[cell])
291
+ for i in range(cur_len):
292
+ PS.entries[cur_start + i] = L[cell][i]
293
+ PS.levels[cur_start + i] = n
294
+ PS_move_min_to_front(PS, cur_start, cur_start+cur_len-1)
295
+ cur_start += cur_len
296
+ PS.levels[cur_start-1] = 0
297
+ if n > 0:
298
+ PS.levels[n-1] = -1
299
+ PS.depth = 0
300
+ PS.degree = n
301
+ return PS
302
+
303
+
304
+ cdef PS_print(PartitionStack *PS):
305
+ """
306
+ Print a visual representation of PS.
307
+ """
308
+ cdef int i
309
+ for i in range(PS.depth + 1):
310
+ PS_print_partition(PS, i)
311
+
312
+
313
+ cdef PS_print_partition(PartitionStack *PS, int k):
314
+ """
315
+ Print the partition at depth k.
316
+ """
317
+ s = '('
318
+ for i in range(PS.degree):
319
+ s += str(PS.entries[i])
320
+ if PS.levels[i] <= k:
321
+ s += '|'
322
+ else:
323
+ s += ' '
324
+ s = s[:-1] + ')'
325
+ print(s)
326
+
327
+
328
+ cdef int PS_first_smallest(PartitionStack *PS, bitset_t b, int *second_pos=NULL) noexcept:
329
+ """
330
+ Find the first occurrence of the smallest cell of size greater than one,
331
+ which is admissible (checked by the function ``test_allowance``).
332
+ Its entries are stored to `b` and its minimum element is returned.
333
+ """
334
+ cdef int i = 0, j = 0, location = 0, n = PS.degree
335
+ bitset_zero(b)
336
+ while True:
337
+ if PS.levels[i] <= PS.depth:
338
+ if i != j and n > i - j + 1:
339
+ n = i - j + 1
340
+ location = j
341
+ j = i + 1
342
+ if PS.levels[i] == -1:
343
+ break
344
+ i += 1
345
+ # location now points to the beginning of the first, smallest,
346
+ # nontrivial cell
347
+ i = location
348
+ while True:
349
+ bitset_flip(b, PS.entries[i])
350
+ if PS.levels[i] <= PS.depth:
351
+ break
352
+ i += 1
353
+
354
+ if second_pos != NULL:
355
+ if n == 2:
356
+ second_pos[0] = PS.entries[location + 1]
357
+ else:
358
+ second_pos[0] = -1
359
+
360
+ return PS.entries[location]
361
+
362
+
363
+ cdef int PS_all_new_cells(PartitionStack *PS, bitset_t** nonsingletons_ptr) noexcept:
364
+ """
365
+ Suppose a cell ``C`` was split into ``a`` components at ``PS.level``.
366
+ Set the rows of the matrix ``nonsingletons_ptr`` to the first
367
+ ``a-1`` components of ``C`` for all those ``C``.
368
+ Return the number of rows of ``nonsingletons_ptr``.
369
+ """
370
+ cdef int beg=0, end, n = PS.degree, count=0, i, n_1 = n-1
371
+ cdef bitset_t scratch
372
+ bitset_init(scratch, n)
373
+ cdef bitset_t* nonsingletons = nonsingletons_ptr[0]
374
+
375
+ while beg < n_1:
376
+ end = beg
377
+ while end!=n and PS.levels[end] > PS.depth:
378
+ end+=1
379
+
380
+ if end != n:
381
+ if PS.levels[end] == PS.depth:
382
+ bitset_zero(scratch)
383
+ for i in range(beg, end + 1):
384
+ bitset_set(scratch, PS.entries[i])
385
+ count +=1
386
+ nonsingletons = <bitset_t*> sig_realloc(nonsingletons, count * sizeof(bitset_t))
387
+ if nonsingletons is NULL:
388
+ raise MemoryError("Memory error in PS_all_new_cells")
389
+ bitset_init(nonsingletons[count-1], n)
390
+ bitset_copy(nonsingletons[count-1], scratch)
391
+ else:
392
+ if beg == 0:
393
+ nonsingletons = <bitset_t*> sig_realloc(nonsingletons, sizeof(bitset_t))
394
+ if nonsingletons is NULL:
395
+ raise MemoryError("Memory error in PS_all_new_cells")
396
+ bitset_init(nonsingletons[0], n)
397
+ bitset_zero(scratch)
398
+ bitset_complement(nonsingletons[0], scratch)
399
+ count = 1
400
+ beg = end+1
401
+ nonsingletons_ptr[0] = nonsingletons
402
+ return count
403
+
404
+
405
+ cdef int PS_find_element(PartitionStack *PS, bitset_t b, int x) except -1:
406
+ """
407
+ Find the cell containing x, store its entries to b and return the location
408
+ of the beginning of the cell.
409
+ """
410
+ cdef int i, location, n = PS.degree
411
+ bitset_zero(b)
412
+ for i in range(n):
413
+ if PS.entries[i] == x:
414
+ location = i
415
+ break
416
+ else:
417
+ raise ValueError("element not found")
418
+ while location > 0 and PS.levels[location-1] > PS.depth:
419
+ location -= 1
420
+ i = 0
421
+ while 1:
422
+ bitset_set(b, PS.entries[location+i])
423
+ if PS.levels[location+i] <= PS.depth:
424
+ break
425
+ i += 1
426
+ return location
427
+
428
+
429
+ cdef list PS_singletons(PartitionStack * part):
430
+ """
431
+ Return the list of all singletons in the ``PartitionStack``.
432
+ """
433
+ cdef list l = []
434
+ cdef int i
435
+
436
+ if part.levels[0] <= part.depth:
437
+ l.append(0)
438
+
439
+ for i in range(1, part.degree):
440
+ if part.levels[i] <= part.depth and part.levels[i - 1] <= part.depth:
441
+ l.append(i)
442
+
443
+ return l
444
+
445
+
446
+ def PS_represent(partition, splits):
447
+ """
448
+ Demonstration and testing.
449
+
450
+ TESTS::
451
+
452
+ sage: from sage.groups.perm_gps.partn_ref.data_structures import PS_represent
453
+ sage: PS_represent([[6],[3,4,8,7],[1,9,5],[0,2]], [6,1,8,2])
454
+ Allocating PartitionStack...
455
+ Allocation passed:
456
+ (0 1 2 3 4 5 6 7 8 9)
457
+ Checking that entries are in order and correct level.
458
+ Everything seems in order, deallocating.
459
+ Deallocated.
460
+ Creating PartitionStack from partition [[6], [3, 4, 8, 7], [1, 9, 5], [0, 2]].
461
+ PartitionStack's data:
462
+ entries -> [6, 3, 4, 8, 7, 1, 9, 5, 0, 2]
463
+ levels -> [0, 10, 10, 10, 0, 10, 10, 0, 10, -1]
464
+ depth = 0, degree = 10
465
+ (6|3 4 8 7|1 9 5|0 2)
466
+ Checking PS_is_discrete:
467
+ False
468
+ Checking PS_num_cells:
469
+ 4
470
+ Checking PS_is_mcr, min cell reps are:
471
+ [6, 3, 1, 0]
472
+ Checking PS_is_fixed, fixed elements are:
473
+ [6]
474
+ Copying PartitionStack:
475
+ (6|3 4 8 7|1 9 5|0 2)
476
+ Checking for consistency.
477
+ Everything is consistent.
478
+ Clearing copy:
479
+ (0 3 4 8 7 1 9 5 6 2)
480
+ Splitting point 6 from original:
481
+ 0
482
+ (6|3 4 8 7|1 9 5|0 2)
483
+ Splitting point 1 from original:
484
+ 5
485
+ (6|3 4 8 7|1|5 9|0 2)
486
+ Splitting point 8 from original:
487
+ 1
488
+ (6|8|3 4 7|1|5 9|0 2)
489
+ Splitting point 2 from original:
490
+ 8
491
+ (6|8|3 4 7|1|5 9|2|0)
492
+ Getting permutation from PS2->PS:
493
+ [6, 1, 0, 8, 3, 9, 2, 7, 4, 5]
494
+ Finding first smallest:
495
+ Minimal element is 5, bitset is:
496
+ 0000010001
497
+ Finding element 1:
498
+ Location is: 5
499
+ Bitset is:
500
+ 0100000000
501
+ Deallocating PartitionStacks.
502
+ Done.
503
+ """
504
+ cdef int i, n = sum([len(cell) for cell in partition])
505
+ cdef int *gamma
506
+ cdef bitset_t b
507
+ print("Allocating PartitionStack...")
508
+ cdef PartitionStack *PS = PS_new(n, 1)
509
+ cdef PartitionStack *PS2
510
+ if PS is NULL:
511
+ print("Allocation failed!")
512
+ return
513
+ print("Allocation passed:")
514
+ PS_print(PS)
515
+ print("Checking that entries are in order and correct level.")
516
+ good = True
517
+ for i in range(n - 1):
518
+ if not (PS.entries[i] == i and PS.levels[i] == n):
519
+ print("Failed at i = %d!" % i)
520
+ print(PS.entries[i], PS.levels[i], i, n)
521
+ good = False
522
+ if not (PS.entries[n-1] == n-1 and PS.levels[n-1] == -1):
523
+ print("Failed at i = %d!" % (n-1))
524
+ good = False
525
+ if not PS.degree == n or not PS.depth == 0:
526
+ print("Incorrect degree or depth!")
527
+ good = False
528
+ if good:
529
+ print("Everything seems in order, deallocating.")
530
+ PS_dealloc(PS)
531
+ print("Deallocated.")
532
+ print("Creating PartitionStack from partition %s." % partition)
533
+ PS = PS_from_list(partition)
534
+ print("PartitionStack's data:")
535
+ print("entries -> %s" % [PS.entries[i] for i in range(n)])
536
+ print("levels -> %s" % [PS.levels[i] for i in range(n)])
537
+ print("depth = %d, degree = %d" % (PS.depth,PS.degree))
538
+ PS_print(PS)
539
+ print("Checking PS_is_discrete:")
540
+ print("True" if PS_is_discrete(PS) else "False")
541
+ print("Checking PS_num_cells:")
542
+ print(PS_num_cells(PS))
543
+ print("Checking PS_is_mcr, min cell reps are:")
544
+ L = [PS.entries[i] for i in range(n) if PS_is_mcr(PS, i)]
545
+ print(L)
546
+ print("Checking PS_is_fixed, fixed elements are:")
547
+ print([PS.entries[l] for l in L if PS_is_fixed(PS, l)])
548
+ print("Copying PartitionStack:")
549
+ PS2 = PS_copy(PS)
550
+ PS_print(PS2)
551
+ print("Checking for consistency.")
552
+ good = True
553
+ for i in range(n):
554
+ if PS.entries[i] != PS2.entries[i] or PS.levels[i] != PS2.levels[i]:
555
+ print("Failed at i = %d!" % i)
556
+ good = False
557
+ if PS.degree != PS2.degree or PS.depth != PS2.depth:
558
+ print("Failure with degree or depth!")
559
+ good = False
560
+ if good:
561
+ print("Everything is consistent.")
562
+ print("Clearing copy:")
563
+ PS_clear(PS2)
564
+ PS_print(PS2)
565
+ for s in splits:
566
+ print("Splitting point %d from original:" % s)
567
+ print(PS_split_point(PS, s))
568
+ PS_print(PS)
569
+ print("Getting permutation from PS2->PS:")
570
+ gamma = <int *> sig_malloc(n * sizeof(int))
571
+ PS_get_perm_from(PS, PS2, gamma)
572
+ print([gamma[i] for i in range(n)])
573
+ sig_free(gamma)
574
+ print("Finding first smallest:")
575
+ bitset_init(b, n)
576
+ i = PS_first_smallest(PS, b)
577
+ print("Minimal element is %d, bitset is:" % i)
578
+ print(bitset_string(b))
579
+ bitset_free(b)
580
+ print("Finding element 1:")
581
+ bitset_init(b, n)
582
+ print("Location is: {}".format(PS_find_element(PS, b, 1)))
583
+ print("Bitset is:")
584
+ print(bitset_string(b))
585
+ bitset_free(b)
586
+ print("Deallocating PartitionStacks.")
587
+ PS_dealloc(PS)
588
+ PS_dealloc(PS2)
589
+ print("Done.")
590
+
591
+
592
+ # StabilizerChain (SC)
593
+
594
+ cdef enum:
595
+ default_num_gens = 8
596
+ default_num_bits = 64
597
+
598
+
599
+ cdef StabilizerChain *SC_new(int n, bint init_gens=True) noexcept:
600
+ """
601
+ Allocate and return a pointer to a new StabilizerChain of degree n. Return
602
+ a null pointer in the case of an allocation failure.
603
+ """
604
+ cdef int i
605
+ cdef StabilizerChain *SC = <StabilizerChain *> \
606
+ sig_calloc(1, sizeof(StabilizerChain))
607
+ if SC is NULL:
608
+ return NULL
609
+ SC.degree = n
610
+ SC.base_size = 0
611
+ if n == 0:
612
+ # All internal pointers have been initialized to NULL by sig_calloc
613
+ return SC
614
+
615
+ # first level allocations
616
+ cdef int *int_array = <int *> sig_malloc( (3*n*n + 6*n + 1) * sizeof(int) )
617
+ cdef int **int_ptrs = <int **> sig_calloc( 5*n, sizeof(int *) )
618
+ SC.OP_scratch = OP_new(n)
619
+ # bitset_init without the MemoryError:
620
+ cdef long limbs = (default_num_bits - 1)/(8*sizeof(unsigned long)) + 1
621
+ SC.gen_used.size = default_num_bits
622
+ SC.gen_is_id.size = default_num_bits
623
+ SC.gen_used.limbs = limbs
624
+ SC.gen_is_id.limbs = limbs
625
+ SC.gen_used.bits = <mp_limb_t*>sig_malloc(limbs * sizeof(mp_limb_t))
626
+ SC.gen_is_id.bits = <mp_limb_t*>sig_malloc(limbs * sizeof(mp_limb_t))
627
+
628
+ # check for allocation failures
629
+ if int_array is NULL or int_ptrs is NULL or \
630
+ SC.gen_used.bits is NULL or SC.gen_is_id.bits is NULL or \
631
+ SC.OP_scratch is NULL:
632
+ sig_free(int_array)
633
+ sig_free(int_ptrs)
634
+ SC_dealloc(SC)
635
+ return NULL
636
+
637
+ SC.gen_used.bits[limbs-1] = 0
638
+ SC.gen_is_id.bits[limbs-1] = 0
639
+
640
+ SC.orbit_sizes = int_array
641
+ SC.num_gens = int_array + n
642
+ SC.array_size = int_array + 2 * n
643
+ SC.perm_scratch = int_array + 3 * n # perm_scratch is length 3*n+1 for sorting
644
+ int_array += 6*n + 1
645
+
646
+ SC.generators = int_ptrs
647
+ SC.gen_inverses = int_ptrs + n
648
+ SC.base_orbits = int_ptrs + 2 * n
649
+ SC.parents = int_ptrs + 3 * n
650
+ SC.labels = int_ptrs + 4 * n
651
+ for i in range(n):
652
+ SC.base_orbits[i] = int_array
653
+ SC.parents[i] = int_array + n
654
+ SC.labels[i] = int_array + 2 * n
655
+ int_array += 3 * n
656
+
657
+ # second level allocations
658
+ if init_gens:
659
+ for i in range(n):
660
+ SC.array_size[i] = default_num_gens
661
+ SC.generators[i] = <int *> sig_malloc( default_num_gens*n * sizeof(int) )
662
+ SC.gen_inverses[i] = <int *> sig_malloc( default_num_gens*n * sizeof(int) )
663
+ if SC.generators[i] is NULL or SC.gen_inverses[i] is NULL:
664
+ SC_dealloc(SC)
665
+ return NULL
666
+
667
+ return SC
668
+
669
+
670
+ cdef inline int SC_realloc_gens(StabilizerChain *SC, int level, int size) noexcept:
671
+ """
672
+ Reallocate generator array at level `level` to size `size`.
673
+
674
+ Return 1 in case of an allocation failure.
675
+ """
676
+ cdef int *temp
677
+ cdef int n = SC.degree
678
+
679
+ temp = <int *> sig_realloc(SC.generators[level], n * size * sizeof(int))
680
+ if temp is NULL:
681
+ return 1
682
+ SC.generators[level] = temp
683
+
684
+ temp = <int *> sig_realloc(SC.gen_inverses[level], n * size * sizeof(int))
685
+ if temp is NULL:
686
+ return 1
687
+ SC.gen_inverses[level] = temp
688
+
689
+ SC.array_size[level] = size
690
+ return 0
691
+
692
+
693
+ cdef inline void SC_dealloc(StabilizerChain *SC) noexcept:
694
+ cdef int i, n
695
+ if SC is not NULL:
696
+ n = SC.degree
697
+ if SC.generators is not NULL:
698
+ for i in range(n):
699
+ sig_free(SC.generators[i])
700
+ sig_free(SC.gen_inverses[i])
701
+ sig_free(SC.generators) # frees int_ptrs
702
+ sig_free(SC.orbit_sizes) # frees int_array
703
+ sig_free(SC.gen_used.bits)
704
+ sig_free(SC.gen_is_id.bits)
705
+ OP_dealloc(SC.OP_scratch)
706
+ sig_free(SC)
707
+
708
+
709
+ cdef StabilizerChain *SC_symmetric_group(int n) noexcept:
710
+ """
711
+ Return a stabilizer chain for the symmetric group on {0, 1, ..., n-1}.
712
+
713
+ Return ``NULL`` in the case of an allocation failure.
714
+ """
715
+ cdef int i, j, b
716
+ cdef StabilizerChain *SC = SC_new(n, False)
717
+ if SC is NULL:
718
+ return NULL
719
+ SC.base_size = n-1
720
+ for i in range(n - 1):
721
+ SC.array_size[i] = n-i-1
722
+ SC.array_size[n-1] = default_num_gens
723
+ for i in range(n):
724
+ SC.generators[i] = <int *> sig_malloc( SC.array_size[i]*n * sizeof(int) )
725
+ SC.gen_inverses[i] = <int *> sig_malloc( SC.array_size[i]*n * sizeof(int) )
726
+ if SC.generators[i] is NULL or SC.gen_inverses[i] is NULL:
727
+ SC_dealloc(SC)
728
+ return NULL
729
+ cdef int *id_perm = SC.perm_scratch
730
+ for i in range(n):
731
+ id_perm[i] = i
732
+ for i in range(n - 1):
733
+ b = i
734
+ SC.orbit_sizes[i] = n-i
735
+ SC.num_gens[i] = n-i-1
736
+ for j in range(i):
737
+ SC.parents[i][j] = -1
738
+ for j in range(n - i):
739
+ SC.base_orbits[i][j] = i+j
740
+ SC.parents[i][i+j] = b
741
+ SC.labels[i][i+j] = j
742
+ for j in range(n - i - 1):
743
+ # j-th generator sends i+j+1 to b
744
+ memcpy(SC.generators[i] + n*j, id_perm, n * sizeof(int) )
745
+ SC.generators[i][n*j + i+j+1] = b
746
+ SC.generators[i][n*j + b] = i+j+1
747
+ memcpy(SC.gen_inverses[i] + n*j, SC.generators[i] + n*j, n * sizeof(int) )
748
+ return SC
749
+
750
+
751
+ cdef StabilizerChain *SC_alternating_group(int n) noexcept:
752
+ """
753
+ Return a stabilizer chain for the alternating group on {0, 1, ..., n-1}.
754
+
755
+ Return ``NULL`` in the case of an allocation failure.
756
+ """
757
+ cdef int i, j, b
758
+ cdef StabilizerChain *SC = SC_new(n, False)
759
+ if SC is NULL:
760
+ return NULL
761
+ SC.base_size = n-2
762
+ for i in range(n - 2):
763
+ SC.array_size[i] = n-i-1
764
+ SC.array_size[n-2] = default_num_gens
765
+ SC.array_size[n-1] = default_num_gens
766
+ for i in range(n):
767
+ SC.generators[i] = <int *> sig_malloc( SC.array_size[i]*n * sizeof(int) )
768
+ SC.gen_inverses[i] = <int *> sig_malloc( SC.array_size[i]*n * sizeof(int) )
769
+ if SC.generators[i] is NULL or SC.gen_inverses[i] is NULL:
770
+ SC_dealloc(SC)
771
+ return NULL
772
+ cdef int *id_perm = SC.perm_scratch
773
+ for i in range(n):
774
+ id_perm[i] = i
775
+ for i in range(n - 2):
776
+ b = i
777
+ SC.orbit_sizes[i] = n-i
778
+ SC.num_gens[i] = n-i-2
779
+ for j in range(i):
780
+ SC.parents[i][j] = -1
781
+ for j in range(n - i):
782
+ SC.base_orbits[i][j] = i+j
783
+ SC.parents[i][i+j] = b
784
+ SC.labels[i][i+j] = j
785
+ SC.labels[i][n-1] = -(n-i-2)
786
+ for j in range(n - i - 2):
787
+ # j-th generator sends i+j+1 to b, i+j+2 to i+j+1, and b to i+j+2
788
+ memcpy(SC.generators[i] + n*j, id_perm, n * sizeof(int) )
789
+ SC.generators[i][n*j + i+j+1] = b
790
+ SC.generators[i][n*j + b ] = i+j+2
791
+ SC.generators[i][n*j + i+j+2] = i+j+1
792
+ SC_invert_perm(SC.gen_inverses[i] + n*j, SC.generators[i] + n*j, n)
793
+ return SC
794
+
795
+
796
+ cdef int SC_realloc_bitsets(StabilizerChain *SC, unsigned long size) noexcept:
797
+ """
798
+ If size is larger than current allocation, double the size of the bitsets
799
+ until it is not.
800
+
801
+ Return 1 in case of an allocation failure.
802
+ """
803
+ cdef unsigned long size_old = SC.gen_used.size
804
+ if size <= size_old:
805
+ return 0
806
+ cdef unsigned long new_size = size_old
807
+ while new_size < size:
808
+ new_size *= 2
809
+ cdef long limbs = (new_size - 1)/(8*sizeof(unsigned long)) + 1
810
+ cdef mp_limb_t *tmp = <mp_limb_t*> sig_realloc(SC.gen_used.bits, limbs * sizeof(mp_limb_t))
811
+ if tmp is not NULL:
812
+ SC.gen_used.bits = tmp
813
+ else:
814
+ return 1
815
+ tmp = <mp_limb_t*> sig_realloc(SC.gen_is_id.bits, limbs * sizeof(mp_limb_t))
816
+ if tmp is not NULL:
817
+ SC.gen_is_id.bits = tmp
818
+ else:
819
+ return 1
820
+ SC.gen_used.limbs = limbs
821
+ SC.gen_is_id.limbs = limbs
822
+ SC.gen_used.size = new_size
823
+ SC.gen_is_id.size = new_size
824
+ SC.gen_used.bits[size_old >> index_shift] &= limb_lower_bits_down(size_old)
825
+ memset(SC.gen_used.bits + (size_old >> index_shift) + 1, 0,
826
+ (limbs - (size_old >> index_shift) - 1) * sizeof(unsigned long))
827
+ SC.gen_is_id.bits[size_old >> index_shift] &= limb_lower_bits_down(size_old)
828
+ memset(SC.gen_is_id.bits + (size_old >> index_shift) + 1, 0,
829
+ (limbs - (size_old >> index_shift) - 1) * sizeof(unsigned long))
830
+ return 0
831
+
832
+
833
+ cdef StabilizerChain *SC_copy(StabilizerChain *SC, int level) noexcept:
834
+ """
835
+ Create a copy of the first `level` levels of SC. Must have 0 < level.
836
+
837
+ Return a null pointer in case of allocation failure.
838
+ """
839
+ cdef int i, n = SC.degree
840
+ cdef StabilizerChain *SCC = SC_new(n, False)
841
+ if SCC is NULL:
842
+ return NULL
843
+ level = min(level, SC.base_size)
844
+ for i in range(level):
845
+ SCC.generators[i] = <int *> sig_malloc( SC.array_size[i]*n * sizeof(int) )
846
+ SCC.gen_inverses[i] = <int *> sig_malloc( SC.array_size[i]*n * sizeof(int) )
847
+ if SCC.generators[i] is NULL or SCC.gen_inverses[i] is NULL:
848
+ SC_dealloc(SCC)
849
+ return NULL
850
+ SCC.array_size[i] = SC.array_size[i]
851
+ for i in range(level, n):
852
+ SCC.generators[i] = <int *> sig_malloc( default_num_gens*n * sizeof(int) )
853
+ SCC.gen_inverses[i] = <int *> sig_malloc( default_num_gens*n * sizeof(int) )
854
+ if SCC.generators[i] is NULL or SCC.gen_inverses[i] is NULL:
855
+ SC_dealloc(SCC)
856
+ return NULL
857
+ SCC.array_size[i] = default_num_gens
858
+ SC_copy_nomalloc(SCC, SC, level) # no chance for memory error here...
859
+ return SCC
860
+
861
+
862
+ cdef int SC_copy_nomalloc(StabilizerChain *SC_dest, StabilizerChain *SC, int level) noexcept:
863
+ cdef int i, n = SC.degree
864
+ level = min(level, SC.base_size)
865
+ SC_dest.base_size = level
866
+ memcpy(SC_dest.orbit_sizes, SC.orbit_sizes, 2*n * sizeof(int) ) # copies orbit_sizes, num_gens
867
+ memcpy(SC_dest.base_orbits[0], SC.base_orbits[0], 3*n*n * sizeof(int) ) # copies base_orbits, parents, labels
868
+ for i in range(level):
869
+ if SC.num_gens[i] > SC_dest.array_size[i]:
870
+ if SC_realloc_gens(SC_dest, i, max(SC.num_gens[i], 2*SC_dest.array_size[i])):
871
+ return 1
872
+ memcpy(SC_dest.generators[i], SC.generators[i], SC.num_gens[i]*n * sizeof(int) )
873
+ memcpy(SC_dest.gen_inverses[i], SC.gen_inverses[i], SC.num_gens[i]*n * sizeof(int) )
874
+ return 0
875
+
876
+
877
+ cdef SC_print_level(StabilizerChain *SC, int level):
878
+ cdef int i, j, n = SC.degree
879
+ if level < SC.base_size:
880
+ print('/ level {}'.format(level))
881
+ print('| orbit {}'.format([SC.base_orbits[level][i]
882
+ for i in range(SC.orbit_sizes[level])]))
883
+ print('| parents {}'.format([SC.parents[level][i] for i in range(n)]))
884
+ print('| labels {}'.format([SC.labels[level][i] for i in range(n)]))
885
+ print('|')
886
+ print('| generators {}'.format([[SC.generators[level][n*i + j]
887
+ for j in range(n)]
888
+ for i in range(SC.num_gens[level])]))
889
+ print(r'\ inverses {}'.format([[SC.gen_inverses[level][n*i + j]
890
+ for j in range(n)]
891
+ for i in range(SC.num_gens[level])]))
892
+ else:
893
+ print('/ level {}'.format(level))
894
+ print('|')
895
+ print(r'\ base_size {}'.format(SC.base_size))
896
+
897
+
898
+ cdef StabilizerChain *SC_new_base(StabilizerChain *SC, int *base, int base_len) noexcept:
899
+ """
900
+ Create a new stabilizer chain whose base starts with the given base, and
901
+ which represents the same permutation group. Original StabilizerChain is
902
+ unmodified.
903
+
904
+ Use SC_cleanup to remove redundant base points.
905
+
906
+ Return a null pointer in case of an allocation failure.
907
+ """
908
+ cdef StabilizerChain *NEW = SC_new(SC.degree)
909
+ if NEW is NULL:
910
+ return NULL
911
+ if SC_new_base_nomalloc(NEW, SC, base, base_len):
912
+ SC_dealloc(NEW)
913
+ return NULL
914
+ return NEW
915
+
916
+
917
+ cdef int SC_new_base_nomalloc(StabilizerChain *SC_dest, StabilizerChain *SC, int *base, int base_len) noexcept:
918
+ cdef int i
919
+ SC_dest.base_size = 0
920
+ for i in range(base_len):
921
+ SC_add_base_point(SC_dest, base[i])
922
+ if SC_update(SC_dest, SC, 0):
923
+ SC_dealloc(SC_dest)
924
+ return 1
925
+ return 0
926
+
927
+
928
+ cdef int SC_update(StabilizerChain *dest, StabilizerChain *source, int level) noexcept:
929
+ cdef mpz_t src_order, dst_order
930
+ cdef int *perm = dest.perm_scratch
931
+ mpz_init(src_order)
932
+ mpz_init(dst_order)
933
+ SC_order(source, level, src_order)
934
+ SC_order(dest, level, dst_order)
935
+ cdef int i, first_moved, b
936
+ while mpz_cmp(dst_order, src_order):
937
+ SC_random_element(source, level, perm)
938
+ i = level
939
+ while i < dest.base_size:
940
+ b = dest.base_orbits[i][0]
941
+ if perm[b] != b:
942
+ break
943
+ i += 1
944
+ else:
945
+ for b in range(dest.degree):
946
+ if perm[b] != b:
947
+ break
948
+ else:
949
+ continue
950
+ SC_add_base_point(dest, b)
951
+ first_moved = i
952
+ for i in range(level, first_moved + 1):
953
+ if SC_insert_and_sift(dest, i, perm, 1, 0): # don't sift!
954
+ mpz_clear(dst_order)
955
+ mpz_clear(src_order)
956
+ return 1
957
+ SC_order(dest, level, dst_order)
958
+ mpz_clear(src_order)
959
+ mpz_clear(dst_order)
960
+ return 0
961
+
962
+
963
+ cdef StabilizerChain *SC_insert_base_point(StabilizerChain *SC, int level, int p) noexcept:
964
+ """
965
+ Insert the point ``p`` as a base point on level ``level``. Return a new
966
+ StabilizerChain with this new base. Original StabilizerChain is unmodified.
967
+
968
+ Use SC_cleanup to remove redundant base points.
969
+
970
+ Return a null pointer in case of an allocation failure.
971
+ """
972
+ cdef int i, b, n = SC.degree
973
+ cdef StabilizerChain *NEW
974
+ if level > 0:
975
+ NEW = SC_copy(SC, level)
976
+ else:
977
+ NEW = SC_new(n)
978
+ if NEW is NULL:
979
+ return NULL
980
+ SC_add_base_point(NEW, p)
981
+ for i in range(level, SC.base_size):
982
+ b = SC.base_orbits[i][0]
983
+ if b != p:
984
+ SC_add_base_point(NEW, b)
985
+ if SC_update(NEW, SC, level):
986
+ SC_dealloc(NEW)
987
+ return NULL
988
+ return NEW
989
+
990
+
991
+ cdef int SC_insert_base_point_nomalloc(StabilizerChain *SC_dest, StabilizerChain *SC, int level, int p) noexcept:
992
+ cdef int i, b
993
+ SC_copy_nomalloc(SC_dest, SC, level)
994
+ SC_add_base_point(SC_dest, p)
995
+ for i in range(level, SC.base_size):
996
+ b = SC.base_orbits[i][0]
997
+ if b != p:
998
+ SC_add_base_point(SC_dest, b)
999
+ if SC_update(SC_dest, SC, level):
1000
+ return 1
1001
+ return 0
1002
+
1003
+
1004
+ cdef int SC_re_tree(StabilizerChain *SC, int level, int *perm, int x) noexcept:
1005
+ """
1006
+ Return values:
1007
+ 0 - No errors.
1008
+ 1 - Allocation failure.
1009
+ """
1010
+ cdef int *gen
1011
+ cdef int *gen_inv
1012
+ cdef int i, b, gen_index, n = SC.degree
1013
+
1014
+ # make sure we have room for the new generator:
1015
+ if SC.array_size[level] == SC.num_gens[level]:
1016
+ if SC_realloc_gens(SC, level, 2*SC.array_size[level]):
1017
+ return 1
1018
+ cdef int *new_gen = SC.generators[level] + n*SC.num_gens[level]
1019
+ cdef int *new_gen_inv = SC.gen_inverses[level] + n*SC.num_gens[level]
1020
+
1021
+ # new generator is perm^(-1) * (path from x to base) (left to right composition)
1022
+ SC_invert_perm(new_gen, perm, n)
1023
+ SC_compose_up_to_base(SC, level, x, new_gen)
1024
+ SC_invert_perm(new_gen_inv, new_gen, n)
1025
+ SC.num_gens[level] += 1
1026
+
1027
+ # now that we have our generators, regenerate the tree, breadth-first
1028
+ b = SC.base_orbits[level][0]
1029
+ for i in range(n):
1030
+ SC.parents[level][i] = -1
1031
+ SC.parents[level][b] = b
1032
+ i = 0
1033
+ SC.orbit_sizes[level] = 1
1034
+ while i < SC.orbit_sizes[level]:
1035
+ x = SC.base_orbits[level][i]
1036
+ for gen_index from SC.num_gens[level] > gen_index >= 0:
1037
+ gen_inv = SC.gen_inverses[level] + n*gen_index
1038
+ SC_scan(SC, level, x, gen_index, gen_inv, 1)
1039
+ for gen_index from 0 <= gen_index < SC.num_gens[level]:
1040
+ gen = SC.generators[level] + n*gen_index
1041
+ SC_scan(SC, level, x, gen_index, gen, -1)
1042
+ i += 1
1043
+ return 0
1044
+
1045
+
1046
+ cdef int SC_sift(StabilizerChain *SC, int level, int x, int *gens, int num_gens, int *new_gens) noexcept:
1047
+ """
1048
+ Apply Schreier's subgroup lemma[1] as follows. Given a level, a point x, and
1049
+ a generator s, find the coset traversal element r coming from x.
1050
+ Try inserting rsR(rs)^(-1) (composing left to right) on level+1, where
1051
+ R(g) is the coset representative of g.
1052
+
1053
+ level - which level we are currently working on
1054
+ x - the object representing r
1055
+ gens - points to the generators to sift by
1056
+ num_gens - how many of these there are
1057
+ new_gens - space of size at least num_gens*n for the sifted perms to go
1058
+
1059
+ Return 1 in case of an allocation failure.
1060
+ """
1061
+ cdef int n = SC.degree
1062
+ if num_gens == 0:
1063
+ return 0
1064
+
1065
+ # copy a representative taking base to the point x to each of these
1066
+ cdef int i
1067
+ cdef int *temp = SC.gen_inverses[level] + n*SC.num_gens[level] # one more scratch space
1068
+ # (available since num_gens > 0)
1069
+ cdef int *rep_inv = temp
1070
+ SC_identify(rep_inv, n)
1071
+ SC_compose_up_to_base(SC, level, x, rep_inv)
1072
+ SC_invert_perm(new_gens, rep_inv, n)
1073
+ for i from 0 < i < num_gens:
1074
+ memcpy(new_gens + n*i, new_gens, n*sizeof(int))
1075
+
1076
+ # post-compose each one with a generator
1077
+ for i from 0 <= i < num_gens:
1078
+ SC_mult_perms(new_gens + n*i, new_gens + n*i, gens + n*i, n)
1079
+
1080
+ # for each one, look up the representative it now gives, and post-compose with that inverse
1081
+ cdef int y, b = SC.base_orbits[level][0]
1082
+ cdef int *perm
1083
+ cdef int *perm_rep_inv = temp
1084
+ for i from 0 <= i < num_gens:
1085
+ perm = new_gens + n*i # this is now rs
1086
+ y = perm[b]
1087
+ SC_identify(perm_rep_inv, n)
1088
+ SC_compose_up_to_base(SC, level, y, perm_rep_inv)
1089
+ SC_mult_perms(perm, perm, perm_rep_inv, n)
1090
+ return SC_insert(SC, level+1, new_gens, num_gens)
1091
+
1092
+
1093
+ cdef int SC_insert_and_sift(StabilizerChain *SC, int level, int *pi, int num_perms, bint sift) noexcept:
1094
+ cdef int i, j, b, n = SC.degree
1095
+ cdef int perm_gen_index
1096
+ if sift:
1097
+ if SC_realloc_bitsets(SC, num_perms):
1098
+ return 1
1099
+ bitset_clear(&SC.gen_used)
1100
+ bitset_clear(&SC.gen_is_id)
1101
+ b = -1
1102
+ for perm_gen_index from 0 <= perm_gen_index < num_perms:
1103
+ for i from 0 <= i < n:
1104
+ if pi[n*perm_gen_index + i] != i:
1105
+ b = i
1106
+ break
1107
+ else:
1108
+ bitset_set(&SC.gen_is_id, perm_gen_index)
1109
+ if b != -1:
1110
+ break
1111
+ if b == -1:
1112
+ return 0
1113
+ if sift and level == SC.base_size:
1114
+ SC_add_base_point(SC, b)
1115
+ else:
1116
+ b = SC.base_orbits[level][0]
1117
+ # Now b is the base element at level `level`
1118
+
1119
+ # Record the old orbit elements and the old generators (see sifting phase)
1120
+ cdef int old_num_gens = SC.num_gens[level]
1121
+
1122
+ # Add new points to the tree:
1123
+ cdef int x
1124
+ cdef int *perm
1125
+ cdef int start_over = 1
1126
+ cdef int re_treed = 0
1127
+ while start_over:
1128
+ start_over = 0
1129
+ for i from 0 <= i < SC.orbit_sizes[level]:
1130
+ x = SC.base_orbits[level][i]
1131
+ for perm_gen_index from 0 <= perm_gen_index < num_perms:
1132
+ if sift and bitset_check(&SC.gen_is_id, perm_gen_index):
1133
+ continue
1134
+ perm = pi + n*perm_gen_index
1135
+ if SC.parents[level][perm[x]] == -1:
1136
+ # now we have an x which maps to a new point under perm,
1137
+ re_treed = 1
1138
+ if sift:
1139
+ bitset_set(&SC.gen_used, perm_gen_index)
1140
+ if SC_re_tree(SC, level, perm, x):
1141
+ return 1
1142
+ start_over = 1 # we must look anew
1143
+ break
1144
+ if start_over:
1145
+ break
1146
+ if not re_treed:
1147
+ continue
1148
+ for perm_gen_index from 0 <= perm_gen_index < old_num_gens:
1149
+ perm = SC.generators[level] + n*perm_gen_index
1150
+ if SC.parents[level][perm[x]] == -1:
1151
+ # now we have an x which maps to a new point under perm,
1152
+ if SC_re_tree(SC, level, perm, x):
1153
+ return 1
1154
+ start_over = 1 # we must look anew
1155
+ break
1156
+ if start_over:
1157
+ break
1158
+ for j from level < j < SC.base_size:
1159
+ for perm_gen_index from 0 <= perm_gen_index < SC.num_gens[j]:
1160
+ perm = SC.generators[j] + n*perm_gen_index
1161
+ if SC.parents[level][perm[x]] == -1:
1162
+ # now we have an x which maps to a new point under perm,
1163
+ if SC_re_tree(SC, level, perm, x):
1164
+ return 1
1165
+ start_over = 1 # we must look anew
1166
+ break
1167
+ if not sift:
1168
+ return 0
1169
+
1170
+ # store the rest of the unused generators in the generator array, after the added ones
1171
+ cdef int new_size
1172
+ cdef int unused_gens = 0
1173
+ for perm_gen_index from 0 <= perm_gen_index < num_perms:
1174
+ if not bitset_check(&SC.gen_used, perm_gen_index) and not bitset_check(&SC.gen_is_id, perm_gen_index):
1175
+ unused_gens += 1
1176
+ if 2*(SC.num_gens[level] + unused_gens) > SC.array_size[level]:
1177
+ new_size = max(2*(SC.num_gens[level] + unused_gens), 2*SC.array_size[level])
1178
+ if SC_realloc_gens(SC, level, new_size):
1179
+ return 1
1180
+ i = 0
1181
+ for perm_gen_index from 0 <= perm_gen_index < num_perms:
1182
+ if not bitset_check(&SC.gen_used, perm_gen_index) and not bitset_check(&SC.gen_is_id, perm_gen_index):
1183
+ memcpy(SC.generators[level] + n*(SC.num_gens[level]+i), pi + n*perm_gen_index, n*sizeof(int))
1184
+ i += 1
1185
+
1186
+ # Sift:
1187
+ cdef int *gens = SC.generators[level]
1188
+ cdef int total_gens = SC.num_gens[level] + unused_gens
1189
+ cdef int section, gens_in_section
1190
+ for i from 0 <= i < SC.orbit_sizes[level]:
1191
+ x = SC.base_orbits[level][i]
1192
+ section = 0
1193
+ while section*n < total_gens:
1194
+ gens_in_section = min(n, total_gens - section*n)
1195
+ if SC_sift(SC, level, x, gens + n*n*section, gens_in_section, gens + n*total_gens):
1196
+ return 1
1197
+ section += 1
1198
+ return 0
1199
+
1200
+
1201
+ cdef bint SC_is_giant(int n, int num_perms, int *perms, float p, bitset_t support) noexcept:
1202
+ """
1203
+ Test whether the group generated by the input permutations is a giant, i.e.,
1204
+ the alternating or symmetric group.
1205
+
1206
+ If the group is not a giant, this routine will return False. This could also
1207
+ indicate an allocation failure.
1208
+
1209
+ If the group is a giant, this routine will return ``True`` with approximate
1210
+ probability ``p``. It will set `support' to the support of the group in this
1211
+ case. Use bitset_len to get the size of support.
1212
+
1213
+ The bitset `support' must be initialized. Must have 0 <= p < 1.
1214
+
1215
+ Running time is roughly O(-ln(1-p)*n*ln(m)) where m <= n is the size of the
1216
+ support of the group.
1217
+ """
1218
+ cdef int i, j, num_steps, support_root
1219
+ cdef size_t m = 1
1220
+ cdef unsigned long q
1221
+ cdef int *gen
1222
+ cdef int *perm = <int *> sig_malloc(n*sizeof(int))
1223
+ cdef OrbitPartition *OP = OP_new(n)
1224
+ if OP is NULL or perm is NULL:
1225
+ OP_dealloc(OP)
1226
+ sig_free(perm)
1227
+ return False
1228
+
1229
+ # giants are transitive
1230
+ for j from 0 <= j < num_perms:
1231
+ gen = perms + n*j
1232
+ for i from 0 <= i < n:
1233
+ OP_join(OP, i, gen[i])
1234
+ for i from 0 <= i < n:
1235
+ if OP.parent[i] == i:
1236
+ if OP.size[i] != 1:
1237
+ if m != 1:
1238
+ m = 1
1239
+ break
1240
+ else:
1241
+ m = OP.size[i]
1242
+ support_root = i
1243
+ if m == 1:
1244
+ OP_dealloc(OP)
1245
+ sig_free(perm)
1246
+ return False
1247
+ bitset_zero(support)
1248
+ for i from 0 <= i < n:
1249
+ if OP_find(OP, i) == support_root:
1250
+ bitset_set(support, i)
1251
+
1252
+ # get a bit lost in the group, so our random elements are more random:
1253
+ SC_identify(perm, n)
1254
+ for i from 0 <= i < 10:
1255
+ SC_mult_perms(perm, perm, perms + n*(rand() % num_perms), n)
1256
+
1257
+ # look for elements with cycles of prime length q, m/2 < q < m-2
1258
+ num_steps = <int> ceil(-log(1-p)*log(m)/log(2))
1259
+ for j from 0 <= j < num_steps:
1260
+ OP_clear(OP)
1261
+ for i from 0 <= i < n:
1262
+ OP_join(OP, i, perm[i])
1263
+ for i from 0 <= i < n:
1264
+ if OP.parent[i] == i:
1265
+ q = OP.size[i]
1266
+ if m < 2*q and q < m-2:
1267
+ if n_is_prime(q):
1268
+ sig_free(perm)
1269
+ OP_dealloc(OP)
1270
+ return True
1271
+ SC_mult_perms(perm, perm, perms + n*(rand() % num_perms), n)
1272
+ OP_dealloc(OP)
1273
+ sig_free(perm)
1274
+ return False
1275
+
1276
+
1277
+ def SC_test_list_perms(list L, int n, int limit, bint gap, bint limit_complain, bint test_contains):
1278
+ """
1279
+ Test that the permutation group generated by list perms in L of degree n
1280
+ is of the correct order, by comparing with GAP. Don't test if the group is
1281
+ of size greater than limit.
1282
+
1283
+ TESTS::
1284
+
1285
+ sage: # needs sage.groups
1286
+ sage: from sage.groups.perm_gps.partn_ref.data_structures import SC_test_list_perms
1287
+ sage: limit = 10^7
1288
+ sage: def test_Sn_on_m_points(n, m, gap, contains):
1289
+ ....: perm1 = [1,0] + list(range(2, m))
1290
+ ....: perm2 = [(i+1)%n for i in range( n )] + list(range(n,m))
1291
+ ....: SC_test_list_perms([perm1, perm2], m, limit, gap, 0, contains)
1292
+ sage: for i in range(2,9):
1293
+ ....: test_Sn_on_m_points(i,i,1,0)
1294
+ sage: for i in range(2,9):
1295
+ ....: test_Sn_on_m_points(i,i,0,1)
1296
+ sage: for i in range(2,9): # long time
1297
+ ....: test_Sn_on_m_points(i,i,1,1)
1298
+ sage: test_Sn_on_m_points(8,8,1,1)
1299
+ sage: def test_stab_chain_fns_1(n, gap, contains):
1300
+ ....: perm1 = sum([[2*i+1,2*i] for i in range(n)], [])
1301
+ ....: perm2 = [(i+1)%(2*n) for i in range( 2*n)]
1302
+ ....: SC_test_list_perms([perm1, perm2], 2*n, limit, gap, 0, contains)
1303
+ sage: for n in range(1,11):
1304
+ ....: test_stab_chain_fns_1(n, 1, 0)
1305
+ sage: for n in range(1,11):
1306
+ ....: test_stab_chain_fns_1(n, 0, 1)
1307
+ sage: for n in range(1,9): # long time
1308
+ ....: test_stab_chain_fns_1(n, 1, 1)
1309
+ sage: test_stab_chain_fns_1(11, 1, 1)
1310
+ sage: def test_stab_chain_fns_2(n, gap, contains):
1311
+ ....: perms = []
1312
+ ....: for p,e in factor(n):
1313
+ ....: perm1 = [(p*(i//p)) + ((i+1)%p) for i in range(n)]
1314
+ ....: perms.append(perm1)
1315
+ ....: SC_test_list_perms(perms, n, limit, gap, 0, contains)
1316
+ sage: for n in range(2,11):
1317
+ ....: test_stab_chain_fns_2(n, 1, 0)
1318
+ sage: for n in range(2,11):
1319
+ ....: test_stab_chain_fns_2(n, 0, 1)
1320
+ sage: for n in range(2,11): # long time
1321
+ ....: test_stab_chain_fns_2(n, 1, 1)
1322
+ sage: test_stab_chain_fns_2(11, 1, 1)
1323
+ sage: def test_stab_chain_fns_3(n, gap, contains):
1324
+ ....: perm1 = [(-i)%n for i in range( n )]
1325
+ ....: perm2 = [(i+1)%n for i in range( n )]
1326
+ ....: SC_test_list_perms([perm1, perm2], n, limit, gap, 0, contains)
1327
+ sage: for n in range(2,20):
1328
+ ....: test_stab_chain_fns_3(n, 1, 0)
1329
+ sage: for n in range(2,20):
1330
+ ....: test_stab_chain_fns_3(n, 0, 1)
1331
+ sage: for n in range(2,14): # long time
1332
+ ....: test_stab_chain_fns_3(n, 1, 1)
1333
+ sage: test_stab_chain_fns_3(20, 1, 1)
1334
+ sage: def test_stab_chain_fns_4(n, g, gap, contains):
1335
+ ....: perms = []
1336
+ ....: for _ in range(g):
1337
+ ....: perm = list(range(n))
1338
+ ....: shuffle(perm)
1339
+ ....: perms.append(perm)
1340
+ ....: SC_test_list_perms(perms, n, limit, gap, 0, contains)
1341
+ sage: for n in range(4,9): # long time
1342
+ ....: test_stab_chain_fns_4(n, 1, 1, 0)
1343
+ ....: test_stab_chain_fns_4(n, 2, 1, 0)
1344
+ ....: test_stab_chain_fns_4(n, 2, 1, 0)
1345
+ ....: test_stab_chain_fns_4(n, 2, 1, 0)
1346
+ ....: test_stab_chain_fns_4(n, 2, 1, 0)
1347
+ ....: test_stab_chain_fns_4(n, 3, 1, 0)
1348
+ sage: for n in range(4,9): # known bug (see :issue:`32187`), not tested
1349
+ ....: test_stab_chain_fns_4(n, 1, 0, 1)
1350
+ ....: for j in range(6):
1351
+ ....: test_stab_chain_fns_4(n, 2, 0, 1)
1352
+ ....: test_stab_chain_fns_4(n, 3, 0, 1)
1353
+ sage: for n in range(4,8): # long time
1354
+ ....: test_stab_chain_fns_4(n, 1, 1, 1)
1355
+ ....: test_stab_chain_fns_4(n, 2, 1, 1)
1356
+ ....: test_stab_chain_fns_4(n, 2, 1, 1)
1357
+ ....: test_stab_chain_fns_4(n, 3, 1, 1)
1358
+ sage: test_stab_chain_fns_4(8, 2, 1, 1)
1359
+ sage: def test_stab_chain_fns_5(n, gap, contains):
1360
+ ....: perms = []
1361
+ ....: m = n//3
1362
+ ....: perm1 = list(range(2*m))
1363
+ ....: shuffle(perm1)
1364
+ ....: perm1 += list(range(2*m,n))
1365
+ ....: perm2 = list(range(m,n))
1366
+ ....: shuffle(perm2)
1367
+ ....: perm2 = list(range(m)) + perm2
1368
+ ....: SC_test_list_perms([perm1, perm2], n, limit, gap, 0, contains)
1369
+ sage: for n in [4..9]: # long time
1370
+ ....: for _ in range(2):
1371
+ ....: test_stab_chain_fns_5(n, 1, 0)
1372
+ sage: for n in [4..8]: # long time
1373
+ ....: test_stab_chain_fns_5(n, 0, 1)
1374
+ sage: for n in [4..9]: # long time
1375
+ ....: test_stab_chain_fns_5(n, 1, 1)
1376
+ sage: def random_perm(x):
1377
+ ....: shuffle(x)
1378
+ ....: return x
1379
+ sage: def test_stab_chain_fns_6(m, n, k, gap, contains):
1380
+ ....: perms = []
1381
+ ....: for i in range(k):
1382
+ ....: perm = sum([random_perm(list(range(i*(n//m),min(n,(i+1)*(n//m))))) for i in range(m)], [])
1383
+ ....: perms.append(perm)
1384
+ ....: SC_test_list_perms(perms, m*(n//m), limit, gap, 0, contains)
1385
+ sage: for m in range(2,9): # long time
1386
+ ....: for n in range(m,3*m):
1387
+ ....: for k in range(1,3):
1388
+ ....: test_stab_chain_fns_6(m,n,k, 1, 0)
1389
+ sage: for m in range(2,10):
1390
+ ....: for n in range(m,4*m):
1391
+ ....: for k in range(1,3):
1392
+ ....: test_stab_chain_fns_6(m,n,k, 0, 1)
1393
+ sage: test_stab_chain_fns_6(10,20,2, 1, 1)
1394
+ sage: test_stab_chain_fns_6(8,16,2, 1, 1)
1395
+ sage: test_stab_chain_fns_6(6,36,2, 1, 1)
1396
+ sage: test_stab_chain_fns_6(4,40,3, 1, 1)
1397
+ sage: test_stab_chain_fns_6(4,40,2, 1, 1)
1398
+ sage: def test_stab_chain_fns_7(n, cop, gap, contains):
1399
+ ....: perms = []
1400
+ ....: for i in range(0,n//2,2):
1401
+ ....: p = list(range(n))
1402
+ ....: p[i] = i+1
1403
+ ....: p[i+1] = i
1404
+ ....: if cop:
1405
+ ....: perms.append([c for c in p])
1406
+ ....: else:
1407
+ ....: perms.append(p)
1408
+ ....: SC_test_list_perms(perms, n, limit, gap, 0, contains)
1409
+ sage: for n in [6..14]:
1410
+ ....: test_stab_chain_fns_7(n, 1, 1, 0)
1411
+ ....: test_stab_chain_fns_7(n, 0, 1, 0)
1412
+ sage: for n in [6..30]:
1413
+ ....: test_stab_chain_fns_7(n, 1, 0, 1)
1414
+ ....: test_stab_chain_fns_7(n, 0, 0, 1)
1415
+ sage: for n in [6..14]: # long time
1416
+ ....: test_stab_chain_fns_7(n, 1, 1, 1)
1417
+ ....: test_stab_chain_fns_7(n, 0, 1, 1)
1418
+ sage: test_stab_chain_fns_7(20, 1, 1, 1)
1419
+ sage: test_stab_chain_fns_7(20, 0, 1, 1)
1420
+ """
1421
+ if gap:
1422
+ from sage.groups.perm_gps.permgroup import PermutationGroup
1423
+ from sage.groups.perm_gps.constructor import PermutationGroupElement
1424
+ from sage.misc.prandom import shuffle
1425
+
1426
+ cdef StabilizerChain *SC
1427
+ cdef StabilizerChain *SCC
1428
+ cdef StabilizerChain *SCCC
1429
+ cdef StabilizerChain *SC_nb
1430
+ cdef Integer order, order2
1431
+ cdef int i, j, m, SC_says
1432
+ cdef bitset_t giant_support
1433
+ if gap:
1434
+ G = PermutationGroup([[i+1 for i in p] for p in L])
1435
+ if G.order() > limit:
1436
+ if limit_complain:
1437
+ print('TOO BIG')
1438
+ return
1439
+ SC = SC_new(n)
1440
+ cdef int *perm = <int *>sig_malloc(n * (len(L)+3) * sizeof(int))
1441
+ try:
1442
+ bitset_init(giant_support, n)
1443
+ except MemoryError:
1444
+ sig_free(perm)
1445
+ SC_dealloc(SC)
1446
+ raise MemoryError
1447
+ if perm is NULL or SC is NULL:
1448
+ bitset_free(giant_support)
1449
+ sig_free(perm)
1450
+ SC_dealloc(SC)
1451
+ raise MemoryError
1452
+ cdef int *perm2 = perm + n
1453
+ cdef int *perm3 = perm + 2 * n
1454
+ for Lperm in L:
1455
+ for i from 0 <= i < n:
1456
+ perm[i] = Lperm[i]
1457
+ if SC_insert(SC, 0, perm, 1):
1458
+ bitset_free(giant_support)
1459
+ sig_free(perm)
1460
+ SC_dealloc(SC)
1461
+ raise MemoryError
1462
+ SCC = SC_copy(SC, n)
1463
+ SCCC = SC_insert_base_point(SC, 0, n-1)
1464
+ for i from 0 <= i < n:
1465
+ perm[i] = n-i-1
1466
+ SC_nb = SC_new_base(SC, perm, n)
1467
+ if SCC is NULL or SCCC is NULL or SC_nb is NULL:
1468
+ bitset_free(giant_support)
1469
+ sig_free(perm)
1470
+ SC_dealloc(SC)
1471
+ SC_dealloc(SCC)
1472
+ SC_dealloc(SCCC)
1473
+ SC_dealloc(SC_nb)
1474
+ raise MemoryError
1475
+ giant = False
1476
+ try:
1477
+ order = Integer(0)
1478
+ SC_order(SC,0,order.value)
1479
+ j = 0
1480
+ for Lperm in L:
1481
+ for i from 0 <= i < n:
1482
+ perm[n*j + i] = Lperm[i]
1483
+ j += 1
1484
+ if SC_is_giant(n, len(L), perm, 0.9, giant_support):
1485
+ giant = True
1486
+ m = bitset_len(giant_support)
1487
+ from sage.arith.misc import factorial
1488
+ if not (order == factorial(m) or order == factorial(m)/2):
1489
+ print("SC_is_giant failed: %s %s" % (str(L), order))
1490
+ raise AssertionError
1491
+ if order == factorial(n):
1492
+ SC_dealloc(SC)
1493
+ SC = SC_symmetric_group(n)
1494
+ SC_order(SC,0,order.value)
1495
+ if not order == factorial(n):
1496
+ print("SC_symmetric_group failed: %s %s" % (str(L), order))
1497
+ raise AssertionError
1498
+ elif order == factorial(n)/2:
1499
+ SC_dealloc(SC)
1500
+ SC = SC_alternating_group(n)
1501
+ SC_order(SC,0,order.value)
1502
+ if not order == factorial(n)/2:
1503
+ print("SC_alternating_group failed: %s %s" % (str(L), order))
1504
+ raise AssertionError
1505
+ order2 = Integer(0)
1506
+ SC_order(SCC,0,order2.value)
1507
+ if order != order2:
1508
+ print("FAIL {}".format(L))
1509
+ print('SC_copy(n) does not agree with order of original {} {}'.format(order, order2))
1510
+ raise AssertionError
1511
+ SC_order(SCCC,0,order2.value)
1512
+ if order != order2:
1513
+ print("FAIL {}".format(L))
1514
+ print('does not agree with order of inserted base point {} {}'.format(order, order2))
1515
+ raise AssertionError
1516
+ SC_order(SC_nb,0,order2.value)
1517
+ if order != order2:
1518
+ print("FAIL {}".format(L))
1519
+ print('does not agree with order of new base {} {}'.format(order, order2))
1520
+ raise AssertionError
1521
+ if test_contains:
1522
+ for i from 0 <= i < 3:
1523
+ SC_random_element(SC, 0, perm)
1524
+ if not SC_contains(SC, 0, perm, 0):
1525
+ print("FAIL {}".format(L))
1526
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1527
+ print('SC_random_element says it is an element, SC_contains(modify=0) does not')
1528
+ raise AssertionError
1529
+ if not SC_contains(SC, 0, perm, 1):
1530
+ print("FAIL {}".format(L))
1531
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1532
+ print('SC_random_element says it is an element, SC_contains(modify=1) does not')
1533
+ raise AssertionError
1534
+ if not SC_contains(SCC, 0, perm, 0):
1535
+ print("FAIL {}".format(L))
1536
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1537
+ print('SC_random_element says it is an element, SC_contains(modify=0) does not on copy')
1538
+ raise AssertionError
1539
+ if not SC_contains(SCC, 0, perm, 1):
1540
+ print("FAIL {}".format(L))
1541
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1542
+ print('SC_random_element says it is an element, SC_contains(modify=1) does not on copy')
1543
+ raise AssertionError
1544
+ if not SC_contains(SCCC, 0, perm, 0):
1545
+ print("FAIL {}".format(L))
1546
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1547
+ print('SC_random_element says it is an element, SC_contains(modify=0) does not on inserted base point')
1548
+ raise AssertionError
1549
+ if not SC_contains(SCCC, 0, perm, 1):
1550
+ print("FAIL {}".format(L))
1551
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1552
+ print('SC_random_element says it is an element, SC_contains(modify=1) does not on inserted base point')
1553
+ raise AssertionError
1554
+ if not SC_contains(SC_nb, 0, perm, 0):
1555
+ print("FAIL {}".format(L))
1556
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1557
+ print('SC_random_element says it is an element, SC_contains(modify=0) does not on new base')
1558
+ raise AssertionError
1559
+ if not SC_contains(SC_nb, 0, perm, 1):
1560
+ print("FAIL {}".format(L))
1561
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1562
+ print('SC_random_element says it is an element, SC_contains(modify=1) does not on new base')
1563
+ raise AssertionError
1564
+ SC_random_element(SCC, 0, perm2)
1565
+ if not SC_contains(SC, 0, perm2, 0):
1566
+ print("FAIL {}".format(L))
1567
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1568
+ print('SC_random_element says it is an element of copy, SC_contains(modify=0) does not')
1569
+ raise AssertionError
1570
+ if not SC_contains(SC, 0, perm2, 1):
1571
+ print("FAIL {}".format(L))
1572
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1573
+ print('SC_random_element says it is an element of copy, SC_contains(modify=1) does not')
1574
+ raise AssertionError
1575
+ SC_random_element(SCCC, 0, perm3)
1576
+ if not SC_contains(SC, 0, perm3, 0):
1577
+ print("FAIL {}".format(L))
1578
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1579
+ print('SC_random_element says it is an element of inserted base point, SC_contains(modify=0) does not')
1580
+ raise AssertionError
1581
+ if not SC_contains(SC, 0, perm3, 1):
1582
+ print("FAIL {}".format(L))
1583
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1584
+ print('SC_random_element says it is an element of inserted base point, SC_contains(modify=1) does not')
1585
+ raise AssertionError
1586
+ SC_random_element(SC_nb, 0, perm3)
1587
+ if not SC_contains(SC, 0, perm3, 0):
1588
+ print("FAIL {}".format(L))
1589
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1590
+ print('SC_random_element says it is an element of new base, SC_contains(modify=0) does not')
1591
+ raise AssertionError
1592
+ if not SC_contains(SC, 0, perm3, 1):
1593
+ print("FAIL {}".format(L))
1594
+ print('element {}'.format([perm[ii] for ii in range(n)]))
1595
+ print('SC_random_element says it is an element of new base, SC_contains(modify=1) does not')
1596
+ raise AssertionError
1597
+ if gap:
1598
+ order = Integer(0)
1599
+ SC_order(SC,0,order.value)
1600
+ j = 0
1601
+ for Lperm in L:
1602
+ for i from 0 <= i < n:
1603
+ perm[n*j + i] = Lperm[i]
1604
+ j += 1
1605
+ if SC_is_giant(n, len(L), perm, 0.9, giant_support):
1606
+ from sage.arith.misc import factorial
1607
+ m = bitset_len(giant_support)
1608
+ if order != factorial(m) and order != factorial(m)//2:
1609
+ print("SC_is_giant failed: %s %s" % (str(L), order))
1610
+ raise AssertionError
1611
+ if order != G.order():
1612
+ print("FAIL {}".format(L))
1613
+ print('order was computed to be {}'.format(order))
1614
+ print('GAP says it is {}'.format(G.order()))
1615
+ raise AssertionError
1616
+ if test_contains:
1617
+ for i from 0 <= i < 3:
1618
+ permy = G.random_element()
1619
+ for j from 0 <= j < n:
1620
+ perm[j] = permy(j+1)-1
1621
+ if not SC_contains(SC, 0, perm, 0):
1622
+ print("FAIL {}".format(L))
1623
+ print('element {}'.format(permy))
1624
+ print('GAP says it is an element, SC_contains(modify=0) does not')
1625
+ raise AssertionError
1626
+ if not SC_contains(SC, 0, perm, 1):
1627
+ print("FAIL {}".format(L))
1628
+ print('element {}'.format(permy))
1629
+ print('GAP says it is an element, SC_contains(modify=1) does not')
1630
+ raise AssertionError
1631
+ permy = list(range(1, n + 1))
1632
+ shuffle(permy)
1633
+ gap_says = (PermutationGroupElement(permy) in G)
1634
+ for j from 0 <= j < n:
1635
+ perm[j] = permy[j]-1
1636
+ SC_says = SC_contains(SC, 0, perm, 0)
1637
+ if bool(SC_says) != bool(gap_says):
1638
+ print("FAIL {}".format(L))
1639
+ print('element {}'.format(permy))
1640
+ print('GAP says %d, SC_contains(modify=0) says %d' % (gap_says, SC_says))
1641
+ raise AssertionError
1642
+ SC_says = SC_contains(SC, 0, perm, 1)
1643
+ if bool(SC_says) != bool(gap_says):
1644
+ print("FAIL {}".format(L))
1645
+ print('element {}'.format(permy))
1646
+ print('GAP says %d, SC_contains(modify=0) says %d' % (gap_says, SC_says))
1647
+ raise AssertionError
1648
+ SC_random_element(SC, 0, perm)
1649
+ for j from 0 <= j < n:
1650
+ permy[j] = perm[j]+1
1651
+ gap_says = (PermutationGroupElement(permy) in G)
1652
+ if not SC_contains(SC, 0, perm, 0):
1653
+ print("FAIL {}".format(L))
1654
+ print('element {}'.format(permy))
1655
+ print('random element not contained in group, modify=false')
1656
+ raise AssertionError
1657
+ if not SC_contains(SC, 0, perm, 1):
1658
+ print("FAIL {}".format(L))
1659
+ print('element {}'.format(permy))
1660
+ print('random element not contained in group, modify=true')
1661
+ raise AssertionError
1662
+ if not gap_says:
1663
+ print("FAIL {}".format(L))
1664
+ print('element {}'.format(permy))
1665
+ print('random element not contained in group, according to GAP')
1666
+ raise AssertionError
1667
+ except Exception:
1668
+ if giant:
1669
+ print("detected giant!")
1670
+ raise
1671
+ finally:
1672
+ bitset_free(giant_support)
1673
+ sig_free(perm)
1674
+ SC_dealloc(SC)
1675
+ SC_dealloc(SCC)
1676
+ SC_dealloc(SCCC)
1677
+ SC_dealloc(SC_nb)
1678
+
1679
+
1680
+ # Functions
1681
+
1682
+ cdef int sort_by_function(PartitionStack *PS, int start, int *degrees) noexcept:
1683
+ """
1684
+ A simple counting sort, given the degrees of vertices to a certain cell.
1685
+
1686
+ INPUT:
1687
+
1688
+ - ``PS`` -- the partition stack to be checked
1689
+ - ``start`` -- beginning index of the cell to be sorted
1690
+ - ``degrees`` -- the values to be sorted by, must have extra scratch space for a
1691
+ total of `3*n+1`
1692
+ """
1693
+ cdef int n = PS.degree
1694
+ cdef int i, j, max, max_location
1695
+ cdef int *counts = degrees + n
1696
+ cdef int *output = degrees + 2*n + 1
1697
+ for i from 0 <= i <= n:
1698
+ counts[i] = 0
1699
+ i = 0
1700
+ while PS.levels[i+start] > PS.depth:
1701
+ counts[degrees[i]] += 1
1702
+ i += 1
1703
+ counts[degrees[i]] += 1
1704
+ # i+start is the right endpoint of the cell now
1705
+ max = counts[0]
1706
+ max_location = 0
1707
+ for j from 0 < j <= n:
1708
+ if counts[j] > max:
1709
+ max = counts[j]
1710
+ max_location = j
1711
+ counts[j] += counts[j - 1]
1712
+ for j from i >= j >= 0:
1713
+ counts[degrees[j]] -= 1
1714
+ output[counts[degrees[j]]] = PS.entries[start+j]
1715
+ max_location = counts[max_location]+start
1716
+ for j from 0 <= j <= i:
1717
+ PS.entries[start+j] = output[j]
1718
+ j = 1
1719
+ while j <= n and counts[j] <= i:
1720
+ if counts[j] > 0:
1721
+ PS.levels[start + counts[j] - 1] = PS.depth
1722
+ PS_move_min_to_front(PS, start + counts[j-1], start + counts[j] - 1)
1723
+ j += 1
1724
+ return max_location
1725
+
1726
+
1727
+ cdef int refine_by_orbits(PartitionStack *PS, StabilizerChain *SC, int *perm_stack, int *cells_to_refine_by, int *ctrb_len) noexcept:
1728
+ """
1729
+ Given a stabilizer chain SC, refine the partition stack PS so that each cell
1730
+ contains elements from at most one orbit, and sort the refined cells by
1731
+ their minimal cell representatives in the orbit of the group.
1732
+ """
1733
+ cdef int start, level, gen_index, i, j, k, x, n = SC.degree
1734
+ cdef int *gen
1735
+ cdef int *min_cell_reps = SC.perm_scratch
1736
+ cdef int *perm = perm_stack + n*PS.depth
1737
+ cdef OrbitPartition *OP = SC.OP_scratch
1738
+ cdef int invariant = 1
1739
+ OP_clear(OP)
1740
+ for level from PS.depth <= level < SC.base_size:
1741
+ for gen_index from 0 <= gen_index < SC.num_gens[level]:
1742
+ gen = SC.generators[level] + gen_index*n
1743
+ for i from 0 <= i < n:
1744
+ OP_join(OP, i, gen[i])
1745
+ start = 0
1746
+ while start < n:
1747
+ i = 0
1748
+ while 1:
1749
+ x = PS.entries[start+i]
1750
+ x = perm[x]
1751
+ min_cell_reps[i] = OP.mcr[OP_find(OP, x)]
1752
+ i += 1
1753
+ if PS.levels[start+i-1] <= PS.depth:
1754
+ break
1755
+ invariant += sort_by_function(PS, start, min_cell_reps)
1756
+ invariant += i
1757
+ # update cells_to_refine_by
1758
+ k = start
1759
+ for j from start <= j < start+i:
1760
+ if PS.levels[j] == PS.depth:
1761
+ k = j+1
1762
+ cells_to_refine_by[ctrb_len[0]] = k
1763
+ ctrb_len[0] += 1
1764
+ start += i
1765
+ return invariant
1766
+
1767
+
1768
+ cdef int compute_relabeling(StabilizerChain *group, StabilizerChain *scratch_group,
1769
+ int *permutation, int *relabeling) noexcept:
1770
+ """
1771
+ Technically, compute the INVERSE of the relabeling
1772
+ """
1773
+ cdef int i, j, x, y, m, n = group.degree, orbit_element
1774
+ cdef int *scratch = group.perm_scratch
1775
+ if SC_new_base_nomalloc(scratch_group, group, permutation, n):
1776
+ return 1
1777
+ group = scratch_group
1778
+ SC_identify(relabeling, n)
1779
+ for i from 0 <= i < n:
1780
+ m = n
1781
+ for j from 0 <= j < group.orbit_sizes[i]:
1782
+ orbit_element = group.base_orbits[i][j]
1783
+ x = relabeling[orbit_element]
1784
+ if x < m:
1785
+ m = x
1786
+ y = orbit_element
1787
+ SC_invert_perm(scratch, relabeling, n)
1788
+ SC_compose_up_to_base(group, i, y, scratch)
1789
+ SC_invert_perm(relabeling, scratch, n)
1790
+ SC_invert_perm(scratch, relabeling, n)
1791
+ memcpy(relabeling, scratch, n*sizeof(int))
1792
+ return 0