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,691 @@
1
+ from .cusp_cross_section_base import CuspCrossSectionBase, HoroTriangleBase
2
+ from .exceptions import IncompleteCuspError
3
+
4
+ from ...snap.kernel_structures import TransferKernelStructuresEngine
5
+ from ...snap import t3mlite as t3m
6
+ from ...snap.t3mlite import simplex
7
+ from ...math_basics import correct_max, correct_min, lower
8
+
9
+ # For each vertex, return an edge connected to it
10
+ _pick_an_edge_for_vertex = {
11
+ vertex : [ edge
12
+ for edge in simplex.OneSubsimplices
13
+ if simplex.is_subset(vertex, edge) ][0]
14
+ for vertex in simplex.ZeroSubsimplices
15
+ }
16
+
17
+ # For each (vertex, face) pair, pick one of the two edges adjacent
18
+ # to both the vertex and face
19
+ _pick_an_edge_for_vertex_and_face = {
20
+ (vertex, face): [ edge
21
+ for edge in simplex.OneSubsimplices
22
+ if (simplex.is_subset(vertex, edge) and
23
+ simplex.is_subset(edge, face)) ][0]
24
+ for vertex in simplex.ZeroSubsimplices
25
+ for face in simplex.TwoSubsimplices
26
+ if simplex.is_subset(vertex, face)
27
+ }
28
+
29
+ # Given a vertex, cyclically order the three adjacent faces in
30
+ # clockwise fashion. For each face, return the triple (face, edge, next face)
31
+ # where edge is adjacent to both faces.
32
+ _face_edge_face_triples_for_vertex_link = {
33
+ vertex : [ (faces[i], faces[i] & faces[(i+1) % 3], faces[(i+1) % 3])
34
+ for i in range(3) ]
35
+ for vertex, faces in simplex.FacesAroundVertexCounterclockwise.items()
36
+ }
37
+
38
+ class ComplexHoroTriangle:
39
+ """
40
+ A horosphere cross section in the corner of an ideal tetrahedron.
41
+ The sides of the triangle correspond to faces of the tetrahedron.
42
+ The lengths stored for the triangle are complex.
43
+ """
44
+ def __init__(self, tet, vertex, known_side, length_of_side=None):
45
+ left_side, center_side, right_side, z_left, z_right = (
46
+ HoroTriangleBase._sides_and_cross_ratios(tet, vertex, known_side))
47
+
48
+ if length_of_side is None:
49
+ CF = z_left.parent()
50
+ L = CF(1)
51
+ else:
52
+ L = length_of_side
53
+ self.lengths = { center_side : L,
54
+ left_side : - z_left * L,
55
+ right_side : - L / z_right }
56
+ absL = abs(L)
57
+ self.area = absL * absL * z_left.imag() / 2
58
+
59
+ self._real_lengths_cache = None
60
+
61
+ def get_real_lengths(self):
62
+ if not self._real_lengths_cache:
63
+ self._real_lengths_cache = {
64
+ side : abs(length)
65
+ for side, length in self.lengths.items() }
66
+ return self._real_lengths_cache
67
+
68
+ def rescale(self, t):
69
+ "Rescales the triangle by a Euclidean dilation"
70
+ for face in self.lengths:
71
+ self.lengths[face] *= t
72
+ self.area *= t * t
73
+
74
+ self._real_lengths_cache = None
75
+
76
+ @staticmethod
77
+ def direction_sign():
78
+ return -1
79
+
80
+ def add_vertex_positions(self, vertex, edge, position):
81
+ """
82
+ Adds a dictionary vertex_positions mapping
83
+ an edge (such as simplex.E01) to complex position
84
+ for the vertex of the horotriangle obtained by
85
+ intersecting the edge with the horosphere.
86
+
87
+ Two of these positions are computed from the one given
88
+ using the complex edge lengths. The given vertex and
89
+ edge are t3m-style.
90
+ """
91
+
92
+ self.vertex_positions = {}
93
+
94
+ # The three triples
95
+ # (face, edge adjacent to face and next face, next face)
96
+ # when going around the vertex counter clockwise
97
+ vertex_link = _face_edge_face_triples_for_vertex_link[vertex]
98
+
99
+ # Find for which of these triples the position is for
100
+ for i in range(3):
101
+ if edge == vertex_link[i][1]:
102
+ break
103
+
104
+ # Now go through the triples starting with the one for
105
+ # which we have given the vertex position
106
+ for j in range(3):
107
+ face0, edge, face1 = vertex_link[(i + j) % 3]
108
+ # Assign vertex position
109
+ self.vertex_positions[edge] = position
110
+ # Update vertex position to be for the next
111
+ # edge using complex edge length
112
+ position += self.lengths[face1]
113
+
114
+ def lift_vertex_positions(self, lifted_position):
115
+ """
116
+ Lift the vertex positions of this triangle. lifted_position is
117
+ used as a guide what branch of the logarithm to use.
118
+
119
+ The lifted position is computed as the log of the vertex
120
+ position where it is assumed that the fixed point of the
121
+ holonomy is at the origin. The branch of the logarithm
122
+ closest to lifted_position is used.
123
+ """
124
+
125
+ NumericalField = lifted_position.parent()
126
+ twoPi = 2 * NumericalField.pi()
127
+ I = NumericalField(1j)
128
+
129
+ def adjust_log(z):
130
+ # Compute log and adjust
131
+ logZ = z.log()
132
+ # Add multiplies of 2 * pi * I so that it is close
133
+ # to lifted_position
134
+ return logZ + ((lifted_position - logZ) / twoPi).imag().round() * twoPi * I
135
+
136
+ self.lifted_vertex_positions = {
137
+ # Take log of vertex position
138
+ # (assuming fixed point is at origin).
139
+ edge: adjust_log(position)
140
+ for edge, position in self.vertex_positions.items()
141
+ }
142
+
143
+ class ComplexCuspCrossSection(CuspCrossSectionBase):
144
+ """
145
+ Similarly to RealCuspCrossSection with the following differences: it
146
+ computes the complex edge lengths and the cusp translations (instead
147
+ of the tilts) and it only works for orientable manifolds.
148
+
149
+ The same comment applies about the type of the shapes. The resulting
150
+ edge lengths and translations will be of the same type as the shapes.
151
+
152
+ For shapes corresponding to a non-boundary unipotent representation
153
+ (in other words, a manifold having an incomplete cusp), a cusp can
154
+ be developed if an appropriate 1-cocycle is given. The 1-cocycle
155
+ is a cellular cocycle in the dual of the cusp triangulations and
156
+ represents an element in H^1(boundary M; C^*) that must match the
157
+ PSL(2,C) boundary holonomy of the representation.
158
+ It is encoded as dictionary with key (tet index, t3m face, t3m vertex).
159
+ """
160
+
161
+ HoroTriangle = ComplexHoroTriangle
162
+
163
+ @staticmethod
164
+ def fromManifoldAndShapes(manifold, shapes, one_cocycle=None):
165
+ if not manifold.is_orientable():
166
+ raise ValueError("Non-orientable")
167
+
168
+ m = t3m.Mcomplex(manifold)
169
+
170
+ t = TransferKernelStructuresEngine(m, manifold)
171
+ t.reindex_cusps_and_transfer_peripheral_curves()
172
+ t.add_shapes(shapes)
173
+
174
+ c = ComplexCuspCrossSection(m)
175
+ c.add_structures(one_cocycle)
176
+
177
+ # For testing against SnapPea kernel data
178
+ c.manifold = manifold
179
+
180
+ return c
181
+
182
+ def _dummy_for_testing(self):
183
+ """
184
+ Compare the computed edge lengths and tilts against the one computed by
185
+ the SnapPea kernel.
186
+
187
+ >>> from snappy import Manifold
188
+
189
+ Convention of the kernel is to use (3/8) sqrt(3) as area (ensuring that
190
+ cusp neighborhoods are disjoint).
191
+
192
+ >>> cusp_area = 0.649519052838329
193
+
194
+ >>> for name in ['m009', 'm015', 't02333']:
195
+ ... M = Manifold(name)
196
+ ... e = ComplexCuspCrossSection.fromManifoldAndShapes(M, M.tetrahedra_shapes('rect'))
197
+ ... e.normalize_cusps(cusp_area)
198
+ ... e._testing_check_against_snappea(1e-10)
199
+
200
+ """
201
+
202
+ @staticmethod
203
+ def _get_translation(vertex, ml):
204
+ """
205
+ Compute the translation corresponding to the meridian (ml = 0) or
206
+ longitude (ml = 1) of the given cusp.
207
+ """
208
+
209
+ # Accumulate result
210
+ result = 0
211
+
212
+ # For each triangle of this cusp's cross-section
213
+ for corner in vertex.Corners:
214
+ # Get the corresponding tetrahedron
215
+ tet = corner.Tetrahedron
216
+ # Get the corresponding vertex of this tetrahedron
217
+ subsimplex = corner.Subsimplex
218
+ # Get the three faces of the tetrahedron adjacent to that vertex
219
+ # Each one intersects the cusp cross-section in an edge of
220
+ # the triangle.
221
+ faces = simplex.FacesAroundVertexCounterclockwise[subsimplex]
222
+ # Get the data for this triangle
223
+ triangle = tet.horotriangles[subsimplex]
224
+
225
+ # Restrict the peripheral curve data to this triangle.
226
+ # The result consists of four integers, but the one at
227
+ # subsimplex will always be zero, so effectively, it
228
+ # is three integers corresponding to the three sides of the
229
+ # triangle.
230
+ # Each of these integers tells us how often the peripheral curve
231
+ # "enters" the triangle from the corresponding side of the
232
+ # triangle.
233
+ # Each time the peripheral curve "enters" the triangle through a
234
+ # side, its contribution to the translation is the vector from the
235
+ # center of the side to the center of the triangle.
236
+ curves = tet.PeripheralCurves[ml][0][subsimplex]
237
+
238
+ # We know need to compute this contribution to the translation.
239
+ # Imagine a triangle with complex edge lengths e_0, e_1, e_2 and,
240
+ # without loss of generality, move it such that its vertices are
241
+ # at v_0 = 0, v_1 = e_0, v_2 = e_0 + e_1.
242
+ # The center of the triangle is at
243
+ # c = (v_0 + v_1 + v_2) / 3 = 2 * e_0 / 3 + e_1 / 3.
244
+ # The vector from the center of the side corresponding to e_0
245
+ # to the center of the triangle is given by
246
+ # c - e_0 / 2 = e_0 / 6 + e_1 / 3
247
+ #
248
+ # If the peripheral curves enters the side of the triangle
249
+ # corresponding to e_i n_i-times, then the total contribution
250
+ # with respect to that triangle is given by
251
+ # n_0 * (e_0 / 6 + e_1 / 3)
252
+ # + n_1 * (e_1 / 6 + e_2 / 3)
253
+ # + n_2 * (e_2 / 6 + e_0 / 3)
254
+ # = ( (n_0 + 2 * n_2) * e_0
255
+ # + (n_1 + 2 * n_0) * e_1
256
+ # + (n_2 + 2 * n_1) * e_2) / 6
257
+ #
258
+ # = (sum_{i=0,1,2} (n_i + 2 * n_{i+2}) * e_i) / 6
259
+
260
+ # Implement this sum
261
+ for i in range(3):
262
+ # Find the t3m faces corresponding to two edges of this
263
+ # triangle
264
+ this_face = faces[ i ]
265
+ prev_face = faces[(i+2) % 3]
266
+
267
+ # n_i + 2 * n_{i+2} in above notation
268
+ f = curves[this_face] + 2 * curves[prev_face]
269
+
270
+ # (n_i + 2 * n_{i+2}) * e_i in above notation
271
+ result += f * triangle.lengths[this_face]
272
+
273
+ return result / 6
274
+
275
+ @staticmethod
276
+ def _compute_translations(vertex):
277
+ vertex.Translations = [
278
+ ComplexCuspCrossSection._get_translation(vertex, ml)
279
+ for ml in range(2) ]
280
+
281
+ def compute_translations(self):
282
+ for vertex in self.mcomplex.Vertices:
283
+ ComplexCuspCrossSection._compute_translations(vertex)
284
+
285
+ @staticmethod
286
+ def _get_normalized_translations(vertex):
287
+ """
288
+ Compute the translations corresponding to the merdian and longitude of
289
+ the given cusp.
290
+ """
291
+
292
+ m, l = vertex.Translations
293
+ return m / l * abs(l), abs(l)
294
+
295
+ def all_normalized_translations(self):
296
+ """
297
+ Compute the translations corresponding to the meridian and longitude
298
+ for each cusp.
299
+ """
300
+
301
+ self.compute_translations()
302
+ return [ ComplexCuspCrossSection._get_normalized_translations(vertex)
303
+ for vertex in self.mcomplex.Vertices ]
304
+
305
+ @staticmethod
306
+ def cusp_shape(vertex : t3m.Vertex):
307
+ m = ComplexCuspCrossSection._get_translation(vertex, 0)
308
+ l = ComplexCuspCrossSection._get_translation(vertex, 1)
309
+ return (l / m).conjugate()
310
+
311
+ def cusp_shapes(self):
312
+ """
313
+ Compute the cusp shapes as conjugate of the quotient of the translations
314
+ corresponding to the longitude and meridian for each cusp (SnapPea
315
+ kernel convention).
316
+ """
317
+ return [ ComplexCuspCrossSection.cusp_shape(vertex)
318
+ for vertex in self.mcomplex.Vertices ]
319
+
320
+ def add_vertex_positions_to_horotriangles(self):
321
+ """
322
+ Develops cusp to assign to each horotriangle the positions of its three
323
+ vertices in the Euclidean plane.
324
+
325
+ Note: For a complete cusp, this is defined only up to translating the
326
+ entire triangle by translations generated by meridian and longitude.
327
+
328
+ For an incomplete cusp, this is defined only up to
329
+ similarities generated by the meridian and longitude. The
330
+ positions can be moved such that the fixed point of these
331
+ similarities is at the origin by calling
332
+ move_fixed_point_to_zero after
333
+ add_vertex_positions_to_horotriangles.
334
+
335
+ Note: This is not working when one_cocycle is passed during the
336
+ construction of the cusp cross section.
337
+ """
338
+ for cusp in self.mcomplex.Vertices:
339
+ self._add_one_cusp_vertex_positions(cusp)
340
+
341
+ def _add_one_cusp_vertex_positions(self, cusp : t3m.Vertex):
342
+ """
343
+ Procedure is similar to _add_one_cusp_cross_section
344
+ """
345
+
346
+ corner0 = cusp.Corners[0]
347
+ tet0, vert0 = corner0.Tetrahedron, corner0.Subsimplex
348
+ zero = tet0.ShapeParameters[simplex.E01].parent()(0)
349
+ tet0.horotriangles[vert0].add_vertex_positions(
350
+ vert0, _pick_an_edge_for_vertex[vert0], zero)
351
+
352
+ active = [(tet0, vert0)]
353
+
354
+ # Pairs (tet index, vertex) indicating what has already been
355
+ # visited
356
+ visited = set()
357
+ visited.add((tet0.Index, vert0))
358
+
359
+ while active:
360
+ tet0, vert0 = active.pop()
361
+ for face0 in simplex.FacesAroundVertexCounterclockwise[vert0]:
362
+ tet1, face1, vert1 = CuspCrossSectionBase._glued_to(
363
+ tet0, face0, vert0)
364
+ if not (tet1.Index, vert1) in visited:
365
+ edge0 = _pick_an_edge_for_vertex_and_face[vert0, face0]
366
+ edge1 = tet0.Gluing[face0].image(edge0)
367
+
368
+ tet1.horotriangles[vert1].add_vertex_positions(
369
+ vert1,
370
+ edge1,
371
+ tet0.horotriangles[vert0].vertex_positions[edge0])
372
+
373
+ active.append( (tet1, vert1) )
374
+ visited.add((tet1.Index, vert1))
375
+
376
+ def _debug_show_horotriangles(self, cusp : int =0):
377
+ from sage.plot.line import line
378
+ from sage.functions.other import real, imag
379
+
380
+ self.add_vertex_positions_to_horotriangles()
381
+
382
+ return sum(
383
+ [ line( [ (real(z0), imag(z0)),
384
+ (real(z1), imag(z1)) ] )
385
+ for tet in self.mcomplex.Tetrahedra
386
+ for V, h in tet.horotriangles.items()
387
+ for z0 in h.vertex_positions.values()
388
+ for z1 in h.vertex_positions.values()
389
+ if tet.Class[V].Index == cusp ])
390
+
391
+ def _debug_show_lifted_horotriangles(self, cusp : int =0):
392
+ from sage.plot.line import line
393
+ from sage.functions.other import real, imag
394
+
395
+ self.add_vertex_positions_to_horotriangles()
396
+
397
+ return sum(
398
+ [ line( [ (real(z0), imag(z0)),
399
+ (real(z1), imag(z1)) ] )
400
+ for tet in self.mcomplex.Tetrahedra
401
+ for V, h in tet.horotriangles.items()
402
+ for z0 in h.lifted_vertex_positions.values()
403
+ for z1 in h.lifted_vertex_positions.values()
404
+ if tet.Class[V].Index == cusp ])
405
+
406
+ def move_fixed_point_to_zero(self):
407
+ """
408
+ Determines the fixed point of the holonomies for all
409
+ incomplete cusps. Then moves the vertex positions of the
410
+ corresponding cusp triangles so that the fixed point is at the
411
+ origin.
412
+ """
413
+
414
+ # For each cusp
415
+ for cusp in self.mcomplex.Vertices:
416
+ if cusp.is_complete:
417
+ continue
418
+ # For an incomplete cusp, compute fixed point
419
+ fixed_pt = self._compute_cusp_fixed_point(cusp)
420
+ for corner in cusp.Corners:
421
+ tet, vert = corner.Tetrahedron, corner.Subsimplex
422
+ trig = tet.horotriangles[vert]
423
+ # Move all vertex positions so that fixed point
424
+ # is at origin
425
+ trig.vertex_positions = {
426
+ edge : position - fixed_pt
427
+ for edge, position in trig.vertex_positions.items() }
428
+
429
+ def _compute_cusp_fixed_point(self, cusp : t3m.Vertex):
430
+ """
431
+ Compute fixed point for an incomplete cusp.
432
+ """
433
+
434
+ # Given a horotriangle trig0 with a vertex and edge, let
435
+ # l0 be the complex position of the vertex and p0 the complex
436
+ # edge length.
437
+ # Let trig1 be the horotriangle glued to trig0 along the edge
438
+ # and the l1 and p1 be the corresponding position and edge length
439
+ # (traversed the opposite direction) in the other horotriangle.
440
+ #
441
+ # Then the similarity is described the complex number z = -l1 / l0
442
+ # which is one or the holonomy of meridian or longitude (depending
443
+ # on whether the common edge is inside or on the boundary of a
444
+ # fundamental domain implicitly chosen when developing the cusp).
445
+ #
446
+ # Furthermore, we can compute the fixed point p of the similarity
447
+ # using p1 - p = z * (p0 - p).
448
+
449
+ # Compute z, p0, p1 for each horotriangle, vertex and edge and pick
450
+ # the one where z is furthest away from one.
451
+ z, p0, p1 = max(self._compute_cusp_fixed_point_data(cusp),
452
+ key=lambda d: lower(abs(1 - d[0])))
453
+
454
+ # Compute fixed point
455
+ return (p1 - z * p0) / (1 - z)
456
+
457
+ def _compute_cusp_fixed_point_data(self, cusp : t3m.Vertex):
458
+ """
459
+ Compute abs(z-1), z, p0, p1 for each horotriangle, vertex and edge
460
+ as described in _compute_cusp_fixed_point.
461
+ """
462
+
463
+ # For each horotriangle
464
+ for corner in cusp.Corners:
465
+ tet0, vert0 = corner.Tetrahedron, corner.Subsimplex
466
+ vertex_link = _face_edge_face_triples_for_vertex_link[vert0]
467
+
468
+ # A flag of a horotriangle corresponds to a face and edge
469
+ # of the tetrahedron.
470
+ for face0, edge0, other_face in vertex_link:
471
+ # How that horotriangle is glued to the neighboring one
472
+ tet1, face1, vert1 = CuspCrossSectionBase._glued_to(
473
+ tet0, face0, vert0)
474
+ edge1 = tet0.Gluing[face0].image(edge0)
475
+
476
+ # Get horotriangle and the complex vertex position and
477
+ # edge length
478
+ trig0 = tet0.horotriangles[vert0]
479
+ l0 = trig0.lengths[face0]
480
+ p0 = trig0.vertex_positions[edge0]
481
+
482
+ # And for neighbor
483
+ trig1 = tet1.horotriangles[vert1]
484
+ l1 = trig1.lengths[face1]
485
+ p1 = trig1.vertex_positions[edge1]
486
+
487
+ # Parameter for similarity
488
+ z = - l1 / l0
489
+ yield (z, p0, p1)
490
+
491
+ def lift_vertex_positions_of_horotriangles(self):
492
+ """
493
+ After developing an incomplete cusp with
494
+ add_vertex_positions_to_horotriangles, this function moves the
495
+ vertex positions first to zero the fixed point (see
496
+ move_ffixed_point_to_zero) and computes logarithms for all the
497
+ vertex positions of the horotriangles in the Euclidean plane
498
+ in a consistent manner. These logarithms are written to a
499
+ dictionary lifted_vertex_positions on the HoroTriangle's.
500
+
501
+ For an incomplete cusp, the respective value in lifted_vertex_positions
502
+ will be None.
503
+
504
+ The three logarithms of the vertex positions of a triangle are only
505
+ defined up to adding mu Z + lambda Z where mu and lambda are the
506
+ logarithmic holonomies of the meridian and longitude.
507
+ """
508
+
509
+ self.move_fixed_point_to_zero()
510
+
511
+ for cusp in self.mcomplex.Vertices:
512
+ self._lift_one_cusp_vertex_positions(cusp)
513
+
514
+ def _lift_one_cusp_vertex_positions(self, cusp : t3m.Vertex):
515
+ # Pick first triangle to develop
516
+ corner0 = cusp.Corners[0]
517
+ tet0, vert0 = corner0.Tetrahedron, corner0.Subsimplex
518
+ trig0 = tet0.horotriangles[vert0]
519
+ edge0 = _pick_an_edge_for_vertex[vert0]
520
+
521
+ if cusp.is_complete:
522
+ # If cusp is complete, we store None for the logarithms
523
+ for corner in cusp.Corners:
524
+ tet0, vert0 = corner.Tetrahedron, corner.Subsimplex
525
+ tet0.horotriangles[vert0].lifted_vertex_positions = {
526
+ vert0 | vert1 : None
527
+ for vert1 in t3m.ZeroSubsimplices
528
+ if vert0 != vert1 }
529
+ return
530
+
531
+ # Lift first triangle, picking main branch of logarithm for
532
+ # the first vertex
533
+ trig0.lift_vertex_positions(trig0.vertex_positions[edge0].log())
534
+
535
+ # Procedure similar to _add_one_cusp_cross_section
536
+ active = [(tet0, vert0)]
537
+
538
+ # Pairs (tet index, vertex) indicating what has already been
539
+ # visited
540
+ visited = set()
541
+
542
+ while active:
543
+ tet0, vert0 = active.pop()
544
+ for face0 in simplex.FacesAroundVertexCounterclockwise[vert0]:
545
+ tet1, face1, vert1 = CuspCrossSectionBase._glued_to(
546
+ tet0, face0, vert0)
547
+ if not (tet1.Index, vert1) in visited:
548
+ edge0 = _pick_an_edge_for_vertex_and_face[vert0, face0]
549
+
550
+ # Lift triangle using lifted vertex position of
551
+ # neighboring triangle as guide (when determining what
552
+ # branch of logarithm to take).
553
+ tet1.horotriangles[vert1].lift_vertex_positions(
554
+ tet0.horotriangles[vert0].lifted_vertex_positions[edge0])
555
+
556
+ active.append( (tet1, vert1) )
557
+ visited.add( (tet1.Index, vert1) )
558
+
559
+ def move_lifted_vertex_positions_to_zero_first(self):
560
+ """
561
+ Shift the lifted vertex positions such that the one associated
562
+ to the first vertex when developing the incomplete cusp is
563
+ zero. This makes the values we obtain more stable when
564
+ changing the Dehn-surgery parameters.
565
+ """
566
+
567
+ for cusp in self.mcomplex.Vertices:
568
+ if not cusp.is_complete:
569
+ ComplexCuspCrossSection._move_lifted_vertex_positions_cusp(cusp)
570
+
571
+ @staticmethod
572
+ def _move_lifted_vertex_positions_cusp(cusp : t3m.Vertex):
573
+ corner0 = cusp.Corners[0]
574
+ tet0, vert0 = corner0.Tetrahedron, corner0.Subsimplex
575
+ trig0 = tet0.horotriangles[vert0]
576
+ edge0 = _pick_an_edge_for_vertex[vert0]
577
+
578
+ log0 = trig0.lifted_vertex_positions[edge0]
579
+
580
+ for corner in cusp.Corners:
581
+ tet, vert = corner.Tetrahedron, corner.Subsimplex
582
+ trig = tet.horotriangles[vert]
583
+
584
+ trig.lifted_vertex_positions = {
585
+ edge: position - log0
586
+ for edge, position in trig.lifted_vertex_positions.items()
587
+ }
588
+
589
+ def scale_triangles_to_avoid_standard_tubes(self):
590
+ r"""
591
+ Scales each horo triangle so that it is guaranteed to be outside of
592
+ a standard tube about the incompleteness locus from the outside (up
593
+ to rounding errors, it will touch the tube from the outside). Note
594
+ that the scale factor is not uniform across the triangles belonging
595
+ to the same (incomplete) cusp.
596
+
597
+ Thus, if we truncated each tetrahedron along the triangle, the
598
+ tetrahedra would not intersect the standard tube.
599
+
600
+
601
+ \ /
602
+ \ * vertex on standard tube when
603
+ \ / applying inverse_scale_to_be_on_tube
604
+ \ /
605
+ \ ---- triangle after calling this method
606
+ \ /
607
+ \ /
608
+ 45degrees \/
609
+ ----------------------------------
610
+
611
+ The resulting neighborhood about the core curve in the filled manifold
612
+ looks like a triangular version of the Giant's Causeway in Northern
613
+ Ireland.
614
+
615
+ Also stores the inverse Euclidean length scale factor in
616
+ inverse_scale_to_be_on_tube for each vertex of the triangle so that
617
+ the vertex lands on the boundary of the standard tube.
618
+ The key is the edge corresponding to that vertex of the triangle.
619
+
620
+ Here, a standard tube is given by a Euclidean cone from zero to
621
+ infinity in the upper halfspace model with cone angle pi/4.
622
+ Its hyperbolic radius is given by
623
+ arcsinh(1) = log(1 + sqrt(2)) = 0.881373... .
624
+ """
625
+
626
+ for cusp in self.mcomplex.Vertices:
627
+ self._scale_triangles_to_avoid_standard_tube(cusp)
628
+
629
+ def _scale_triangles_to_avoid_standard_tube(self, cusp : t3m.Vertex):
630
+ for corner in cusp.Corners:
631
+ tet, vert = corner.Tetrahedron, corner.Subsimplex
632
+ trig = tet.horotriangles[vert]
633
+
634
+ if cusp.is_complete:
635
+ z = tet.ShapeParameters[simplex.E01]
636
+ RF = z.real().parent()
637
+ one = RF(1)
638
+ trig.inverse_scale_to_be_on_tube = {
639
+ vert | vert1 : one
640
+ for vert1 in simplex.ZeroSubsimplices
641
+ if vert != vert1 }
642
+ else:
643
+ _scale_triangle_to_avoid_standard_tube(trig, vert)
644
+
645
+ def _lower_bound_distance_origin_line_segment(a, b):
646
+ """
647
+ Given two complex numbers a and b, compute a lower bound for
648
+ the (Euclidean) distance of the line segment from a to b to 0.
649
+ """
650
+
651
+ # The similarity
652
+ # f : z |-> (a - z) / (a - b)
653
+ # takes a to 0 and b to 1.
654
+
655
+ d = a - b
656
+
657
+ # The image of f(0).
658
+ z0 = a / d
659
+
660
+ if z0.real() > 1:
661
+ return abs(b)
662
+
663
+ if z0.real() < 0:
664
+ return abs(a)
665
+
666
+ # This is only the distance if we can show that z0.real() >= 0
667
+ # and z0.real() <= 1.
668
+ #
669
+ # But it is still a lower bound for the distance.
670
+ return abs(z0.imag()) * abs(d)
671
+
672
+ def _scale_triangle_to_avoid_standard_tube(trig, vert):
673
+ vertex_positions = [
674
+ trig.vertex_positions[vert | vert1]
675
+ for vert1 in simplex.ZeroSubsimplices
676
+ if vert != vert1 ]
677
+
678
+ min_height = correct_min(
679
+ [ _lower_bound_distance_origin_line_segment(
680
+ vertex_positions[0], vertex_positions[1]),
681
+ _lower_bound_distance_origin_line_segment(
682
+ vertex_positions[1], vertex_positions[2]),
683
+ _lower_bound_distance_origin_line_segment(
684
+ vertex_positions[2], vertex_positions[0]) ])
685
+
686
+ trig.rescale(1 / min_height)
687
+
688
+ trig.inverse_scale_to_be_on_tube = {
689
+ vert | vert1 : abs(trig.vertex_positions[vert | vert1]) / min_height
690
+ for vert1 in simplex.ZeroSubsimplices
691
+ if vert != vert1 }