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,569 @@
1
+ from .mcomplex_base import *
2
+ from .kernel_structures import *
3
+ from . import t3mlite as t3m
4
+ from .t3mlite import ZeroSubsimplices, simplex
5
+ from .t3mlite import Corner, Perm4
6
+ from .t3mlite import V0, V1, V2, V3
7
+ from ..math_basics import prod
8
+ from functools import reduce
9
+
10
+ __all__ = ['FundamentalPolyhedronEngine']
11
+
12
+ from ..sage_helper import _within_sage
13
+ if _within_sage:
14
+ from ..sage_helper import matrix
15
+ else:
16
+ from .utilities import Matrix2x2 as matrix
17
+
18
+ _VerticesInFace = {
19
+ F: [V for V in simplex.ZeroSubsimplices if t3m.is_subset(V, F)]
20
+ for F in simplex.TwoSubsimplices }
21
+
22
+
23
+ class FundamentalPolyhedronEngine(McomplexEngine):
24
+ @staticmethod
25
+ def from_manifold_and_shapes(
26
+ manifold, shapes, normalize_matrices=False, match_kernel=True):
27
+ """
28
+ Given a SnapPy.Manifold and shapes (which can be numbers or intervals),
29
+ create a t3mlite.Mcomplex for the fundamental polyhedron that the
30
+ SnapPea kernel computed, assign each vertex of it to a point on the
31
+ boundary of upper half space H^3, and compute the matrices pairing the
32
+ faces of the fundamental polyhedron. The matrices will have determinant
33
+ one if normalize_matrices is True.
34
+
35
+ Some notes about the vertices: We use the one-point
36
+ compactification to represent the boundary of H^3, i.e., we
37
+ either assign a complex number (or interval) to a vertex or
38
+ Infinity (a sentinel in kernel_structures). If match_kernel is True,
39
+ the vertices are at the same positions than in the SnapPea kernel.
40
+ This has the disadvantage that the matrices computed that way no longer
41
+ have entries in the trace field. Use match_kernel is False for matrices
42
+ over the trace field (e.g., obtain the quaternion algebra).
43
+
44
+ Some notes about the matrices: If normalize_matrices is False, the
45
+ product of a matrix for a generator and its inverse is not necessarily
46
+ the identity, but a multiple of the identity.
47
+ Even if normalize_matrices is True, the product of matrices
48
+ corresponding to the letters in a relation might still yield minus the
49
+ identity (i.e., we do not lift to SL(2,C)).
50
+
51
+ >>> M = Manifold("m004")
52
+ >>> F = FundamentalPolyhedronEngine.from_manifold_and_shapes(
53
+ ... M, M.tetrahedra_shapes('rect'))
54
+
55
+ The above code adds the given shapes to each edge (here 01) of each
56
+ tetrahedron::
57
+
58
+ >>> from snappy.snap.t3mlite import simplex
59
+ >>> F.mcomplex.Tetrahedra[0].ShapeParameters[simplex.E01] # doctest: +NUMERIC6
60
+ 0.500000000000000 + 0.866025403784438*I
61
+
62
+ And annotates each face (here 1) of each tetrahedron with the
63
+ corresponding generator (here, the inverse of the second generator)
64
+ or 0 if the face is internal to the fundamental polyhedron::
65
+
66
+ >>> F.mcomplex.Tetrahedra[0].GeneratorsInfo[simplex.F1]
67
+ -2
68
+
69
+ This information is also available in a dict keyed by generator.
70
+ For each generator, it gives a list of the corresponding face pairing
71
+ data (there might be multiple face pairings corresponding to the same
72
+ generator). The face pairing data consists of a pair of t3mlite.Corner's
73
+ indicating the paired faces as well as the permutation to take one
74
+ face to the other.
75
+ Here, for example, the generator corresponds to exactly one face
76
+ pairing of face 2 of tet 1 to face 1 of tet0 such that face 2 is
77
+ taken to face 1 by the permutation (3, 0, 1, 2)::
78
+
79
+ >>> F.mcomplex.Generators[2]
80
+ [((<F2 of tet1>, <F1 of tet0>), (3, 0, 1, 2))]
81
+
82
+ The four vertices of tetrahedron 1::
83
+
84
+ >>> for v in simplex.ZeroSubsimplices: # doctest: +NUMERIC6
85
+ ... F.mcomplex.Tetrahedra[1].Class[v].IdealPoint
86
+ 'Infinity'
87
+ 0.000000000000000
88
+ 0.866025403784439 - 0.500000000000000*I
89
+ 0.866025403784439 + 0.500000000000000*I
90
+
91
+ The matrix for generator 1 (of the unsimplified presentation)::
92
+
93
+ >>> F.mcomplex.GeneratorMatrices[1] # doctest: +NUMERIC6 +ELLIPSIS
94
+ [ -0.577350269189626 - 1.00000000000000*I 0.500000000000000 + 0.288675134594813*I...]
95
+ [ -0.500000000000000 - 0.288675134594813*I 0.577350269189626 + 2.22044604925031e-16*I...]
96
+
97
+ Get the cusp that a vertex of the fundamental polyhedron corresponds
98
+ to::
99
+
100
+ >>> F.mcomplex.Tetrahedra[1].Class[simplex.V0].SubsimplexIndexInManifold
101
+ 0
102
+
103
+ """
104
+
105
+ m = t3m.Mcomplex(manifold)
106
+
107
+ f = FundamentalPolyhedronEngine(m)
108
+ t = TransferKernelStructuresEngine(m, manifold)
109
+
110
+ t.add_shapes(shapes)
111
+ t.choose_and_transfer_generators(
112
+ compute_corners=True, centroid_at_origin=False)
113
+
114
+ f.unglue()
115
+
116
+ if match_kernel:
117
+ init_verts = f.init_vertices_kernel()
118
+ else:
119
+ init_verts = f.init_vertices()
120
+
121
+ f.visit_tetrahedra_to_compute_vertices(
122
+ m.ChooseGenInitialTet, init_verts)
123
+ f.compute_matrices(normalize_matrices=normalize_matrices)
124
+
125
+ return f
126
+
127
+ def unglue(self):
128
+ """
129
+ It will unglue all face-pairings corresponding to generators.
130
+ What is left is a fundamental polyhedron.
131
+
132
+ It assumes that GeneratorsInfo has been set (by the
133
+ TranferKernelStructuresEngine).
134
+
135
+ Besides ungluing, it will add the field Generators to the Mcomplex
136
+ and SubsimplexIndexInManifold to each Vertex, Edge, Face, see
137
+ examples in from_manifold_and_shapes.
138
+ """
139
+
140
+ originalSubsimplexIndices = [
141
+ [ tet.Class[subsimplex].Index for subsimplex in range(1, 15) ]
142
+ for tet in self.mcomplex.Tetrahedra ]
143
+
144
+ self.mcomplex.Generators = {}
145
+
146
+ # Record for each generators what faces need to be unglued as well as
147
+ # the permutations.
148
+ for tet in self.mcomplex.Tetrahedra:
149
+ for face in simplex.TwoSubsimplices:
150
+ # Index of generator
151
+ g = tet.GeneratorsInfo[face]
152
+ # g == 0 does not correspond to a generator
153
+ if g != 0:
154
+ # Add to dictionary value
155
+ l = self.mcomplex.Generators.setdefault(g, [])
156
+ l.append(
157
+ ( (
158
+ # Inbound face
159
+ Corner(tet, face),
160
+ # Outbound face
161
+ Corner(tet.Neighbor[face], tet.Gluing[face].image(face))),
162
+ # Permutation
163
+ tet.Gluing[face]))
164
+
165
+ # Unglue
166
+ for g, pairings in self.mcomplex.Generators.items():
167
+ # Unglue only once, ignore inverse
168
+ if g > 0:
169
+ for corners, perm in pairings:
170
+ for corner in corners:
171
+ corner.Tetrahedron.attach(corner.Subsimplex, None, None)
172
+
173
+ # Rebuild the vertex classes, edge classes, ...
174
+ self.mcomplex.rebuild()
175
+
176
+ # Use the saved data to populate SubsimplexIndexInManifold
177
+ for tet, o in zip(self.mcomplex.Tetrahedra, originalSubsimplexIndices):
178
+ for subsimplex, index in enumerate(o):
179
+ tet.Class[subsimplex + 1].SubsimplexIndexInManifold = index
180
+
181
+ def visit_tetrahedra_to_compute_vertices(self, init_tet, init_vertices):
182
+ """
183
+ Computes the positions of the vertices of fundamental polyhedron in
184
+ the boundary of H^3, assuming the Mcomplex has been unglued and
185
+ ShapeParameters were assigned to the tetrahedra.
186
+
187
+ It starts by assigning the vertices of the given init_tet using
188
+ init_vertices.
189
+ """
190
+
191
+ for vertex in self.mcomplex.Vertices:
192
+ vertex.IdealPoint = None
193
+ for tet in self.mcomplex.Tetrahedra:
194
+ tet.visited = False
195
+
196
+ self.mcomplex.InitialTet = init_tet
197
+
198
+ for v, idealPoint in init_vertices.items():
199
+ init_tet.Class[v].IdealPoint = idealPoint
200
+ init_tet.visited = True
201
+
202
+ queue = [ init_tet ]
203
+ while len(queue) > 0:
204
+ tet = queue.pop(0)
205
+ for F in simplex.TwoSubsimplices:
206
+ if bool(tet.Neighbor[F]) != bool(tet.GeneratorsInfo[F] == 0):
207
+ raise Exception(
208
+ "Improper fundamental domain, "
209
+ "probably a bug in unglue code")
210
+
211
+ S = tet.Neighbor[F]
212
+ if S and not S.visited:
213
+ perm = tet.Gluing[F]
214
+ for V in _VerticesInFace[F]:
215
+ vertex_class = S.Class[perm.image(V)]
216
+ if vertex_class.IdealPoint is None:
217
+ vertex_class.IdealPoint = tet.Class[V].IdealPoint
218
+ _compute_fourth_corner(S)
219
+ S.visited = True
220
+ queue.append(S)
221
+
222
+ def init_vertices(self):
223
+ """
224
+ Computes vertices for the initial tetrahedron such that vertex 0, 1
225
+ and 2 are at Infinity, 0 and z.
226
+ """
227
+
228
+ tet = self.mcomplex.ChooseGenInitialTet
229
+
230
+ z = tet.ShapeParameters[simplex.E01]
231
+ CF = z.parent()
232
+
233
+ return { simplex.V0 : Infinity,
234
+ simplex.V1 : CF(0),
235
+ simplex.V2 : CF(1),
236
+ simplex.V3 : z }
237
+
238
+ def init_vertices_kernel(self):
239
+ """
240
+ Computes vertices for the initial tetrahedron matching the choices
241
+ made by the SnapPea kernel.
242
+ """
243
+
244
+ # Note that initial_tetrahedron in choose_generators.c picks
245
+ # the initial tetrahedron and best edge in a purely combinatorial way -
246
+ # and doesn't use shapes to assign 0 and Infinity to the ends of
247
+ # the edges.
248
+ #
249
+ # Hence, the code below can't be tricked into picking a different
250
+ # permutation by setting the unverified shapes stored in the
251
+ # kernel Triangulation (to some non-sensical values). It would fail
252
+ # instead.
253
+
254
+ tet = self.mcomplex.ChooseGenInitialTet
255
+
256
+ candidates = []
257
+
258
+ for perm in Perm4.A4():
259
+ z = tet.ShapeParameters[perm.image(simplex.E01)]
260
+ # Complex field
261
+ CF = z.parent()
262
+ sqrt_z = z.sqrt()
263
+ sqrt_z_inv = CF(1) / sqrt_z
264
+
265
+ candidate = {
266
+ perm.image(simplex.V0) : Infinity,
267
+ perm.image(simplex.V1) : CF(0),
268
+ perm.image(simplex.V2) : sqrt_z_inv,
269
+ perm.image(simplex.V3) : sqrt_z
270
+ }
271
+
272
+ if _are_vertices_close_to_kernel(
273
+ candidate, tet.SnapPeaIdealVertices):
274
+ candidates.append(candidate)
275
+
276
+ if len(candidates) == 1:
277
+ return candidates[0]
278
+
279
+ raise Exception(
280
+ "Could not match vertices to vertices from SnapPea kernel")
281
+
282
+ def compute_matrices(self, normalize_matrices=False):
283
+ """
284
+ Assuming positions were assigned to the vertices, adds
285
+ GeneratorMatrices to the Mcomplex which assigns a matrix to each
286
+ generator.
287
+
288
+ Compute generator matrices:
289
+
290
+ >>> M = Manifold("s776")
291
+ >>> F = FundamentalPolyhedronEngine.from_manifold_and_shapes(
292
+ ... M, M.tetrahedra_shapes('rect'), normalize_matrices = True)
293
+ >>> generatorMatrices = F.mcomplex.GeneratorMatrices
294
+
295
+ Given a letter such as 'a' or 'A', return matrix for corresponding
296
+ generator:
297
+
298
+ >>> def letterToMatrix(l, generatorMatrices):
299
+ ... g = ord(l.lower()) - ord('a') + 1
300
+ ... if l.isupper():
301
+ ... g = -g
302
+ ... return generatorMatrices[g]
303
+
304
+ Check that relations are fulfilled up to sign:
305
+
306
+ >>> def p(L): return reduce(lambda x, y: x * y, L)
307
+ >>> def close_to_identity(m, epsilon = 1e-12):
308
+ ... return abs(m[(0,0)] - 1) < epsilon and abs(m[(1,1)] - 1) < epsilon and abs(m[(0,1)]) < epsilon and abs(m[(1,0)]) < epsilon
309
+ >>> def close_to_pm_identity(m, epsilon = 1e-12):
310
+ ... return close_to_identity(m, epsilon) or close_to_identity(-m, epsilon)
311
+ >>> G = M.fundamental_group(simplify_presentation = False)
312
+ >>> for rel in G.relators():
313
+ ... close_to_pm_identity(p([letterToMatrix(l, generatorMatrices) for l in rel]))
314
+ True
315
+ True
316
+ True
317
+ True
318
+
319
+ """
320
+
321
+ z = self.mcomplex.Tetrahedra[0].ShapeParameters[simplex.E01]
322
+ CF = z.parent()
323
+
324
+ self.mcomplex.GeneratorMatrices = { 0 : matrix([[CF(1), CF(0)],
325
+ [CF(0), CF(1)]]) }
326
+
327
+ for g, pairings in self.mcomplex.Generators.items():
328
+ # We compute the matrix for the generator and its inverse at the
329
+ # same time, so ignore inverses.
330
+ if g > 0:
331
+ m = _compute_pairing_matrix(pairings[0])
332
+ if normalize_matrices:
333
+ m = m / m.det().sqrt()
334
+ self.mcomplex.GeneratorMatrices[ g] = m
335
+ self.mcomplex.GeneratorMatrices[-g] = _adjoint2(m)
336
+
337
+ def matrices_for_presentation(self, G, match_kernel=False):
338
+ """
339
+ Given the result of M.fundamental_group(...) where M is the
340
+ corresponding SnapPy.Manifold, return the matrices for that
341
+ presentation of the fundamental polyhedron.
342
+
343
+ The GeneratorMatrices computed here are for the face-pairing
344
+ presentation with respect to the fundamental polyhedron.
345
+ That presentation can be simplified by M.fundamental_group(...)
346
+ and this function will compute the matrices for the simplified
347
+ presentation from the GeneratorMatrices.
348
+
349
+ If match_kernel is True, it will flip the signs of some of
350
+ the matrices to match the ones in the given G (which were determined
351
+ by the SnapPea kernel).
352
+
353
+ This makes the result stable when changing precision (when normalizing
354
+ matrices with determinant -1, sqrt(-1) might jump between i and -i when
355
+ increasing precision).
356
+ """
357
+
358
+ num_generators = len(self.mcomplex.GeneratorMatrices) // 2
359
+ matrices = [ self.mcomplex.GeneratorMatrices[g + 1]
360
+ for g in range(num_generators) ]
361
+
362
+ result = _perform_word_moves(matrices, G)
363
+ if match_kernel:
364
+ return _negate_matrices_to_match_kernel(result, G)
365
+ else:
366
+ return result
367
+
368
+
369
+ def _diff_to_kernel(value, snappeaValue):
370
+ """
371
+ The SnapPea kernel will always give us a number, but we might deal
372
+ with a number or an interval.
373
+
374
+ Cast to our numeric type so that we can compare.
375
+ """
376
+ CF = value.parent()
377
+ return value - CF(snappeaValue)
378
+
379
+
380
+ def _is_number_close_to_kernel(value, snappeaValue, error=10**-6):
381
+ CF = value.parent()
382
+ return abs(_diff_to_kernel(value, snappeaValue)) < CF(error)
383
+
384
+
385
+ def _is_vertex_close_to_kernel(vertex, snappeaVertex):
386
+ if vertex == Infinity or snappeaVertex == Infinity:
387
+ return vertex == snappeaVertex
388
+ return _is_number_close_to_kernel(vertex, snappeaVertex)
389
+
390
+
391
+ def _are_vertices_close_to_kernel(verts, snappeaVerts):
392
+ for key, vert in verts.items():
393
+ snappeaVert = snappeaVerts[key]
394
+ if not _is_vertex_close_to_kernel(vert, snappeaVert):
395
+ return False
396
+ return True
397
+
398
+
399
+ _RemainingFace = { (V0, V1): V3, (V0, V2): V1, (V0, V3): V2,
400
+ (V1, V0): V2, (V1, V2): V3, (V1, V3): V0,
401
+ (V2, V0): V3, (V2, V1): V0, (V2, V3): V1,
402
+ (V3, V0): V1, (V3, V1): V2, (V3, V2): V0}
403
+
404
+
405
+ def _compute_fourth_corner(T):
406
+ v = 4 * [ None ]
407
+ missing_corners = [V for V in ZeroSubsimplices if T.Class[V].IdealPoint is None]
408
+ if not missing_corners:
409
+ return
410
+ missing_corner = missing_corners[0]
411
+
412
+ v[3] = missing_corner
413
+ v[0] = ( [V for V in ZeroSubsimplices if T.Class[V].IdealPoint == Infinity] +
414
+ [V for V in ZeroSubsimplices if V != missing_corner])[0]
415
+ v[1], v[2] = _RemainingFace[ (v[3], v[0]) ], _RemainingFace[ (v[0], v[3]) ]
416
+ z = [T.Class[V].IdealPoint for V in v]
417
+
418
+ cross_ratio = T.ShapeParameters[ v[0] | v[1] ]
419
+ if z[0] == Infinity:
420
+ z[3] = z[1] + cross_ratio * (z[2] - z[1])
421
+ else:
422
+ diff20 = z[2] - z[0]
423
+ diff21 = z[2] - z[1]
424
+ numerator = (z[1]*diff20 - cross_ratio*(z[0]*diff21))
425
+ denominator = (diff20 - cross_ratio*diff21)
426
+ if abs(denominator) == 0 and abs(numerator) > 0:
427
+ z[3] = Infinity
428
+ else:
429
+ z[3] = numerator/denominator
430
+
431
+ T.Class[missing_corner].IdealPoint = z[3]
432
+
433
+
434
+ def _normalize_points(a, b):
435
+ """
436
+ Reduce the number of cases involving infinity that we need to
437
+ consider.
438
+
439
+ In particular (assuming no degeneracy), a[0], a[1] and b[0] are
440
+ never infinite.
441
+ """
442
+ a_infinities = [i for i, z in enumerate(a) if z == Infinity]
443
+ if len(a_infinities) > 0:
444
+ i = a_infinities[0]
445
+ a, b = a[i : ] + a[ : i], b[i : ] + b[ : i]
446
+
447
+ b_infinities = [i for i, z in enumerate(b) if z == Infinity]
448
+ if len(b_infinities) > 0:
449
+ i = b_infinities[0]
450
+ if a[0] != Infinity:
451
+ a, b = a[i : ] + a[ : i], b[i : ] + b[ : i]
452
+ else:
453
+ if i == 2:
454
+ a, b = [a[0], a[2], a[1]], [b[0], b[2], b[1]]
455
+
456
+ a.reverse(), b.reverse()
457
+ return a, b
458
+
459
+
460
+ def _matrix_taking_triple_to_triple(a, b):
461
+ """
462
+ To quote Jeff:
463
+
464
+ The formula for the Moebius transformation taking the a[] to the b[]
465
+ is simple enough:
466
+
467
+ f(z) = [ (b1*k - b0) * z + (b0*a1 - b1*a0*k)] /
468
+ [ (k - 1) * z + (a1 - k*a0) ]
469
+
470
+ where
471
+
472
+ k = [(b2-b0)/(b2-b1)] * [(a2-a1)/(a2-a0)]
473
+ """
474
+ # Let's make it so that a[0], a[1], and b[0] are never infinite
475
+
476
+ (a0, a1, a2), (b0, b1, b2) = _normalize_points(a,b)
477
+
478
+ ka = (a2 - a1)/(a2 - a0) if a2 != Infinity else 1
479
+
480
+ if b1 == Infinity:
481
+ kb, b1kb = 0, -(b2 - b0)
482
+ else:
483
+ kb = (b2 - b0)/(b2 - b1) if b2 != Infinity else 1
484
+ b1kb = b1 * kb
485
+
486
+ k = kb * ka
487
+
488
+ return matrix([(b1kb * ka - b0, b0 * a1 - a0 * b1kb * ka),
489
+ (k - 1, a1 - k * a0)])
490
+
491
+
492
+ def _adjoint2(m):
493
+ """
494
+ Sage matrix.adjoint() produces an unnecessary large interval for
495
+ ComplexIntervalField entries.
496
+ """
497
+ return matrix([[m[1, 1], -m[0, 1]], [-m[1, 0], m[0, 0]]])
498
+
499
+
500
+ def _perform_word_moves(matrices, G):
501
+ mats = [ None ] + matrices
502
+ moves = G._word_moves()
503
+ while moves:
504
+ a = moves.pop(0)
505
+ if a >= len(mats): # new generator added
506
+ n = moves.index(a) # end symbol location
507
+ word, moves = moves[:n], moves[n+1:]
508
+ mats.append( prod( [mats[g] if g > 0 else _adjoint2(mats[-g]) for g in word] ) )
509
+ else:
510
+ b = moves.pop(0)
511
+ if a == b: # generator removed
512
+ mats[a] = mats[-1]
513
+ mats = mats[:-1]
514
+ elif a == -b: # invert generator
515
+ mats[a] = _adjoint2(mats[a])
516
+ else: # handle slide
517
+ A, B = mats[abs(a)], mats[abs(b)]
518
+ if a*b < 0:
519
+ B = _adjoint2(B)
520
+ mats[abs(a)] = A*B if a > 0 else B*A
521
+
522
+ return mats[1 : G.num_generators() + 1]
523
+
524
+
525
+ def _matrix_L1_distance_to_kernel(m, snappeaM):
526
+ return sum([ abs(_diff_to_kernel(m[i,j], snappeaM[i,j]))
527
+ for i in range(2)
528
+ for j in range(2)])
529
+
530
+
531
+ def _negate_matrix_to_match_kernel(m, snappeaM):
532
+ diff_plus = _matrix_L1_distance_to_kernel(m, snappeaM)
533
+
534
+ diff_minus = _matrix_L1_distance_to_kernel(m, -snappeaM)
535
+
536
+ # Note that from an interval perspective, (not diff_plus < diff_minus)
537
+ # is not implying that diff_plus >= diff_minus and that "-m" is the
538
+ # "correct" answer.
539
+ # But both +m and -m are valid, we just try to heuristically match the
540
+ # choice that the SnapPea kernel made.
541
+
542
+ if diff_plus < diff_minus:
543
+ return m
544
+ else:
545
+ return -m
546
+
547
+
548
+ def _negate_matrices_to_match_kernel(matrices, G):
549
+ """
550
+ Normalize things so the signs of the matices match SnapPy's default
551
+ This makes the representations stay close as one increases the precision.
552
+ """
553
+
554
+ return [ _negate_matrix_to_match_kernel(m, matrix(G.SL2C(g)))
555
+ for m, g in zip(matrices, G.generators()) ]
556
+
557
+
558
+ def _compute_pairing_matrix(pairing):
559
+ (inCorner, outCorner), perm = pairing
560
+
561
+ inTriple = []
562
+ outTriple = []
563
+
564
+ for v in simplex.ZeroSubsimplices:
565
+ if simplex.is_subset(v, inCorner.Subsimplex):
566
+ inTriple.append(inCorner.Tetrahedron.Class[v].IdealPoint)
567
+ outTriple.append(outCorner.Tetrahedron.Class[perm.image(v)].IdealPoint)
568
+
569
+ return _matrix_taking_triple_to_triple(outTriple, inTriple)
@@ -0,0 +1,39 @@
1
+ """
2
+ This has been moved to FundamentalPolyhedronEngine.
3
+ Only the testing code was left here.
4
+
5
+ Replicating how SnapPea finds the matrices of the geometric generators,
6
+ so that this can replicated using e.g. extended precision.
7
+ """
8
+
9
+ from .fundamental_polyhedron import *
10
+ from . import t3mlite as t3m
11
+ from .t3mlite import ZeroSubsimplices
12
+
13
+
14
+ # Testing code
15
+
16
+ def matrix_norm(A):
17
+ return max(map(abs, A.list()))
18
+
19
+
20
+ def check_example(M, shapes=None):
21
+ e = fromManifoldAndShapes(M, shapes)
22
+
23
+ MM = e.mcomplex
24
+ max_error = 0
25
+ for T in MM:
26
+ for V in ZeroSubsimplices:
27
+ vs, vn = T.SnapPeaIdealVertices[V], T.IdealVertices[V]
28
+ if vn != vs:
29
+ max_error = max(max_error, abs(vs-vn))
30
+
31
+ G = M.fundamental_group(False, False, False)
32
+ mats = compute_matrices(MM)
33
+ for i in range(1, G.num_generators() + 1):
34
+ A = mats[i]
35
+ B = G.SL2C(G.generators()[i - 1])
36
+ error = min(matrix_norm(A - B), matrix_norm(A + B))
37
+ max_error = max(max_error, error)
38
+
39
+ return max_error
@@ -0,0 +1,81 @@
1
+ """
2
+ Creating a group representation from shape *intervals*,
3
+ specifically elements of Sage's ComplexIntervalField. Also contains
4
+ some utility functions for dealing with such representations.
5
+ """
6
+
7
+ from .polished_reps import ManifoldGroup
8
+ from .fundamental_polyhedron import *
9
+
10
+ # Most of the below small functions are not used in SnapPy proper, but
11
+ # published code (https://doi.org/10.7910/DVN/LCYXPO) depends on them,
12
+ # so they should not be removed.
13
+
14
+
15
+ def matrix_difference_norm(A, B):
16
+ B = B.change_ring(A.base_ring())
17
+ return max([abs(a - b) for a,b in zip(A.list(), B.list())])
18
+
19
+
20
+ def diameter(A):
21
+ return max(x.diameter() for x in A.list())
22
+
23
+
24
+ def contains_zero(A):
25
+ return all(x.contains_zero() for x in A.list())
26
+
27
+
28
+ def contains_one(A):
29
+ return contains_zero(A - 1)
30
+
31
+
32
+ def contains_plus_minus_one(A):
33
+ return contains_one(A) or contains_one(-A)
34
+
35
+
36
+ def could_be_equal_numbers(x, y):
37
+ return (x - y).contains_zero()
38
+
39
+
40
+ def could_be_equal(A, B):
41
+ return contains_zero(A - B)
42
+
43
+
44
+ def holonomy_from_shape_intervals(manifold, shape_intervals,
45
+ fundamental_group_args=[], lift_to_SL2=True):
46
+ """
47
+ Returns the representation
48
+
49
+ rho: pi_1(manifold) -> (P)SL(2, ComplexIntervalField)
50
+
51
+ determined by the given shape_intervals. If shape_intervals
52
+ contains an exact solution z0 to the gluing equations with
53
+ corresponding holonomy representation rho0, then for all g the
54
+ ComplexIntervalField matrix rho(g) contains rho0(g)::
55
+
56
+ sage: M = Manifold('m004(1,2)')
57
+ sage: success, shapes = M.verify_hyperbolicity(bits_prec=53)
58
+ sage: success
59
+ True
60
+ sage: rho = holonomy_from_shape_intervals(M, shapes)
61
+ sage: (rho('a').det() - 1).contains_zero()
62
+ True
63
+
64
+ Of course, for long words the matrix entries will smear out::
65
+
66
+ sage: diameter(rho('a')).log10() # doctest: +NUMERIC0
67
+ -10.9576580520835
68
+ sage: diameter(rho(10*'abAB')).log10() # doctest: +NUMERIC0
69
+ -8.39987365046327
70
+ """
71
+
72
+ M = manifold
73
+ G = M.fundamental_group(*fundamental_group_args)
74
+ f = FundamentalPolyhedronEngine.from_manifold_and_shapes(
75
+ M, shape_intervals, normalize_matrices=True)
76
+ mats = f.matrices_for_presentation(G, match_kernel=True)
77
+ PG = ManifoldGroup(G.generators(), G.relators(),
78
+ G.peripheral_curves(), mats)
79
+ if lift_to_SL2:
80
+ PG.lift_to_SL2C()
81
+ return PG