snappy 3.2__cp313-cp313-macosx_11_0_arm64.whl

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