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,620 @@
1
+ from .cusps import CuspPostDrillInfo
2
+ from .tracing import compute_plane_intersection_param, Endpoint, GeodesicPiece
3
+ from .epsilons import compute_epsilon
4
+ from . import constants
5
+ from . import exceptions
6
+
7
+ from ..geometric_structure import add_r13_planes_to_tetrahedron
8
+ from ..snap.t3mlite import simplex, Perm4, Tetrahedron, Corner # type: ignore
9
+ from ..matrix import make_identity_matrix # type: ignore
10
+ from ..exceptions import InsufficientPrecisionError # type: ignore
11
+
12
+ from typing import Sequence, Optional, List
13
+
14
+ __all__ = ['one_four_move', 'two_three_move']
15
+
16
+ def one_four_move(given_pieces : Sequence[GeodesicPiece],
17
+ verified : bool) -> Sequence[GeodesicPiece]:
18
+ """
19
+ Performs a 1-4 move.
20
+
21
+ Given pieces are supposed to be either two pieces
22
+ F-T-F (see subdivide.py for notation) or just one piece F-F.
23
+
24
+ For F-T-F, the new point for the 1-4 move will be the one given
25
+ for T. For F-F, the 1-4 move will pick a point on the line segment
26
+ (not picking exactly the middle to avoid coincidences).
27
+ """
28
+
29
+ tet : Tetrahedron = given_pieces[0].tet
30
+ RF = tet.O13_matrices[simplex.F0].base_ring()
31
+
32
+ if not given_pieces[0].endpoints[0].subsimplex in simplex.TwoSubsimplices:
33
+ raise Exception("Expected given geodesic piece to start "
34
+ "on a face for one-four move.")
35
+ if not given_pieces[-1].endpoints[1].subsimplex in simplex.TwoSubsimplices:
36
+ raise Exception("Expected given geodesic piece to end "
37
+ "on a face for one-four move.")
38
+
39
+ n = len(given_pieces)
40
+
41
+ if n == 1:
42
+ bias = RF(constants.piece_midpoint_bias)
43
+ new_point = (
44
+ given_pieces[0].endpoints[0].r13_point +
45
+ bias * given_pieces[0].endpoints[1].r13_point)
46
+ elif n == 2:
47
+ if not given_pieces[0].endpoints[1].subsimplex == simplex.T:
48
+ raise Exception("Expected middle point to be in the tetrahedron "
49
+ "when given two pieces to one-four move.")
50
+ if not given_pieces[1].endpoints[0].subsimplex == simplex.T:
51
+ raise Exception("Expected middle point to be in the tetrahedron "
52
+ "when given two pieces to one-four move.")
53
+
54
+ if not given_pieces[0].tet is given_pieces[1].tet:
55
+ raise Exception("Expected pieces to be in the same tetrahedron "
56
+ "when given two pieces to one-four move.")
57
+
58
+ new_point = given_pieces[0].endpoints[1].r13_point
59
+ else:
60
+ raise Exception("Bad 1-4 move")
61
+
62
+ # The new tetrahedra.
63
+ # new_tets[f] shares face f with the old tetrahedron.
64
+ # That is vertex v of the new tetrahedron corresponds to
65
+ # vertex v of the old tetrahedron if v is on the face f.
66
+ # Otherwise, the vertex v of the new tetrahedron corresponds
67
+ # to the new vertex in the center.
68
+
69
+ new_tets : dict[int, Tetrahedron] = {
70
+ f : Tetrahedron() for f in simplex.TwoSubsimplices }
71
+
72
+ neighbors : dict[int, Tetrahedron] = dict(tet.Neighbor.items())
73
+ gluings : dict[int, Perm4] = dict(tet.Gluing.items())
74
+
75
+ id_matrix = make_identity_matrix(ring=RF, n=4)
76
+
77
+ for f0, new_tet0 in new_tets.items():
78
+ new_tet0.geodesic_pieces = []
79
+ v0 = simplex.comp(f0)
80
+ new_tet0.R13_vertices = { v0 : new_point }
81
+ new_tet0.post_drill_infos = {
82
+ v0 : CuspPostDrillInfo(index=given_pieces[0].index) }
83
+ new_tet0.O13_matrices = {}
84
+ new_tet0.PeripheralCurves = [
85
+ [ { v : { face : 0 for face in simplex.TwoSubsimplices }
86
+ for v in simplex.ZeroSubsimplices }
87
+ for sheet in range(2) ]
88
+ for ml in range(2) ]
89
+
90
+ for f1, new_tet1 in new_tets.items():
91
+ if f0 != f1:
92
+ new_tet0.attach(f1, new_tet1, _swap_perms[f0, f1])
93
+ v1 = simplex.comp(f1)
94
+ new_tet0.R13_vertices[v1] = tet.R13_vertices[v1]
95
+ new_tet0.post_drill_infos[v1] = tet.post_drill_infos[v1]
96
+ new_tet0.O13_matrices[f1] = id_matrix
97
+
98
+ neighbor : Tetrahedron = neighbors[f0]
99
+ gluing : Perm4 = gluings[f0]
100
+ if neighbor is tet:
101
+ other_tet = new_tets[gluing.image(f0)]
102
+ else:
103
+ other_tet = neighbor
104
+ new_tet0.attach(f0, other_tet, gluing.tuple())
105
+
106
+ new_tet0.O13_matrices[f0] = tet.O13_matrices[f0]
107
+
108
+ add_r13_planes_to_tetrahedron(new_tet0)
109
+
110
+ for ml in range(2):
111
+ for sheet in range(2):
112
+ for v, faces in simplex.FacesAroundVertexCounterclockwise.items():
113
+ for face in faces:
114
+ new_tets[face].PeripheralCurves[ml][sheet][v][face] = (
115
+ tet.PeripheralCurves[ml][sheet][v][face])
116
+ f0, f1, f2 = faces
117
+ new_tets[f0].PeripheralCurves[ml][sheet][v][f1] = (
118
+ -tet.PeripheralCurves[ml][sheet][v][f0])
119
+ new_tets[f1].PeripheralCurves[ml][sheet][v][f0] = (
120
+ tet.PeripheralCurves[ml][sheet][v][f0])
121
+ new_tets[f1].PeripheralCurves[ml][sheet][v][f2] = (
122
+ tet.PeripheralCurves[ml][sheet][v][f2])
123
+ new_tets[f2].PeripheralCurves[ml][sheet][v][f1] = (
124
+ -tet.PeripheralCurves[ml][sheet][v][f2])
125
+
126
+ # Transfer or re-trace the other pieces of the geodesic going through
127
+ # the old tetrahedron in the new tetrahedra.
128
+ for old_piece in tet.geodesic_pieces:
129
+ if old_piece in given_pieces:
130
+ continue
131
+
132
+ start_subsimplex : int = old_piece.endpoints[0].subsimplex
133
+ end_subsimplex : int = old_piece.endpoints[1].subsimplex
134
+
135
+ dimension_start_subsimplex = simplex.dimension(start_subsimplex)
136
+ dimension_end_subsimplex = simplex.dimension(end_subsimplex)
137
+
138
+ if dimension_start_subsimplex == 0 and dimension_end_subsimplex == 0:
139
+ # Both endpoints are vertices, no re-tracing necessary.
140
+ total_subsimplex = start_subsimplex | end_subsimplex
141
+ for new_face, new_tet in new_tets.items():
142
+ if simplex.is_subset(total_subsimplex, new_face):
143
+ GeodesicPiece.replace_by(
144
+ old_piece, old_piece,
145
+ [ GeodesicPiece.create_and_attach(
146
+ old_piece.index,
147
+ new_tet,
148
+ old_piece.endpoints) ])
149
+ break
150
+ else:
151
+ raise Exception("Unhandled edge case")
152
+ else:
153
+ # Re-trace.
154
+ r13_endpoints = [ e.r13_point for e in old_piece.endpoints ]
155
+
156
+ GeodesicPiece.replace_by(
157
+ old_piece, old_piece,
158
+ _retrace_geodesic_piece(
159
+ index=old_piece.index,
160
+ r13_points=r13_endpoints,
161
+ start_corners=[ Corner(new_tets[f], start_subsimplex)
162
+ for f in simplex.TwoSubsimplices
163
+ if simplex.is_subset(start_subsimplex, f) ],
164
+ end_corners=[ Corner(new_tets[f], end_subsimplex)
165
+ for f in simplex.TwoSubsimplices
166
+ if simplex.is_subset(end_subsimplex, f) ],
167
+ verified=verified))
168
+
169
+ # Turn given pieces into F-V-F
170
+ start_point : Endpoint = given_pieces[0].endpoints[0]
171
+ end_point : Endpoint = given_pieces[-1].endpoints[1]
172
+ new_pieces : Sequence[GeodesicPiece] = [
173
+ GeodesicPiece.create_face_to_vertex_and_attach(
174
+ given_pieces[0].index,
175
+ new_tets[start_point.subsimplex],
176
+ start_point,
177
+ direction=+1),
178
+ GeodesicPiece.create_face_to_vertex_and_attach(
179
+ given_pieces[0].index,
180
+ new_tets[end_point.subsimplex],
181
+ end_point,
182
+ direction=-1) ]
183
+
184
+ GeodesicPiece.replace_by(
185
+ given_pieces[0], given_pieces[-1], new_pieces)
186
+
187
+ return new_pieces
188
+
189
+ def two_three_move(given_pieces : Sequence[GeodesicPiece],
190
+ verified : bool) -> Sequence[GeodesicPiece]:
191
+ """
192
+ Expects two given pieces V-F-V which form one straight line
193
+ segment from V to V.
194
+
195
+ The 2-3 move is performed on the two tetrahedra adjacent to
196
+ that face.
197
+ """
198
+
199
+ # We imagine the two old tetrahedra such that the shared face
200
+ # is horizontal. We list them in the order where the top one
201
+ # is first and has index 0.
202
+
203
+ old_tets = [ old_piece.tet for old_piece in given_pieces ]
204
+ old_tips = [ given_pieces[i].endpoints[i].subsimplex
205
+ for i in range(2) ]
206
+ # For each old tetrahedron, its face that it shared with the other
207
+ # tetrahedron.
208
+ old_shared_faces = [ simplex.comp(old_tip)
209
+ for old_tip in old_tips ]
210
+
211
+ RF = old_tets[0].O13_matrices[simplex.F0].base_ring()
212
+ id_matrix = make_identity_matrix(ring=RF, n=4)
213
+
214
+ # Embeddings to map both tetrahedra into the same coordinate
215
+ # system
216
+ O13_embeddings = [ old_tets[0].O13_matrices[old_shared_faces[0]],
217
+ id_matrix ]
218
+ O13_inverse_embeddings = [ old_tets[1].O13_matrices[old_shared_faces[1]],
219
+ id_matrix ]
220
+
221
+ tip_points = [
222
+ O13_embeddings[i] * old_tets[i].R13_vertices[old_tips[i]]
223
+ for i in range(2) ]
224
+
225
+ # Find permutation such that we can label the top vertex of
226
+ # the top tetrahedron by 0.
227
+ for perm in Perm4.A4():
228
+ if perm.image(simplex.V0) == old_tips[0]:
229
+ break
230
+ gluing = old_tets[0].Gluing[old_shared_faces[0]]
231
+
232
+ new_to_old_tets = [ [ p, gluing * p * Perm4((1,0,2,3)) ]
233
+ for p in [ perm,
234
+ perm * Perm4((0,2,3,1)),
235
+ perm * Perm4((0,3,1,2)) ] ]
236
+
237
+ # The new tetrahedra have vertices as follows:
238
+ # Vertex 0 always corresponds to the top vertex of the
239
+ # top tetrahedron.
240
+ # Vertex 1 always corresponds to the top vertex of the
241
+ # bottom tetrahedron
242
+ # Vertex 3 is glued to vertex 2 of the next tetrahedron.
243
+ #
244
+ # Note that face 0 of a new tetrahedron is shared with
245
+ # some face of the old top tetrahedron (index=1).
246
+ # Similarly for face 1 and the bottom tetrahedron (index=0).
247
+ #
248
+ new_tets = [ Tetrahedron() for i in range(3) ]
249
+
250
+ for i, new_tet in enumerate(new_tets):
251
+ new_tet.geodesic_pieces = []
252
+ new_tet.O13_matrices = {
253
+ simplex.F2 : id_matrix,
254
+ simplex.F3 : id_matrix
255
+ }
256
+ new_tet.PeripheralCurves = [
257
+ [ { v : { face : 0 for face in simplex.TwoSubsimplices }
258
+ for v in simplex.ZeroSubsimplices }
259
+ for sheet in range(2) ]
260
+ for ml in range(2) ]
261
+
262
+ for j, old_tet in enumerate(old_tets):
263
+ new_face = simplex.TwoSubsimplices[1-j]
264
+ old_face = new_to_old_tets[i][j].image(new_face)
265
+ neighbor = old_tet.Neighbor[old_face]
266
+ new_tet.attach(
267
+ new_face,
268
+ neighbor,
269
+ old_tet.Gluing[old_face] * new_to_old_tets[i][j])
270
+ new_tet.O13_matrices[new_face] = (
271
+ old_tet.O13_matrices[old_face] * O13_inverse_embeddings[j])
272
+
273
+ neighbor_face = new_tet.Gluing[new_face].image(new_face)
274
+ neighbor.O13_matrices[neighbor_face] = (
275
+ O13_embeddings[j] * neighbor.O13_matrices[neighbor_face])
276
+
277
+ for ml in range(2):
278
+ for sheet in range(2):
279
+ for v in [ simplex.V2, simplex.V3 ]:
280
+ old_v = new_to_old_tets[i][j].image(v)
281
+ new_tet.PeripheralCurves[ml][sheet][v][new_face] = (
282
+ old_tet.PeripheralCurves[ml][sheet][old_v][old_face])
283
+
284
+ for ml in range(2):
285
+ for sheet in range(2):
286
+ for v, f in [ (simplex.V2, simplex.F3), (simplex.V3, simplex.F2) ]:
287
+ p = new_tet.PeripheralCurves[ml][sheet][v]
288
+ p[f] = - (p[simplex.F0] + p[simplex.F1])
289
+
290
+ new_tet.attach(
291
+ simplex.F2,
292
+ new_tets[(i+1) % 3],
293
+ (0,1,3,2))
294
+
295
+ new_tet.R13_vertices = {
296
+ simplex.V0 : tip_points[0],
297
+ simplex.V1 : tip_points[1],
298
+ simplex.V2 : old_tets[1].R13_vertices[new_to_old_tets[i][1].image(simplex.V2)],
299
+ simplex.V3 : old_tets[1].R13_vertices[new_to_old_tets[i][1].image(simplex.V3)],
300
+ }
301
+
302
+ new_tet.post_drill_infos = {
303
+ simplex.V0 : old_tets[0].post_drill_infos[old_tips[0]],
304
+ simplex.V1 : old_tets[1].post_drill_infos[old_tips[1]],
305
+ simplex.V2 : old_tets[1].post_drill_infos[new_to_old_tets[i][1].image(simplex.V2)],
306
+ simplex.V3 : old_tets[1].post_drill_infos[new_to_old_tets[i][1].image(simplex.V3)],
307
+ }
308
+
309
+ add_r13_planes_to_tetrahedron(new_tet)
310
+
311
+ old_to_new_tets = [ [ ~new_to_old_tets[j][i] for j in range(3) ]
312
+ for i in range(2) ]
313
+
314
+ # Transfer or re-trace the other pieces of the geodesic going through
315
+ # the old tetrahedron in the new tetrahedra.
316
+ # Consider one old tetrahedron at a time.
317
+ for j, old_tet in enumerate(old_tets):
318
+ for old_piece in old_tet.geodesic_pieces:
319
+
320
+ if old_piece in given_pieces:
321
+ continue
322
+
323
+ start_point = old_piece.endpoints[0]
324
+ start_subsimplex = start_point.subsimplex
325
+ # Index of old tet where piece is starting
326
+ start_j = j
327
+
328
+ # A geodesic piece crossing the face shared between the bottom and
329
+ # top tetrahedron was originally two pieces. Of these two pieces,
330
+ # discard the one after crossing the shared face.
331
+ if start_subsimplex == old_shared_faces[j]:
332
+ continue
333
+
334
+ end_point = old_piece.endpoints[1]
335
+ end_subsimplex = end_point.subsimplex
336
+ # Index of old tet where piece is ending
337
+ end_j = j
338
+
339
+ old_pieces = [ old_piece ]
340
+ # If a geodesic piece ends at the shared face, merge it
341
+ # with the next piece.
342
+ if end_subsimplex == old_shared_faces[j]:
343
+ old_pieces.append(old_piece.next_)
344
+ end_point = old_piece.next_.endpoints[1]
345
+ end_subsimplex = end_point.subsimplex
346
+ end_j = 1 - j
347
+
348
+ dimension_start_subsimplex = simplex.dimension(start_subsimplex)
349
+ dimension_end_subsimplex = simplex.dimension(end_subsimplex)
350
+
351
+ # Face of new tetrahedron that is shared with old tetrahedron.
352
+ new_start_face = simplex.TwoSubsimplices[1 - start_j]
353
+ new_end_face = simplex.TwoSubsimplices[1 - end_j]
354
+
355
+ if dimension_start_subsimplex == 0 and dimension_end_subsimplex == 0:
356
+ # Vertex to vertex piece. We can just transfer.
357
+ for i, new_tet in enumerate(new_tets):
358
+ # We need to find the right new tetrahedron such that the
359
+ # geodesic piece is an edge of the face shared with the old
360
+ # tetrahedron.
361
+ new_start_subsimplex = old_to_new_tets[j][i].image(start_subsimplex)
362
+ new_end_subsimplex = old_to_new_tets[j][i].image(end_subsimplex)
363
+ new_subsimplex = new_start_subsimplex | new_end_subsimplex
364
+
365
+ if simplex.is_subset(new_subsimplex, new_start_face):
366
+ GeodesicPiece.replace_by(
367
+ old_pieces[0], old_pieces[-1],
368
+ [
369
+ GeodesicPiece.create_and_attach(
370
+ old_piece.index,
371
+ new_tet,
372
+ [ Endpoint(new_tet.R13_vertices[v], v)
373
+ for v in [ new_start_subsimplex, new_end_subsimplex ] ])])
374
+ break
375
+ else:
376
+ raise Exception("Unhandled edge case.")
377
+ else:
378
+ # We need to re-trace.
379
+ r13_endpoints = [
380
+ O13_embeddings[start_j] * start_point.r13_point,
381
+ O13_embeddings[end_j] * end_point.r13_point
382
+ ]
383
+
384
+ new_start_subsimplices = [
385
+ old_to_new_tets[start_j][i].image(start_subsimplex)
386
+ for i in range(3) ]
387
+ start_corners = [
388
+ Corner(new_tets[i], new_start_subsimplices[i])
389
+ for i in range(3)
390
+ if simplex.is_subset(new_start_subsimplices[i], new_start_face) ]
391
+ new_end_subsimplices = [
392
+ old_to_new_tets[end_j][i].image(end_subsimplex)
393
+ for i in range(3) ]
394
+ end_corners = [
395
+ Corner(new_tets[i], new_end_subsimplices[i])
396
+ for i in range(3)
397
+ if simplex.is_subset(new_end_subsimplices[i], new_end_face) ]
398
+
399
+ GeodesicPiece.replace_by(
400
+ old_pieces[0], old_pieces[-1],
401
+ _retrace_geodesic_piece(
402
+ index=old_piece.index,
403
+ r13_points=r13_endpoints,
404
+ start_corners=start_corners,
405
+ end_corners=end_corners,
406
+ verified=verified))
407
+
408
+ # Given pieces are converted to one V-V piece.
409
+ new_piece = GeodesicPiece.create_and_attach(
410
+ given_pieces[0].index,
411
+ new_tets[0],
412
+ [ Endpoint(tip_points[0], simplex.V0),
413
+ Endpoint(tip_points[1], simplex.V1) ])
414
+ GeodesicPiece.replace_by(
415
+ given_pieces[0], given_pieces[1],
416
+ [new_piece])
417
+
418
+ return new_piece
419
+
420
+ def _swap_perm(i, j):
421
+ result = [0, 1, 2, 3]
422
+ result[i] = j
423
+ result[j] = i
424
+ return result
425
+
426
+ _swap_perms = { (f0, f1) : _swap_perm(i, j)
427
+ for i, f0 in enumerate(simplex.TwoSubsimplices)
428
+ for j, f1 in enumerate(simplex.TwoSubsimplices) }
429
+
430
+ # Re-trace a line segment between two points in R^{1,3} in the new
431
+ # tetrahedra (which are assumed to be all in the same coordinate system).
432
+ #
433
+ # We are given the combinatorial information about the start and end points
434
+ # of the line segment through Corner's which are pairs of a tetrahedron and
435
+ # subsimplex.
436
+ #
437
+ # If such a start or end point is on a face, we give retrace exactly one
438
+ # corner encoding the face of the respective tetrahedron.
439
+ #
440
+ # If such a point is inside one of the new tetrahedra (we do not know yet
441
+ # which), we given an empty list of Corner's.
442
+ #
443
+ # If such a point is a vertex, we give all pairs of a new tetrahedron
444
+ # and one of its vertices that correspond to this vertex.
445
+ #
446
+ # index identifies to which of the geodesics we want to drill the retraced
447
+ # pieces belong. It is the index of the cusp that the geodesic will become
448
+ # in the drilled manifold.
449
+ #
450
+ def _retrace_geodesic_piece(
451
+ index : int,
452
+ r13_points,
453
+ start_corners : Sequence[Corner],
454
+ end_corners : Sequence[Corner],
455
+ verified : bool) -> Sequence[GeodesicPiece]:
456
+
457
+ if len(start_corners) == 1:
458
+ # If we have a unique start corner (which is supposed
459
+ # to be a face of a tetrahedron), we can just start
460
+ # tracing from that face.
461
+ trace_direction = +1
462
+ else:
463
+ # Otherwise, we need to trace the other way.
464
+ # The end corner was supposed to be a face of a tetrahedron
465
+ # in this case.
466
+ trace_direction = -1
467
+ start_corners, end_corners = end_corners, start_corners
468
+ r13_points = r13_points[::-1]
469
+
470
+ if len(start_corners) != 1:
471
+ raise Exception("No unique start corner")
472
+
473
+ # Tet and face to start re-tracing
474
+ tet = start_corners[0].Tetrahedron
475
+ face = start_corners[0].Subsimplex
476
+
477
+ if face not in simplex.TwoSubsimplices:
478
+ raise Exception("Tracing not starting on a face")
479
+
480
+ # Get dimension of subsimplex where line segment
481
+ # we are re-tracing ends.
482
+ dimension_end_subsimplex = 3
483
+ if len(end_corners) > 0:
484
+ dimension_end_subsimplex = simplex.dimension(
485
+ end_corners[0].Subsimplex)
486
+
487
+ start_point, end_point = r13_points
488
+
489
+ RF = start_point[0].parent()
490
+ if verified:
491
+ epsilon = 0
492
+ else:
493
+ epsilon = compute_epsilon(RF)
494
+
495
+ # Result
496
+ pieces : List[GeodesicPiece] = []
497
+
498
+ # Parametrizes ray. That is, we are start_point + param * direction.
499
+ param = RF(0)
500
+ direction = end_point - start_point
501
+
502
+ # 1-4 and 2-3 move never breaks up one line segment into more
503
+ # than 4 pieces.
504
+ for i in range(4):
505
+ hit_end : bool = False
506
+ # Record the face and param through which the ray is leaving
507
+ # the tet - that is which face the ray is hitting next.
508
+ hit_subsimplex : Optional[int] = None
509
+ hit_param = None
510
+
511
+ if dimension_end_subsimplex == 0:
512
+ # Check if we just entered a tetrahedron adjacent to the
513
+ # vertex where the line segments stops.
514
+ for end_corner in end_corners:
515
+ if tet == end_corner.Tetrahedron:
516
+ # If that is true, we have finished re-tracing
517
+ # and just need to emit the final F-V piece below.
518
+ # Do some sanity checks first though.
519
+ hit_subsimplex = simplex.comp(face)
520
+ if hit_subsimplex != end_corner.Subsimplex:
521
+ raise Exception("Implementation error: "
522
+ "ray entered tetrahedron through "
523
+ "unexpected face.")
524
+ hit_end = True
525
+
526
+ if not hit_end:
527
+ # Above condition not met, do actual ray-tracing.
528
+ if dimension_end_subsimplex == 3:
529
+ # The line-segment to be re-traced ends in the interior
530
+ # of a simplex. We set hit_param to 1 so that any face
531
+ # the ray hits after reaching the end of the line
532
+ # segment are ignored.
533
+ hit_subsimplex = simplex.T
534
+ hit_param = RF(1)
535
+
536
+ # Now intersect the ray with each face we did not enter through.
537
+ for candidate_face, plane in tet.R13_unnormalised_planes.items():
538
+ # Skip the face through which the ray just entered the tet
539
+ if candidate_face == face:
540
+ continue
541
+ # Compute the param at which the ray intersects this face
542
+ candidate_param = compute_plane_intersection_param(
543
+ plane, start_point, direction, verified)
544
+
545
+ # If the ray crossed this face before it crossed the
546
+ # entry face, ignore. Can happen when a dihedral angle is obtuse.
547
+ if candidate_param < param - epsilon:
548
+ continue
549
+ if not candidate_param > param + epsilon:
550
+ raise InsufficientPrecisionError(
551
+ "When re-tracing the geodesic, the intersection with the "
552
+ "next tetrahedron face was too close to the previous "
553
+ "to tell them apart. Increasing the precision will "
554
+ "probably avoid this problem.")
555
+
556
+ # This face is the (potential) exit face if the ray crossed
557
+ # it before it crossed the other faces (encountered so far).
558
+ if hit_param is None:
559
+ # No other face encountered so far
560
+ hit_param = candidate_param
561
+ hit_subsimplex = candidate_face
562
+ else:
563
+ # Check this face crossed before other faces
564
+ if candidate_param + epsilon < hit_param:
565
+ hit_param = candidate_param
566
+ hit_subsimplex = candidate_face
567
+ elif not candidate_param > hit_param + epsilon:
568
+ # If there is any ambiguity whether this face was
569
+ # crossed before the other face, fail!
570
+ # Most likely, this is because the ray is close to
571
+ # or crossing an edge of the triangulation.
572
+ raise exceptions.RetracingRayHittingOneSkeletonError()
573
+
574
+ if hit_param is None or hit_subsimplex is None:
575
+ raise InsufficientPrecisionError(
576
+ "Could not find the next intersection of the geodesic with a "
577
+ "tetrahedron face. Increasing the precision should solve this "
578
+ "problem.")
579
+
580
+ if dimension_end_subsimplex == 3:
581
+ # If we hit not face before the line segment ended, we are done
582
+ # Emit final F-T segment below.
583
+ if hit_subsimplex == simplex.T:
584
+ hit_end = True
585
+ else:
586
+ if hit_subsimplex == simplex.T:
587
+ raise Exception("Implementation error. Got interior of "
588
+ "simplex when expected face.")
589
+ # Did we hit the face where the line segment is ending at?
590
+ hit_end = (
591
+ tet == end_corners[0].Tetrahedron and
592
+ hit_subsimplex == end_corners[0].Subsimplex)
593
+
594
+ if hit_end:
595
+ # Use end point of line segment if we hit the end.
596
+ point = end_point
597
+ else:
598
+ # Advance ray.
599
+ point = start_point + hit_param * direction
600
+
601
+ endpoints = [ Endpoint(start_point + param * direction, face),
602
+ Endpoint(point, hit_subsimplex) ][::trace_direction]
603
+
604
+ pieces.append(
605
+ GeodesicPiece.create_and_attach(index, tet, endpoints))
606
+
607
+ if hit_end:
608
+ break
609
+
610
+ # Teleport to the next tetrahedron.
611
+ face = tet.Gluing[hit_subsimplex].image(hit_subsimplex)
612
+ tet = tet.Neighbor[hit_subsimplex]
613
+ param = hit_param
614
+ else:
615
+ raise Exception(
616
+ "Too many steps when re-tracing a geodesic piece. "
617
+ "This is either due to a lack of precision or an "
618
+ "implementation bug.")
619
+
620
+ return pieces[::trace_direction]