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,112 @@
1
+ def pos_tets(manifold):
2
+ return manifold.solution_type() == 'all tetrahedra positively oriented'
3
+
4
+
5
+ def basic_improve_tri(manifold, tries=10):
6
+ M = manifold.copy()
7
+ for i in range(tries):
8
+ if pos_tets(M):
9
+ return M
10
+ M.randomize()
11
+ return manifold.copy()
12
+
13
+
14
+ def improved_triangulation(manifold, tries=10):
15
+ M = basic_improve_tri(manifold, tries=tries)
16
+ if pos_tets(M):
17
+ return M
18
+
19
+ curves = M.dual_curves()
20
+ for i, c in zip(range(tries), curves):
21
+ D = M.drill(c)
22
+ D.dehn_fill((1, 0), M.num_cusps())
23
+ F = D.filled_triangulation()
24
+ if pos_tets(F):
25
+ return F
26
+
27
+ return manifold.copy()
28
+
29
+
30
+ def is_isometric_to_with_effort(A, B, return_isometries=False, tries=10):
31
+ A = improved_triangulation(A, tries=tries)
32
+ B = improved_triangulation(B, tries=tries)
33
+ try:
34
+ return A.is_isometric_to(B, return_isometries=return_isometries)
35
+ except RuntimeError: # SnapPea kernel failed
36
+ return []
37
+
38
+
39
+ def orient_pres(isometry):
40
+ """
41
+ >>> M = Manifold('K4a1')
42
+ >>> kinds = {orient_pres(iso) for iso in M.is_isometric_to(M, True)}
43
+ >>> sorted(kinds)
44
+ [False, True]
45
+ """
46
+ return isometry.cusp_maps()[0].det() > 0
47
+
48
+
49
+ def are_orient_pres_isometric_as_ordered_links(A, B):
50
+ """
51
+ All of the following manifolds isometric, but not as ordered links
52
+
53
+ >>> A = Manifold('L10n1')
54
+ >>> B = Manifold('L7a2')
55
+ >>> C = Manifold('L10n1')
56
+ >>> C._reindex_cusps([1, 0])
57
+ >>> are_orient_pres_isometric_as_ordered_links(A, B)
58
+ False
59
+ >>> are_orient_pres_isometric_as_ordered_links(A, C)
60
+ False
61
+ >>> are_orient_pres_isometric_as_ordered_links(C, C)
62
+ True
63
+ """
64
+ isos = is_isometric_to_with_effort(A, B, return_isometries=True)
65
+ isos = [iso for iso in isos if iso.extends_to_link() and orient_pres(iso)]
66
+ ident = list(range(A.num_cusps()))
67
+ return any(iso.cusp_images() == ident for iso in isos)
68
+
69
+
70
+ def orientation_preserving_link_isometries(A, B, tries=100):
71
+ isos = is_isometric_to_with_effort(A, B, return_isometries=True, tries=tries)
72
+ ans = any(iso.extends_to_link() for iso in isos)
73
+ if not ans:
74
+ A, B = A.high_precision(), B.high_precision()
75
+ isos = is_isometric_to_with_effort(A, B, return_isometries=True, tries=tries)
76
+ good_isos = [iso for iso in isos if iso.extends_to_link() and orient_pres(iso)]
77
+ if good_isos:
78
+ return good_isos[0]
79
+
80
+
81
+ def reorder_link_components(link, perm):
82
+ """
83
+ This link has three components, which are in order a trefoil, the
84
+ figure 8, and an unknot.
85
+
86
+ >>> L0 = Manifold('DT[uciicOFRTIQKUDsMpgBelAnjCH.000001011100110110010]').link()
87
+ >>> [len(L0.sublink([i]).crossings) for i in range(3)]
88
+ [3, 4, 0]
89
+
90
+ perm is the permutation of {0, 1, ... , num_comps - 1} where
91
+ perm[old_comp_index] = new_comp_index.
92
+
93
+ >>> L1 = reorder_link_components(L0, [1, 2, 0])
94
+ >>> [len(L1.sublink([i]).crossings) for i in range(3)]
95
+ [0, 3, 4]
96
+ >>> L2 = reorder_link_components(L0, [2, 0, 1])
97
+ >>> [len(L2.sublink([i]).crossings) for i in range(3)]
98
+ [4, 0, 3]
99
+ """
100
+ n = len(link.link_components)
101
+ assert len(perm) == n and link.unlinked_unknot_components == 0
102
+ L = link.copy()
103
+ component_starts = n * [None]
104
+ for a, b in enumerate(perm):
105
+ component_starts[b] = L.link_components[a][0]
106
+ L._build_components(component_starts)
107
+ return L
108
+
109
+
110
+ if __name__ == '__main__':
111
+ import doctest
112
+ doctest.testmod()
@@ -0,0 +1,323 @@
1
+ """
2
+ For a PL link in R^3, produce a link diagram by projecting it onto a
3
+ plane (by default a randomly chosen one). Also includes code for
4
+ simplifying a PL link by basic straightening moves.
5
+ """
6
+
7
+ import spherogram
8
+ import random
9
+ import itertools
10
+ from . import pl_utils
11
+ from .rational_linear_algebra import QQ, Matrix, Vector3
12
+ from .exceptions import GeneralPositionError
13
+
14
+
15
+ def fig8_points():
16
+ # Extracted from put_in_S3.example10, used for testing.
17
+ pts = [(1564, 148, 0, 1117), (765, 1137, 786, 1117), (1117, 1882, 1490, 1117),
18
+ (1469, 1137, 786, 1117), (698, 280, 0, 1117), (1166, 372, -744, 1117),
19
+ (1862, 372, -1440, 1117), (1514, 1068, -744, 1117), (380, 198, 0, 279),
20
+ (564, 604, 604, 559), (701, 219, 438, 1117), (-679, -241, 0, 1117),
21
+ (460, 679, -482, 1117)]
22
+ return [[Vector3([a, b, c])/d for a, b, c, d in pts]]
23
+
24
+
25
+ def twist_knot_points():
26
+ """
27
+ The knot 5_2 = K5a1
28
+ """
29
+ pts = [(25, 36, 5), (14, 36, -3), (14, 14, 0), (47, 14, 0), (47, 25, 0),
30
+ (3, 25, 0), (3, 47, 0), (36, 47, -6), (36, 3, 4), (25, 3, -5)]
31
+ return [[Vector3(pt) for pt in pts]]
32
+
33
+
34
+ def proj(point): # projection onto z = 0
35
+ return Vector3([point[i] for i in [0,1]]+[0])
36
+
37
+
38
+ def random_transform(steps=5):
39
+ """
40
+ Generators of SL(3, Z) from
41
+
42
+ https://doi.org/10.1090/S0002-9939-1992-1079696-5
43
+
44
+ >>> random_transform(5).det()
45
+ 1
46
+ """
47
+ I = Matrix([[1, 0, 0], [0, 1, 0], [ 0, 0, 1]])
48
+ X = Matrix([[0, 1, 0], [0, 0, 1], [ 1, 0, 0]])
49
+ Y = Matrix([[1, 0, 1], [0, -1, -1], [ 0, 1, 0]])
50
+ Z = Matrix([[0, 1, 0], [1, 0, 0], [-1, -1, -1]])
51
+ # X and Y have order two and Z order three, so there are
52
+ # symmetric gens:
53
+ gens = [I, X, X*X, Y, Y*Y, Z, Z]
54
+ ans = I
55
+ for s in range(steps):
56
+ ans = ans * random.choice(gens)
57
+ return ans
58
+
59
+
60
+ def norm_sq(v):
61
+ return sum(x**2 for x in v)
62
+
63
+
64
+ def min_dist_sq(points):
65
+ pairs = itertools.combinations(points, 2)
66
+ return min(norm_sq(p - q) for p, q in pairs)
67
+
68
+
69
+ def straightenable_tri(points, extra_arcs=None):
70
+ if extra_arcs is None:
71
+ extra_arcs = []
72
+ n = len(points)
73
+ for i in range(n):
74
+ indices = i, (i + 1) % n, (i + 2) % n
75
+ tri = [points[k] for k in indices]
76
+ other_arcs = [(points[k], points[(k+1) % n])
77
+ for k in range(n) if k not in indices[:2]]
78
+ if pl_utils.colinear(*tri):
79
+ return indices
80
+ M = pl_utils.standardize_bend_matrix(*tri)
81
+ if all(pl_utils.can_straighten_bend(a, tri, False, M)
82
+ for a in other_arcs + extra_arcs):
83
+ return indices
84
+
85
+
86
+ def arcs_from_points(points_list):
87
+ arcs = []
88
+ for p in points_list:
89
+ n = len(p)
90
+ arcs += [(p[k], p[(k+1) % n]) for k in range(n)]
91
+ return arcs
92
+
93
+
94
+ def straighten_knot(points):
95
+ while True:
96
+ tri = straightenable_tri(points)
97
+ if tri:
98
+ a, b, c = tri
99
+ # We shuffle is so that we look for next triangle in less examined location
100
+ if a < b < c:
101
+ points = points[c:] + points[:b]
102
+ else:
103
+ points = points[:b] + points[b + 1:]
104
+ else:
105
+ break
106
+ return points
107
+
108
+
109
+ def straighten_link(points_list):
110
+ for i in range(len(points_list)):
111
+ other_points = points_list.copy()
112
+ del other_points[i]
113
+ other_arcs = arcs_from_points(other_points)
114
+ while True:
115
+ points = points_list[i]
116
+ tri = straightenable_tri(points, other_arcs)
117
+ if tri:
118
+ a, b, c = tri
119
+ if a < b < c:
120
+ points = points[c:] + points[:b]
121
+ else:
122
+ points = points[:b] + points[b + 1:]
123
+ else:
124
+ break
125
+ points_list[i] = points
126
+ return points_list
127
+
128
+
129
+ class Arc():
130
+ """
131
+ An arc from point a to point b where a and b are labeled by i and j.
132
+ """
133
+ def __init__(self, a, i, b, j, label):
134
+ self.a, self.i, self.b, self.j, self.label = a, i, b, j, label
135
+ self.proj = a[:2], b[:2]
136
+ self.crossings = []
137
+
138
+ def __getitem__(self, index):
139
+ return [self.a, self.b][index]
140
+
141
+ def add_crossing(self, crossing, t):
142
+ self.crossings.append((t, crossing))
143
+ try:
144
+ self.crossings.sort()
145
+ except TypeError:
146
+ raise GeneralPositionError('Two crossings on top of one another')
147
+
148
+
149
+ class Crossing():
150
+ def __init__(self, over_arc, under_arc, s, t, label):
151
+ self.over, self.under, self.label = over_arc, under_arc, label
152
+ self.s, self.t = s, t
153
+ a, b = over_arc.proj
154
+ u, v = under_arc.proj
155
+ M = Matrix([b - a, v - u])
156
+ self.sign = 1 if M.det() > 0 else -1
157
+ e = 1e-12
158
+ assert (1 - s)*a + s*b == (1 - t)*u + t*v
159
+ assert ((e < s < 1 - e) and (e < t < 1 - e))
160
+ over_arc.add_crossing(self, s)
161
+ under_arc.add_crossing(self, t)
162
+
163
+
164
+ class LinkProjection():
165
+ """
166
+ The idea is to apply a unimodular matrix and to project the knot
167
+ onto the z=0 plane. We then recover the crossing data by finding
168
+ points that intersect after projecting then taking the over
169
+ crossing to be the lift with larger z coord.
170
+
171
+ >>> pts = fig8_points()
172
+ >>> kp = LinkProjection(pts)
173
+ >>> K = kp.link()
174
+ >>> K.exterior().identify()
175
+ [m004(0,0), 4_1(0,0), K2_1(0,0), K4a1(0,0), otet02_00001(0,0)]
176
+
177
+ >>> M = Matrix([[0,1,1],[1,1,0],[0,0,2]])
178
+ >>> kp = LinkProjection(pts, M)
179
+ >>> K = kp.link()
180
+ >>> K.exterior().identify()
181
+ [m004(0,0), 4_1(0,0), K2_1(0,0), K4a1(0,0), otet02_00001(0,0)]
182
+
183
+ >>> kp = LinkProjection(twist_knot_points())
184
+ >>> K = kp.link()
185
+ >>> M = Manifold('K5a1')
186
+ >>> isos = M.is_isometric_to(K.exterior(), True)
187
+ >>> {iso.cusp_maps()[0].det() for iso in isos}
188
+ {1}
189
+ """
190
+
191
+ def __init__(self, points_by_component, mat=None):
192
+ # mat is a matrix, we transform the points by mat then project
193
+ # onto z = 0 plane, plane is point and vector
194
+ if mat is None:
195
+ mat = Matrix([[0, -2, -1], [1, 2, 2], [-1, 1, 0]])
196
+ self.mat = mat
197
+
198
+ components = []
199
+ for component_points in points_by_component:
200
+ start = sum(len(C) for C in components)
201
+ comp_len = len(component_points)
202
+ components.append(list(range(start, start + comp_len)))
203
+
204
+ self.components = components
205
+ all_points = sum(points_by_component, [])
206
+ self.points = [mat*p for p in all_points]
207
+ self.projected_points = [proj(p) for p in self.points]
208
+
209
+ # Check that nothing is too degenerate:
210
+ assert min_dist_sq(self.points) > 1e-15
211
+ if min_dist_sq(self.projected_points) < 1e-16:
212
+ raise GeneralPositionError('Projection is nearly degenerate')
213
+
214
+ self._setup_crossings()
215
+
216
+ def _setup_crossings(self):
217
+ # compute the over and under crossings of the link projection
218
+
219
+ pts = self.points
220
+ crossings, arcs = [], []
221
+ for component in self.components:
222
+ successive_pairs = [(c, component[(i + 1) % len(component)]) for
223
+ i, c in enumerate(component)]
224
+ arcs += [Arc(pts[i], i, pts[j], j, i) for i, j in successive_pairs]
225
+
226
+ for A, B in itertools.combinations(arcs, 2):
227
+ a = proj(A[0]), proj(A[1])
228
+ b = proj(B[0]), proj(B[1])
229
+
230
+ # When A and B are successive arcs, we just need to test
231
+ # things are sufficiently generic.
232
+
233
+ if A.j == B.i:
234
+ # assert not near_reverse(a[0], a[1], b[1])
235
+ continue
236
+ elif B.j == A.i:
237
+ # assert not near_reverse(b[0], b[1], a[1])
238
+ continue
239
+ elif pl_utils.segments_meet_not_at_endpoint(a, b):
240
+ # There is a crossing and now we figure out which arc
241
+ # crosses over the other.
242
+
243
+ # find the intersection point
244
+ M = Matrix([a[1]-a[0], b[0]-b[1]]).transpose()
245
+ if M.rank() != 2:
246
+ raise GeneralPositionError('Segments overlap on their interiors')
247
+ s, t = M.solve_right(b[0]-a[0])
248
+ e = 1e-12
249
+ if not ((e < s < 1 - e) and (e < t < 1 - e)):
250
+ raise GeneralPositionError('Intersection too near the end of one segment')
251
+
252
+ x_a = (1-s)*A[0] + s*A[1] # lift of intersection to A
253
+ x_b = (1-t)*B[0] + t*B[1] # lift of intersection to B
254
+
255
+ # make sure our lifts project to same point in plane
256
+ assert norm_sq(proj(x_a - x_b)) < 1e-5
257
+
258
+ # whichever arc contains the higher intersection
259
+ # lifted point is the over crossing arc
260
+ height_a = x_a[2]
261
+ height_b = x_b[2]
262
+
263
+ assert abs(height_a - height_b) > 1e-14
264
+ if height_a > height_b:
265
+ crossings.append(Crossing(A, B, s, t, len(crossings)))
266
+ else:
267
+ crossings.append(Crossing(B, A, t, s, len(crossings)))
268
+
269
+ self.crossings, self.arcs = crossings, arcs
270
+
271
+ def link(self):
272
+ # For bookkeeping, we use a Strand for each point the
273
+ # projection, together with the obviously needed crossings.
274
+
275
+ strands = [spherogram.Strand(label='S%d' % i)
276
+ for i, p in enumerate(self.points)]
277
+ crossings = [spherogram.Crossing(label='C%d' % i)
278
+ for i, c in enumerate(self.crossings)]
279
+
280
+ for arc in self.arcs:
281
+ A, a = strands[arc.i], 1
282
+ for t, C in arc.crossings:
283
+ B = crossings[C.label]
284
+ if arc == C.over:
285
+ b = 3 if C.sign == 1 else 1
286
+ else:
287
+ b = 0
288
+ # glue up
289
+ A[a] = B[b]
290
+ A, a = B, (b + 2) % 4
291
+
292
+ # glue to Strand corresponding to the endpoint of the arc.
293
+ B, b = strands[arc.j], 0
294
+ A[a] = B[b]
295
+
296
+ L = spherogram.Link(strands + crossings)
297
+ return L
298
+
299
+
300
+ def project_to_diagram(link_in_R3):
301
+ """
302
+ >>> project_to_diagram(fig8_points())
303
+ <Link: 1 comp; 4 cross>
304
+ """
305
+ diagram = None
306
+ for mat_size in [None, 15, 25, 15, 25, 15, 25, 100, 250, 100, 250, 500, 500]:
307
+ if mat_size is None:
308
+ proj_mat = Matrix([[3, 1, 0], [1, -1, 5], [0, 0, -1]])
309
+ else:
310
+ proj_mat = random_transform(mat_size)
311
+ try:
312
+ projection = LinkProjection(link_in_R3, proj_mat)
313
+ diagram = projection.link()
314
+ break
315
+ except GeneralPositionError as e:
316
+ pass
317
+
318
+ return diagram
319
+
320
+
321
+ if __name__ == '__main__':
322
+ import doctest
323
+ print(doctest.testmod())
@@ -0,0 +1,198 @@
1
+ """
2
+ Defines the main function `exterior_to_link`.
3
+ """
4
+
5
+ import random
6
+ import typing
7
+ from .exceptions import ExteriorToLinkError
8
+ from .simplify_to_base_tri import good_simplification
9
+ from . import put_in_S3
10
+ from . import link_projection
11
+ from .rational_linear_algebra import Matrix
12
+ from . import hyp_utils
13
+ from ..SnapPy import set_rand_seed
14
+
15
+
16
+ def filled_is_3sphere(manifold):
17
+ """
18
+ >>> isosig = 'nLvLLLPQQkcfejimhklkmlkmuphkvuoupilhhv_Bbba(1, 0)'
19
+ >>> filled_is_3sphere(Manifold(isosig))
20
+ True
21
+ >>> filled_is_3sphere(Triangulation('m004(1, 2)'))
22
+ False
23
+ """
24
+ if hasattr(manifold, 'without_hyperbolic_structure'):
25
+ T = manifold.without_hyperbolic_structure()
26
+ else:
27
+ T = manifold.copy()
28
+ for i in range(T.num_cusps()):
29
+ if T.cusp_info(i).is_complete:
30
+ T.dehn_fill((1, 0), i)
31
+
32
+ for i in range(10):
33
+ if T.fundamental_group().num_generators() == 0:
34
+ return True
35
+ F = T.filled_triangulation()
36
+ if F.fundamental_group().num_generators() == 0:
37
+ return True
38
+ T.randomize()
39
+
40
+ return False
41
+
42
+
43
+ def exterior_to_link(manifold,
44
+ verbose : bool = False,
45
+ check_input : bool = True,
46
+ check_answer : bool = True,
47
+ careful_perturbation : bool = True,
48
+ simplify_link : bool = True,
49
+ pachner_search_tries :int = 10,
50
+ seed : typing.Optional[int] = None) -> 'Link':
51
+ """
52
+ For a triangulation of the exterior of a link in the 3-sphere,
53
+ return a planar diagram for the link. The peripheral curves whose
54
+ Dehn filling is the 3-sphere are **part of the input**, specified
55
+ by either:
56
+
57
+ a. If no cusp is filled, then they are the meridians of the
58
+ current peripheral curves.
59
+
60
+ b. If every cusp is filled, then they are the current Dehn filling
61
+ curves.
62
+
63
+ In particular, it does **not** try to determine whether there exist
64
+ fillings on the input which give the 3-sphere. Example usage:
65
+
66
+ >>> M = Manifold('m016')
67
+ >>> L = exterior_to_link(M)
68
+ >>> L.exterior().is_isometric_to(M)
69
+ True
70
+
71
+ The algorithm used is that of `Dunfield, Obeidin, and Rudd
72
+ <https://arxiv.org/abs/2112.03251>`_. The optional arguments are
73
+ as follows.
74
+
75
+ * ``verbose``: When ``True``, prints progress updates as the algorithm
76
+ goes along.
77
+
78
+ * ``check_input``: When ``True`` (the default), first checks that the
79
+ fundamental group of the specified Dehn filling is trivial. As
80
+ it doesn't try too hard to simplify the group presentation, it
81
+ can happen that this check fails but the algorithm still finds a
82
+ diagram if you pass ``check_input=False``.
83
+
84
+ * ``check_answer``: When ``True`` (the default), take the exterior of
85
+ the final link diagram and use ``Manifold.is_isometric_to`` to
86
+ confirm that it is homeomorphic to the input. If the input is
87
+ not hyperbolic or is very large, this check may fail even though
88
+ the diagram is correct.
89
+
90
+ * ``careful_perturbation``: The rational coordinates of the
91
+ intermediate PL links are periodically rounded to control the
92
+ size of their denominators. When ``careful_perturbation=True``
93
+ (the default), computations are performed to ensure this
94
+ rounding does not change the isotopy class of the link.
95
+
96
+ * ``simplify_link``: When ``True`` (the default), uses
97
+ ``Link.simplify('global')`` to minimize the size of the final
98
+ diagram; otherwise, it just does ``basic`` simplifications, which
99
+ can be much faster if the initial link is complicated.
100
+
101
+ * ``pachner_search_tries``: Controls how hard to search for a
102
+ suitable sequence of Pachner moves from the filled input
103
+ triangulation to a standard triangulation of the 3-sphere.
104
+
105
+ * ``seed``: The algorithm involves many random choices, and hence
106
+ each run typically produces a different diagram of the
107
+ underlying link. If you need the same output each time, you can
108
+ specify a fixed seed for the various pseudo-random number
109
+ generators.
110
+
111
+ Note on rigor: Provided at least one of ``check_answer`` and
112
+ ``careful_perturbation`` is ``True``, the exterior of the output
113
+ link is guaranteed to match the input (including the choice of
114
+ meridians).
115
+
116
+ **Warning:** The order of the link components and the cusps of the
117
+ input manifold is only guaranteed to match when
118
+ ``check_answer=True``. Even then, the implicit orientation along
119
+ each component of the link may not be preserved.
120
+ """
121
+
122
+ unfilled = set(manifold.cusp_info('is_complete'))
123
+ if unfilled == {True, False}:
124
+ raise ValueError('Cusps should either be all filled or all unfilled')
125
+
126
+ if check_input and not filled_is_3sphere(manifold):
127
+ raise ValueError('Filling in the meridians does not obviously give S^3')
128
+
129
+ def print_status(*args, **kwargs):
130
+ if verbose:
131
+ print(*args, **kwargs, flush=True)
132
+
133
+ print_status(f'Finding link for {manifold.name()}')
134
+ if seed is not None:
135
+ seed = int(seed)
136
+ random.seed(seed)
137
+ set_rand_seed(seed)
138
+ print_status(' Seed:', seed)
139
+
140
+ print_status(' Finding moves to base triangulation of S^3...')
141
+ tris_with_moves = good_simplification(manifold,
142
+ max_tries=pachner_search_tries)
143
+ if tris_with_moves:
144
+ M, moves, expanded_moves = tris_with_moves
145
+ else:
146
+ raise ExteriorToLinkError('Could not simplify to standard triangulation of S^3')
147
+
148
+ print_status(f' Starting with {len(M)} tets, to do {len(moves)} simple Pachner moves.')
149
+ M.perform_moves(moves, push=True, straighten=True, round=True, careful=careful_perturbation)
150
+ M.rebuild()
151
+ M.connect_arcs()
152
+ print_status(' Moves resulted in', sum(len(tet.arcs) for tet in M),
153
+ f'PL segments; max denom of coor is {M._curr_max_denom()}.')
154
+ print_status(' Embedding in S3...', end='')
155
+ link_in_R3 = put_in_S3.embed_link_in_S3(M)
156
+ link_in_R3 = link_projection.straighten_link(link_in_R3)
157
+ num_seg = sum(len(component) + 1 for component in link_in_R3)
158
+ print_status('got PL link of', num_seg ,'segments.')
159
+ print_status(' Projecting...', end='')
160
+
161
+ L = link_projection.project_to_diagram(link_in_R3)
162
+ if L is None:
163
+ raise ExteriorToLinkError('Was unable to project link')
164
+
165
+ L.simplify('basic')
166
+ print_status(f'got diagram with {len(L.crossings)} crossings.')
167
+
168
+ if simplify_link:
169
+ print_status(' Simplifying diagram...', end='')
170
+ L.simplify('pickup')
171
+ print_status(f'{len(L.crossings)} crossings...', end='')
172
+ L.simplify('global')
173
+ print_status(f'{len(L.crossings)} crossings.')
174
+
175
+ if check_answer:
176
+ E = L.exterior()
177
+ if unfilled == {True}:
178
+ F = manifold
179
+ else:
180
+ F = manifold.copy()
181
+ F.set_peripheral_curves('fillings')
182
+ F.dehn_fill(F.num_cusps()*[(0, 0)])
183
+ F.randomize()
184
+ if hasattr(F, 'with_hyperbolic_structure'):
185
+ F = F.with_hyperbolic_structure()
186
+
187
+ iso = hyp_utils.orientation_preserving_link_isometries(E, F, tries=1000)
188
+ if iso is not None:
189
+ L = hyp_utils.reorder_link_components(L, iso.cusp_images())
190
+ E = L.exterior()
191
+ if hyp_utils.are_orient_pres_isometric_as_ordered_links(E, F):
192
+ print_status(' Exterior of final link checks!\n')
193
+ else:
194
+ ExteriorToLinkError('Could not correctly order link components')
195
+ else:
196
+ raise ExteriorToLinkError('Could not confirm topology of link exterior')
197
+
198
+ return L