snappy 3.3__cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. snappy/CyOpenGL.cpython-310-aarch64-linux-gnu.so +0 -0
  2. snappy/SnapPy.cpython-310-aarch64-linux-gnu.so +0 -0
  3. snappy/SnapPy.ico +0 -0
  4. snappy/SnapPy.png +0 -0
  5. snappy/SnapPyHP.cpython-310-aarch64-linux-gnu.so +0 -0
  6. snappy/__init__.py +534 -0
  7. snappy/app.py +604 -0
  8. snappy/app_menus.py +372 -0
  9. snappy/browser.py +998 -0
  10. snappy/cache.py +25 -0
  11. snappy/canonical.py +249 -0
  12. snappy/cusps/__init__.py +280 -0
  13. snappy/cusps/cusp_area_matrix.py +98 -0
  14. snappy/cusps/cusp_areas_from_matrix.py +96 -0
  15. snappy/cusps/maximal_cusp_area_matrix.py +136 -0
  16. snappy/cusps/short_slopes_for_cusp.py +217 -0
  17. snappy/cusps/test.py +22 -0
  18. snappy/cusps/trig_cusp_area_matrix.py +63 -0
  19. snappy/database.py +454 -0
  20. snappy/db_utilities.py +79 -0
  21. snappy/decorated_isosig.py +717 -0
  22. snappy/dev/__init__.py +0 -0
  23. snappy/dev/extended_ptolemy/__init__.py +8 -0
  24. snappy/dev/extended_ptolemy/closed.py +106 -0
  25. snappy/dev/extended_ptolemy/complexVolumesClosed.py +149 -0
  26. snappy/dev/extended_ptolemy/direct.py +42 -0
  27. snappy/dev/extended_ptolemy/extended.py +406 -0
  28. snappy/dev/extended_ptolemy/giac_helper.py +43 -0
  29. snappy/dev/extended_ptolemy/giac_rur.py +129 -0
  30. snappy/dev/extended_ptolemy/gluing.py +46 -0
  31. snappy/dev/extended_ptolemy/phc_wrapper.py +220 -0
  32. snappy/dev/extended_ptolemy/printMatrices.py +70 -0
  33. snappy/dev/vericlosed/__init__.py +1 -0
  34. snappy/dev/vericlosed/computeApproxHyperbolicStructureNew.py +159 -0
  35. snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +90 -0
  36. snappy/dev/vericlosed/computeVerifiedHyperbolicStructure.py +111 -0
  37. snappy/dev/vericlosed/gimbalLoopFinder.py +130 -0
  38. snappy/dev/vericlosed/hyperbolicStructure.py +313 -0
  39. snappy/dev/vericlosed/krawczykCertifiedEdgeLengthsEngine.py +165 -0
  40. snappy/dev/vericlosed/oneVertexTruncatedComplex.py +122 -0
  41. snappy/dev/vericlosed/orb/__init__.py +1 -0
  42. snappy/dev/vericlosed/orb/orb_solution_for_snappea_finite_triangulation_mac +0 -0
  43. snappy/dev/vericlosed/parseVertexGramMatrixFile.py +47 -0
  44. snappy/dev/vericlosed/polishApproxHyperbolicStructure.py +61 -0
  45. snappy/dev/vericlosed/test.py +54 -0
  46. snappy/dev/vericlosed/truncatedComplex.py +176 -0
  47. snappy/dev/vericlosed/verificationError.py +58 -0
  48. snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +177 -0
  49. snappy/doc/_images/SnapPy-196.png +0 -0
  50. snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
  51. snappy/doc/_images/m125_paper_plane.jpg +0 -0
  52. snappy/doc/_images/mac.png +0 -0
  53. snappy/doc/_images/o9_00000_systole_paper_plane.jpg +0 -0
  54. snappy/doc/_images/o9_00000_systole_paper_plane_closer.jpg +0 -0
  55. snappy/doc/_images/plink-action.png +0 -0
  56. snappy/doc/_images/ubuntu.png +0 -0
  57. snappy/doc/_images/win7.png +0 -0
  58. snappy/doc/_sources/additional_classes.rst.txt +40 -0
  59. snappy/doc/_sources/bugs.rst.txt +14 -0
  60. snappy/doc/_sources/censuses.rst.txt +52 -0
  61. snappy/doc/_sources/credits.rst.txt +81 -0
  62. snappy/doc/_sources/development.rst.txt +261 -0
  63. snappy/doc/_sources/index.rst.txt +215 -0
  64. snappy/doc/_sources/installing.rst.txt +249 -0
  65. snappy/doc/_sources/manifold.rst.txt +6 -0
  66. snappy/doc/_sources/manifoldhp.rst.txt +46 -0
  67. snappy/doc/_sources/news.rst.txt +425 -0
  68. snappy/doc/_sources/other.rst.txt +25 -0
  69. snappy/doc/_sources/platonic_census.rst.txt +20 -0
  70. snappy/doc/_sources/plink.rst.txt +102 -0
  71. snappy/doc/_sources/ptolemy.rst.txt +66 -0
  72. snappy/doc/_sources/ptolemy_classes.rst.txt +42 -0
  73. snappy/doc/_sources/ptolemy_examples1.rst.txt +298 -0
  74. snappy/doc/_sources/ptolemy_examples2.rst.txt +363 -0
  75. snappy/doc/_sources/ptolemy_examples3.rst.txt +301 -0
  76. snappy/doc/_sources/ptolemy_examples4.rst.txt +61 -0
  77. snappy/doc/_sources/ptolemy_prelim.rst.txt +105 -0
  78. snappy/doc/_sources/screenshots.rst.txt +21 -0
  79. snappy/doc/_sources/snap.rst.txt +87 -0
  80. snappy/doc/_sources/snappy.rst.txt +28 -0
  81. snappy/doc/_sources/spherogram.rst.txt +103 -0
  82. snappy/doc/_sources/todo.rst.txt +47 -0
  83. snappy/doc/_sources/triangulation.rst.txt +11 -0
  84. snappy/doc/_sources/tutorial.rst.txt +49 -0
  85. snappy/doc/_sources/verify.rst.txt +210 -0
  86. snappy/doc/_sources/verify_internals.rst.txt +79 -0
  87. snappy/doc/_static/SnapPy-horizontal-128.png +0 -0
  88. snappy/doc/_static/SnapPy.ico +0 -0
  89. snappy/doc/_static/_sphinx_javascript_frameworks_compat.js +123 -0
  90. snappy/doc/_static/basic.css +906 -0
  91. snappy/doc/_static/css/badge_only.css +1 -0
  92. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  93. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  94. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  95. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  96. snappy/doc/_static/css/fonts/fontawesome-webfont.eot +0 -0
  97. snappy/doc/_static/css/fonts/fontawesome-webfont.svg +2671 -0
  98. snappy/doc/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  99. snappy/doc/_static/css/fonts/fontawesome-webfont.woff +0 -0
  100. snappy/doc/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  101. snappy/doc/_static/css/fonts/lato-bold-italic.woff +0 -0
  102. snappy/doc/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  103. snappy/doc/_static/css/fonts/lato-bold.woff +0 -0
  104. snappy/doc/_static/css/fonts/lato-bold.woff2 +0 -0
  105. snappy/doc/_static/css/fonts/lato-normal-italic.woff +0 -0
  106. snappy/doc/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  107. snappy/doc/_static/css/fonts/lato-normal.woff +0 -0
  108. snappy/doc/_static/css/fonts/lato-normal.woff2 +0 -0
  109. snappy/doc/_static/css/theme.css +4 -0
  110. snappy/doc/_static/doctools.js +149 -0
  111. snappy/doc/_static/documentation_options.js +13 -0
  112. snappy/doc/_static/file.png +0 -0
  113. snappy/doc/_static/fonts/Lato/lato-bold.eot +0 -0
  114. snappy/doc/_static/fonts/Lato/lato-bold.ttf +0 -0
  115. snappy/doc/_static/fonts/Lato/lato-bold.woff +0 -0
  116. snappy/doc/_static/fonts/Lato/lato-bold.woff2 +0 -0
  117. snappy/doc/_static/fonts/Lato/lato-bolditalic.eot +0 -0
  118. snappy/doc/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
  119. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff +0 -0
  120. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
  121. snappy/doc/_static/fonts/Lato/lato-italic.eot +0 -0
  122. snappy/doc/_static/fonts/Lato/lato-italic.ttf +0 -0
  123. snappy/doc/_static/fonts/Lato/lato-italic.woff +0 -0
  124. snappy/doc/_static/fonts/Lato/lato-italic.woff2 +0 -0
  125. snappy/doc/_static/fonts/Lato/lato-regular.eot +0 -0
  126. snappy/doc/_static/fonts/Lato/lato-regular.ttf +0 -0
  127. snappy/doc/_static/fonts/Lato/lato-regular.woff +0 -0
  128. snappy/doc/_static/fonts/Lato/lato-regular.woff2 +0 -0
  129. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
  130. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
  131. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
  132. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
  133. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
  134. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
  135. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
  136. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
  137. snappy/doc/_static/jquery.js +2 -0
  138. snappy/doc/_static/js/badge_only.js +1 -0
  139. snappy/doc/_static/js/theme.js +1 -0
  140. snappy/doc/_static/js/versions.js +228 -0
  141. snappy/doc/_static/language_data.js +192 -0
  142. snappy/doc/_static/minus.png +0 -0
  143. snappy/doc/_static/plus.png +0 -0
  144. snappy/doc/_static/pygments.css +75 -0
  145. snappy/doc/_static/searchtools.js +635 -0
  146. snappy/doc/_static/snappy_furo.css +33 -0
  147. snappy/doc/_static/snappy_sphinx_rtd_theme.css +42 -0
  148. snappy/doc/_static/sphinx_highlight.js +154 -0
  149. snappy/doc/additional_classes.html +1500 -0
  150. snappy/doc/bugs.html +132 -0
  151. snappy/doc/censuses.html +453 -0
  152. snappy/doc/credits.html +184 -0
  153. snappy/doc/development.html +385 -0
  154. snappy/doc/doc-latest/additional_classes.html +1500 -0
  155. snappy/doc/doc-latest/bugs.html +132 -0
  156. snappy/doc/doc-latest/censuses.html +453 -0
  157. snappy/doc/doc-latest/credits.html +184 -0
  158. snappy/doc/doc-latest/development.html +385 -0
  159. snappy/doc/doc-latest/genindex.html +1349 -0
  160. snappy/doc/doc-latest/index.html +287 -0
  161. snappy/doc/doc-latest/installing.html +346 -0
  162. snappy/doc/doc-latest/manifold.html +3632 -0
  163. snappy/doc/doc-latest/manifoldhp.html +180 -0
  164. snappy/doc/doc-latest/news.html +438 -0
  165. snappy/doc/doc-latest/objects.inv +0 -0
  166. snappy/doc/doc-latest/other.html +160 -0
  167. snappy/doc/doc-latest/platonic_census.html +376 -0
  168. snappy/doc/doc-latest/plink.html +210 -0
  169. snappy/doc/doc-latest/ptolemy.html +253 -0
  170. snappy/doc/doc-latest/ptolemy_classes.html +1144 -0
  171. snappy/doc/doc-latest/ptolemy_examples1.html +409 -0
  172. snappy/doc/doc-latest/ptolemy_examples2.html +471 -0
  173. snappy/doc/doc-latest/ptolemy_examples3.html +414 -0
  174. snappy/doc/doc-latest/ptolemy_examples4.html +195 -0
  175. snappy/doc/doc-latest/ptolemy_prelim.html +248 -0
  176. snappy/doc/doc-latest/py-modindex.html +165 -0
  177. snappy/doc/doc-latest/screenshots.html +141 -0
  178. snappy/doc/doc-latest/search.html +135 -0
  179. snappy/doc/doc-latest/searchindex.js +1 -0
  180. snappy/doc/doc-latest/snap.html +202 -0
  181. snappy/doc/doc-latest/snappy.html +181 -0
  182. snappy/doc/doc-latest/spherogram.html +1346 -0
  183. snappy/doc/doc-latest/todo.html +166 -0
  184. snappy/doc/doc-latest/triangulation.html +1676 -0
  185. snappy/doc/doc-latest/tutorial.html +159 -0
  186. snappy/doc/doc-latest/verify.html +330 -0
  187. snappy/doc/doc-latest/verify_internals.html +1235 -0
  188. snappy/doc/genindex.html +1349 -0
  189. snappy/doc/index.html +287 -0
  190. snappy/doc/installing.html +346 -0
  191. snappy/doc/manifold.html +3632 -0
  192. snappy/doc/manifoldhp.html +180 -0
  193. snappy/doc/news.html +438 -0
  194. snappy/doc/objects.inv +0 -0
  195. snappy/doc/other.html +160 -0
  196. snappy/doc/platonic_census.html +376 -0
  197. snappy/doc/plink.html +210 -0
  198. snappy/doc/ptolemy.html +253 -0
  199. snappy/doc/ptolemy_classes.html +1144 -0
  200. snappy/doc/ptolemy_examples1.html +409 -0
  201. snappy/doc/ptolemy_examples2.html +471 -0
  202. snappy/doc/ptolemy_examples3.html +414 -0
  203. snappy/doc/ptolemy_examples4.html +195 -0
  204. snappy/doc/ptolemy_prelim.html +248 -0
  205. snappy/doc/py-modindex.html +165 -0
  206. snappy/doc/screenshots.html +141 -0
  207. snappy/doc/search.html +135 -0
  208. snappy/doc/searchindex.js +1 -0
  209. snappy/doc/snap.html +202 -0
  210. snappy/doc/snappy.html +181 -0
  211. snappy/doc/spherogram.html +1346 -0
  212. snappy/doc/todo.html +166 -0
  213. snappy/doc/triangulation.html +1676 -0
  214. snappy/doc/tutorial.html +159 -0
  215. snappy/doc/verify.html +330 -0
  216. snappy/doc/verify_internals.html +1235 -0
  217. snappy/drilling/__init__.py +456 -0
  218. snappy/drilling/barycentric.py +103 -0
  219. snappy/drilling/constants.py +5 -0
  220. snappy/drilling/crush.py +270 -0
  221. snappy/drilling/cusps.py +125 -0
  222. snappy/drilling/debug.py +242 -0
  223. snappy/drilling/epsilons.py +6 -0
  224. snappy/drilling/exceptions.py +55 -0
  225. snappy/drilling/moves.py +620 -0
  226. snappy/drilling/peripheral_curves.py +210 -0
  227. snappy/drilling/perturb.py +188 -0
  228. snappy/drilling/shorten.py +36 -0
  229. snappy/drilling/subdivide.py +274 -0
  230. snappy/drilling/test.py +23 -0
  231. snappy/drilling/test_cases.py +132 -0
  232. snappy/drilling/tracing.py +351 -0
  233. snappy/exceptions.py +26 -0
  234. snappy/export_stl.py +120 -0
  235. snappy/exterior_to_link/__init__.py +2 -0
  236. snappy/exterior_to_link/barycentric_geometry.py +463 -0
  237. snappy/exterior_to_link/exceptions.py +6 -0
  238. snappy/exterior_to_link/geodesic_map.json +14408 -0
  239. snappy/exterior_to_link/hyp_utils.py +112 -0
  240. snappy/exterior_to_link/link_projection.py +323 -0
  241. snappy/exterior_to_link/main.py +198 -0
  242. snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
  243. snappy/exterior_to_link/mcomplex_with_link.py +687 -0
  244. snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
  245. snappy/exterior_to_link/pl_utils.py +491 -0
  246. snappy/exterior_to_link/put_in_S3.py +156 -0
  247. snappy/exterior_to_link/rational_linear_algebra.py +130 -0
  248. snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
  249. snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
  250. snappy/exterior_to_link/stored_moves.py +475 -0
  251. snappy/exterior_to_link/test.py +31 -0
  252. snappy/filedialog.py +28 -0
  253. snappy/geometric_structure/__init__.py +212 -0
  254. snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
  255. snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +691 -0
  256. snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +480 -0
  257. snappy/geometric_structure/cusp_neighborhood/exceptions.py +41 -0
  258. snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +294 -0
  259. snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +156 -0
  260. snappy/geometric_structure/cusp_neighborhood/vertices.py +35 -0
  261. snappy/geometric_structure/geodesic/__init__.py +0 -0
  262. snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
  263. snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
  264. snappy/geometric_structure/geodesic/canonical_representatives.py +52 -0
  265. snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
  266. snappy/geometric_structure/geodesic/constants.py +6 -0
  267. snappy/geometric_structure/geodesic/exceptions.py +22 -0
  268. snappy/geometric_structure/geodesic/fixed_points.py +106 -0
  269. snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
  270. snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
  271. snappy/geometric_structure/geodesic/line.py +30 -0
  272. snappy/geometric_structure/geodesic/multiplicity.py +127 -0
  273. snappy/geometric_structure/geodesic/tiles_for_geodesic.py +128 -0
  274. snappy/geometric_structure/test.py +22 -0
  275. snappy/gui.py +121 -0
  276. snappy/horoviewer.py +443 -0
  277. snappy/hyperboloid/__init__.py +212 -0
  278. snappy/hyperboloid/distances.py +259 -0
  279. snappy/hyperboloid/horoball.py +19 -0
  280. snappy/hyperboloid/line.py +35 -0
  281. snappy/hyperboloid/point.py +9 -0
  282. snappy/hyperboloid/triangle.py +29 -0
  283. snappy/info_icon.gif +0 -0
  284. snappy/infowindow.py +65 -0
  285. snappy/isometry_signature.py +389 -0
  286. snappy/len_spec/__init__.py +609 -0
  287. snappy/len_spec/geodesic_info.py +129 -0
  288. snappy/len_spec/geodesic_key_info_dict.py +116 -0
  289. snappy/len_spec/geodesic_piece.py +146 -0
  290. snappy/len_spec/geometric_structure.py +182 -0
  291. snappy/len_spec/geometry.py +136 -0
  292. snappy/len_spec/length_spectrum_geodesic_info.py +185 -0
  293. snappy/len_spec/spine.py +128 -0
  294. snappy/len_spec/test.py +24 -0
  295. snappy/len_spec/test_cases.py +69 -0
  296. snappy/len_spec/tile.py +276 -0
  297. snappy/len_spec/word.py +86 -0
  298. snappy/manifolds/HTWKnots/alternating.gz +0 -0
  299. snappy/manifolds/HTWKnots/nonalternating.gz +0 -0
  300. snappy/manifolds/__init__.py +3 -0
  301. snappy/margulis/__init__.py +332 -0
  302. snappy/margulis/cusp_neighborhood_neighborhood.py +66 -0
  303. snappy/margulis/geodesic_neighborhood.py +152 -0
  304. snappy/margulis/margulis_info.py +21 -0
  305. snappy/margulis/mu_from_neighborhood_pair.py +175 -0
  306. snappy/margulis/neighborhood.py +29 -0
  307. snappy/margulis/test.py +22 -0
  308. snappy/math_basics.py +187 -0
  309. snappy/matrix.py +525 -0
  310. snappy/number.py +657 -0
  311. snappy/numeric_output_checker.py +345 -0
  312. snappy/pari.py +41 -0
  313. snappy/phone_home.py +57 -0
  314. snappy/polyviewer.py +259 -0
  315. snappy/ptolemy/__init__.py +17 -0
  316. snappy/ptolemy/component.py +103 -0
  317. snappy/ptolemy/coordinates.py +2290 -0
  318. snappy/ptolemy/fieldExtensions.py +153 -0
  319. snappy/ptolemy/findLoops.py +473 -0
  320. snappy/ptolemy/geometricRep.py +59 -0
  321. snappy/ptolemy/homology.py +165 -0
  322. snappy/ptolemy/magma/default.magma_template +229 -0
  323. snappy/ptolemy/magma/radicalsOfPrimaryDecomposition.magma_template +79 -0
  324. snappy/ptolemy/manifoldMethods.py +395 -0
  325. snappy/ptolemy/matrix.py +350 -0
  326. snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +113 -0
  327. snappy/ptolemy/polynomial.py +856 -0
  328. snappy/ptolemy/processComponents.py +173 -0
  329. snappy/ptolemy/processFileBase.py +247 -0
  330. snappy/ptolemy/processFileDispatch.py +46 -0
  331. snappy/ptolemy/processMagmaFile.py +392 -0
  332. snappy/ptolemy/processRurFile.py +150 -0
  333. snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +102 -0
  334. snappy/ptolemy/ptolemyObstructionClass.py +64 -0
  335. snappy/ptolemy/ptolemyVariety.py +995 -0
  336. snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +140 -0
  337. snappy/ptolemy/reginaWrapper.py +698 -0
  338. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  339. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  340. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  341. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  342. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  343. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  344. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  345. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  346. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  347. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  348. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c0.magma_out.bz2 +0 -0
  349. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  350. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  351. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c1.magma_out.bz2 +0 -0
  352. snappy/ptolemy/rur.py +545 -0
  353. snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +277 -0
  354. snappy/ptolemy/test.py +1126 -0
  355. snappy/ptolemy/testing_files/3_1__sl2_c0.magma_out.bz2 +0 -0
  356. snappy/ptolemy/testing_files/3_1__sl2_c1.magma_out.bz2 +0 -0
  357. snappy/ptolemy/testing_files/4_1__sl2_c0.magma_out.bz2 +0 -0
  358. snappy/ptolemy/testing_files/4_1__sl2_c1.magma_out.bz2 +0 -0
  359. snappy/ptolemy/testing_files/4_1__sl3_c0.magma_out.bz2 +0 -0
  360. snappy/ptolemy/testing_files/4_1__sl4_c0.magma_out.bz2 +0 -0
  361. snappy/ptolemy/testing_files/4_1__sl4_c1.magma_out.bz2 +0 -0
  362. snappy/ptolemy/testing_files/5_2__sl2_c0.magma_out.bz2 +0 -0
  363. snappy/ptolemy/testing_files/5_2__sl2_c1.magma_out.bz2 +0 -0
  364. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  365. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  366. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  367. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  368. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  369. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  370. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  371. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  372. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c0.magma_out +95 -0
  373. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c1.magma_out +95 -0
  374. snappy/ptolemy/testing_files/m015__sl3_c0.magma_out.bz2 +0 -0
  375. snappy/ptolemy/testing_files/m135__sl2_c0.magma_out.bz2 +0 -0
  376. snappy/ptolemy/testing_files/m135__sl2_c1.magma_out.bz2 +0 -0
  377. snappy/ptolemy/testing_files/m135__sl2_c2.magma_out.bz2 +0 -0
  378. snappy/ptolemy/testing_files/m135__sl2_c3.magma_out.bz2 +0 -0
  379. snappy/ptolemy/testing_files/m135__sl2_c4.magma_out.bz2 +0 -0
  380. snappy/ptolemy/testing_files/m135__sl2_c5.magma_out.bz2 +0 -0
  381. snappy/ptolemy/testing_files/m135__sl2_c6.magma_out.bz2 +0 -0
  382. snappy/ptolemy/testing_files/m135__sl2_c7.magma_out.bz2 +0 -0
  383. snappy/ptolemy/testing_files/s000__sl2_c0.magma_out.bz2 +0 -0
  384. snappy/ptolemy/testing_files/s000__sl2_c1.magma_out.bz2 +0 -0
  385. snappy/ptolemy/testing_files/t00000__sl2_c0.magma_out.bz2 +0 -0
  386. snappy/ptolemy/testing_files/t00000__sl2_c1.magma_out.bz2 +0 -0
  387. snappy/ptolemy/testing_files/v0000__sl2_c0.magma_out.bz2 +0 -0
  388. snappy/ptolemy/testing_files/v0000__sl2_c1.magma_out.bz2 +0 -0
  389. snappy/ptolemy/testing_files/v0000__sl2_c2.magma_out.bz2 +0 -0
  390. snappy/ptolemy/testing_files/v0000__sl2_c3.magma_out.bz2 +0 -0
  391. snappy/ptolemy/testing_files_generalized/m003__sl2_c0.magma_out.bz2 +0 -0
  392. snappy/ptolemy/testing_files_generalized/m003__sl2_c1.magma_out.bz2 +0 -0
  393. snappy/ptolemy/testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  394. snappy/ptolemy/testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  395. snappy/ptolemy/testing_files_generalized/m004__sl2_c0.magma_out.bz2 +0 -0
  396. snappy/ptolemy/testing_files_generalized/m004__sl2_c1.magma_out.bz2 +0 -0
  397. snappy/ptolemy/testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  398. snappy/ptolemy/testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  399. snappy/ptolemy/testing_files_rur/m052__sl3_c0.rur.bz2 +0 -0
  400. snappy/ptolemy/utilities.py +236 -0
  401. snappy/raytracing/__init__.py +64 -0
  402. snappy/raytracing/additional_horospheres.py +64 -0
  403. snappy/raytracing/additional_len_spec_choices.py +63 -0
  404. snappy/raytracing/cohomology_fractal.py +197 -0
  405. snappy/raytracing/eyeball.py +124 -0
  406. snappy/raytracing/finite_raytracing_data.py +237 -0
  407. snappy/raytracing/finite_viewer.py +590 -0
  408. snappy/raytracing/geodesic_tube_info.py +174 -0
  409. snappy/raytracing/geodesics.py +246 -0
  410. snappy/raytracing/geodesics_window.py +258 -0
  411. snappy/raytracing/gui_utilities.py +293 -0
  412. snappy/raytracing/hyperboloid_navigation.py +556 -0
  413. snappy/raytracing/hyperboloid_utilities.py +234 -0
  414. snappy/raytracing/ideal_raytracing_data.py +592 -0
  415. snappy/raytracing/inside_viewer.py +974 -0
  416. snappy/raytracing/pack.py +22 -0
  417. snappy/raytracing/raytracing_data.py +126 -0
  418. snappy/raytracing/raytracing_view.py +454 -0
  419. snappy/raytracing/shaders/Eye.png +0 -0
  420. snappy/raytracing/shaders/NonGeometric.png +0 -0
  421. snappy/raytracing/shaders/__init__.py +101 -0
  422. snappy/raytracing/shaders/fragment.glsl +1744 -0
  423. snappy/raytracing/test.py +29 -0
  424. snappy/raytracing/tooltip.py +146 -0
  425. snappy/raytracing/upper_halfspace_utilities.py +98 -0
  426. snappy/raytracing/view_scale_controller.py +98 -0
  427. snappy/raytracing/zoom_slider/__init__.py +263 -0
  428. snappy/raytracing/zoom_slider/inward.png +0 -0
  429. snappy/raytracing/zoom_slider/inward18.png +0 -0
  430. snappy/raytracing/zoom_slider/outward.png +0 -0
  431. snappy/raytracing/zoom_slider/outward18.png +0 -0
  432. snappy/raytracing/zoom_slider/test.py +20 -0
  433. snappy/sage_helper.py +119 -0
  434. snappy/settings.py +407 -0
  435. snappy/shell.py +53 -0
  436. snappy/snap/__init__.py +117 -0
  437. snappy/snap/character_varieties.py +375 -0
  438. snappy/snap/find_field.py +372 -0
  439. snappy/snap/fox_milnor.py +271 -0
  440. snappy/snap/fundamental_polyhedron.py +569 -0
  441. snappy/snap/generators.py +39 -0
  442. snappy/snap/interval_reps.py +81 -0
  443. snappy/snap/kernel_structures.py +128 -0
  444. snappy/snap/mcomplex_base.py +18 -0
  445. snappy/snap/nsagetools.py +716 -0
  446. snappy/snap/peripheral/__init__.py +1 -0
  447. snappy/snap/peripheral/dual_cellulation.py +219 -0
  448. snappy/snap/peripheral/link.py +127 -0
  449. snappy/snap/peripheral/peripheral.py +159 -0
  450. snappy/snap/peripheral/surface.py +522 -0
  451. snappy/snap/peripheral/test.py +35 -0
  452. snappy/snap/polished_reps.py +335 -0
  453. snappy/snap/shapes.py +152 -0
  454. snappy/snap/slice_obs_HKL/__init__.py +194 -0
  455. snappy/snap/slice_obs_HKL/basics.py +236 -0
  456. snappy/snap/slice_obs_HKL/direct.py +217 -0
  457. snappy/snap/slice_obs_HKL/poly_norm.py +212 -0
  458. snappy/snap/slice_obs_HKL/rep_theory.py +424 -0
  459. snappy/snap/t3mlite/__init__.py +2 -0
  460. snappy/snap/t3mlite/arrow.py +243 -0
  461. snappy/snap/t3mlite/corner.py +22 -0
  462. snappy/snap/t3mlite/edge.py +172 -0
  463. snappy/snap/t3mlite/face.py +37 -0
  464. snappy/snap/t3mlite/files.py +211 -0
  465. snappy/snap/t3mlite/homology.py +53 -0
  466. snappy/snap/t3mlite/linalg.py +419 -0
  467. snappy/snap/t3mlite/mcomplex.py +1499 -0
  468. snappy/snap/t3mlite/perm4.py +320 -0
  469. snappy/snap/t3mlite/setup.py +12 -0
  470. snappy/snap/t3mlite/simplex.py +199 -0
  471. snappy/snap/t3mlite/spun.py +297 -0
  472. snappy/snap/t3mlite/surface.py +519 -0
  473. snappy/snap/t3mlite/test.py +20 -0
  474. snappy/snap/t3mlite/test_vs_regina.py +86 -0
  475. snappy/snap/t3mlite/tetrahedron.py +109 -0
  476. snappy/snap/t3mlite/vertex.py +42 -0
  477. snappy/snap/test.py +139 -0
  478. snappy/snap/utilities.py +288 -0
  479. snappy/test.py +213 -0
  480. snappy/test_cases.py +263 -0
  481. snappy/testing.py +131 -0
  482. snappy/tiling/__init__.py +2 -0
  483. snappy/tiling/dict_based_set.py +79 -0
  484. snappy/tiling/floor.py +49 -0
  485. snappy/tiling/hyperboloid_dict.py +54 -0
  486. snappy/tiling/iter_utils.py +78 -0
  487. snappy/tiling/lifted_tetrahedron.py +22 -0
  488. snappy/tiling/lifted_tetrahedron_set.py +54 -0
  489. snappy/tiling/quotient_dict.py +70 -0
  490. snappy/tiling/real_hash_dict.py +164 -0
  491. snappy/tiling/test.py +23 -0
  492. snappy/tiling/tile.py +224 -0
  493. snappy/tiling/triangle.py +33 -0
  494. snappy/tkterminal.py +920 -0
  495. snappy/twister/__init__.py +20 -0
  496. snappy/twister/main.py +646 -0
  497. snappy/twister/surfaces/S_0_1 +3 -0
  498. snappy/twister/surfaces/S_0_2 +3 -0
  499. snappy/twister/surfaces/S_0_4 +7 -0
  500. snappy/twister/surfaces/S_0_4_Lantern +8 -0
  501. snappy/twister/surfaces/S_1 +3 -0
  502. snappy/twister/surfaces/S_1_1 +4 -0
  503. snappy/twister/surfaces/S_1_2 +5 -0
  504. snappy/twister/surfaces/S_1_2_5 +6 -0
  505. snappy/twister/surfaces/S_2 +6 -0
  506. snappy/twister/surfaces/S_2_1 +8 -0
  507. snappy/twister/surfaces/S_2_heeg +10 -0
  508. snappy/twister/surfaces/S_3 +8 -0
  509. snappy/twister/surfaces/S_3_1 +10 -0
  510. snappy/twister/surfaces/S_4_1 +12 -0
  511. snappy/twister/surfaces/S_5_1 +14 -0
  512. snappy/twister/surfaces/heeg_fig8 +9 -0
  513. snappy/twister/twister_core.cpython-310-aarch64-linux-gnu.so +0 -0
  514. snappy/upper_halfspace/__init__.py +146 -0
  515. snappy/upper_halfspace/ideal_point.py +29 -0
  516. snappy/verify/__init__.py +13 -0
  517. snappy/verify/canonical.py +542 -0
  518. snappy/verify/complex_volume/__init__.py +18 -0
  519. snappy/verify/complex_volume/adjust_torsion.py +86 -0
  520. snappy/verify/complex_volume/closed.py +168 -0
  521. snappy/verify/complex_volume/compute_ptolemys.py +90 -0
  522. snappy/verify/complex_volume/cusped.py +56 -0
  523. snappy/verify/complex_volume/extended_bloch.py +201 -0
  524. snappy/verify/cusp_translations.py +85 -0
  525. snappy/verify/edge_equations.py +80 -0
  526. snappy/verify/exceptions.py +254 -0
  527. snappy/verify/hyperbolicity.py +224 -0
  528. snappy/verify/interval_newton_shapes_engine.py +523 -0
  529. snappy/verify/interval_tree.py +400 -0
  530. snappy/verify/krawczyk_shapes_engine.py +518 -0
  531. snappy/verify/real_algebra.py +286 -0
  532. snappy/verify/shapes.py +25 -0
  533. snappy/verify/square_extensions.py +1005 -0
  534. snappy/verify/test.py +72 -0
  535. snappy/verify/volume.py +128 -0
  536. snappy/version.py +2 -0
  537. snappy-3.3.dist-info/METADATA +58 -0
  538. snappy-3.3.dist-info/RECORD +541 -0
  539. snappy-3.3.dist-info/WHEEL +6 -0
  540. snappy-3.3.dist-info/entry_points.txt +2 -0
  541. snappy-3.3.dist-info/top_level.txt +28 -0
