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,351 @@
1
+ from . import constants
2
+ from . import epsilons
3
+ from . import exceptions
4
+
5
+ from ..snap.t3mlite import simplex, Tetrahedron, Mcomplex # type: ignore
6
+
7
+ from ..hyperboloid import r13_dot # type: ignore
8
+ from ..geometric_structure.geodesic.geodesic_start_point_info import GeodesicStartPointInfo
9
+ from ..geometric_structure.geodesic.line import R13LineWithMatrix
10
+ from ..geometric_structure.geodesic.check_away_from_core_curve import check_away_from_core_curve
11
+ from ..exceptions import InsufficientPrecisionError # type: ignore
12
+
13
+ from typing import Sequence, Optional, List
14
+
15
+
16
+ class Endpoint:
17
+ """
18
+ Used to represent an endpoint of a line segment in a tetrahedron
19
+ in the hyperboloid model.
20
+
21
+ That is, a pair of an (unnormalised) time vector and a t3mlite' style
22
+ subsimplex saying whether the point is a vertex, on a face or in the
23
+ interior of the tetrahedron.
24
+ """
25
+
26
+ def __init__(self,
27
+ r13_point, # Unnormalised time vector
28
+ subsimplex : int): # t3mlite' style vertex, face, simplex.T
29
+ self.r13_point = r13_point
30
+ self.subsimplex : int = subsimplex
31
+
32
+ def __repr__(self):
33
+ return "Endpoint(%r, %r)" % (self.r13_point, self.subsimplex)
34
+
35
+
36
+ class GeodesicPiece:
37
+ """
38
+ A line segment in a tetrahedron that can participate in a linked list
39
+ (via prev and next_) to make a loop.
40
+
41
+ The line segment is going from endpoints[0] to endpoints[1] of the
42
+ given tetrahedron tet such that endpoints[1] of this piece matches
43
+ endpoints[0] of the next piece (in, probably, a different tetrahedron).
44
+
45
+ There is an additional field index that can be used by clients for
46
+ book-keeping purposes, for example, to store the index of the cusp
47
+ obtained by drilling this geodesic.
48
+ """
49
+
50
+ def __init__(self,
51
+ index : Optional[int],
52
+ tet : Tetrahedron,
53
+ endpoints : Sequence[Endpoint]):
54
+ self.index : Optional[int] = index
55
+ self.tet : Tetrahedron = tet
56
+ self.endpoints : Sequence[Endpoint] = endpoints
57
+ self.prev = None
58
+ self.next_ = None
59
+ self.tracker = None
60
+
61
+ @staticmethod
62
+ def create_and_attach(index : int,
63
+ tet : Tetrahedron,
64
+ endpoints : Sequence[Endpoint]):
65
+ """
66
+ Creates a line segment and appends it to tet.geodesic_pieces.
67
+ """
68
+ g = GeodesicPiece(index, tet, endpoints)
69
+ tet.geodesic_pieces.append(g)
70
+ return g
71
+
72
+ @staticmethod
73
+ def create_face_to_vertex_and_attach(index : int,
74
+ tet : Tetrahedron,
75
+ point : Endpoint,
76
+ direction : int):
77
+ """
78
+ Creates a line segment between the given endpoint on
79
+ a face and the opposite vertex. If direction is +1,
80
+ the pieces goes from the endpoint to the vertex.
81
+ If direction is -1, it goes the opposite way.
82
+
83
+ Also appends the new geodesic piece to tet.geodesic_pieces.
84
+ """
85
+ if point.subsimplex not in simplex.TwoSubsimplices:
86
+ raise ValueError(
87
+ "Expected point to be on a face, but its "
88
+ "subsimplex is %d" % point.subsimplex)
89
+ v = simplex.comp(point.subsimplex)
90
+ return GeodesicPiece.create_and_attach(
91
+ index,
92
+ tet,
93
+ [ point,
94
+ Endpoint(tet.R13_vertices[v], v) ][::direction])
95
+
96
+ @staticmethod
97
+ def make_linked_list(pieces):
98
+ """
99
+ Given a list of pieces, populates next_ and prev of each
100
+ piece to turn it into a linked list.
101
+ """
102
+
103
+ n = len(pieces)
104
+ for i in range(n):
105
+ a = pieces[i]
106
+ b = pieces[(i+1) % n]
107
+ a.next_ = b
108
+ b.prev = a
109
+
110
+ def is_face_to_vertex(self) -> bool:
111
+ """
112
+ True if line segment starts on a face and goes to a vertex.
113
+ """
114
+
115
+ return (
116
+ (self.endpoints[0].subsimplex in simplex.TwoSubsimplices) and
117
+ (self.endpoints[1].subsimplex in simplex.ZeroSubsimplices))
118
+
119
+ @staticmethod
120
+ def replace_by(start_piece, end_piece, pieces) -> None:
121
+ """
122
+ Replaces the pieces between start_piece and end_piece (inclusive)
123
+ by the given (not linked) list of pieces in the linked list that
124
+ start_piece and end_piece participate in.
125
+ """
126
+ if start_piece.prev is end_piece:
127
+ items = pieces + [ pieces[0] ]
128
+ else:
129
+ items = [ start_piece.prev ] + pieces + [ end_piece.next_ ]
130
+ for i in range(len(items) - 1):
131
+ a = items[i]
132
+ b = items[i + 1]
133
+ a.next_ = b
134
+ b.prev = a
135
+ for piece in [ start_piece, end_piece ]:
136
+ if piece.tracker:
137
+ piece.tracker.set_geodesic_piece(pieces[0])
138
+ break
139
+
140
+ def __repr__(self):
141
+ return "GeodesicPiece(%d, %r, %r)" % (self.index, self.tet, self.endpoints)
142
+
143
+
144
+ class GeodesicPieceTracker:
145
+ def __init__(self, geodesic_piece):
146
+ self.set_geodesic_piece(geodesic_piece)
147
+
148
+ def set_geodesic_piece(self, geodesic_piece):
149
+ self.geodesic_piece = geodesic_piece
150
+ geodesic_piece.tracker = self
151
+
152
+
153
+ def compute_plane_intersection_param(
154
+ plane, # Unnormalised space-like vector/plane equation
155
+ point, # Unnormalised time-like vector
156
+ direction, # Unnormalised space-like vector
157
+ verified : bool):
158
+ """
159
+ Compute for which p the ray point + p * direction intersects the
160
+ given plane, that is r13_dot(plane, point + p * direction) = 0.
161
+
162
+ Note that when verified is true and intervals are given, only the
163
+ positive possible values will be returned. That is, if the direction
164
+ lies in the plane or is close to lying in the plane, the possible
165
+ values are of the form (-inf, a) and (b, inf). In this case, the function
166
+ returns the interval (b, inf) rather than (-inf, inf).
167
+ """
168
+
169
+ num = -r13_dot(plane, point)
170
+ denom = r13_dot(plane, direction)
171
+
172
+ # Avoid division by zero differently for numbers and intervals.
173
+ if verified:
174
+ # Note that this is not equivalent to denom == 0!
175
+ if not denom != 0:
176
+ # The case we described above.
177
+ # Unless the num interval contained zero,
178
+ # abs(num) is an interval [a, b] with a > 0.
179
+ # abs(denom) returns an interval of the form [0, x].
180
+ # The quotient [a, b] / [0, x] is of the form [t, inf) with t > 0.
181
+ return abs(num) / abs(denom)
182
+ else:
183
+ if denom == 0:
184
+ # Not verified: just make denom something very small rather than
185
+ # zero.
186
+ RF = denom.parent()
187
+ denom = RF(1e-200)
188
+
189
+ return num / denom
190
+
191
+
192
+ def trace_geodesic(geodesic : GeodesicStartPointInfo, verified : bool):
193
+ """
194
+ Traces line segment through the tetrahedra in the hyperboloid
195
+ model (though using time-like but not necessarily unit time-like vectors)
196
+ starting from the given start point in the given tetrahdra
197
+ to the given end point (assumed to be related to the start point
198
+ by a primitive Decktransformation).
199
+
200
+ The output is a (python) list of GeodesicPiece's (that is also
201
+ a cyclic linked list). The first piece is going from the interior of a
202
+ tetrahedron to a point on the face of the tetrahedron. The last piece
203
+ goes the other way to close the loop. All other pieces go from a
204
+ point on a face to a point on another face.
205
+
206
+ If geodesic.line is set, it also checks that the geodesic is not
207
+ too close to a core curve.
208
+ """
209
+
210
+ obj_name = "Geodesic %s" % geodesic.word
211
+
212
+ if geodesic.tet is None:
213
+ raise ValueError(
214
+ "Expected geodesic with tetrahedron to start tracing.")
215
+
216
+ # start_point and direction forming the ray we are tracing.
217
+ # Note that we apply the face-pairing matrices to the ray when we go
218
+ # from one tetrahedron to the next, but we do not move the
219
+ # start_point "forward" when we trace from one face to the next face.
220
+ start_point = geodesic.unnormalised_start_point
221
+ direction = (
222
+ geodesic.unnormalised_end_point - geodesic.unnormalised_start_point)
223
+ # Line object transformed similarly. Used to check whether geodesic
224
+ # is too close to a core curve.
225
+ line : Optional[R13LineWithMatrix] = geodesic.line
226
+
227
+ # Tetrahedron we start at.
228
+ tet : Tetrahedron = geodesic.tet
229
+ # Set face to simplex.T to indicate we start in the interior of the tet.
230
+ face : int = simplex.T
231
+
232
+ RF = start_point[0].parent()
233
+
234
+ if verified:
235
+ epsilon = 0
236
+ else:
237
+ epsilon = epsilons.compute_epsilon(RF)
238
+
239
+ # Result
240
+ pieces : List[GeodesicPiece] = [ ]
241
+
242
+ # Parametrizes ray. That is, we are start_point + param * direction.
243
+ param = RF(0)
244
+
245
+ # Trace
246
+ for i in range(constants.trace_max_steps):
247
+ # Record the face and param through which the ray is leaving
248
+ # the tet - that is which face the ray is hitting next.
249
+ hit_face : Optional[int] = None
250
+ hit_param = None
251
+ for candidate_face, plane in tet.R13_unnormalised_planes.items():
252
+ # Skip the face through which the ray just entered the tet
253
+ if candidate_face == face:
254
+ continue
255
+ # Compute the param at which the ray intersects this face
256
+ candidate_param = compute_plane_intersection_param(
257
+ plane, start_point, direction, verified)
258
+
259
+ # If the ray crossed this face before it crossed the
260
+ # entry face, ignore. Can happen when a dihedral angle is obtuse.
261
+ if candidate_param < param - epsilon:
262
+ continue
263
+ if not candidate_param > param + epsilon:
264
+ raise InsufficientPrecisionError(
265
+ "When tracing the geodesic, the intersection with the "
266
+ "next tetrahedron face was too close to the previous "
267
+ "to tell them apart. Increasing the precision will "
268
+ "probably avoid this problem.")
269
+
270
+ # This face is the (potential) exit face if the ray crossed
271
+ # it before it crossed the other faces (encountered so far).
272
+
273
+ if hit_param is None:
274
+ # No other face encountered so far
275
+ hit_param = candidate_param
276
+ hit_face = candidate_face
277
+ else:
278
+ # Check this face crossed before other faces
279
+ if candidate_param + epsilon < hit_param:
280
+ hit_param = candidate_param
281
+ hit_face = candidate_face
282
+ elif not candidate_param > hit_param + epsilon:
283
+ # If there is any ambiguity whether this face was
284
+ # crossed before the other face, fail!
285
+ # Most likely, this is because the ray is close to
286
+ # or crossing an edge of the triangulation.
287
+ raise exceptions.RayHittingOneSkeletonError()
288
+
289
+ if hit_param is None or hit_face is None:
290
+ raise InsufficientPrecisionError(
291
+ "Could not find the next intersection of the geodesic with a "
292
+ "tetrahedron face. Increasing the precision should solve this "
293
+ "problem.")
294
+
295
+ # Check geodesic does not intersect core curve - if line is given.
296
+ if line is not None:
297
+ check_away_from_core_curve(
298
+ line.r13_line, tet, hit_face, epsilon, obj_name)
299
+
300
+ # The crossing of the ray with the exit face is beyond the given
301
+ # end point. Thus, we are at the last piece.
302
+ if hit_param > RF(1) + epsilon:
303
+ # Force us to end at the given end point
304
+ hit_param = RF(1)
305
+ # The last piece ends in the interior of a tetrahedron.
306
+ T : int = simplex.T # Make mypy happy.
307
+ hit_face = T
308
+ elif not hit_param < RF(1) - epsilon:
309
+ raise InsufficientPrecisionError(
310
+ "Could not determine whether we finished tracing the geodesic. "
311
+ "Increasing the precision will most likely fix the "
312
+ "problem.")
313
+
314
+ pieces.append(
315
+ GeodesicPiece(
316
+ geodesic.index,
317
+ tet,
318
+ [Endpoint(start_point + param * direction, face),
319
+ Endpoint(start_point + hit_param * direction, hit_face)]))
320
+
321
+ if hit_face == simplex.T:
322
+ if tet is not geodesic.tet:
323
+ raise InsufficientPrecisionError(
324
+ "Tracing geodesic ended up in a different "
325
+ "tetrahedron than it started. "
326
+ "Increasing the precision will probably fix this problem.")
327
+
328
+ GeodesicPiece.make_linked_list(pieces)
329
+
330
+ return pieces
331
+
332
+ # Face-pairing matrix to transform data from this tetrahedron
333
+ # to next tetrahedron.
334
+ m = tet.O13_matrices[hit_face]
335
+
336
+ # Transform data
337
+ start_point = m * start_point
338
+ direction = m * direction
339
+ if line is not None:
340
+ line = line.transformed(m)
341
+ param = hit_param
342
+
343
+ # Determine what the entry face of the next tetrahedron is
344
+ face = tet.Gluing[hit_face].image(hit_face)
345
+
346
+ # The next tetrahedron - set last because we used it when
347
+ # computing face.
348
+ tet = tet.Neighbor[hit_face]
349
+
350
+ raise exceptions.UnfinishedTraceGeodesicError(
351
+ constants.trace_max_steps)
snappy/exceptions.py ADDED
@@ -0,0 +1,26 @@
1
+ class SnapPeaFatalError(Exception):
2
+ """
3
+ Exception raised by SnapPy when the SnapPea kernel encounters a fatal
4
+ error.
5
+ """
6
+
7
+
8
+ class InsufficientPrecisionError(Exception):
9
+ """
10
+ Exception raised when a computation fails and is likely to succeed if
11
+ higher precision is used.
12
+ """
13
+
14
+
15
+ class NonorientableManifoldError(ValueError):
16
+ """
17
+ Exception raised when a non-orientable manifold is given to a method
18
+ only supporting orientable manifolds.
19
+ """
20
+ def __init__(self, method_name, manifold):
21
+ self.method_name = method_name
22
+ self.manifold = manifold
23
+
24
+ def __str__(self):
25
+ return ('%s only supports orientable manifolds but %s is '
26
+ 'non-orientable.') % (self.method_name, self.manifold)
snappy/export_stl.py ADDED
@@ -0,0 +1,120 @@
1
+ import math
2
+
3
+
4
+ def facet_stl(triangle):
5
+ vertex1, vertex2, vertex3 = triangle
6
+ a = (vertex3[0]-vertex1[0], vertex3[1]-vertex1[1], vertex3[2]-vertex1[2])
7
+ b = (vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2])
8
+ normal = (a[1]*b[2] - a[2]*b[1], a[2]*b[0] - a[0]*b[2], a[0]*b[1] - a[1]*b[0])
9
+ return ''.join([
10
+ ' facet normal %f %f %f\n' % tuple(normal),
11
+ ' outer loop\n',
12
+ ' vertex %f %f %f\n' % tuple(vertex1),
13
+ ' vertex %f %f %f\n' % tuple(vertex2),
14
+ ' vertex %f %f %f\n' % tuple(vertex3),
15
+ ' endloop\n',
16
+ ' endfacet\n'
17
+ ])
18
+
19
+
20
+ def subdivide_triangles(triangles, num_subdivisions):
21
+ if num_subdivisions == 0:
22
+ for triangle in triangles:
23
+ yield triangle
24
+ elif num_subdivisions == 1:
25
+ # A small function for getting the midpoint of two points.
26
+ midpoint = lambda P, Q: ((P[0] + Q[0]) / 2, (P[1] + Q[1]) / 2, (P[2] + Q[2]) / 2)
27
+ for (x, y, z) in triangles:
28
+ yield (x, midpoint(x, y), midpoint(x, z))
29
+ yield (midpoint(y, x), y, midpoint(y, z))
30
+ yield (midpoint(z, x), midpoint(z, y), z)
31
+ yield (midpoint(x, y), midpoint(y, z), midpoint(z, x))
32
+ else:
33
+ for triangle in subdivide_triangles(subdivide_triangles(triangles, 1), num_subdivisions - 1):
34
+ yield triangle
35
+ return
36
+
37
+
38
+ def projection(triangle, cutoff_radius):
39
+ ''' Return the projection of a point in the Klein model to the Poincare model. '''
40
+ x, y, z = triangle
41
+ scale = min(1 / (1 + math.sqrt(max(0, 1 - (x**2 + y**2 + z**2)))), cutoff_radius)
42
+ return (scale*x, scale*y, scale*z)
43
+
44
+
45
+ def klein_stl(face_dicts):
46
+ ''' Yield triangles describing these faces. '''
47
+ for face in face_dicts:
48
+ vertices = face['vertices']
49
+ for i in range(len(vertices)-2):
50
+ yield (vertices[0], vertices[i+1], vertices[i+2])
51
+ return
52
+
53
+
54
+ def klein_cutout_stl(face_dicts, shrink_factor=0.9):
55
+ ''' Yield triangles describing these faces after removing a fraction of the interior.
56
+
57
+ The fraction removed is given by shrink_factor. '''
58
+ for face in face_dicts:
59
+ vertices = face['vertices']
60
+ center = [sum(vertex[i] for vertex in vertices) / len(vertices) for i in range(3)]
61
+ new_vertices = [[vertex[i] + (center[i] - vertex[i]) / 3 for i in range(3)] for vertex in vertices]
62
+ new_inside_points = [[point[i] * shrink_factor for i in range(3)] for point in new_vertices]
63
+ for i in range(len(new_vertices)):
64
+ yield (new_vertices[i], new_inside_points[(i+1) % len(new_vertices)], new_inside_points[i])
65
+ yield (new_vertices[i], new_vertices[(i+1) % len(new_vertices)], new_inside_points[(i+1) % len(new_vertices)])
66
+ yield (vertices[i], new_vertices[(i+1) % len(vertices)], new_vertices[i])
67
+ yield (vertices[i], vertices[(i+1) % len(vertices)], new_vertices[(i+1) % len(vertices)])
68
+ # We have to go in the opposite direction this time as the normal should point in towards O.
69
+ yield tuple(tuple(shrink_factor * coord for coord in point) for point in (vertices[i], new_vertices[i], new_vertices[(i+1) % len(vertices)]))
70
+ yield tuple(tuple(shrink_factor * coord for coord in point) for point in (vertices[i], new_vertices[(i+1) % len(vertices)], vertices[(i+1) % len(vertices)]))
71
+ return
72
+
73
+
74
+ def poincare_stl(face_dicts, num_subdivisions=5, cutoff_radius=0.9):
75
+ ''' Yield the output of klein_stl(face_dicts, ...) after applying projection to every vertex produced. '''
76
+ for triangle in subdivide_triangles(klein_stl(face_dicts), num_subdivisions):
77
+ yield (projection(triangle[0], cutoff_radius), projection(triangle[1], cutoff_radius), projection(triangle[2], cutoff_radius))
78
+ return
79
+
80
+
81
+ def poincare_cutout_stl(face_dicts, num_subdivisions=3, shrink_factor=0.9, cutoff_radius=0.9):
82
+ ''' Yield the output of klein_cutout_stl(face_dicts, ...) after applying projection to every vertex produced. '''
83
+ for triangle in subdivide_triangles(klein_cutout_stl(face_dicts, shrink_factor), num_subdivisions):
84
+ yield (projection(triangle[0], cutoff_radius), projection(triangle[1], cutoff_radius), projection(triangle[2], cutoff_radius))
85
+ return
86
+
87
+
88
+ def stl(face_dicts, model='klein', cutout=False, num_subdivisions=3, shrink_factor=0.9, cutoff_radius=0.9):
89
+ """
90
+ Yield the lines of an stl file corresponding to the solid given by face_dicts that is suitable for 3d printing.
91
+
92
+ Arguments can be given to modify the model produced:
93
+
94
+ - model='klein' -- (alt. 'poincare') the model of HH^3 to use.
95
+ - cutout=False -- remove the interior of each face
96
+ - shrink_factor=0.9 -- the fraction to cut out of each face
97
+ - cuttoff_radius=0.9 -- maximum rescaling for projection into Poincaré model
98
+ - num_subdivision=3 -- number of times to subdivide for the Poincaré model
99
+
100
+ For printing domains in the Poincaré model, cutoff_radius is
101
+ critical for avoiding infinitely thin cusps, which cannot be printed.
102
+ """
103
+ if shrink_factor < 0 or shrink_factor > 1:
104
+ raise ValueError('shrink_factor must be between 0 and 1.')
105
+
106
+ if model == 'klein' and cutout:
107
+ output = klein_cutout_stl(face_dicts, shrink_factor=shrink_factor)
108
+ elif model == 'klein' and not cutout:
109
+ output = klein_stl(face_dicts)
110
+ elif model == 'poincare' and cutout:
111
+ output = poincare_cutout_stl(face_dicts, num_subdivisions=num_subdivisions, shrink_factor=shrink_factor, cutoff_radius=cutoff_radius)
112
+ elif model == 'poincare' and not cutout:
113
+ output = poincare_stl(face_dicts, num_subdivisions=num_subdivisions, cutoff_radius=cutoff_radius)
114
+ else:
115
+ raise ValueError('Unknown model. Known models: \'klein\' and \'poincare\'.')
116
+
117
+ yield 'solid\n'
118
+ for triangle in output:
119
+ yield facet_stl(triangle)
120
+ yield 'endsolid\n'
@@ -0,0 +1,2 @@
1
+ from .main import exterior_to_link
2
+ from .exceptions import ExteriorToLinkError, GeneralPositionError