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,716 @@
1
+ """
2
+ Tools for use in Sage.
3
+ """
4
+ import string
5
+ from ..sage_helper import _within_sage, sage_method
6
+
7
+ if _within_sage:
8
+ from ..sage_helper import ZZ, vector, matrix, block_matrix, identity_matrix, gcd, prod, det
9
+ from ..sage_helper import MatrixSpace, PolynomialRing, LaurentPolynomialRing
10
+ from ..sage_helper import SageObject, AbelianGroup, GroupAlgebra
11
+ from .polished_reps import polished_holonomy, MatrixRepresentation
12
+ Id2 = MatrixSpace(ZZ, 2)(1)
13
+ else:
14
+ SageObject = object
15
+ ZZ, Id2 = None, None
16
+
17
+
18
+ def search_for_low_rank_triangulation(M, tries=100, target_lower_bound=0):
19
+ rank_lower_bound = max(M.homology().rank(), target_lower_bound)
20
+
21
+ rank_upper_bound = M.fundamental_group().num_generators()
22
+ N = M.copy()
23
+ curr_best_tri = N.copy()
24
+ for i in range(tries):
25
+ if rank_upper_bound == rank_lower_bound:
26
+ break
27
+ N.randomize()
28
+ new_rank = N.fundamental_group().num_generators()
29
+ if new_rank < rank_upper_bound:
30
+ rank_upper_bound = new_rank
31
+ curr_best_tri = N.copy()
32
+
33
+ return rank_upper_bound, rank_lower_bound, curr_best_tri
34
+
35
+
36
+ # ----------------------------------------------------------------
37
+ #
38
+ # Abelianization of the fundamental group
39
+ #
40
+ # ----------------------------------------------------------------
41
+
42
+ def abelianize_word(word, gens):
43
+ return vector(ZZ, [ word.count(g) - word.count(g.swapcase()) for g in gens])
44
+
45
+
46
+ class MapToAbelianization(SageObject):
47
+ """
48
+ sage: M = Manifold('v2037')
49
+ sage: ab = MapToAbelianization(M.fundamental_group())
50
+ sage: ab.range()
51
+ Multiplicative Abelian group isomorphic to C2 x C4 x Z
52
+ sage: ab('ab').order()
53
+ 4
54
+ sage: ab('abc').order()
55
+ +Infinity
56
+
57
+ sage: U = Manifold('dLQbcbchecv')
58
+ sage: ab = MapToAbelianization(U.fundamental_group())
59
+ sage: ab.range()
60
+ Multiplicative Abelian group isomorphic to Z
61
+ sage: ab('aaa')
62
+ t^3
63
+ """
64
+ def __init__(self, fund_group):
65
+ self.domain_gens = fund_group.generators()
66
+ ab_words = [abelianize_word(R, self.domain_gens) for R in fund_group.relators()]
67
+ if not ab_words:
68
+ n = fund_group.num_generators()
69
+ self.elementary_divisors = n*[0,]
70
+ self.U = identity_matrix(n)
71
+ else:
72
+ R = matrix(ZZ, ab_words).transpose()
73
+ D, U, V = R.smith_form()
74
+ m = U.nrows()
75
+ assert m == D.nrows()
76
+ d = min(D.nrows(), D.ncols())
77
+ diag = D.diagonal()
78
+ num_ones = diag.count(1)
79
+ self.elementary_divisors = diag[num_ones:] + [0,]*(m - d)
80
+ self.U = U[num_ones:]
81
+
82
+ tor = [d for d in self.elementary_divisors if d != 0]
83
+ free = [d for d in self.elementary_divisors if d == 0]
84
+ names = []
85
+ if len(tor) == 1:
86
+ names.append('u')
87
+ else:
88
+ names += ['u%d' % i for i in range(len(tor))]
89
+ if len(free) == 1:
90
+ names.append('t')
91
+ else:
92
+ names += ['t%d' % i for i in range(len(free))]
93
+ self._range = AbelianGroup(self.elementary_divisors, names=names)
94
+
95
+ def range(self):
96
+ return self._range
97
+
98
+ def _normalize_exponents(self, exponents):
99
+ D = self.elementary_divisors
100
+ return [v % d if d > 0 else v for (v, d) in zip(exponents, D)]
101
+
102
+ def _exponents_of_word(self, word):
103
+ exponents = self.U*abelianize_word(word, self.domain_gens)
104
+ return self._normalize_exponents(exponents)
105
+
106
+ def __call__(self, word):
107
+ return self._range(self._exponents_of_word(word))
108
+
109
+
110
+ class MapToFreeAbelianization(MapToAbelianization):
111
+ def range(self):
112
+ return ZZ**self.elementary_divisors.count(0)
113
+
114
+ def __call__(self, word):
115
+ D = self.elementary_divisors
116
+ v = self.U*abelianize_word(word, self.domain_gens)
117
+ return vector(ZZ, [v[i] for i in range(len(D)) if D[i] == 0])
118
+
119
+ # Finding the longitude
120
+
121
+
122
+ @sage_method
123
+ def homological_longitude(manifold, cusp=None):
124
+ """
125
+ Returns the peripheral curve in the given cusp, if any, which is
126
+ homologically trivial (with rational coefficients) in the manifold::
127
+
128
+ sage: M = Manifold('m015')
129
+ sage: M.homological_longitude()
130
+ (2, -1)
131
+
132
+ If no cusp is specified, the default is the first unfilled cusp;
133
+ if all cusps are filled, the default is the first cusp::
134
+
135
+ sage: M = Manifold('L5a1(3,4)(0,0)')
136
+ sage: M.homological_longitude()
137
+ (0, 1)
138
+
139
+ The components of the next link have nontrivial linking number
140
+ so there is no such curve::
141
+
142
+ sage: W = Manifold('L7a2')
143
+ sage: W.homological_longitude(cusp=1) is None
144
+ True
145
+
146
+ If every curve in the given cusp is trivial in the rational homology of
147
+ the manifold, an exception is raised::
148
+
149
+ sage: M = Manifold('4_1(1,0)')
150
+ sage: M.homological_longitude()
151
+ Traceback (most recent call last):
152
+ ...
153
+ ValueError: Every curve on cusp is homologically trivial
154
+ """
155
+ if cusp is None:
156
+ unfilled = [i for i, status in
157
+ enumerate(manifold.cusp_info('complete?')) if status]
158
+ if len(unfilled):
159
+ cusp = unfilled[0]
160
+ else:
161
+ cusp = 0
162
+ G = manifold.fundamental_group()
163
+ f = MapToFreeAbelianization(G)
164
+ m, l = G.peripheral_curves()[cusp]
165
+ kernel_basis = matrix(ZZ, [f(m), f(l)]).left_kernel().basis()
166
+ if len(kernel_basis) >= 2:
167
+ raise ValueError('Every curve on cusp is homologically trivial')
168
+ if len(kernel_basis) == 0:
169
+ return None
170
+ return kernel_basis[0]
171
+
172
+ # --------------------------------------------------------------
173
+ #
174
+ # Computing the Alexander polynomial
175
+ #
176
+ # --------------------------------------------------------------
177
+
178
+
179
+ class MapToGroupRingOfAbelianization(MapToAbelianization):
180
+ """
181
+ sage: M = Manifold('m003')
182
+ sage: G = M.fundamental_group()
183
+ sage: psi = MapToGroupRingOfAbelianization(G)
184
+ sage: psi('ab') + psi('AAAAB')
185
+ u*t + u^4*t^-4
186
+ """
187
+ def __init__(self, fund_group, base_ring=ZZ):
188
+ MapToAbelianization.__init__(self, fund_group)
189
+ self.H = H = self._range # The abelian group
190
+ self.R = GroupAlgebra(H, base_ring)
191
+
192
+ def range(self):
193
+ return self.R
194
+
195
+ def __call__(self, word):
196
+ v = MapToAbelianization.__call__(self, word)
197
+ return self.R.monomial(v)
198
+
199
+
200
+ class MapToGroupRingOfFreeAbelianization(MapToFreeAbelianization):
201
+ def __init__(self, fund_group, base_ring=ZZ):
202
+ MapToFreeAbelianization.__init__(self, fund_group)
203
+ n = self.elementary_divisors.count(0)
204
+ self.R = LaurentPolynomialRing(base_ring, list(string.ascii_lowercase[:n]))
205
+
206
+ def range(self):
207
+ return self.R
208
+
209
+ def __call__(self, word):
210
+ v = MapToFreeAbelianization.__call__(self, word)
211
+ return prod([ g**v[i] for i, g in enumerate(self.R.gens())])
212
+
213
+
214
+ def setup_fox_derivative(word, phi, var, involute=False):
215
+ R = phi.range()
216
+ if len(word) == 0:
217
+ return R.zero()
218
+
219
+ # Cache things for speed
220
+
221
+ gens = list(set( (var + word).lower() ))
222
+ gens += [g.upper() for g in gens]
223
+
224
+ phi_ims = {}
225
+ fox_ders = {}
226
+ for g in gens:
227
+ phi_ims[g] = phi(g) if not involute else phi(g.swapcase())
228
+ if g == g.lower():
229
+ fox_ders[g] = R.zero() if g != var else R.one()
230
+ else:
231
+ fox_ders[g] = R.zero() if g.lower() != var else -phi_ims[var.upper()]
232
+
233
+ return R, phi_ims, fox_ders
234
+
235
+
236
+ def fox_derivative(word, phi, var):
237
+ """
238
+ Given a homorphism phi of a group pi, computes
239
+ phi( d word / d var), i.e. the image of the fox derivative
240
+ of the word with respect to var.
241
+ """
242
+
243
+ R, phi_ims, fox_ders = setup_fox_derivative(word, phi, var)
244
+ D = 0
245
+ for w in reverse_word(word):
246
+ D = fox_ders[w] + phi_ims[w] * D
247
+ return D
248
+
249
+
250
+ def fox_derivative_with_involution(word, phi, var):
251
+ """
252
+ The group ring Z[pi] has a natural involution iota sends
253
+ g in pi to g^-1 and respects addition. This function
254
+ computes
255
+
256
+ phi( iota( d word / d var) )
257
+ """
258
+ R, phi_ims, fox_ders = setup_fox_derivative(word, phi, var, involute=True)
259
+ D = 0
260
+ for w in reverse_word(word):
261
+ D = fox_ders[w] + D * phi_ims[w]
262
+ return D
263
+
264
+
265
+ # It's best to deal with matrices of polynomials rather than Laurent
266
+ # polynomials, so we need to be able to clear denominators. This add
267
+ # to the complexity of the code.
268
+
269
+
270
+ def join_lists(list_of_lists):
271
+ for L in list_of_lists:
272
+ yield from L
273
+
274
+
275
+ def uniform_poly_exponents(poly):
276
+ if poly.parent().ngens() == 1:
277
+ return [(e,) for e in poly.exponents()]
278
+ return poly.exponents()
279
+
280
+
281
+ def minimum_exponents(elts):
282
+ exps = iter(join_lists(uniform_poly_exponents(p) for p in elts))
283
+ mins = list(next(exps))
284
+ n = len(mins)
285
+ for e in exps:
286
+ for i in range(n):
287
+ if e[i] < mins[i]:
288
+ mins[i] = e[i]
289
+ return mins
290
+
291
+
292
+ def convert_laurent_to_poly(elt, minexp, P):
293
+ if P.ngens() == 1:
294
+ f = minexp[0]
295
+ return P({e - f: c for e, c in elt.dict().items()})
296
+ return P({tuple(e - f for e, f in zip(exps, minexp)): c
297
+ for exps, c in elt.dict().items()})
298
+
299
+
300
+ def alexander_polynomial_basic(G, phi, d=0, pos_leading_coeff=False):
301
+ """
302
+ Compute the d-th Alexander polynomial, i.e. the gcd of the
303
+ (d + 1)-st elementrary ideal of A(M).
304
+ """
305
+ R = phi.range()
306
+ P = R.polynomial_ring()
307
+ if G.num_relators() == 0:
308
+ return 1 if G.num_generators() <= d + 1 else 0
309
+ M = [[fox_derivative(rel, phi, var) for rel in G.relators()]
310
+ for var in G.generators()]
311
+ entries = sum(M, [])
312
+ if all(e == 0 for e in entries):
313
+ M = matrix(P, M)
314
+ else:
315
+ minexp = minimum_exponents(entries)
316
+ M = matrix(P, [[ convert_laurent_to_poly(p, minexp, P) for p in row]
317
+ for row in M])
318
+ alex_poly = gcd(M.minors(G.num_generators() - d - 1))
319
+ if alex_poly == 0:
320
+ return alex_poly
321
+
322
+ # Normalize it
323
+ alex_poly = convert_laurent_to_poly(alex_poly, minimum_exponents([alex_poly]), P)
324
+ if pos_leading_coeff:
325
+ e = max(alex_poly.exponents())
326
+ if alex_poly[e] < 0:
327
+ alex_poly = -alex_poly
328
+
329
+ return alex_poly
330
+
331
+
332
+ def alexander_polynomial_group(G):
333
+ phi = MapToGroupRingOfFreeAbelianization(G)
334
+ return alexander_polynomial_basic(G, phi, d=0, pos_leading_coeff=True)
335
+
336
+
337
+ @sage_method
338
+ def alexander_polynomial(manifold, **kwargs):
339
+ """
340
+ Computes the multivariable Alexander polynomial of the manifold::
341
+
342
+ sage: M = Manifold('K12n123')
343
+ sage: M.alexander_polynomial()
344
+ 2*a^6 - 14*a^5 + 34*a^4 - 45*a^3 + 34*a^2 - 14*a + 2
345
+
346
+ sage: N = Triangulation('v1539(5,1)')
347
+ sage: N.alexander_polynomial()
348
+ a^2*b + a*b^2 + a*b + a + b
349
+
350
+ Any provided keyword arguments are passed to
351
+ :meth:`fundamental_group <snappy.Triangulation.fundamental_group>` and
352
+ so affect the group presentation used in the computation.
353
+ """
354
+ if manifold.homology().order() != 'infinite':
355
+ raise ValueError(
356
+ "Alexander polynomial only defined for manifolds with "
357
+ "infinite homology.")
358
+
359
+ return alexander_polynomial_group(manifold.fundamental_group(**kwargs))
360
+
361
+
362
+ # --------------------------------------------------------------
363
+ #
364
+ # Computing the twisted torsion polynomials
365
+ # for deficiency one presentations.
366
+ #
367
+ # --------------------------------------------------------------
368
+
369
+
370
+ class PhiAlpha():
371
+ def __init__(self, phi, alpha):
372
+ self.base_ring = phi.range()
373
+ self.image_ring = MatrixSpace(self.base_ring, 2)
374
+ self.phi, self.alpha = phi, alpha
375
+
376
+ def range(self):
377
+ return self.image_ring
378
+
379
+ def __call__(self, word):
380
+ a = self.phi(word)
381
+ A = self.alpha(word)
382
+ M = self.image_ring(0)
383
+ M[0,0], M[0,1], M[1,0], M[1,1] = a*A[0,0], a*A[0,1], a*A[1,0], a*A[1,1]
384
+ return M
385
+
386
+
387
+ def free_monoid_elt_to_string(elt):
388
+ vars = elt.parent().variable_names()
389
+ return "".join([e*vars[v] for v, e in elt._element_list])
390
+
391
+
392
+ def inverse_word(word):
393
+ L = list(word.swapcase())
394
+ L.reverse()
395
+ return "".join(L)
396
+
397
+
398
+ def reverse_word(word):
399
+ L = list(word)
400
+ L.reverse()
401
+ return "".join(L)
402
+
403
+
404
+ def clean_RR(r, error):
405
+ return 0 if abs(r) < error else r
406
+
407
+
408
+ def clean_CC(z, error):
409
+ CC = z.parent()
410
+ return CC( clean_RR(z.real(),error), clean_RR(z.imag(), error) ) if not CC.is_exact() else z
411
+
412
+
413
+ def univ_exponents(p):
414
+ try:
415
+ return [a[0] for a in p.exponents()]
416
+ except TypeError:
417
+ return p.exponents()
418
+
419
+
420
+ def clean_laurent(p, error):
421
+ R = p.parent()
422
+ t = R.gen()
423
+ new_coeffs = [clean_CC(z, error) for z in p.coefficients()]
424
+ return sum( [a*t**n for a , n in zip(new_coeffs, univ_exponents(p))], R.zero())
425
+
426
+
427
+ def clean_laurent_to_poly(p, error=10**-8):
428
+ R = p.parent()
429
+ P = PolynomialRing(R.base_ring(), R.variable_names())
430
+ t = P.gen()
431
+ cp = clean_laurent(p,error)
432
+ exponents = univ_exponents(cp)
433
+ if len(exponents) == 0:
434
+ return P(0)
435
+ m = min(exponents)
436
+ return sum( [a*t**(n-m) for a,n in zip(cp.coefficients(), exponents)], P(0))
437
+
438
+
439
+ def univ_abs(z):
440
+ """
441
+ Compute a reasonable choice for the absolute value of z.
442
+ """
443
+ try:
444
+ return z.abs()
445
+ except (TypeError, AttributeError):
446
+ if hasattr(z, 'coefficients'):
447
+ return max([0,] + [univ_abs(c) for c in z.coefficients()])
448
+ else:
449
+ return 0 if z == 0 else Infinity
450
+
451
+
452
+ def univ_matrix_norm(A):
453
+ return max([0] + [univ_abs(a) for a in A.list()])
454
+
455
+
456
+ def matrix_has_small_entries(A, bound):
457
+ if A.base_ring().is_exact():
458
+ return A == 0
459
+ else:
460
+ return univ_matrix_norm(A) < bound
461
+
462
+
463
+ def last_square_submatrix(A):
464
+ r, c = A.nrows(), A.ncols()
465
+ if r <= c:
466
+ return A.matrix_from_columns( range(c - r, c) )
467
+ else:
468
+ return A.matrix_from_rows( range( r - c, r) )
469
+
470
+
471
+ def first_square_submatrix(A):
472
+ r, c = A.nrows(), A.ncols()
473
+ if r <= c:
474
+ return A.matrix_from_columns( range(r) )
475
+ else:
476
+ return A.matrix_from_rows( range(c) )
477
+
478
+
479
+ class TorsionComputationError(Exception):
480
+ pass
481
+
482
+
483
+ def fast_determinant_of_laurent_poly_matrix(A):
484
+ """
485
+ Return the determinant of the given matrix up to
486
+ a power of t^n, using the faster algorithm for
487
+ polynomial entries.
488
+ """
489
+ R = A.base_ring()
490
+ P = R.polynomial_ring()
491
+ if A == 0:
492
+ return P(0)
493
+ minexp = minimum_exponents(A.list())
494
+ MS = A.parent().change_ring(P)
495
+ Ap = MS([convert_laurent_to_poly(p, minexp, P) for p in A.list()])
496
+ return Ap.det()
497
+
498
+
499
+ def compute_torsion(G, bits_prec, alpha=None, phi=None, phialpha=None,
500
+ return_parts=False, return_as_poly=True,
501
+ wada_conventions=False, symmetry_test=True):
502
+ if alpha:
503
+ F = alpha('a').base_ring()
504
+ elif phialpha:
505
+ F = phialpha('a').base_ring().base_ring()
506
+ epsilon = ZZ(2)**(-bits_prec//3) if not F.is_exact() else None
507
+ big_epsilon = ZZ(2)**(-bits_prec//5) if not F.is_exact() else None
508
+ gens, rels = G.generators(), G.relators()
509
+
510
+ if len(rels) != len(gens) - 1:
511
+ raise ValueError(
512
+ "Algorithm to compute torsion requires a group presentation "
513
+ "with deficiency one")
514
+
515
+ k = len(gens)
516
+ if phi is None:
517
+ phi = MapToGroupRingOfFreeAbelianization(G, F)
518
+
519
+ if len(phi.range().gens()) != 1:
520
+ raise ValueError(
521
+ "Algorithm to compute torsion requires betti number 1")
522
+
523
+ # Want the first variable to be homologically nontrivial
524
+ i0 = [i for i, g in enumerate(gens) if phi(g) != 1][0]
525
+ gens = gens[i0:] + gens[:i0]
526
+ if phialpha is None:
527
+ phialpha = PhiAlpha(phi, alpha)
528
+
529
+ # Boundary maps for chain complex
530
+
531
+ if not wada_conventions: # Using the conventions of our paper.
532
+ d2 = [ [fox_derivative_with_involution(R, phialpha, g) for R in rels] for g in gens]
533
+ d2 = block_matrix(d2, nrows=k, ncols=k-1)
534
+ d1 = [phialpha(g.swapcase()) - 1 for g in gens]
535
+ d1 = block_matrix(d1, nrows=1, ncols=k)
536
+ dsquared = d1 * d2
537
+
538
+ else: # Using those implicit in Wada's paper.
539
+ d2 = [ [fox_derivative(R, phialpha, g) for g in gens] for R in rels]
540
+ d2 = block_matrix(sum(d2, []), nrows=k-1, ncols=k)
541
+ d1 = [phialpha(g) - 1 for g in gens]
542
+ d1 = block_matrix(d1, nrows=k, ncols=1)
543
+ dsquared = d2 * d1
544
+
545
+ if not matrix_has_small_entries( dsquared, epsilon ):
546
+ raise TorsionComputationError("(boundary)^2 != 0")
547
+
548
+ T = last_square_submatrix(d2)
549
+ if return_as_poly:
550
+ T = fast_determinant_of_laurent_poly_matrix(T)
551
+ else:
552
+ T = det(T)
553
+ B = first_square_submatrix(d1)
554
+ B = det(B)
555
+ if return_as_poly:
556
+ T = clean_laurent_to_poly(T, epsilon)
557
+ B = clean_laurent_to_poly(B, epsilon)
558
+ else:
559
+ T = clean_laurent(T, epsilon)
560
+ B = clean_laurent(B, epsilon)
561
+
562
+ if return_parts:
563
+ return (T, B)
564
+
565
+ q, r = T.quo_rem(B)
566
+ ans = clean_laurent_to_poly(q, epsilon)
567
+ if (not F.is_exact() and univ_abs(r) > epsilon) or (F.is_exact() and r != 0):
568
+ raise TorsionComputationError("Division failed")
569
+
570
+ # Now do a quick sanity check
571
+
572
+ if symmetry_test:
573
+ coeffs = ans.coefficients()
574
+ error = max([univ_abs(a-b) for a,b in zip(coeffs, reversed(coeffs))], default=0)
575
+ if (not F.is_exact() and error > epsilon) or (F.is_exact() and error != 0):
576
+ raise TorsionComputationError("Torsion polynomial doesn't seem symmetric")
577
+
578
+ return ans
579
+
580
+ # --------------------------------------------------------------
581
+ #
582
+ # Computing the torsion polynomials
583
+ # for the *adjoint* representation
584
+ # i.e. the poly of Dubois-Yamaguichi
585
+ # --------------------------------------------------------------
586
+
587
+
588
+ def adjoint_action(A):
589
+ a, b, c, d = A.list()
590
+ return matrix( [[a**2, 2*a*b, b**2],[a*c,b*c+a*d,b*d],[c**2,2*c*d,d**2]] )
591
+
592
+
593
+ def SL2_to_SLN(A, N):
594
+ F = A.base_ring()
595
+ R = PolynomialRing(F, ['x', 'y'])
596
+ x, y = R.gens()
597
+ X, Y = A * vector(R, (x, y))
598
+ monomials = [x**(N - 1 - i) * y**i for i in range(N)]
599
+ image_vectors = [m(X, Y) for m in monomials]
600
+ return matrix(F, [[v.monomial_coefficient(m) for m in monomials] for v in image_vectors])
601
+
602
+
603
+ class PhiAlpha3():
604
+ def __init__(self, phi, alpha):
605
+ self.base_ring = phi.range()
606
+ self.image_ring = MatrixSpace(self.base_ring, 3)
607
+ self.phi, self.alpha = phi, alpha
608
+
609
+ def range(self):
610
+ return self.image_ring
611
+
612
+ def __call__(self, word):
613
+ a = self.phi(word)
614
+ A = adjoint_action(self.alpha(word))
615
+ M = self.image_ring(0)
616
+ for i in range(3):
617
+ for j in range(3):
618
+ M[i,j] = a*A[i,j]
619
+
620
+ return M
621
+
622
+
623
+ class PhiAlphaN():
624
+ def __init__(self, phi, alpha, N):
625
+ self.base_ring = phi.range()
626
+ self.image_ring = MatrixSpace(self.base_ring, N)
627
+ self.phi, self.alpha, self.N = phi, alpha, N
628
+
629
+ def range(self):
630
+ return self.image_ring
631
+
632
+ def __call__(self, word):
633
+ a = self.phi(word)
634
+ A = SL2_to_SLN(self.alpha(word), self.N)
635
+ M = self.image_ring(0)
636
+ for i in range(self.N):
637
+ for j in range(self.N):
638
+ M[i,j] = a*A[i,j]
639
+
640
+ return M
641
+
642
+
643
+ def test_rep(G, phialpha):
644
+ def manually_apply_word(w):
645
+ return prod(phialpha(x) for x in w)
646
+ return max([univ_matrix_norm(manually_apply_word(R) - 1) for R in G.relators()])
647
+
648
+
649
+ @sage_method
650
+ def hyperbolic_torsion(manifold, bits_prec=100, all_lifts=False, wada_conventions=False, phi=None):
651
+ """
652
+ Computes the hyperbolic torsion polynomial as defined in
653
+ `[DFJ] <http://arxiv.org/abs/1108.3045>`_::
654
+
655
+ sage: M = Manifold('K11n42')
656
+ sage: M.alexander_polynomial()
657
+ 1
658
+ sage: tau = M.hyperbolic_torsion(bits_prec=200)
659
+ sage: tau.degree()
660
+ 6
661
+ """
662
+ if manifold.homology().betti_number() != 1:
663
+ raise ValueError('Algorithm needs H^1(M; Z) = Z to be able to compute torsion')
664
+ H = manifold.fundamental_group()
665
+ if H.num_generators() != H.num_relators() + 1:
666
+ raise ValueError('Algorithm to compute torsion requires a group presentation '
667
+ 'with deficiency one')
668
+ G = alpha = polished_holonomy(manifold, bits_prec=bits_prec, lift_to_SL2=True)
669
+ if not all_lifts:
670
+ return compute_torsion(G, bits_prec, alpha, phi, wada_conventions=wada_conventions)
671
+ else:
672
+ return [compute_torsion(G, bits_prec, beta, phi, wada_conventions=wada_conventions)
673
+ for beta in alpha.all_lifts_to_SL2C()]
674
+
675
+
676
+ @sage_method
677
+ def hyperbolic_SLN_torsion(manifold, N, bits_prec=100):
678
+ """
679
+ Compute the torsion polynomial of the holonomy representation lifted
680
+ to SL(2, C) and then followed by the irreducible representation
681
+ from SL(2, C) -> SL(N, C)::
682
+
683
+ sage: M = Manifold('m016')
684
+ sage: [M.hyperbolic_SLN_torsion(N).degree() for N in [2, 3, 4]]
685
+ [18, 27, 36]
686
+ """
687
+ if manifold.homology().betti_number() != 1:
688
+ raise ValueError('Algorithm needs H^1(M; Z) = Z to be able to compute torsion')
689
+ H = manifold.fundamental_group()
690
+ if H.num_generators() != H.num_relators() + 1:
691
+ raise ValueError('Algorithm to compute torsion requires a group presentation '
692
+ 'with deficiency one')
693
+ G = alpha = polished_holonomy(manifold, bits_prec)
694
+ phi = MapToGroupRingOfFreeAbelianization(G, alpha('a').base_ring())
695
+ phialpha = PhiAlphaN(phi, alpha, N)
696
+ if not test_rep(G, phialpha) < ZZ(2)**(bits_prec // 2):
697
+ raise RuntimeError("Invalid representation")
698
+ return compute_torsion(G, bits_prec, phialpha=phialpha, symmetry_test=False)
699
+
700
+
701
+ @sage_method
702
+ def hyperbolic_adjoint_torsion(manifold, bits_prec=100):
703
+ """
704
+ Computes the torsion polynomial of the adjoint representation
705
+ a la Dubois-Yamaguichi. This is not a sign-refined computation
706
+ so the result is only defined up to sign, not to mention a power
707
+ of the variable 'a'::
708
+
709
+ sage: M = Manifold('K11n42')
710
+ sage: tau = M.hyperbolic_adjoint_torsion()
711
+ sage: tau.parent()
712
+ Univariate Polynomial Ring in a over Complex Field with 100 bits of precision
713
+ sage: tau.degree()
714
+ 7
715
+ """
716
+ return hyperbolic_SLN_torsion(manifold, 3, bits_prec)
@@ -0,0 +1 @@
1
+ from .peripheral import peripheral_cohomology_basis