snappy 3.2__cp311-cp311-macosx_10_12_x86_64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (503) hide show
  1. snappy/CyOpenGL.cpython-311-darwin.so +0 -0
  2. snappy/SnapPy.cpython-311-darwin.so +0 -0
  3. snappy/SnapPy.ico +0 -0
  4. snappy/SnapPy.png +0 -0
  5. snappy/SnapPyHP.cpython-311-darwin.so +0 -0
  6. snappy/__init__.py +760 -0
  7. snappy/app.py +605 -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 +38 -0
  13. snappy/cusps/cusp_area_matrix.py +101 -0
  14. snappy/cusps/cusp_areas_from_matrix.py +173 -0
  15. snappy/cusps/maximal_cusp_area_matrix.py +136 -0
  16. snappy/cusps/test.py +21 -0
  17. snappy/cusps/trig_cusp_area_matrix.py +63 -0
  18. snappy/database.py +454 -0
  19. snappy/db_utilities.py +79 -0
  20. snappy/decorated_isosig.py +710 -0
  21. snappy/dev/__init__.py +0 -0
  22. snappy/dev/extended_ptolemy/__init__.py +8 -0
  23. snappy/dev/extended_ptolemy/closed.py +106 -0
  24. snappy/dev/extended_ptolemy/complexVolumesClosed.py +149 -0
  25. snappy/dev/extended_ptolemy/direct.py +42 -0
  26. snappy/dev/extended_ptolemy/extended.py +406 -0
  27. snappy/dev/extended_ptolemy/giac_helper.py +43 -0
  28. snappy/dev/extended_ptolemy/giac_rur.py +129 -0
  29. snappy/dev/extended_ptolemy/gluing.py +46 -0
  30. snappy/dev/extended_ptolemy/phc_wrapper.py +220 -0
  31. snappy/dev/extended_ptolemy/printMatrices.py +70 -0
  32. snappy/dev/vericlosed/__init__.py +1 -0
  33. snappy/dev/vericlosed/computeApproxHyperbolicStructureNew.py +159 -0
  34. snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +90 -0
  35. snappy/dev/vericlosed/computeVerifiedHyperbolicStructure.py +111 -0
  36. snappy/dev/vericlosed/gimbalLoopFinder.py +130 -0
  37. snappy/dev/vericlosed/hyperbolicStructure.py +313 -0
  38. snappy/dev/vericlosed/krawczykCertifiedEdgeLengthsEngine.py +165 -0
  39. snappy/dev/vericlosed/oneVertexTruncatedComplex.py +122 -0
  40. snappy/dev/vericlosed/orb/__init__.py +1 -0
  41. snappy/dev/vericlosed/orb/orb_solution_for_snappea_finite_triangulation_mac +0 -0
  42. snappy/dev/vericlosed/parseVertexGramMatrixFile.py +47 -0
  43. snappy/dev/vericlosed/polishApproxHyperbolicStructure.py +61 -0
  44. snappy/dev/vericlosed/test.py +54 -0
  45. snappy/dev/vericlosed/truncatedComplex.py +176 -0
  46. snappy/dev/vericlosed/verificationError.py +58 -0
  47. snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +177 -0
  48. snappy/doc/_images/SnapPy-196.png +0 -0
  49. snappy/doc/_images/geodesics.jpg +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 +51 -0
  61. snappy/doc/_sources/credits.rst.txt +75 -0
  62. snappy/doc/_sources/development.rst.txt +259 -0
  63. snappy/doc/_sources/index.rst.txt +182 -0
  64. snappy/doc/_sources/installing.rst.txt +247 -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 +355 -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 +925 -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 +156 -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 +199 -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 +620 -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 +427 -0
  152. snappy/doc/credits.html +181 -0
  153. snappy/doc/development.html +384 -0
  154. snappy/doc/genindex.html +1331 -0
  155. snappy/doc/index.html +262 -0
  156. snappy/doc/installing.html +346 -0
  157. snappy/doc/manifold.html +3452 -0
  158. snappy/doc/manifoldhp.html +180 -0
  159. snappy/doc/news.html +388 -0
  160. snappy/doc/objects.inv +0 -0
  161. snappy/doc/other.html +161 -0
  162. snappy/doc/platonic_census.html +375 -0
  163. snappy/doc/plink.html +210 -0
  164. snappy/doc/ptolemy.html +254 -0
  165. snappy/doc/ptolemy_classes.html +1144 -0
  166. snappy/doc/ptolemy_examples1.html +409 -0
  167. snappy/doc/ptolemy_examples2.html +471 -0
  168. snappy/doc/ptolemy_examples3.html +414 -0
  169. snappy/doc/ptolemy_examples4.html +195 -0
  170. snappy/doc/ptolemy_prelim.html +248 -0
  171. snappy/doc/py-modindex.html +165 -0
  172. snappy/doc/screenshots.html +141 -0
  173. snappy/doc/search.html +135 -0
  174. snappy/doc/searchindex.js +1 -0
  175. snappy/doc/snap.html +202 -0
  176. snappy/doc/snappy.html +181 -0
  177. snappy/doc/spherogram.html +1211 -0
  178. snappy/doc/todo.html +166 -0
  179. snappy/doc/triangulation.html +1584 -0
  180. snappy/doc/tutorial.html +159 -0
  181. snappy/doc/verify.html +330 -0
  182. snappy/doc/verify_internals.html +1235 -0
  183. snappy/drilling/__init__.py +456 -0
  184. snappy/drilling/barycentric.py +103 -0
  185. snappy/drilling/constants.py +5 -0
  186. snappy/drilling/crush.py +270 -0
  187. snappy/drilling/cusps.py +125 -0
  188. snappy/drilling/debug.py +242 -0
  189. snappy/drilling/epsilons.py +6 -0
  190. snappy/drilling/exceptions.py +55 -0
  191. snappy/drilling/moves.py +620 -0
  192. snappy/drilling/peripheral_curves.py +210 -0
  193. snappy/drilling/perturb.py +188 -0
  194. snappy/drilling/shorten.py +36 -0
  195. snappy/drilling/subdivide.py +274 -0
  196. snappy/drilling/test.py +23 -0
  197. snappy/drilling/test_cases.py +126 -0
  198. snappy/drilling/tracing.py +351 -0
  199. snappy/exceptions.py +26 -0
  200. snappy/export_stl.py +120 -0
  201. snappy/exterior_to_link/__init__.py +2 -0
  202. snappy/exterior_to_link/barycentric_geometry.py +463 -0
  203. snappy/exterior_to_link/exceptions.py +6 -0
  204. snappy/exterior_to_link/geodesic_map.json +14408 -0
  205. snappy/exterior_to_link/hyp_utils.py +112 -0
  206. snappy/exterior_to_link/link_projection.py +323 -0
  207. snappy/exterior_to_link/main.py +197 -0
  208. snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
  209. snappy/exterior_to_link/mcomplex_with_link.py +687 -0
  210. snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
  211. snappy/exterior_to_link/pl_utils.py +491 -0
  212. snappy/exterior_to_link/put_in_S3.py +156 -0
  213. snappy/exterior_to_link/rational_linear_algebra.py +123 -0
  214. snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
  215. snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
  216. snappy/exterior_to_link/stored_moves.py +475 -0
  217. snappy/exterior_to_link/test.py +31 -0
  218. snappy/filedialog.py +28 -0
  219. snappy/geometric_structure/__init__.py +212 -0
  220. snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
  221. snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +697 -0
  222. snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +484 -0
  223. snappy/geometric_structure/cusp_neighborhood/exceptions.py +42 -0
  224. snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +298 -0
  225. snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +159 -0
  226. snappy/geometric_structure/cusp_neighborhood/vertices.py +32 -0
  227. snappy/geometric_structure/geodesic/__init__.py +0 -0
  228. snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
  229. snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
  230. snappy/geometric_structure/geodesic/canonical_keys.py +52 -0
  231. snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
  232. snappy/geometric_structure/geodesic/constants.py +6 -0
  233. snappy/geometric_structure/geodesic/exceptions.py +22 -0
  234. snappy/geometric_structure/geodesic/fixed_points.py +93 -0
  235. snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
  236. snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
  237. snappy/geometric_structure/geodesic/line.py +30 -0
  238. snappy/geometric_structure/geodesic/multiplicity.py +127 -0
  239. snappy/geometric_structure/geodesic/tiles_for_geodesic.py +101 -0
  240. snappy/geometric_structure/test.py +22 -0
  241. snappy/gui.py +121 -0
  242. snappy/horoviewer.py +443 -0
  243. snappy/hyperboloid/__init__.py +212 -0
  244. snappy/hyperboloid/distances.py +245 -0
  245. snappy/hyperboloid/horoball.py +19 -0
  246. snappy/hyperboloid/line.py +35 -0
  247. snappy/hyperboloid/point.py +9 -0
  248. snappy/hyperboloid/triangle.py +29 -0
  249. snappy/info_icon.gif +0 -0
  250. snappy/infowindow.py +65 -0
  251. snappy/isometry_signature.py +382 -0
  252. snappy/len_spec/__init__.py +596 -0
  253. snappy/len_spec/geodesic_info.py +110 -0
  254. snappy/len_spec/geodesic_key_info_dict.py +117 -0
  255. snappy/len_spec/geodesic_piece.py +143 -0
  256. snappy/len_spec/geometric_structure.py +182 -0
  257. snappy/len_spec/geometry.py +80 -0
  258. snappy/len_spec/length_spectrum_geodesic_info.py +170 -0
  259. snappy/len_spec/spine.py +206 -0
  260. snappy/len_spec/test.py +24 -0
  261. snappy/len_spec/test_cases.py +69 -0
  262. snappy/len_spec/tile.py +275 -0
  263. snappy/len_spec/word.py +86 -0
  264. snappy/manifolds/HTWKnots/alternating.gz +0 -0
  265. snappy/manifolds/HTWKnots/nonalternating.gz +0 -0
  266. snappy/manifolds/__init__.py +3 -0
  267. snappy/math_basics.py +176 -0
  268. snappy/matrix.py +525 -0
  269. snappy/number.py +657 -0
  270. snappy/numeric_output_checker.py +345 -0
  271. snappy/pari.py +41 -0
  272. snappy/phone_home.py +57 -0
  273. snappy/polyviewer.py +259 -0
  274. snappy/ptolemy/__init__.py +17 -0
  275. snappy/ptolemy/component.py +103 -0
  276. snappy/ptolemy/coordinates.py +2290 -0
  277. snappy/ptolemy/fieldExtensions.py +153 -0
  278. snappy/ptolemy/findLoops.py +473 -0
  279. snappy/ptolemy/geometricRep.py +59 -0
  280. snappy/ptolemy/homology.py +165 -0
  281. snappy/ptolemy/magma/default.magma_template +229 -0
  282. snappy/ptolemy/magma/radicalsOfPrimaryDecomposition.magma_template +79 -0
  283. snappy/ptolemy/manifoldMethods.py +395 -0
  284. snappy/ptolemy/matrix.py +350 -0
  285. snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +113 -0
  286. snappy/ptolemy/polynomial.py +857 -0
  287. snappy/ptolemy/processComponents.py +173 -0
  288. snappy/ptolemy/processFileBase.py +247 -0
  289. snappy/ptolemy/processFileDispatch.py +46 -0
  290. snappy/ptolemy/processMagmaFile.py +392 -0
  291. snappy/ptolemy/processRurFile.py +150 -0
  292. snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +102 -0
  293. snappy/ptolemy/ptolemyObstructionClass.py +64 -0
  294. snappy/ptolemy/ptolemyVariety.py +1029 -0
  295. snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +140 -0
  296. snappy/ptolemy/reginaWrapper.py +698 -0
  297. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  298. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  299. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  300. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  301. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  302. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  303. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  304. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  305. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  306. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  307. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c0.magma_out.bz2 +0 -0
  308. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  309. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  310. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c1.magma_out.bz2 +0 -0
  311. snappy/ptolemy/rur.py +545 -0
  312. snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +277 -0
  313. snappy/ptolemy/test.py +1126 -0
  314. snappy/ptolemy/testing_files/3_1__sl2_c0.magma_out.bz2 +0 -0
  315. snappy/ptolemy/testing_files/3_1__sl2_c1.magma_out.bz2 +0 -0
  316. snappy/ptolemy/testing_files/4_1__sl2_c0.magma_out.bz2 +0 -0
  317. snappy/ptolemy/testing_files/4_1__sl2_c1.magma_out.bz2 +0 -0
  318. snappy/ptolemy/testing_files/4_1__sl3_c0.magma_out.bz2 +0 -0
  319. snappy/ptolemy/testing_files/4_1__sl4_c0.magma_out.bz2 +0 -0
  320. snappy/ptolemy/testing_files/4_1__sl4_c1.magma_out.bz2 +0 -0
  321. snappy/ptolemy/testing_files/5_2__sl2_c0.magma_out.bz2 +0 -0
  322. snappy/ptolemy/testing_files/5_2__sl2_c1.magma_out.bz2 +0 -0
  323. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  324. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  325. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  326. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  327. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  328. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  329. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  330. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  331. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c0.magma_out +95 -0
  332. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c1.magma_out +95 -0
  333. snappy/ptolemy/testing_files/m015__sl3_c0.magma_out.bz2 +0 -0
  334. snappy/ptolemy/testing_files/m135__sl2_c0.magma_out.bz2 +0 -0
  335. snappy/ptolemy/testing_files/m135__sl2_c1.magma_out.bz2 +0 -0
  336. snappy/ptolemy/testing_files/m135__sl2_c2.magma_out.bz2 +0 -0
  337. snappy/ptolemy/testing_files/m135__sl2_c3.magma_out.bz2 +0 -0
  338. snappy/ptolemy/testing_files/m135__sl2_c4.magma_out.bz2 +0 -0
  339. snappy/ptolemy/testing_files/m135__sl2_c5.magma_out.bz2 +0 -0
  340. snappy/ptolemy/testing_files/m135__sl2_c6.magma_out.bz2 +0 -0
  341. snappy/ptolemy/testing_files/m135__sl2_c7.magma_out.bz2 +0 -0
  342. snappy/ptolemy/testing_files/s000__sl2_c0.magma_out.bz2 +0 -0
  343. snappy/ptolemy/testing_files/s000__sl2_c1.magma_out.bz2 +0 -0
  344. snappy/ptolemy/testing_files/t00000__sl2_c0.magma_out.bz2 +0 -0
  345. snappy/ptolemy/testing_files/t00000__sl2_c1.magma_out.bz2 +0 -0
  346. snappy/ptolemy/testing_files/v0000__sl2_c0.magma_out.bz2 +0 -0
  347. snappy/ptolemy/testing_files/v0000__sl2_c1.magma_out.bz2 +0 -0
  348. snappy/ptolemy/testing_files/v0000__sl2_c2.magma_out.bz2 +0 -0
  349. snappy/ptolemy/testing_files/v0000__sl2_c3.magma_out.bz2 +0 -0
  350. snappy/ptolemy/testing_files_generalized/m003__sl2_c0.magma_out.bz2 +0 -0
  351. snappy/ptolemy/testing_files_generalized/m003__sl2_c1.magma_out.bz2 +0 -0
  352. snappy/ptolemy/testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  353. snappy/ptolemy/testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  354. snappy/ptolemy/testing_files_generalized/m004__sl2_c0.magma_out.bz2 +0 -0
  355. snappy/ptolemy/testing_files_generalized/m004__sl2_c1.magma_out.bz2 +0 -0
  356. snappy/ptolemy/testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  357. snappy/ptolemy/testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  358. snappy/ptolemy/testing_files_rur/m052__sl3_c0.rur.bz2 +0 -0
  359. snappy/ptolemy/utilities.py +236 -0
  360. snappy/raytracing/__init__.py +64 -0
  361. snappy/raytracing/additional_horospheres.py +64 -0
  362. snappy/raytracing/additional_len_spec_choices.py +63 -0
  363. snappy/raytracing/cohomology_fractal.py +197 -0
  364. snappy/raytracing/eyeball.py +123 -0
  365. snappy/raytracing/finite_raytracing_data.py +237 -0
  366. snappy/raytracing/finite_viewer.py +590 -0
  367. snappy/raytracing/geodesic_tube_info.py +174 -0
  368. snappy/raytracing/geodesics.py +246 -0
  369. snappy/raytracing/geodesics_window.py +258 -0
  370. snappy/raytracing/gui_utilities.py +293 -0
  371. snappy/raytracing/hyperboloid_navigation.py +556 -0
  372. snappy/raytracing/hyperboloid_utilities.py +234 -0
  373. snappy/raytracing/ideal_raytracing_data.py +592 -0
  374. snappy/raytracing/inside_viewer.py +974 -0
  375. snappy/raytracing/pack.py +22 -0
  376. snappy/raytracing/raytracing_data.py +126 -0
  377. snappy/raytracing/raytracing_view.py +454 -0
  378. snappy/raytracing/shaders/Eye.png +0 -0
  379. snappy/raytracing/shaders/NonGeometric.png +0 -0
  380. snappy/raytracing/shaders/__init__.py +101 -0
  381. snappy/raytracing/shaders/fragment.glsl +1744 -0
  382. snappy/raytracing/test.py +29 -0
  383. snappy/raytracing/tooltip.py +146 -0
  384. snappy/raytracing/upper_halfspace_utilities.py +98 -0
  385. snappy/raytracing/view_scale_controller.py +98 -0
  386. snappy/raytracing/zoom_slider/__init__.py +263 -0
  387. snappy/raytracing/zoom_slider/inward.png +0 -0
  388. snappy/raytracing/zoom_slider/inward18.png +0 -0
  389. snappy/raytracing/zoom_slider/outward.png +0 -0
  390. snappy/raytracing/zoom_slider/outward18.png +0 -0
  391. snappy/raytracing/zoom_slider/test.py +20 -0
  392. snappy/sage_helper.py +117 -0
  393. snappy/settings.py +409 -0
  394. snappy/shell.py +53 -0
  395. snappy/snap/__init__.py +114 -0
  396. snappy/snap/character_varieties.py +375 -0
  397. snappy/snap/find_field.py +372 -0
  398. snappy/snap/fundamental_polyhedron.py +569 -0
  399. snappy/snap/generators.py +39 -0
  400. snappy/snap/interval_reps.py +81 -0
  401. snappy/snap/kernel_structures.py +128 -0
  402. snappy/snap/mcomplex_base.py +18 -0
  403. snappy/snap/nsagetools.py +702 -0
  404. snappy/snap/peripheral/__init__.py +1 -0
  405. snappy/snap/peripheral/dual_cellulation.py +219 -0
  406. snappy/snap/peripheral/link.py +127 -0
  407. snappy/snap/peripheral/peripheral.py +159 -0
  408. snappy/snap/peripheral/surface.py +522 -0
  409. snappy/snap/peripheral/test.py +35 -0
  410. snappy/snap/polished_reps.py +335 -0
  411. snappy/snap/shapes.py +152 -0
  412. snappy/snap/slice_obs_HKL.py +668 -0
  413. snappy/snap/t3mlite/__init__.py +2 -0
  414. snappy/snap/t3mlite/arrow.py +243 -0
  415. snappy/snap/t3mlite/corner.py +22 -0
  416. snappy/snap/t3mlite/edge.py +172 -0
  417. snappy/snap/t3mlite/face.py +37 -0
  418. snappy/snap/t3mlite/files.py +211 -0
  419. snappy/snap/t3mlite/homology.py +53 -0
  420. snappy/snap/t3mlite/linalg.py +419 -0
  421. snappy/snap/t3mlite/mcomplex.py +1499 -0
  422. snappy/snap/t3mlite/perm4.py +320 -0
  423. snappy/snap/t3mlite/setup.py +12 -0
  424. snappy/snap/t3mlite/simplex.py +199 -0
  425. snappy/snap/t3mlite/spun.py +297 -0
  426. snappy/snap/t3mlite/surface.py +519 -0
  427. snappy/snap/t3mlite/test.py +20 -0
  428. snappy/snap/t3mlite/test_vs_regina.py +86 -0
  429. snappy/snap/t3mlite/tetrahedron.py +109 -0
  430. snappy/snap/t3mlite/vertex.py +42 -0
  431. snappy/snap/test.py +134 -0
  432. snappy/snap/utilities.py +288 -0
  433. snappy/test.py +209 -0
  434. snappy/test_cases.py +263 -0
  435. snappy/testing.py +131 -0
  436. snappy/tiling/__init__.py +2 -0
  437. snappy/tiling/canonical_key_dict.py +59 -0
  438. snappy/tiling/dict_based_set.py +79 -0
  439. snappy/tiling/floor.py +49 -0
  440. snappy/tiling/hyperboloid_dict.py +54 -0
  441. snappy/tiling/iter_utils.py +78 -0
  442. snappy/tiling/lifted_tetrahedron.py +22 -0
  443. snappy/tiling/lifted_tetrahedron_set.py +54 -0
  444. snappy/tiling/real_hash_dict.py +164 -0
  445. snappy/tiling/test.py +23 -0
  446. snappy/tiling/tile.py +215 -0
  447. snappy/tiling/triangle.py +33 -0
  448. snappy/tkterminal.py +920 -0
  449. snappy/twister/__init__.py +20 -0
  450. snappy/twister/main.py +646 -0
  451. snappy/twister/surfaces/S_0_1 +3 -0
  452. snappy/twister/surfaces/S_0_2 +3 -0
  453. snappy/twister/surfaces/S_0_4 +7 -0
  454. snappy/twister/surfaces/S_0_4_Lantern +8 -0
  455. snappy/twister/surfaces/S_1 +3 -0
  456. snappy/twister/surfaces/S_1_1 +4 -0
  457. snappy/twister/surfaces/S_1_2 +5 -0
  458. snappy/twister/surfaces/S_1_2_5 +6 -0
  459. snappy/twister/surfaces/S_2 +6 -0
  460. snappy/twister/surfaces/S_2_1 +8 -0
  461. snappy/twister/surfaces/S_2_heeg +10 -0
  462. snappy/twister/surfaces/S_3 +8 -0
  463. snappy/twister/surfaces/S_3_1 +10 -0
  464. snappy/twister/surfaces/S_4_1 +12 -0
  465. snappy/twister/surfaces/S_5_1 +14 -0
  466. snappy/twister/surfaces/heeg_fig8 +9 -0
  467. snappy/twister/twister_core.cpython-311-darwin.so +0 -0
  468. snappy/upper_halfspace/__init__.py +146 -0
  469. snappy/upper_halfspace/ideal_point.py +26 -0
  470. snappy/verify/__init__.py +13 -0
  471. snappy/verify/canonical.py +542 -0
  472. snappy/verify/complex_volume/__init__.py +18 -0
  473. snappy/verify/complex_volume/adjust_torsion.py +86 -0
  474. snappy/verify/complex_volume/closed.py +168 -0
  475. snappy/verify/complex_volume/compute_ptolemys.py +90 -0
  476. snappy/verify/complex_volume/cusped.py +56 -0
  477. snappy/verify/complex_volume/extended_bloch.py +201 -0
  478. snappy/verify/cusp_translations.py +85 -0
  479. snappy/verify/edge_equations.py +80 -0
  480. snappy/verify/exceptions.py +254 -0
  481. snappy/verify/hyperbolicity.py +224 -0
  482. snappy/verify/interval_newton_shapes_engine.py +523 -0
  483. snappy/verify/interval_tree.py +400 -0
  484. snappy/verify/krawczyk_shapes_engine.py +518 -0
  485. snappy/verify/maximal_cusp_area_matrix/__init__.py +46 -0
  486. snappy/verify/maximal_cusp_area_matrix/cusp_tiling_engine.py +419 -0
  487. snappy/verify/maximal_cusp_area_matrix/cusp_translate_engine.py +153 -0
  488. snappy/verify/real_algebra.py +286 -0
  489. snappy/verify/shapes.py +25 -0
  490. snappy/verify/short_slopes.py +200 -0
  491. snappy/verify/square_extensions.py +1005 -0
  492. snappy/verify/test.py +78 -0
  493. snappy/verify/upper_halfspace/__init__.py +9 -0
  494. snappy/verify/upper_halfspace/extended_matrix.py +100 -0
  495. snappy/verify/upper_halfspace/finite_point.py +283 -0
  496. snappy/verify/upper_halfspace/ideal_point.py +426 -0
  497. snappy/verify/volume.py +128 -0
  498. snappy/version.py +2 -0
  499. snappy-3.2.dist-info/METADATA +58 -0
  500. snappy-3.2.dist-info/RECORD +503 -0
  501. snappy-3.2.dist-info/WHEEL +5 -0
  502. snappy-3.2.dist-info/entry_points.txt +2 -0
  503. snappy-3.2.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]