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,335 @@
1
+ """
2
+ A Sage module for finding the holonomy representation of a hyperbolic
3
+ 3-manifold to very high precision.
4
+ """
5
+ from itertools import product, chain
6
+ from ..sage_helper import _within_sage
7
+ from ..math_basics import prod
8
+ from ..pari import pari
9
+
10
+ from .fundamental_polyhedron import *
11
+
12
+ if _within_sage:
13
+ from ..sage_helper import RealField, ComplexField, gcd, prod, powerset
14
+ from ..sage_helper import MatrixSpace, matrix, vector, ZZ
15
+ from ..sage_helper import SageObject as Object
16
+
17
+ identity = lambda A: MatrixSpace(A.base_ring(), A.nrows())(1)
18
+ abelian_group_elt = lambda v: vector(ZZ, v)
19
+ else:
20
+ Object = object
21
+ from .utilities import Matrix2x2 as matrix, powerset
22
+ from ..number import Number
23
+
24
+ def identity(A):
25
+ return matrix(A.base_ring(), 1.0, 0.0, 0.0, 1.0)
26
+ abelian_group_elt = lambda v: v
27
+
28
+
29
+ # ----------------------------------------------------------------
30
+ #
31
+ # Abelianization of the fundamental group
32
+ #
33
+ # ----------------------------------------------------------------
34
+
35
+ class MapToFreeAbelianization(Object):
36
+ """
37
+ >>> import snappy
38
+ >>> M = snappy.Manifold('m125')
39
+ >>> G = M.fundamental_group(False, False, False)
40
+ >>> rho = MapToFreeAbelianization(G)
41
+ >>> for g in G.generators(): print( g, rho(g) )
42
+ ...
43
+ a (3, -1)
44
+ b (5, -2)
45
+ c (0, 1)
46
+ d (1, 0)
47
+ """
48
+
49
+ def __init__(self, fund_group):
50
+ self.generators = gens = fund_group.generators()
51
+ self.relators = rels = fund_group.relators()
52
+ entries = list(chain(*(self.abelianize_word(r) for r in rels)))
53
+ presentation = pari.matrix(len(rels), len(gens), entries).mattranspose()
54
+ U, V, D = presentation.matsnf(flag=1) # D = U*R*V is the smith form
55
+ self.U = U
56
+ elementary_divisors = D.matsnf().list()
57
+ self._rank = elementary_divisors.count(0)
58
+
59
+ def abelianize_word(self, word):
60
+ return [word.count(g) - word.count(g.swapcase()) for g in self.generators]
61
+
62
+ @property
63
+ def rank(self):
64
+ return self._rank
65
+
66
+ def __call__(self, word):
67
+ v = self.U*pari(self.abelianize_word(word)).mattranspose()
68
+ return abelian_group_elt( tuple(int(x) for x in list(v[0])[:self._rank]) )
69
+
70
+ # General code for storing high-precision representations.
71
+
72
+
73
+ def clean_RR(r, error):
74
+ return 0 if abs(r) < error else r
75
+
76
+
77
+ if _within_sage:
78
+ def clean_CC(z, error, prec):
79
+ CC = ComplexField(prec)
80
+ return CC( clean_RR(z.real(),error), clean_RR(z.imag(), error) )
81
+ else:
82
+ def clean_CC(z, error, prec):
83
+ re, im = z.real(), z.imag()
84
+ prec = re.prec()
85
+ clean_z = pari.complex( clean_RR(re.gen, error), clean_RR(im.gen, error) )
86
+ return Number(clean_z, precision=prec)
87
+
88
+
89
+ def clean_matrix(A, error, prec):
90
+ return matrix([[clean_CC(A[x], error, prec) for x in ((i,0),(i,1))]
91
+ for i in (0,1)])
92
+
93
+
94
+ def SL2C_inverse(A):
95
+ return matrix([[A[1,1], -A[0, 1]], [-A[1, 0], A[0, 0]]])
96
+
97
+
98
+ def matrix_norm(A):
99
+ return max( [abs(a) for a in A.list()])
100
+
101
+
102
+ def matrix_difference_norm(A, B):
103
+ return max([abs(a - b) for a, b in zip(A.list(), B.list())])
104
+
105
+
106
+ def projective_distance(A, B):
107
+ return min( matrix_norm(A-B), matrix_norm(A+B) )
108
+
109
+
110
+ def compare_matrices(Mats0, Mats1):
111
+ return max([projective_distance(A, B) for A, B in zip(Mats0, Mats1)])
112
+
113
+
114
+ def make_epsilon(A):
115
+ prec = A.base_ring().precision()
116
+ RR = RealField(prec)
117
+ return RR(2)**(RR(-0.6)*prec)
118
+
119
+
120
+ def make_trace_2(A):
121
+ P = A if A.trace() > 0 else - A
122
+ if abs(P.trace() - 2) < make_epsilon(A):
123
+ return P
124
+ else:
125
+ raise ValueError("Matrix of peripheral element doesn't seem to be parabolic")
126
+
127
+
128
+ def parabolic_eigenvector(A):
129
+ P, CC, epsilon = make_trace_2(A), A.base_ring(), make_epsilon(A)
130
+ for v in [vector(CC, (1, 0) ), vector(CC, (0, 1))]:
131
+ if (v - P*v).norm() < epsilon:
132
+ return v
133
+
134
+ v = vector( CC , pari(P - 1).matker()[0])
135
+ assert (v - P*v).norm() < epsilon
136
+ return v
137
+
138
+
139
+ def extend_to_basis(v):
140
+ u = (1/v.norm())*v
141
+ w = vector(v.base_ring(), (-u[1].conjugate(), u[0].conjugate()))
142
+ return matrix( [u, w] ).transpose()
143
+
144
+
145
+ def is_essentially_Id2(M, error=10**-3):
146
+ diff = M - identity(M)
147
+ error = diff.base_ring()(error)
148
+ return all(abs(d) < error for d in diff.list())
149
+
150
+
151
+ class MatrixRepresentation(Object):
152
+ def __init__(self, gens, relators, matrices):
153
+ self._gens, self._relators, self._matrices = gens, relators, matrices
154
+ self._build_hom_dict()
155
+ A = matrices[0]
156
+ self._id = identity(A)
157
+
158
+ def _build_hom_dict(self):
159
+ gens, matrices = self._gens, self._matrices
160
+ inv_gens = [g.upper() for g in gens]
161
+ inv_mat = [SL2C_inverse(m) for m in matrices]
162
+ self._hom_dict = dict(zip(gens + inv_gens, matrices + inv_mat))
163
+
164
+ def generators(self):
165
+ return self._gens
166
+
167
+ def num_generators(self):
168
+ return len(self._gens)
169
+
170
+ def relators(self):
171
+ return self._relators
172
+
173
+ def __call__(self, word):
174
+ return prod([self._hom_dict[g] for g in word], self._id)
175
+
176
+ def is_nonprojective_representation(self):
177
+ """
178
+ True if this is an SL(2,C)-representation, i.e., if multiplying the generators
179
+ in a word yields the identity matrix.
180
+ """
181
+ return all(is_essentially_Id2(self(R)) for R in self.relators())
182
+
183
+ def is_projective_representation(self):
184
+ """
185
+ True if this is an PSL(2,C)-representation, i.e., if multiplying the generators
186
+ in a word yields the identity matrix or its negative.
187
+ """
188
+ rel_images = (self(R) for R in self.relators())
189
+ return all(is_essentially_Id2(M) or is_essentially_Id2(-M)
190
+ for M in rel_images)
191
+
192
+ def lift_to_SL2C(self):
193
+ assert self.is_projective_representation()
194
+ base_gen_images = [self(g) for g in self.generators()]
195
+ generators, relators = self.generators(), self.relators()
196
+
197
+ # Make into a real rep
198
+ pos_signs = product( *([(1, -1)]*len(base_gen_images)))
199
+ for signs in pos_signs:
200
+ gen_images = [ s*M for s, M in zip(signs, base_gen_images)]
201
+ rho = MatrixRepresentation(generators, relators, gen_images)
202
+ if rho.is_nonprojective_representation():
203
+ self._matrices = gen_images
204
+ self._build_hom_dict()
205
+ break
206
+
207
+ assert self.is_nonprojective_representation()
208
+
209
+ def all_lifts_to_SL2C(self):
210
+ ans = []
211
+ self.lift_to_SL2C()
212
+ base_gen_images = [self(g) for g in self.generators()]
213
+ pos_signs = product( *([(1, -1)]*len(base_gen_images)))
214
+ for signs in pos_signs:
215
+ beta = MatrixRepresentation(self.generators(), self.relators(), [ s*A for s, A in zip(signs, base_gen_images)])
216
+ if beta.is_nonprojective_representation():
217
+ ans.append(beta)
218
+ return ans
219
+
220
+ def trace_field_generators(self):
221
+ gens = self.generators()
222
+ enough_elts = [ ''.join(sorted(s)) for s in powerset(gens) if len(s) > 0]
223
+ return [self(w).trace() for w in enough_elts]
224
+
225
+ def invariant_trace_field_generators(self):
226
+ gens = self.generators()
227
+ if min([abs(self(g).trace()) for g in gens]) < 0.001:
228
+ raise ValueError("Algorithm fails when a generator has trace 0, see page 125 of ML")
229
+ gens = [2*g for g in gens]
230
+ enough_elts = [ ''.join(sorted(s)) for s in powerset(gens) if len(s) > 0]
231
+ return [self(w).trace() for w in enough_elts]
232
+
233
+
234
+ class ManifoldGroup(MatrixRepresentation):
235
+ def __init__(self, gens, relators, peripheral_curves=None, matrices=None):
236
+ MatrixRepresentation.__init__(self, gens, relators, matrices)
237
+ self._peripheral_curves = peripheral_curves
238
+
239
+ def peripheral_curves(self):
240
+ return self._peripheral_curves
241
+
242
+ def SL2C(self, word):
243
+ return self(word)
244
+
245
+ def check_representation(self):
246
+ relator_matrices = (self.SL2C(R) for R in self.relators())
247
+ return max(projective_distance(A, identity(A)) for A in relator_matrices)
248
+
249
+ def cusp_shape(self, cusp_num=0):
250
+ """
251
+ Get the polished cusp shape for this representation::
252
+
253
+ sage: M = ManifoldHP('m015')
254
+ sage: rho = M.polished_holonomy(bits_prec=100)
255
+ sage: rho.cusp_shape() # doctest: +NUMERIC24
256
+ -0.49024466750661447990098220731 + 2.9794470664789769463726817144*I
257
+
258
+ """
259
+ M, L = (self.SL2C(w) for w in self.peripheral_curves()[cusp_num])
260
+ C = extend_to_basis(parabolic_eigenvector(M))
261
+ M, L = ( make_trace_2( C**(-1)*A*C ) for A in [M, L] )
262
+ z = L[0][1]/M[0][1]
263
+ return z.conjugate()
264
+
265
+ def lift_to_SL2C(self):
266
+ MatrixRepresentation.lift_to_SL2C(self)
267
+ # Now make things correspond to our convention that tr(rho(meridian)) = +2, *when possible*.
268
+ phi = MapToFreeAbelianization(self)
269
+ meridian = self.peripheral_curves()[0][0]
270
+ meridian_trace = self(meridian).trace()
271
+ if phi.rank == 1 and phi(meridian) % 2 != 0 and meridian_trace < 0:
272
+ def twist(g, gen_image):
273
+ return gen_image if phi(g)[0] % 2 == 0 else -gen_image
274
+ self._matrices = [ twist(g, M) for g, M in zip(self._gens, self._matrices) ]
275
+ self._build_hom_dict()
276
+ assert self.is_nonprojective_representation()
277
+ assert self(meridian).trace() > 0
278
+
279
+ def all_lifts_to_SL2C(self):
280
+ ans = []
281
+ self.lift_to_SL2C()
282
+ base_gen_images = [self(g) for g in self.generators()]
283
+ pos_signs = product( *([(1, -1)]*len(base_gen_images)))
284
+ for signs in pos_signs:
285
+ beta = ManifoldGroup(self.generators(), self.relators(),
286
+ self.peripheral_curves(),
287
+ [ s*A for s, A in zip(signs, base_gen_images)])
288
+ if beta.is_nonprojective_representation():
289
+ ans.append(beta)
290
+ return ans
291
+
292
+ def __repr__(self):
293
+ return 'Generators:\n %s\nRelators:\n %s' % (
294
+ ','.join(self.generators()),
295
+ '\n '.join(self.relators()))
296
+
297
+
298
+ def polished_holonomy(manifold,
299
+ bits_prec=100,
300
+ fundamental_group_args=[],
301
+ lift_to_SL2=True,
302
+ ignore_solution_type=False,
303
+ dec_prec=None,
304
+ match_kernel=True):
305
+ """
306
+ Return the fundamental group of M equipped with a high-precision version of
307
+ the holonomy representation::
308
+
309
+ sage: M = Manifold('m004')
310
+ sage: G = M.polished_holonomy()
311
+ sage: G('a').trace()
312
+ 1.5000000000000000000000000000 - 0.86602540378443864676372317075*I
313
+ sage: G = M.polished_holonomy(bits_prec=1000)
314
+ sage: G('a').trace().parent()
315
+ Complex Field with 1000 bits of precision
316
+ """
317
+ M = manifold
318
+ if dec_prec:
319
+ bits_prec = None
320
+ error = 10**(-dec_prec*0.8)
321
+ else:
322
+ error = 2**(-bits_prec*0.8)
323
+ shapes = M.tetrahedra_shapes('rect', bits_prec=bits_prec, dec_prec=dec_prec)
324
+ G = M.fundamental_group(*fundamental_group_args)
325
+ f = FundamentalPolyhedronEngine.from_manifold_and_shapes(
326
+ M, shapes, normalize_matrices=True, match_kernel=match_kernel)
327
+ mats = f.matrices_for_presentation(G, match_kernel=True)
328
+ clean_mats = [clean_matrix(A, error=error, prec=bits_prec) for A in mats]
329
+ PG = ManifoldGroup(G.generators(), G.relators(), G.peripheral_curves(), clean_mats)
330
+ if lift_to_SL2:
331
+ PG.lift_to_SL2C()
332
+ else:
333
+ assert PG.is_projective_representation()
334
+
335
+ return PG
snappy/snap/shapes.py ADDED
@@ -0,0 +1,152 @@
1
+ from ..sage_helper import _within_sage
2
+ from ..pari import pari, prec_dec_to_bits, prec_bits_to_dec, Gen
3
+
4
+ if _within_sage:
5
+ from ..sage_helper import ComplexField
6
+ else:
7
+ from snappy.number import Number
8
+
9
+
10
+ def is_pari(x) -> bool:
11
+ return isinstance(x, Gen)
12
+
13
+
14
+ def pari_matrix(A):
15
+ return pari.matrix(len(A), len(A[0]), [pari(x) for x in sum(A, [])])
16
+
17
+
18
+ def pari_row_vector(v):
19
+ return pari(v).Vec()
20
+
21
+
22
+ def pari_column_vector(v):
23
+ return pari(v).Col()
24
+
25
+
26
+ def pari_vector_to_list(v):
27
+ return v.Vec().python_list()
28
+
29
+
30
+ def pari_matrix_to_lists(A):
31
+ 'Return the entries of A in *column major* order'
32
+ return [pari_vector_to_list(v) for v in A.list()]
33
+
34
+
35
+ def eval_gluing_equation(eqn, shapes):
36
+ if is_pari(eqn):
37
+ shapes = pari_vector_to_list(shapes)
38
+ a, b, c = eqn
39
+ ans = int(c)
40
+ for i, z in enumerate(shapes):
41
+ ans = ans * (z**int(a[i]) * (1 - z)**int(b[i]))
42
+ return ans
43
+
44
+
45
+ def gluing_equation_errors(eqns, shapes):
46
+ return [eval_gluing_equation(eqn, shapes) - 1 for eqn in eqns]
47
+
48
+
49
+ def infinity_norm(L):
50
+ if is_pari(L):
51
+ L = pari_vector_to_list(L)
52
+ return max([abs(x) for x in L])
53
+
54
+
55
+ def gluing_equation_error(eqns, shapes):
56
+ return infinity_norm(gluing_equation_errors(eqns, shapes))
57
+
58
+
59
+ def enough_gluing_equations(manifold):
60
+ """
61
+ Select a full-rank portion of the gluing equations.
62
+ """
63
+ n_tet = manifold.num_tetrahedra()
64
+ n_cusps = manifold.num_cusps()
65
+ eqns = manifold.gluing_equations("rect")
66
+ edge_eqns = pari_matrix([a + b for a, b, _ in eqns[:n_tet]])
67
+ edge_eqns_with_RHS = pari_matrix([a + b + [(1 - c) // 2]
68
+ for a, b, c in eqns[:n_tet]])
69
+ H, U = edge_eqns.mattranspose().mathnf(flag=1)
70
+ assert H.ncols() == n_tet - n_cusps
71
+ edge_eqns_with_RHS = pari_matrix_to_lists((edge_eqns_with_RHS.mattranspose() * U))[n_cusps:]
72
+ edge_eqns_with_RHS = [(e[:n_tet], e[n_tet: 2 * n_tet], pari(-1)**e[-1])
73
+ for e in edge_eqns_with_RHS]
74
+
75
+ cusp_eqns = []
76
+ j = n_tet
77
+ for i in range(n_cusps):
78
+ cusp_eqns.append(eqns[j])
79
+ j += 2 if manifold.cusp_info(i)['complete?'] else 1
80
+
81
+ ans_eqns = edge_eqns_with_RHS + cusp_eqns
82
+
83
+ ans_matrix = pari_matrix([a + b for a, b, _ in ans_eqns])
84
+ assert len(ans_eqns) == n_tet and len(ans_matrix.mattranspose().matkerint()) == 0
85
+ return [(list(map(int, A)), list(map(int, B)), int(c)) for A, B, c in ans_eqns]
86
+
87
+
88
+ def float_to_pari(x, dec_prec):
89
+ return pari(0) if x == 0 else pari(x).precision(dec_prec)
90
+
91
+
92
+ def complex_to_pari(z, dec_prec):
93
+ return pari.complex(float_to_pari(z.real, dec_prec),
94
+ float_to_pari(z.imag, dec_prec))
95
+
96
+
97
+ def polished_tetrahedra_shapes(manifold, dec_prec=None, bits_prec=200, ignore_solution_type=False):
98
+ """
99
+ Refines the current solution to the gluing equations to one with
100
+ the specified accuracy.
101
+ """
102
+ if dec_prec is None:
103
+ dec_prec = prec_bits_to_dec(bits_prec)
104
+ else:
105
+ bits_prec = prec_dec_to_bits(dec_prec)
106
+ working_prec = dec_prec + 10
107
+ target_espilon = float_to_pari(10.0, working_prec)**-dec_prec
108
+ if _within_sage:
109
+ CC = ComplexField(bits_prec)
110
+ number = CC
111
+ else:
112
+ def number(z):
113
+ return Number(z, precision=bits_prec)
114
+
115
+ # This is a potentially long calculation, so we cache the result
116
+
117
+ if "polished_shapes" in manifold._cache:
118
+ curr_bits_prec, curr_sol = manifold._cache["polished_shapes"]
119
+ if bits_prec <= curr_bits_prec:
120
+ return [number(s) for s in pari_vector_to_list(curr_sol)]
121
+
122
+ # Check and make sure initial solution is reasonable
123
+
124
+ if not ignore_solution_type and manifold.solution_type() not in ['all tetrahedra positively oriented', 'contains negatively oriented tetrahedra']:
125
+ raise ValueError('Initial solution to gluing equations has flat or degenerate tetrahedra')
126
+
127
+ init_shapes = pari_column_vector([complex_to_pari(complex(z), working_prec) for z in manifold.tetrahedra_shapes('rect')])
128
+ init_equations = manifold.gluing_equations('rect')
129
+ if gluing_equation_error(init_equations, init_shapes) > pari(0.000001):
130
+ raise ValueError('Initial solution not very good')
131
+
132
+ # Now begin the actual computation
133
+ eqns = enough_gluing_equations(manifold)
134
+ shapes = init_shapes
135
+ initial_error = infinity_norm(gluing_equation_errors(eqns, shapes))
136
+ for i in range(100):
137
+ errors = gluing_equation_errors(eqns, shapes)
138
+ error = infinity_norm(errors)
139
+ if error < target_espilon or error > 100 * initial_error:
140
+ break
141
+ derivative = pari_matrix([[eqn[0][i] / z - eqn[1][i] / (1 - z)
142
+ for i, z in enumerate(pari_vector_to_list(shapes))] for eqn in eqns])
143
+ gauss = derivative.matsolve(pari_column_vector(errors))
144
+ shapes = shapes - gauss
145
+
146
+ # Check to make sure things worked out ok.
147
+ error = gluing_equation_error(init_equations, shapes)
148
+ total_change = infinity_norm(init_shapes - shapes)
149
+ if error > 1000 * target_espilon or total_change > pari(0.0000001):
150
+ raise ValueError('Did not find a good solution to the gluing equations')
151
+ manifold._cache["polished_shapes"] = (bits_prec, shapes)
152
+ return [number(s) for s in pari_vector_to_list(shapes)]
@@ -0,0 +1,194 @@
1
+ """
2
+ Using metabelian representations to obstruct slicing
3
+ ====================================================
4
+
5
+ Based on::
6
+
7
+ Herald, Kirk, and Livingston, Math Zeit., 2010
8
+ https://dx.doi.org/10.1007/s00209-009-0548-1
9
+ https://arXiv.org/abs/0804.1355
10
+
11
+ and::
12
+
13
+ Dunfield and Gong, "Ribbon concordances and slice obstructions:
14
+ experiments and examples", https://arXiv.org/abs/2512.21825
15
+
16
+ In in the basic case, the implementation follows the [HKL] paper closely, with a
17
+ few minor changes:
18
+
19
+ 1. We use the default simplified presentation for pi_1(knot exterior)
20
+ that SnapPy provides, rather than a Wirtinger presentation, as the
21
+ former has many fewer generators (but of course much longer
22
+ relators).
23
+
24
+ 2. The construction of the metabelian representations in Section 7 of
25
+ [HKL] is done the language of twisted cohomology and specifically
26
+ twisted cocycles, whereas this viewpoint is not quite explicit
27
+ (though clearly implied) in [HKL].
28
+
29
+ 3. To match the conventions of the other twisted Alexander polynomials
30
+ computed by SnapPy, we insist on all actions are on the left,
31
+ rather than the mix of left and right actions used in [HKL].
32
+
33
+ 4. For the final check of whether the twisted polynomial is a norm, we
34
+ simply use that Sage can factor univariate polynomials over
35
+ cyclotomic fields into irreducibles, rather than the various
36
+ generalizations of Gauss's Lemma in [HKL].
37
+
38
+ Additionally, we implement the refinements and generalizations
39
+ introduced in [DG].
40
+ """
41
+
42
+ from ... import SnapPy
43
+ from ...sage_helper import _within_sage, sage_method
44
+ if _within_sage:
45
+ from ...sage_helper import ZZ, prime_range, prime_powers
46
+ from . import basics, rep_theory, direct
47
+
48
+
49
+ def expand_prime_power_spec(spec):
50
+ if spec in ZZ:
51
+ a, b = 0, spec
52
+ else:
53
+ if len(spec) != 2:
54
+ raise ValueError(f'Spec {spec} does not specify a range')
55
+ a, b = spec
56
+ return prime_powers(a, b + 1)
57
+
58
+
59
+ def expand_prime_spec(spec):
60
+ if spec in ZZ:
61
+ a, b = 0, spec
62
+ else:
63
+ if len(spec) != 2:
64
+ raise ValueError(f'Spec {spec} does not specify a range')
65
+ a, b = spec
66
+ return prime_range(a, b + 1)
67
+
68
+
69
+ @sage_method
70
+ def slice_obstruction_HKL(self,
71
+ primes_spec,
72
+ verbose=0,
73
+ check_in_S3=True,
74
+ method='advanced',
75
+ ribbon_mode=False):
76
+ """
77
+
78
+ For the exterior of a knot in the 3-sphere, search for a
79
+ Herald-Kirk-Livingston (HKL) topological slice obstruction as
80
+ described in Section 3 of Dunfield and Gong's paper
81
+ `[DG] <https://arXiv.org/abs/2512.21825>`_.
82
+
83
+ Specifically, it looks at the cyclic branched covers of the knot
84
+ of prime-power order p and the F_q homology thereof where q is
85
+ prime. The range of such (p, q) pairs searched is given by
86
+ primes_spec as a list of (p_max, [q_min, q_max]). It returns the
87
+ pair (p, q) of the first nonzero obstruction found (in which case
88
+ K is not slice), and otherwise returns ``None``::
89
+
90
+ sage: M = Manifold('K12n813')
91
+ sage: spec = [(10, [0, 20]), (20, [0, 10])]
92
+ sage: M.slice_obstruction_HKL(spec, method='basic', verbose=1)
93
+ Looking at (2, 3) ...
94
+ Looking at (3, 2) ...
95
+ Looking at (3, 7) ...
96
+ (3, 7)
97
+
98
+ You can also specify the p to examine by a range [p_min, p_max] or
99
+ the q by just q_max::
100
+
101
+ sage: spec = [([5, 10], 10)]
102
+ sage: M.slice_obstruction_HKL(spec, method='advanced', verbose=1)
103
+ Looking at (8, 3) ...
104
+ (8, 3)
105
+
106
+ If primes_spec is just a pair (p, q) then only that obstruction is
107
+ checked::
108
+
109
+ sage: M.slice_obstruction_HKL((3, 7))
110
+ (3, 7)
111
+
112
+ The ``method`` argument determines which HKL tests are employed:
113
+
114
+ * ``method='basic'`` employs Lemma 3.5 of [DG] and corresponds
115
+ roughly to the test used in SnapPy 3.1 and 3.2, though these
116
+ earlier versions required p to be prime and forbid q = 2.
117
+
118
+ * ``method='advanced'`` is the default and employs Theorem 3.8
119
+ from [DG]. This subsumes the `basic` method, but can be quite
120
+ slow when the multiplicity of an irreducible V_i is large.
121
+
122
+ An example where this method has more success::
123
+
124
+ sage: M.slice_obstruction_HKL((2, 3), method='basic') # returns None
125
+ sage: M.slice_obstruction_HKL((2, 3), method='advanced')
126
+ (2, 3)
127
+
128
+ * ``method='direct'`` employs the method of Section 3.20 of [DG] to
129
+ consider not just the F_q homology of the cover, but
130
+ epimorphisms of its group to Z/q^e Z for e > 1. This is the
131
+ most computationally expensive method. Example::
132
+
133
+ sage: M = Manifold('K14n16945')
134
+ sage: M.slice_obstruction_HKL((2, 3), method='advanced') # returns None
135
+ sage: M.slice_obstruction_HKL((2, 3), method='direct')
136
+ (2, 3)
137
+
138
+ For any method, q = 2 is handled using Section 3.11 of [DG].
139
+
140
+ If ``verbose`` is ``1`` or ``True``, it prints each pair (p, q) being considered;
141
+ when ``verbose`` is ``2``, information is printed about each step.
142
+
143
+ Finally, if ``ribbon_mode`` is ``True`` then it searches for
144
+ obstructions to being topologically homotopy ribbon. These differ
145
+ from the slice case only when q = 2; see Theorem 3.12 of [DG]::
146
+
147
+ sage: M = Manifold('DT: qaqcJpEHnoDKBMqIgfal') # The knot 17nh_0630889
148
+ sage: M.slice_obstruction_HKL((3, 2)) # returns None
149
+ sage: M.slice_obstruction_HKL((3, 2), ribbon_mode=True)
150
+ (3, 2)
151
+ """
152
+ if method not in ['basic', 'advanced', 'direct']:
153
+ raise ValueError("Argument method is not 'basic', 'advanced', or 'direct'")
154
+
155
+ M = self
156
+
157
+ if M.cusp_info('is_complete') != [True]:
158
+ raise ValueError('Need exactly one cusp which should be unfilled')
159
+ if M.homology().elementary_divisors() != [0]:
160
+ raise ValueError('Not the exterior of knot in S^3 as H_1 != Z')
161
+ if check_in_S3:
162
+ T = SnapPy.Triangulation(M)
163
+ T.dehn_fill((1, 0))
164
+ if T.fundamental_group().num_generators() != 0:
165
+ raise ValueError('The (1, 0) filling is not obviously S^3')
166
+
167
+ # Special case of only one (p, q) to check
168
+ if len(primes_spec) == 2 and primes_spec[0] in ZZ and primes_spec[1] in ZZ:
169
+ primes_spec = [([primes_spec[0]], [primes_spec[1]])]
170
+ else:
171
+ primes_spec = [(expand_prime_power_spec(a), expand_prime_spec(b))
172
+ for a, b in primes_spec]
173
+
174
+ for ps, qs in primes_spec:
175
+ for p in ps:
176
+ d = basics.nonzero_divisor_product(M, p)
177
+ for q in qs:
178
+ if d % q == 0:
179
+ if verbose:
180
+ print(' Looking at', (p, q), '...')
181
+ if method=='direct':
182
+ success = direct.slicing_obstructed_by_larger_quotient(M, p, q,
183
+ ribbon_mode=ribbon_mode,
184
+ verbose=(verbose > 1))
185
+ else:
186
+ success = rep_theory.slicing_is_obstructed(M, p, q,
187
+ skip_higher_mult=(method=='basic'),
188
+ ribbon_mode=ribbon_mode,
189
+ verbose=(verbose > 1))
190
+ if verbose > 1:
191
+ print()
192
+
193
+ if success:
194
+ return (p, q)