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,687 @@
1
+ """
2
+ The class McomplexWithLink is an Mcomplex containing a PL link that is
3
+ disjoint from the one-skeleton.
4
+ """
5
+
6
+ from ..snap.t3mlite.simplex import *
7
+ from ..snap.t3mlite.edge import Edge
8
+ from ..snap.t3mlite.arrow import Arrow
9
+ from ..snap.t3mlite.tetrahedron import Tetrahedron
10
+ from ..snap.t3mlite.mcomplex import VERBOSE
11
+
12
+ from .exceptions import GeneralPositionError
13
+ from .rational_linear_algebra import Vector3, QQ
14
+ from . import pl_utils
15
+ from . import stored_moves
16
+ from .mcomplex_with_expansion import McomplexWithExpansion
17
+ from .mcomplex_with_memory import McomplexWithMemory
18
+ from .barycentric_geometry import (BarycentricPoint, BarycentricArc,
19
+ InfinitesimalArc, Arc,
20
+ barycentric_edge_embedding,
21
+ barycentric_face_embedding,
22
+ barycentric_quad_embedding0,
23
+ barycentric_quad_embedding1)
24
+
25
+ import random
26
+ import collections
27
+ import time
28
+
29
+
30
+ def arcs_to_add(arcs):
31
+ ans = []
32
+ on_boundary = set()
33
+ for arc in arcs:
34
+ trimmed = arc.trim()
35
+ if trimmed:
36
+ a, b = trimmed.start, trimmed.end
37
+ zeros_a, zeros_b = a.zero_coordinates(), b.zero_coordinates()
38
+ if len(zeros_a) > 1 or len(zeros_b) > 1:
39
+ raise GeneralPositionError('Nongeneric interesection')
40
+ if a != b:
41
+ if len(zeros_a) == 1 and zeros_a == zeros_b:
42
+ raise GeneralPositionError('Lies in face')
43
+
44
+ if len(zeros_a) == 1:
45
+ if a in on_boundary:
46
+ raise GeneralPositionError('Bounce')
47
+ on_boundary.add(a)
48
+
49
+ if len(zeros_b) == 1:
50
+ if b in on_boundary:
51
+ raise GeneralPositionError('Bounce')
52
+ on_boundary.add(b)
53
+
54
+ ans.append(trimmed)
55
+
56
+ return ans
57
+
58
+
59
+ def can_straighten_bend(arc_a, arc_b, arcs, return_obstruction=False):
60
+ x = arc_a.start.to_3d_point()
61
+ y = arc_a.end.to_3d_point()
62
+ z = arc_b.end.to_3d_point()
63
+ if pl_utils.colinear(x, y, z):
64
+ return (True, None) if return_obstruction else True
65
+
66
+ M = pl_utils.standardize_bend_matrix(x, y, z)
67
+ for arc in arcs:
68
+ if arc != arc_a and arc != arc_b:
69
+ u, v = arc.start.to_3d_point(), arc.end.to_3d_point()
70
+ if not pl_utils.can_straighten_bend((u, v), (x, y, z), False, M):
71
+ return (False, arc) if return_obstruction else False
72
+
73
+ return (True, None) if return_obstruction else True
74
+
75
+
76
+ def pushable_tri_in_tet(arcs):
77
+ for arc_a in arcs:
78
+ if arc_a.start.on_boundary() and arc_a.end.is_interior():
79
+ arc_b = arc_a.next
80
+ start_zeros = arc_a.start.zero_coordinates()
81
+ end_zeros = arc_b.end.zero_coordinates()
82
+ if start_zeros == end_zeros:
83
+ if can_straighten_bend(arc_a, arc_b, arcs):
84
+ return arc_a, arc_b
85
+
86
+
87
+ def pair_arcs_across_face(face):
88
+ if face.IntOrBdry == 'bdry':
89
+ return []
90
+ a, b = face.Corners
91
+ a_face = a.Subsimplex
92
+ tet_a = a.Tetrahedron
93
+ tet_b = b.Tetrahedron
94
+ arcs_a = tet_a.arcs
95
+ arcs_b = tet_b.arcs
96
+ perm = tet_a.Gluing[a_face]
97
+ # triple of [arc, zero_index, 0 or 1] where the 0/1 correspond to start/end
98
+ face_arcs_a = []
99
+ face_ind = FaceIndex[a_face]
100
+ for arc in arcs_a:
101
+ zero_start_inds = arc.start.zero_coordinates()
102
+ zero_end_inds = arc.end.zero_coordinates()
103
+ if len(zero_start_inds) == 1:
104
+ face_arcs_a = face_arcs_a + [[arc,zero_start_inds[0], 0]]
105
+ if len(zero_end_inds) == 1:
106
+ face_arcs_a = face_arcs_a + [[arc,zero_end_inds[0], 1]]
107
+ else:
108
+ if len(zero_end_inds) > 1 or len(zero_start_inds) > 1:
109
+ assert False
110
+ pairs = []
111
+ for arc in face_arcs_a:
112
+ arc_a = arc[0]
113
+ i = arc[1]
114
+ j = arc[2]
115
+ x = arc_a.start if j == 0 else arc_a.end
116
+ if i == face_ind:
117
+ x_b = x.permute(perm)
118
+ for arc_b in arcs_b:
119
+ u = arc_b.start
120
+ v = arc_b.end
121
+ if x_b == u:
122
+ pairs = pairs + [[arc_a, arc_b]]
123
+ elif x_b == v:
124
+ pairs = pairs + [[arc_b, arc_a]]
125
+ return pairs
126
+
127
+
128
+ def glue_up_arcs_in_R3(arcs):
129
+ count = 0
130
+ starts = {arc.start:arc for arc in arcs}
131
+ for arc in arcs:
132
+ if arc.end in starts:
133
+ count += 1
134
+ arc.glue_to(starts[arc.end])
135
+ return count
136
+
137
+
138
+ def straightenable_tri(arcs):
139
+ for arc_a in arcs:
140
+ if not arc_a.end.on_boundary():
141
+ arc_b = arc_a.next
142
+ if arc_a.start.on_boundary() and arc_b.end.on_boundary():
143
+ face_a = arc_a.start.boundary_face()
144
+ face_b = arc_b.end.boundary_face()
145
+ if face_a == face_b:
146
+ continue
147
+
148
+ if can_straighten_bend(arc_a, arc_b, arcs):
149
+ return arc_a, arc_b
150
+
151
+
152
+ def straighten_arcs(arcs):
153
+ any_success, success = False, True
154
+ # To reduce the number of times we check the same triangle, we
155
+ # keep track of where we most recently had success.
156
+ offset = 0
157
+ # We also keep track of arcs obstructing a given triangle
158
+ obstructions = {}
159
+ # Every success reduces the number of arcs by one, so
160
+ # terminates.
161
+ while success:
162
+ success = False
163
+ for b in arcs[offset:] + arcs[:offset]:
164
+ if not b.end.on_boundary():
165
+ c = b.next # tri is b -> c
166
+ # Make sure the arcs don't form a triangle with both
167
+ # ends on the same face.
168
+ if (b.start.on_boundary() and c.end.on_boundary() and
169
+ b.start.boundary_face() == c.end.boundary_face()):
170
+ continue
171
+
172
+ if (b, c) in obstructions:
173
+ if obstructions[b, c] in arcs:
174
+ continue
175
+ else:
176
+ obstructions.pop((b, c))
177
+
178
+ poss, obs = can_straighten_bend(b, c, arcs, True)
179
+ if poss:
180
+ a, d = b.past, c.next
181
+ if hasattr(b, 'tet'):
182
+ new_arc = type(b)(b.start, c.end, tet=b.tet)
183
+ else:
184
+ new_arc = type(b)(b.start, c.end)
185
+ if a is not None:
186
+ a.glue_to(new_arc)
187
+ if d is not None:
188
+ new_arc.glue_to(d)
189
+ arcs.remove(c)
190
+ offset = arcs.index(b)
191
+ arcs.remove(b)
192
+ arcs.append(new_arc)
193
+ success, any_success = True, True
194
+ break
195
+ else:
196
+ obstructions[b, c] = obs
197
+
198
+ return any_success
199
+
200
+
201
+ def two_to_three_arc_transfer(old_arrow, new_arrows, north_pole=None):
202
+ arcs_in_R3 = []
203
+ for old_tet, emb in barycentric_face_embedding(old_arrow, north_pole):
204
+ arcs_in_R3.extend(emb.transfer_arcs_to_R3(old_tet.arcs))
205
+ glue_up_arcs_in_R3(arcs_in_R3)
206
+ straighten_arcs(arcs_in_R3)
207
+ for new_tet, emb in barycentric_edge_embedding(new_arrows[2], north_pole):
208
+ new_tet.arcs = arcs_to_add(emb.transfer_arcs_from_R3(arcs_in_R3))
209
+
210
+
211
+ def three_to_two_arc_transfer(old_arrow, new_arrows, north_pole=None):
212
+ a = old_arrow
213
+ b_orig, b, c = new_arrows
214
+ arcs_in_R3 = []
215
+ # We permute the embeddings because this performs better in some
216
+ # examples. The order makes a difference because of which bunch
217
+ # of arcs we try to simplify first in the call to
218
+ # "straighten_arcs", but why this worked better is a complete
219
+ # mystery.
220
+ embeds = barycentric_edge_embedding(a.glued().glued(), north_pole)
221
+ for old_tet, emb in [embeds[1], embeds[2], embeds[0]]:
222
+ arcs_in_R3.extend(emb.transfer_arcs_to_R3(old_tet.arcs))
223
+ glue_up_arcs_in_R3(arcs_in_R3)
224
+ straighten_arcs(arcs_in_R3)
225
+ for new_tet, emb in barycentric_face_embedding(b_orig, north_pole):
226
+ new_tet.arcs = arcs_to_add(emb.transfer_arcs_from_R3(arcs_in_R3))
227
+
228
+
229
+ def four_to_four_arc_transfer(old_arrow, new_arrows, north_pole=None):
230
+ arcs_in_R3 = []
231
+ for old_tet, emb in barycentric_quad_embedding0(old_arrow, north_pole):
232
+ arcs_in_R3.extend(emb.transfer_arcs_to_R3(old_tet.arcs))
233
+ # We do not straighten things inside the octahedron because this
234
+ # increased the number of arcs for unknown reasons.
235
+ b = new_arrows[0]
236
+ for new_tet, emb in barycentric_quad_embedding1(b, north_pole):
237
+ new_tet.arcs = arcs_to_add(emb.transfer_arcs_from_R3(arcs_in_R3))
238
+
239
+
240
+ class McomplexWithLink(McomplexWithExpansion):
241
+ """
242
+ An Mcomplex containing a PL link that is disjoint from the one
243
+ skeleton.
244
+
245
+ >>> KT = McomplexWithLink(stored_moves.move_db['K4a1']['tri_data'])
246
+ >>> KT.name ='K4a1'
247
+ >>> add_arcs_to_standard_solid_tori(KT, 1)
248
+ >>> KT.run_example_moves()
249
+ >>> len(KT), len(KT[0].arcs), len(KT[1].arcs)
250
+ (2, 10, 10)
251
+ >>> LT = link_triangulation(Manifold('L6a4'), simplify=True)
252
+ >>> len(LT.link_components())
253
+ 3
254
+ """
255
+ def __init__(self, tetrahedron_list=None):
256
+ McomplexWithExpansion.__init__(self, tetrahedron_list)
257
+ for tet in self:
258
+ if not hasattr(tet, 'arcs'):
259
+ tet.arcs = []
260
+ self.connect_arcs()
261
+ self.init_sig = self.isosig()
262
+
263
+ def new_tet(self):
264
+ tet = Tetrahedron()
265
+ tet.arcs = []
266
+ self.add_tet(tet)
267
+ return tet
268
+
269
+ def new_arrow(self):
270
+ tet = Tetrahedron()
271
+ tet.arcs = []
272
+ self.add_tet(tet)
273
+ return Arrow(E01,F3,tet)
274
+
275
+ def _four_to_four_move_hook(self, old_arrow, new_arrows):
276
+ self._add_to_move_memory('four_to_four', old_arrow)
277
+ for north in [None,
278
+ Vector3(Vector3([-1, 2, 10])/11),
279
+ Vector3(Vector3([1, -2, 10])/13),
280
+ Vector3(Vector3([2, -1, 13])/9)]:
281
+ try:
282
+ four_to_four_arc_transfer(old_arrow, new_arrows, north)
283
+ return
284
+ except GeneralPositionError:
285
+ continue
286
+
287
+ raise GeneralPositionError('four_to_four could not find good north pole')
288
+
289
+ def _two_to_three_move_hook(self, old_arrow, new_arrows):
290
+ self._add_to_move_memory('two_to_three', old_arrow)
291
+ for north in [None,
292
+ Vector3(Vector3([1, -3, 2])/11),
293
+ Vector3(Vector3([1, 3, -2])/13)]:
294
+ try:
295
+ two_to_three_arc_transfer(old_arrow, new_arrows, north)
296
+ return
297
+ except GeneralPositionError:
298
+ continue
299
+
300
+ raise GeneralPositionError('two_to_three could not find good north pole')
301
+
302
+ def _three_to_two_move_hook(self, old_arrow, new_arrows):
303
+ self._add_to_move_memory('three_to_two', old_arrow)
304
+ for north in [None,
305
+ Vector3(Vector3([1, 3, 2])/11),
306
+ Vector3(Vector3([1, 3, -2])/13)]:
307
+ try:
308
+ three_to_two_arc_transfer(old_arrow, new_arrows, north)
309
+ return
310
+ except GeneralPositionError:
311
+ continue
312
+
313
+ raise GeneralPositionError('three_to_two could not find good north pole')
314
+
315
+ def check_arcs_are_embedded(self):
316
+ for tet in manifold:
317
+ for arc0, arc1 in itertools.combinations(tet.arcs, 2):
318
+ a, b = arc0.to_3d_points()
319
+ c, d = arc1.to_3d_points()
320
+ assert not pl_utils.segments_meet_not_at_endpoint((a, b), (c, d))
321
+
322
+ def _curr_max_denom(self):
323
+ return max([arc.max_denom() for tet in self for arc in tet.arcs], default=1)
324
+
325
+ def safe_perturbation(self):
326
+ """
327
+ Return an integer N so that moving all the vertices in the PL
328
+ link independently by at most 1/N (per coordinate) cannot change
329
+ the topology.
330
+ """
331
+ min_distance_sq = 2**(-12) # kinda arbitrary default
332
+ for tet in self:
333
+ m = len(tet.arcs)
334
+ points_3d = [arc.to_3d_points() for arc in tet.arcs]
335
+ # For each arc, store the min/max for each coordinate.
336
+ coor_min = [[min(x[i], y[i]) for i in range(3)] for x, y in points_3d]
337
+ coor_max = [[max(x[i], y[i]) for i in range(3)] for x, y in points_3d]
338
+
339
+ for a in range(m):
340
+ arc_a = tet.arcs[a]
341
+ min_a, max_a = coor_min[a], coor_max[a]
342
+ for b in range(a + 1, m):
343
+ arc_b = tet.arcs[b]
344
+ if arc_a != arc_b.past and arc_a != arc_b.next: # so distance nonzero
345
+ # now quick check to try and avoid computing distance
346
+ check = True
347
+ min_b, max_b = coor_min[b], coor_max[b]
348
+ for i in range(3):
349
+ if (((min_a[i]-max_b[i])**2 >= min_distance_sq and (min_a[i]-max_b[i]) > 0)
350
+ or ((min_b[i]-max_a[i])**2 >= min_distance_sq and (min_b[i]-max_a[i]) > 0)):
351
+ # arcs lie in different regions which are far apart so dont compare
352
+ check = False
353
+ break
354
+
355
+ if check:
356
+ d2 = pl_utils.arc_distance_sq(points_3d[a], points_3d[b])
357
+ min_distance_sq = min(d2, min_distance_sq)
358
+
359
+ return int(4/pl_utils.rational_sqrt(min_distance_sq)) + 1
360
+
361
+ def round(self, careful=True):
362
+ max_denom = self.safe_perturbation() if careful else 2**32
363
+ for tet in self:
364
+ for arc in tet.arcs:
365
+ arc.start.round(max_denom)
366
+ past_arc = arc.past
367
+ if isinstance(past_arc, InfinitesimalArc):
368
+ past_arc.start.round(max_denom)
369
+
370
+ def connect_arcs(self, tetrahedra=None):
371
+ if tetrahedra is None:
372
+ tetrahedra = self.Tetrahedra
373
+ for tet in tetrahedra:
374
+ on_faces = collections.Counter()
375
+ for arc in tet.arcs:
376
+ arc.tet = tet
377
+ if not isinstance(arc,list):
378
+ if arc.past is None or arc.next is None:
379
+ for other_arc in tet.arcs:
380
+ if arc.end == other_arc.start:
381
+ arc.glue_to(other_arc)
382
+ elif other_arc.end == arc.start:
383
+ other_arc.glue_to(arc)
384
+ elif arc.past is not None and arc.next is not None:
385
+ break
386
+ on_faces.update([pt for pt in [arc.start, arc.end] if pt.on_boundary()])
387
+ if max(on_faces.values(), default=0) > 1:
388
+ raise ValueError('Houston, we have a bounce')
389
+
390
+ if tetrahedra == self.Tetrahedra:
391
+ faces = self.Faces
392
+ else:
393
+ faces = {tet.Class[F] for tet in tetrahedra for F in TwoSubsimplices}
394
+
395
+ for face in faces:
396
+ for x, y in pair_arcs_across_face(face):
397
+ between = InfinitesimalArc(x.end, y.start, x.tet, y.tet,
398
+ past=x, next=y)
399
+ x.next = between
400
+ y.past = between
401
+
402
+ def link_components(self):
403
+ arcs = sum([tet.arcs for tet in self], [])
404
+ num_arcs = len(arcs)
405
+ components = []
406
+ while len(arcs) > 0:
407
+ arc0 = arcs.pop()
408
+ component = [arc0]
409
+ arc = arc0
410
+ while arc.next != arc0:
411
+ arc = arc.next
412
+ if not isinstance(arc, InfinitesimalArc):
413
+ arcs.remove(arc)
414
+ component.append(arc)
415
+ components.append(component)
416
+
417
+ return components
418
+
419
+ def push_through_face(self, tri, tet0):
420
+ def can_straighten(arc, tri):
421
+ arc_pts = arc.to_3d_points()
422
+ tri_pts = [p.to_3d_point() for p in tri]
423
+ return pl_utils.can_straighten_bend(arc_pts, tri_pts)
424
+
425
+ # we start with an arc in a tet (equivalently, a graph vertex)
426
+ # and try and see if we can do a push through the face move
427
+ # write arc in terms of path graph vertices we are only gonna
428
+ # deal with the case the arc ends at a face
429
+ arc0_a, arc0_b = tri
430
+
431
+ # Here are the points in tet0: a --> b --> c
432
+ a, b, c = arc0_a.start, arc0_a.end, arc0_b.end
433
+ assert b == arc0_b.start
434
+
435
+ # Check that tri(a, b, c) does not contain another arc
436
+
437
+ other_arcs = [arc for arc in tet0.arcs if arc != arc0_a and arc != arc0_b]
438
+ assert all(can_straighten(arc, [a, b, c]) for arc in other_arcs)
439
+
440
+ # Now we collect the points in the adjacent tet1, so the full
441
+ # arc is: u --> v --> a --> b --> c --> x --> y
442
+
443
+ back = arc0_a.past.past
444
+ u, v = back.start, back.end
445
+ next = arc0_b.next.next
446
+ x, y = next.start, next.end
447
+ tet1 = back.tet
448
+
449
+ assert back.tet == next.tet
450
+ assert v.on_boundary() and x.on_boundary()
451
+ assert v.zero_coordinates() == x.zero_coordinates()
452
+
453
+ # Determine points w on (u, v) and z on (x, y) so that no arc
454
+ # enters the twisted quad (u, w, z, y).
455
+
456
+ uv = BarycentricArc(u, v, tet=tet1)
457
+ xy = BarycentricArc(x, y, tet=tet1)
458
+
459
+ other_arcs = [arc for arc in tet1.arcs if arc not in [uv, xy]]
460
+
461
+ success = False
462
+ for l in range(1, 12):
463
+ t = QQ(2)**(-l)
464
+ w = v.convex_combination(u, t) # close to v
465
+ z = x.convex_combination(y, t) # close to x
466
+ # Below needs to be checked to confirm it does what's intended.
467
+ if all(can_straighten(arc, [w, v, x]) for arc in other_arcs):
468
+ if all(can_straighten(arc, [w, x, z]) for arc in other_arcs):
469
+ success = True
470
+ break
471
+
472
+ if not success:
473
+ # Must have an arc on the other side very close to the
474
+ # face that's getting in the way. So let's just not do
475
+ # the move.
476
+ return False
477
+
478
+ uw = BarycentricArc(u, w, tet=tet1)
479
+ wz = BarycentricArc(w, z, tet=tet1)
480
+ zy = BarycentricArc(z, y, tet=tet1)
481
+
482
+ back.past.glue_to(uw)
483
+ uw.glue_to(wz)
484
+ wz.glue_to(zy)
485
+ zy.glue_to(next.next)
486
+
487
+ tet0.arcs.remove(arc0_a)
488
+ tet0.arcs.remove(arc0_b)
489
+ tet1.arcs.remove(uv)
490
+ tet1.arcs.remove(xy)
491
+ tet1.arcs += [uw, wz, zy]
492
+ return True
493
+
494
+ def completely_simplify_link(self, straighten=True, push=True, around_edges=True, limit=10):
495
+ any_success, success, l = False, True, 0
496
+ while success and l < limit:
497
+ success = False
498
+ for tet in self:
499
+ if self.simplify_link(tet, straighten, push):
500
+ success, any_success = True, True
501
+ l += 1
502
+ return any_success
503
+
504
+ def simplify_link(self, tet, straighten=True, push=True):
505
+ if straighten:
506
+ any_success = straighten_arcs(tet.arcs)
507
+
508
+ if push:
509
+ success = True
510
+ # Every success reduces the number of arcs by at least
511
+ # one, so terminates.
512
+ while success:
513
+ success = False
514
+ tri = pushable_tri_in_tet(tet.arcs)
515
+ if tri is not None:
516
+ if self.push_through_face(tri, tet):
517
+ success, any_success = True, True
518
+ return any_success
519
+
520
+ def perform_moves(self, moves, straighten=True, push=True,
521
+ round=True, careful=True, tet_stop_num=0):
522
+ """
523
+ Assumes that three_to_two and two_to_three rebuild after each move
524
+ and that they accept arrows as spec for the moves.
525
+ """
526
+ c = len(self.link_components())
527
+ t = 0
528
+ T0 = time.time()
529
+ for move, edge, face, tet_index in moves:
530
+ if len(self) <= tet_stop_num:
531
+ break
532
+ init_num_arcs = sum(len(tet.arcs) for tet in self)
533
+ # init_height = max([arc.height() for tet in self for arc in tet.arcs], default=0)
534
+ start_time = time.time()
535
+ t = t+1
536
+ arrow = Arrow(edge, face, self.Tetrahedra[tet_index])
537
+ move_fn = getattr(self, move)
538
+ move_fn(arrow, must_succeed=True, unsafe_mode=False)
539
+ self.build_face_classes()
540
+ if move == 'three_to_two':
541
+ num_new_tets = 2
542
+ elif move == 'two_to_three':
543
+ num_new_tets = 3
544
+ elif move == 'four_to_four':
545
+ num_new_tets = 4
546
+ new_tets = self.Tetrahedra[-num_new_tets:]
547
+ self.connect_arcs(new_tets)
548
+ move_complete = time.time()
549
+ if straighten or push:
550
+ self.completely_simplify_link(straighten, push)
551
+ if round:
552
+ self.round(careful)
553
+ # assert len(self.link_components()) == c
554
+ simplify_complete = time.time()
555
+ self.rebuild()
556
+ self._build_link()
557
+
558
+ def run_example_moves(self, k=None, straighten=True, push=True,
559
+ round=True, careful=True, start=0):
560
+ """
561
+ Assuming this example appears in stored_moves, perform the
562
+ first k moves.
563
+ """
564
+ db = stored_moves.move_db
565
+ if self.name not in db:
566
+ raise ValueError('Manifold not found in stored_moves')
567
+ moves = stored_moves.move_db[self.name]['moves']
568
+ if k is not None:
569
+ moves = moves[start:k]
570
+ self.perform_moves(moves, straighten , push, round, careful)
571
+
572
+ def _build_link(self):
573
+ self.build_face_classes()
574
+ self.connect_arcs()
575
+
576
+ def how_edgy_in_faces(self):
577
+ return min(arc.start.min_nonzero()
578
+ for tet in self.Tetrahedra
579
+ for arc in tet.arcs)
580
+
581
+
582
+ def no_fixed_point(perm):
583
+ t = perm.tuple()
584
+ return all(t[i] != i for i in range(4))
585
+
586
+
587
+ def add_core_arc_in_one_tet_solid_torus(mcomplex, tet):
588
+ M = mcomplex
589
+ assert tet.Neighbor[F2] == tet.Neighbor[F3] == tet
590
+ assert no_fixed_point(tet.Gluing[F2]) and no_fixed_point(tet.Gluing[F3])
591
+ # c0, c1, c2, c3 = [QQ(x) for x in ['1/5', '1/7', '0', '23/35']] # original
592
+ # c0, c1, c2, c3 = [QQ(x) for x in ['21874/65536', '21841/65536', '0', '21821/65536']]
593
+ c0, c1, c2, c3 = (QQ(x) for x in ['1/3', '1/3', '0', '1/3'])
594
+ p1 = BarycentricPoint(c0, c1, c2, c3)
595
+ p2 = p1.permute(tet.Gluing[F2])
596
+ tet.arcs = [BarycentricArc(p1, p2)]
597
+ M.connect_arcs()
598
+
599
+
600
+ def is_standard_solid_torus(tet):
601
+ if tet.Neighbor[F2] == tet.Neighbor[F3] == tet:
602
+ return no_fixed_point(tet.Gluing[F2]) and no_fixed_point(tet.Gluing[F3])
603
+ return False
604
+
605
+
606
+ def add_arcs_to_standard_solid_tori(mcomplex, num_tori):
607
+ """
608
+ Assumes all the tori are at the end of the list of tets
609
+ """
610
+ M, n = mcomplex, num_tori
611
+ assert all(is_standard_solid_torus(tet) for tet in M.Tetrahedra[-n:])
612
+
613
+ for tet in M.Tetrahedra[-n:]:
614
+ add_core_arc_in_one_tet_solid_torus(M, tet)
615
+
616
+
617
+ def link_triangulation(manifold, add_arcs=True, simplify=True,
618
+ easy_simplify=False, jiggle_limit=100,
619
+ randomize=0):
620
+ """
621
+ Given the SnapPy manifold of a link exterior, return an Mcomplex
622
+ with the barycentric arcs representing the link.
623
+
624
+ >>> KT = link_triangulation(Manifold('K4a1'), simplify=True)
625
+ >>> len(KT)
626
+ 13
627
+ >>> KT = link_triangulation(Manifold('L5a1'), simplify=True)
628
+ >>> len(KT) <= 25
629
+ True
630
+
631
+ """
632
+ if hasattr(manifold, 'without_hyperbolic_structure'):
633
+ M = manifold.without_hyperbolic_structure()
634
+ else:
635
+ M = manifold.copy()
636
+
637
+ n = M.num_cusps()
638
+ if M.cusp_info('is_complete') == n*[True]:
639
+ M.dehn_fill(n*[(1, 0)])
640
+ assert M.cusp_info('is_complete') == n*[False]
641
+
642
+ T = M._unsimplified_filled_triangulation(method='layered_and_marked')
643
+ T.simplify(passes_at_fours=jiggle_limit)
644
+ for i in range(randomize):
645
+ T.randomize(passes_at_fours=jiggle_limit)
646
+ MC = McomplexWithMemory(T)
647
+
648
+ solid_tori_indices = []
649
+ for i, m in enumerate(T._marked_tetrahedra()):
650
+ if m > 0:
651
+ solid_tori_indices.append((m, i))
652
+
653
+ solid_tori_indices.sort()
654
+ solid_tori_tets = [MC[i] for m, i in solid_tori_indices]
655
+ assert len(solid_tori_tets) == n
656
+
657
+ MC.invariant_tetrahedra = solid_tori_tets
658
+ if not MC.smash_all_edges():
659
+ return None
660
+
661
+ if easy_simplify:
662
+ MC.easy_simplify()
663
+ elif simplify:
664
+ # Now we simplify what we can without touching tet.
665
+ MC.easy_simplify()
666
+ MC.simplify(jiggle_limit=jiggle_limit)
667
+
668
+ # move the solid tori to the end for convenience
669
+ for tet in solid_tori_tets:
670
+ MC.Tetrahedra.remove(tet)
671
+ MC.Tetrahedra += solid_tori_tets
672
+
673
+ MA = McomplexWithLink(MC._triangulation_data())
674
+ MA.name = M.name()
675
+
676
+ # Double check have correct number of solid tori
677
+ assert all(is_standard_solid_torus(tet) for tet in MA.Tetrahedra[-n:])
678
+
679
+ if add_arcs:
680
+ add_arcs_to_standard_solid_tori(MA, n)
681
+
682
+ return MA
683
+
684
+
685
+ if __name__ == '__main__':
686
+ import doctest
687
+ print(doctest.testmod())