@@ -0,0 +1,856 @@
1
+ from ..sage_helper import _within_sage, sage_method
2
+
3
+ import re
4
+ import operator
5
+ from fractions import Fraction
6
+
7
+ if _within_sage:
8
+ from ..sage_helper import prod
9
+ from sage.symbolic.ring import var as sage_var
10
+
11
+ #######################################################
12
+ # Public Definitions of Monomial and Polynomial class
13
+
14
+ # The coefficients of a polynomial can be any type, the
15
+ # policy for mixed coefficients is defined in
16
+ # _storage_type_policy and _operator_type_policy.
17
+
18
+ # Definition of Monomial Class
19
+
20
+
21
+ class Monomial():
22
+
23
+ @classmethod
24
+ def from_variable_name(cls, var):
25
+ """Construct a monomial with a single variable given as a string."""
26
+ assert isinstance(var, str)
27
+ return Monomial(1, ((var, 1),))
28
+
29
+ # Constructs a constant monomial
30
+ @classmethod
31
+ def constant_monomial(cls, coefficient):
32
+ return Monomial(coefficient, ())
33
+
34
+ # Constructor takes
35
+ # * a number type as coefficient
36
+ # * a list of pairs (variable_name, exponent) sorted by variable_name or
37
+ # a dictionary variable_name -> exponent
38
+ def __init__(self, coefficient, vars):
39
+ """
40
+ >>> M = Monomial(2, (('a', 2), ('b', 3)))
41
+ >>> str(M)
42
+ '2 * a^2 * b^3'
43
+ """
44
+
45
+ self._coefficient = coefficient
46
+
47
+ if isinstance(vars, dict):
48
+ self._vars = _dict_to_ordered_tuple_of_pairs(vars)
49
+ else:
50
+ assert isinstance(vars, tuple)
51
+ for var, expo in vars:
52
+ assert isinstance(var, str)
53
+ assert isinstance(expo, int)
54
+ assert expo > 0
55
+ self._vars = vars
56
+
57
+ def __str__(self):
58
+ return self.to_string(
59
+ print_coefficient_method=default_print_coefficient_method,
60
+ force_print_sign=False)
61
+
62
+ __repr__ = __str__
63
+
64
+ def to_string(self, print_coefficient_method, force_print_sign):
65
+ """
66
+ Print the polynomial. The print_coefficient_method is used to print the
67
+ coefficients. If force_print_sign is True, a sign is always included,
68
+ e.g., "+ 3 * x".
69
+ """
70
+
71
+ v = [var if expo == 1
72
+ else "%s^%s" % (var, expo)
73
+ for var, expo in self._vars]
74
+
75
+ coefficient_sign, coefficient_str = (
76
+ print_coefficient_method(self._coefficient))
77
+
78
+ if coefficient_str:
79
+ v = [coefficient_str] + v
80
+ if not v:
81
+ v = ["1"]
82
+
83
+ sign_less_str = " * ".join(v)
84
+
85
+ if force_print_sign or coefficient_sign == "-":
86
+ return coefficient_sign + " " + sign_less_str
87
+
88
+ return sign_less_str
89
+
90
+ def get_coefficient(self):
91
+ """Return the coefficient."""
92
+ return self._coefficient
93
+
94
+ def coefficient_type(self):
95
+ """Return the type of the coefficient."""
96
+ return type(self._coefficient)
97
+
98
+ def get_vars(self):
99
+ """
100
+ Return a tuple of pairs (variable_name, exponent).
101
+ """
102
+ return self._vars
103
+
104
+ def variables(self):
105
+ """Return a list containing the variable names."""
106
+ return [var for var, expo in self._vars if expo > 0]
107
+
108
+ def degree(self, var=None):
109
+ """Return the total degree of this monomial."""
110
+ return sum(this_degree
111
+ for this_var, this_degree in self._vars
112
+ if var is None or this_var == var)
113
+
114
+ def __mul__(self, other):
115
+ """Multiply two monomials."""
116
+
117
+ assert isinstance(other, Monomial)
118
+
119
+ # Compute coefficient
120
+ coefficient = _operator_type_policy(
121
+ self._coefficient, other._coefficient, operator.mul)
122
+
123
+ # Compute the variables
124
+ var_dict = _combine_dicts(
125
+ [dict(self._vars), dict(other._vars)],
126
+ operator.add)
127
+
128
+ return Monomial(coefficient, var_dict)
129
+
130
+ def __pow__(self, other):
131
+
132
+ assert isinstance(other, int)
133
+ assert other >= 0
134
+
135
+ if other == 0:
136
+ return Monomial.constant_monomial(1)
137
+ if other == 1:
138
+ return self
139
+ if other % 2:
140
+ return self * (self ** (other - 1))
141
+ return (self * self) ** (other // 2)
142
+
143
+ def __neg__(self):
144
+ """Negate this monomial."""
145
+ return Monomial(-self._coefficient, self._vars)
146
+
147
+ def __eq__(self, other):
148
+ """Check whether two monomials are equal."""
149
+
150
+ assert isinstance(other, Monomial)
151
+
152
+ return (
153
+ self._coefficient == other._coefficient and
154
+ self._vars == other._vars)
155
+
156
+ def convert_coefficient(self, conversion_function):
157
+ """
158
+ Apply the specified conversion_function to the coefficient.
159
+ e.g. monomial.convert_coefficient(float)
160
+ """
161
+ return Monomial(
162
+ conversion_function(self._coefficient),
163
+ self._vars)
164
+
165
+ def split_variable(self, variable):
166
+ """Split the specified variable from the others."""
167
+ remaining_terms = {}
168
+ exponent = 0
169
+ for var, expo in self._vars:
170
+ if var == variable:
171
+ exponent = expo
172
+ else:
173
+ remaining_terms[var] = expo
174
+ return exponent, Monomial(self.get_coefficient(), remaining_terms)
175
+
176
+ def reduce_exponents(self, d):
177
+
178
+ assert isinstance(d, dict)
179
+
180
+ vars = [(var, expo - d[var]) for var, expo in self._vars]
181
+ vars = tuple([(var, expo) for var, expo in vars if expo > 0])
182
+
183
+ return Monomial(self.get_coefficient(), vars)
184
+
185
+ @sage_method
186
+ def sage(self):
187
+ return (
188
+ self.get_coefficient() *
189
+ prod(sage_var(var) ** expo for var, expo in self.get_vars()))
190
+
191
+ # Definition of Polynomial class
192
+
193
+ class Polynomial():
194
+
195
+ """
196
+ >>> m1 = Monomial(1, (('t', 1), ('x', 1), ('y', 1)))
197
+ >>> m2 = Monomial(3, (('t', 2),))
198
+ >>> m3 = Monomial(1, (('t', 6),))
199
+ >>> p1 = Polynomial( (m1, m2, m3) )
200
+ >>> p2 = Polynomial.parse_string('3 * t * t + t ^ 6 + x * t * y')
201
+ >>> p3 = Polynomial.parse_string('t * x * y + t^6 + 3 * t^2')
202
+ >>> p1 == p2
203
+ True
204
+ >>> p2 == p3
205
+ True
206
+ >>> str(p1)
207
+ 't * x * y + 3 * t^2 + t^6'
208
+ >>> p4 = Polynomial.parse_string('x + t^2')
209
+ >>> str(p4)
210
+ 't^2 + x'
211
+ >>> p1 == p4
212
+ False
213
+ >>> str(p1 + p4)
214
+ 't * x * y + 4 * t^2 + t^6 + x'
215
+ >>> str(p1 - p2)
216
+ ''
217
+ >>> str(p1 * p4)
218
+ 't * x^2 * y + 3 * t^2 * x + t^3 * x * y + 3 * t^4 + t^6 * x + t^8'
219
+ >>> str(p4 ** 5)
220
+ '5 * t^2 * x^4 + 10 * t^4 * x^3 + 10 * t^6 * x^2 + 5 * t^8 * x + t^10 + x^5'
221
+ >>> p5 = Polynomial.parse_string('x + 1')
222
+ >>> p6 = p5 ** 3
223
+ >>> str(p6)
224
+ '1 + 3 * x + 3 * x^2 + x^3'
225
+ >>> p7 = p6.substitute({'x':Polynomial.constant_polynomial(Fraction(5,3))})
226
+ >>> str(p7)
227
+ '512/27'
228
+ >>> p8 = Polynomial.parse_string('')
229
+ >>> p8 == Polynomial(())
230
+ True
231
+ >>> p6.is_constant()
232
+ False
233
+ >>> p7.is_constant()
234
+ True
235
+ >>> p7.get_constant()
236
+ Fraction(512, 27)
237
+ >>> p9 = p4.substitute({'t':p5})
238
+ >>> str(p9)
239
+ '1 + 3 * x + x^2'
240
+ >>> p1.variables()
241
+ ['t', 'x', 'y']
242
+ >>> p1.is_univariate()
243
+ False
244
+ >>> p9.is_univariate()
245
+ True
246
+ >>> p1.leading_coefficient()
247
+ Traceback (most recent call last):
248
+ ...
249
+ AssertionError
250
+ >>> p9.leading_coefficient()
251
+ 1
252
+ >>> p6 = Polynomial.parse_string('1+x^2')
253
+
254
+ # >>> str(p4 % p6)
255
+ # '- 2 + 2 * x'
256
+
257
+ #>>> str(Polynomial.parse_string('4+3*x').make_monic())
258
+ #'(4/3) + x'
259
+ """
260
+
261
+ @classmethod
262
+ def constant_polynomial(cls, constant):
263
+ """Construct a constant polynomial."""
264
+ return Polynomial((Monomial.constant_monomial(constant),))
265
+
266
+ @classmethod
267
+ def from_variable_name(cls, var):
268
+ """Construct a polynomial consisting of a single variable."""
269
+ return Polynomial((Monomial.from_variable_name(var),))
270
+
271
+ # constructor takes a tuple of polynomials which are combined
272
+
273
+ def __init__(self, monomials=()):
274
+
275
+ # combine monomials with the same variables and exponents
276
+ # and bring them into canonical order
277
+
278
+ assert isinstance(monomials, tuple)
279
+
280
+ # create for each monomial a dictionary
281
+ # with key being the variables and exponents
282
+ # and value being the coefficient
283
+
284
+ list_of_vars_coeff_dicts = [
285
+ {monomial.get_vars(): monomial.get_coefficient()}
286
+ for monomial in monomials]
287
+
288
+ # combine the dictionaries using sum
289
+ combined_vars_coeff_dict = _combine_dicts(
290
+ list_of_vars_coeff_dicts,
291
+ _operator_type_policy)
292
+
293
+ # turn dictionary into a list of pairs (vars, coefficient)
294
+ # in canonical order
295
+ ordered_tuple_of_vars_coeff_pairs = (
296
+ _dict_to_ordered_tuple_of_pairs(combined_vars_coeff_dict))
297
+
298
+ # turn pairs into monomials, skip trivial monomials
299
+ combined_monomials = [
300
+ Monomial(coefficient, vars)
301
+ for vars, coefficient in ordered_tuple_of_vars_coeff_pairs
302
+ if _coefficient_is_non_trivial(coefficient)]
303
+
304
+ # convert to tuple
305
+ self._monomials = tuple(combined_monomials)
306
+
307
+ def __eq__(self, other):
308
+ return self._monomials == other._monomials
309
+
310
+ def __add__(self, other):
311
+ assert isinstance(other, Polynomial)
312
+ return Polynomial(self._monomials + other._monomials)
313
+
314
+ def __neg__(self):
315
+ return Polynomial(
316
+ tuple([-monomial for monomial in self._monomials]))
317
+
318
+ def __sub__(self, other):
319
+ return self + (-other)
320
+
321
+ def __pow__(self, other):
322
+
323
+ if isinstance(other, Polynomial):
324
+ assert other.is_constant()
325
+ other = other.get_constant()
326
+
327
+ assert isinstance(other, int)
328
+ assert other >= 0
329
+ if other == 0:
330
+ return Polynomial((Monomial.constant_monomial(1),))
331
+ if other == 1:
332
+ return self
333
+ if other % 2:
334
+ return self * (self ** (other - 1))
335
+ return (self * self) ** (other // 2)
336
+
337
+ def __mul__(self, other):
338
+ return Polynomial(tuple(
339
+ m * n for m in self._monomials for n in other._monomials))
340
+
341
+ def __mod__(self, other):
342
+
343
+ assert isinstance(other, Polynomial)
344
+ assert self.is_univariate()
345
+ assert other.is_univariate()
346
+ self.coefficient_type(Fraction)
347
+
348
+ if self.degree() < other.degree():
349
+ return self
350
+
351
+ other = other.convert_coefficients(Fraction)
352
+ other = other * Polynomial.constant_polynomial(
353
+ Fraction(1, 1) / other.leading_coefficient())
354
+
355
+ variable = other.variables()[0]
356
+ assert ((not other.variables())
357
+ or other.variables()[0] == variable)
358
+
359
+ rest = self
360
+ while rest.degree() >= other.degree():
361
+ degree_diff = rest.degree() - other.degree()
362
+ leading_coeff = rest.leading_coefficient()
363
+ rest = rest - (
364
+ Polynomial.constant_polynomial(leading_coeff)
365
+ * Polynomial.from_variable_name(variable) ** degree_diff
366
+ * other)
367
+
368
+ return rest
369
+
370
+ def __str__(self):
371
+ return self.to_string(default_print_coefficient_method)
372
+
373
+ __repr__ = __str__
374
+
375
+ # print
376
+ # a method to print the coefficients can be supplied
377
+
378
+ def to_string(self, print_coefficient_method):
379
+ s = " ".join(monomial.to_string(print_coefficient_method,
380
+ force_print_sign=True)
381
+ for monomial in self._monomials)
382
+ if s and s[0] == '+':
383
+ return s[1:].lstrip()
384
+ return s
385
+
386
+ def convert_coefficients(self, conversion_function):
387
+ """Convert all coefficients using conversion_function."""
388
+
389
+ return Polynomial(tuple(
390
+ monomial.convert_coefficient(conversion_function)
391
+ for monomial in self._monomials))
392
+
393
+ def substitute(self, d):
394
+ """
395
+ Take a dictionary mapping variable name -> polynomial and
396
+ replace each variable by the corresponding polynomial.
397
+ """
398
+ variables = self.variables()
399
+
400
+ skip_computation = True
401
+
402
+ for v in variables:
403
+ if v in d:
404
+ skip_computation = False
405
+
406
+ if skip_computation:
407
+ return self
408
+
409
+ def substitute_monomial(monomial):
410
+ vars = monomial.get_vars()
411
+
412
+ new_vars = tuple(
413
+ (var, expo)
414
+ for var, expo in vars
415
+ if var not in d)
416
+
417
+ poly = Polynomial((
418
+ Monomial(monomial.get_coefficient(), new_vars),))
419
+
420
+ for var, expo in vars:
421
+ if var in d:
422
+ poly = poly * (d[var] ** expo)
423
+
424
+ return poly
425
+
426
+ return sum((substitute_monomial(monomial)
427
+ for monomial in self._monomials), Polynomial(()))
428
+
429
+ def variables(self):
430
+ """Return a list of all variables in the polynomial."""
431
+ return sorted(set(
432
+ v for monomial in self._monomials for v in monomial.variables()))
433
+
434
+ def is_constant(self):
435
+ """Return True iff the polynomial is constant."""
436
+ return not self.variables()
437
+
438
+ def get_constant(self):
439
+ """Returns the constant term of this polynomial."""
440
+ constants = [monomial.get_coefficient()
441
+ for monomial in self._monomials
442
+ if not monomial.get_vars()]
443
+ assert len(constants) <= 1
444
+ if constants:
445
+ return constants[0]
446
+ else:
447
+ return 0
448
+
449
+ def is_univariate(self):
450
+ """Return True iff the polynomial has at most one variable."""
451
+ return len(self.variables()) <= 1
452
+
453
+ def is_linear(self):
454
+ """Assert univariance; return True iff this polynomial is linear."""
455
+ return self.is_univariate() and self.degree() == 1
456
+
457
+ def leading_coefficient(self):
458
+ """
459
+ Assert univariance; return the leading coefficient.
460
+ """
461
+ assert self.is_univariate()
462
+ # use that monomials are sorted by degree
463
+ if self._monomials:
464
+ return self._monomials[-1].get_coefficient()
465
+ else:
466
+ return 0
467
+
468
+ def is_monic(self):
469
+ """Assert univariance; return True iff this polynomial is monic."""
470
+ return self.leading_coefficient() == 1
471
+
472
+ def get_coefficients(self, conversion_function=lambda x: x):
473
+ """Assert univariance; return the coefficients in degree order."""
474
+ assert self.is_univariate()
475
+ degree = self.degree()
476
+ list_of_coefficients = (degree + 1) * [conversion_function(0)]
477
+ for monomial in self._monomials:
478
+ list_of_coefficients[degree - monomial.degree()] = (
479
+ conversion_function(monomial.get_coefficient()))
480
+ return list_of_coefficients
481
+
482
+ def get_any_coefficient(self):
483
+ if len(self._monomials) == 0:
484
+ return None
485
+ else:
486
+ return self._monomials[0].get_coefficient()
487
+
488
+ def degree(self, var=None):
489
+ """Return the total degree of this polynomial."""
490
+ return max(
491
+ [monomial.degree(var) for monomial in self._monomials] + [0])
492
+
493
+ @classmethod
494
+ def parse_string(cls, s, parse_coefficient_function=None):
495
+ """
496
+ Construct a polynomial from a string using an optional function to parse the
497
+ coefficients.
498
+ """
499
+ if parse_coefficient_function is None:
500
+ return _parse_polynomial_from_string(s, parse_int_or_fraction)
501
+ return _parse_polynomial_from_string(s, parse_coefficient_function)
502
+
503
+ def coefficient_type(self, the_type=int):
504
+ """Returns the type of the coefficients."""
505
+ for monomial in self._monomials:
506
+ the_type = _storage_type_policy(the_type, monomial.coefficient_type())
507
+ return the_type
508
+
509
+ def curried_polynomial(self, variable):
510
+ """
511
+ Return a polynomial in the variable whose coefficients are polynomials in
512
+ the other variables.
513
+ """
514
+ poly = Polynomial()
515
+ for monomial in self._monomials:
516
+ exponent, remainder = monomial.split_variable(variable)
517
+ poly = poly + (
518
+ (Polynomial.from_variable_name(variable) ** exponent).convert_coefficients(Polynomial.constant_polynomial) *
519
+ Polynomial.constant_polynomial(Polynomial((remainder,))))
520
+ return poly
521
+
522
+ def get_monomials(self):
523
+ return self._monomials
524
+
525
+ def factor_out_variables(self):
526
+
527
+ if not self._monomials:
528
+ return self
529
+
530
+ def intersect(lists):
531
+ s = set(lists[0])
532
+ for l in lists:
533
+ s &= set(l)
534
+ return s
535
+
536
+ non_trivial_variables = intersect(
537
+ [monomial.variables() for monomial in self._monomials])
538
+
539
+ lowest_powers = {var: 1000000 for var in non_trivial_variables}
540
+
541
+ def safe_dict(d, var):
542
+ if var in d:
543
+ return d[var]
544
+ return 0
545
+
546
+ for monomial in self._monomials:
547
+ for var, expo in monomial.get_vars():
548
+ lowest_powers[var] = min(safe_dict(lowest_powers, var), expo)
549
+
550
+ return Polynomial(tuple([monomial.reduce_exponents(lowest_powers)
551
+ for monomial in self._monomials]))
552
+
553
+ @sage_method
554
+ def sage(self):
555
+ return sum(m.sage() for m in self.get_monomials())
556
+
557
+ ###############################################################
558
+ # Default functions for parsing and printing the coefficients
559
+
560
+ # The user will rewrite these for other types and supply to
561
+ # the respective methods of Monomial and Polynomial.
562
+
563
+
564
+ def parse_int_coefficient(s):
565
+ coeff, rest = re.match('([0-9]*)(.*)', s).groups()
566
+ if coeff:
567
+ coeff = int(coeff)
568
+ else:
569
+ coeff = None
570
+ return coeff, rest
571
+
572
+
573
+ def parse_int_or_fraction(s):
574
+ m = re.match('([0-9]+/[0-9]+)(.*)', s)
575
+ if m:
576
+ frac, rest = m.groups()
577
+ return Fraction(frac), rest
578
+
579
+ return parse_int_coefficient(s)
580
+
581
+
582
+ def parenthesis_coefficient_method(i):
583
+ if isinstance(i, int) or isinstance(i, Fraction):
584
+ return default_print_coefficient_method(i)
585
+
586
+ else:
587
+ return '+', '(%s)' % repr(i)
588
+
589
+
590
+ def default_print_coefficient_method(i):
591
+ try:
592
+ sign = '+' if i >= 0 else '-'
593
+ if abs(i) == 1:
594
+ print_str = None
595
+ else:
596
+ print_str = str(abs(i))
597
+ return sign, print_str
598
+ except (TypeError, ValueError):
599
+ return uncomparable_print_coefficient_method(i)
600
+
601
+
602
+ def uncomparable_print_coefficient_method(i):
603
+ print_str = str(i)
604
+ if '+' in print_str or '-' in print_str:
605
+ return '+', '(%s)' % print_str
606
+ else:
607
+ return '+', print_str
608
+
609
+
610
+ ##############################################################################
611
+ # Private Definitions
612
+
613
+ # Methods defining what coefficient types can be mixed a polynomial
614
+ # Type Mixing Policy: only int can be mixed with another type
615
+
616
+ def _storage_type_policy(type_a, type_b):
617
+ assert isinstance(type_a, type)
618
+ assert isinstance(type_b, type)
619
+
620
+ if type_a in [int]:
621
+ return type_b
622
+ if type_b in [int]:
623
+ return type_a
624
+
625
+ if not type_a == type_b:
626
+
627
+ print(type_a, type_b)
628
+ raise Exception("Bad _storage_type_policy call")
629
+
630
+ return type_a
631
+
632
+
633
+ def _operator_type_policy(obj_a, obj_b, op=operator.add):
634
+
635
+ try:
636
+
637
+ if type(obj_a) == type(obj_b):
638
+ return op(obj_a, obj_b)
639
+ if type(obj_a) in [int]:
640
+ return op(type(obj_b)(obj_a), obj_b)
641
+ if type(obj_b) in [int]:
642
+ return op(type(obj_a)(obj_b), obj_a)
643
+
644
+ raise Exception
645
+
646
+ except (TypeError, ValueError):
647
+
648
+ print(obj_a, obj_b)
649
+ print(type(obj_a), type(obj_b))
650
+
651
+ raise Exception("In _operator_type_policy, cannot apply operator")
652
+
653
+ # Definitions of parsable operators and their precedence
654
+
655
+
656
+ _operators = {
657
+ '+': operator.add,
658
+ '-': operator.sub,
659
+ '*': operator.mul,
660
+ '^': operator.pow}
661
+
662
+ _operator_precedence = {
663
+ None: 0,
664
+ '+': 1,
665
+ '-': 1,
666
+ '*': 2,
667
+ '^': 3}
668
+
669
+
670
+ def _apply_operator(op, l, r):
671
+ return _operators[op](l, r)
672
+
673
+ # Helper functions for parsing
674
+
675
+
676
+ def _coefficient_is_non_trivial(c):
677
+
678
+ if isinstance(c, Polynomial):
679
+ return c._monomials
680
+
681
+ return not c == 0
682
+
683
+
684
+ def _parse_variable(s):
685
+ r = re.match(r'([_A-Za-z][_A-Za-z0-9]*)(.*)$', s)
686
+ if r:
687
+ return r.groups()
688
+ else:
689
+ return None, s
690
+
691
+ # Parsing function for Polynomial
692
+
693
+
694
+ def _parse_polynomial_from_string(s, parse_coefficient_function):
695
+
696
+ # Stack holding the operands encountered
697
+ operand_stack = []
698
+ # Stack holding the operators encountered
699
+ # The stack includes "("
700
+ operator_stack = []
701
+
702
+ # Has there been an operand since the opening parenthesis
703
+ # e.g. parse things like "(+ x)"
704
+ no_operand_since_opening_parenthesis = [True]
705
+
706
+ def debug_print(s):
707
+ print("=" * 75)
708
+ print("Remaining string : ", s)
709
+ print("Operator Stack : ", operator_stack)
710
+ print("Operand Stack : ", operand_stack)
711
+
712
+ # pop the top operator from the stack and apply it to the
713
+ # two top operands from the stack, repeat as long as there are preceding
714
+ # operators left on the stack.
715
+ def eval_preceding_operators_on_stack(operator=None):
716
+ while operator_stack:
717
+ top_operator = operator_stack[-1]
718
+
719
+ # stop if the top operator is "("
720
+ if top_operator == '(':
721
+ return
722
+
723
+ # or if the top operator is not preceding
724
+ if (_operator_precedence[top_operator] <
725
+ _operator_precedence[operator]):
726
+ return
727
+
728
+ top_operator = operator_stack.pop()
729
+ r = operand_stack.pop()
730
+ l = operand_stack.pop()
731
+
732
+ operand_stack.append(
733
+ _apply_operator(top_operator, l, r))
734
+
735
+ # this function is called iteratively and consumes
736
+ # the next operator or operand from the string
737
+ def process_next_token(s):
738
+ s = s.lstrip()
739
+
740
+ # parse constants or variables and push them onto the operand stack
741
+ constant, rest = parse_coefficient_function(s)
742
+ if constant is not None:
743
+ operand_stack.append(Polynomial.constant_polynomial(constant))
744
+ no_operand_since_opening_parenthesis[0] = False
745
+ return rest
746
+
747
+ variable, rest = _parse_variable(s)
748
+ if variable:
749
+ operand_stack.append(Polynomial.from_variable_name(variable))
750
+ no_operand_since_opening_parenthesis[0] = False
751
+ return rest
752
+
753
+ # parse an operator and push it onto the stack
754
+ # after evaluating all preceding operators
755
+ #
756
+ # detect strings such as "(+ 3)" and push a null string
757
+ # onto the operand stack as to emulate parsing "(0 + 3)"
758
+
759
+ next_char, rest = s[0], s[1:]
760
+
761
+ if next_char in _operators:
762
+ operator = next_char
763
+ eval_preceding_operators_on_stack(operator)
764
+ operator_stack.append(operator)
765
+
766
+ if operator in '+-':
767
+ if no_operand_since_opening_parenthesis[0]:
768
+ operand_stack.append(Polynomial())
769
+ no_operand_since_opening_parenthesis[0] = False
770
+
771
+ return rest
772
+
773
+ # handle parenthesis
774
+ # an opening parenthesis is just popped onto the stack
775
+ # a closing parenthesis evaluates all operators on the stack
776
+ # until the corresponding opening parenthesis is encountered
777
+ if next_char in '()':
778
+ parenthesis = next_char
779
+ if parenthesis == '(':
780
+ operator_stack.append('(')
781
+ no_operand_since_opening_parenthesis[0] = True
782
+ else:
783
+ eval_preceding_operators_on_stack()
784
+ top_operator = operator_stack.pop()
785
+ assert top_operator == '('
786
+ return rest
787
+
788
+ # This place should not be reached when a well-formed polynomial is supplied
789
+ raise Exception("While parsing polynomial %s" % s)
790
+
791
+ # iterate through the string to parse
792
+ s = s.strip()
793
+ while s:
794
+ # debug_print(s)
795
+ s = process_next_token(s)
796
+
797
+ # finish any remaining operators on the stack
798
+ # debug_print(s)
799
+ eval_preceding_operators_on_stack(None)
800
+ # debug_print(s)
801
+
802
+ # check that the operator stack is empty
803
+ # the operand stack should only contain the result or maybe
804
+ # an additional empty polynomial
805
+
806
+ assert not operator_stack
807
+
808
+ if not operand_stack:
809
+ return Polynomial(())
810
+
811
+ assert (len(operand_stack) == 1
812
+ or (
813
+ len(operand_stack) == 2 and
814
+ operand_stack[0] == Polynomial()))
815
+
816
+ return operand_stack[-1]
817
+
818
+
819
+ # ## Other help functions to deal with the internal representation
820
+
821
+ # take a dictionary and turn it into a tuple of pairs sorted by keys
822
+
823
+ def _dict_to_ordered_tuple_of_pairs(d):
824
+ """
825
+ >>> _dict_to_ordered_tuple_of_pairs(
826
+ ... { 'key3':'value3', 'key1':'value1', 'key2':'value2' })
827
+ (('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3'))
828
+ """
829
+ l = list(d.items())
830
+ l.sort(key=lambda x: x[0])
831
+ return tuple(l)
832
+
833
+
834
+ # given a list of dictionaries, combine values of the different
835
+ # dictionaries having the same key using combine_function.
836
+
837
+ def _combine_dicts(list_of_dicts, combine_function):
838
+ """
839
+ >>> d = _combine_dicts(
840
+ ... [ {'key1': 1, 'key2': 2},
841
+ ... {'key1': 1} ],
842
+ ... combine_function = operator.add)
843
+ >>> d['key1']
844
+ 2
845
+ >>> d['key2']
846
+ 2
847
+ """
848
+
849
+ result = {}
850
+ for a_dict in list_of_dicts:
851
+ for k, v in list(a_dict.items()):
852
+ if k in result:
853
+ result[k] = combine_function(result[k], v)
854
+ else:
855
+ result[k] = v
856
+ return result