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,519 @@
1
+ # t3m - software for studying triangulated 3-manifolds
2
+ # Copyright (C) 2002 Marc Culler, Nathan Dunfield and others
3
+ #
4
+ # This program is distributed under the terms of the
5
+ # GNU General Public License, version 2 or later, as published by
6
+ # the Free Software Foundation. See the file GPL.txt for details.
7
+
8
+ from .simplex import *
9
+ from .tetrahedron import Tetrahedron
10
+ # from numpy import dot, not_equal, zeros, compress
11
+ # from numpy.linalg import pinv as generalized_inverse
12
+ import sys
13
+ from .linalg import Vector, Matrix
14
+
15
+ # NOTE (1) The functions in this module only make sense for closed
16
+ # manifolds. It will need to be rewritten to accommodate spun normal
17
+ # surfaces. In particular, build_weights tries to compute the
18
+ # triangle weights from the quad weights. We could set them to
19
+ # infinity, I suppose, near a torus cusp.
20
+ #
21
+ # For spun surfaces we will want to compute the boundary slope. We
22
+ # should perhaps decide what the degenerate form of the boundary slope
23
+ # is for a spherical vertex link. (0/0?) For a higher genus vertex
24
+ # link the object that corresponds to a boundary slope is an element
25
+ # of H^1 of the link. This is the class represented by the shift
26
+ # cocycle. The boundary class generates the kernel of the shift
27
+ # class, in the genus 1 case. Now that I mention it, I think that
28
+ # the shift class is the natural object to compute in all cases.
29
+ #
30
+ # NOTE (2) Many of the functions in this module also assume that the
31
+ # triangulation has only one vertex. If there are more vertices then one
32
+ # has to be more careful about saying things like "bounds a thick subcomplex"
33
+ # or "bounds a thin subcomplex" - it might bound both. And an edge linkig
34
+ # surface might not be a torus. It might be good to distinguish surfaces
35
+ # that bound regular neighborhoods of graphs from other surfaces that bound
36
+ # thin subcomplexes.
37
+ #
38
+ # NOTE (3) Our plan is to create (at least) three subclasses of the
39
+ # Surface class: Closed_Surface, Spun_Surface, Bounded_Surface.
40
+
41
+ # Incidence dictionaries for quads, triangles and octagons
42
+
43
+ MeetsQuad = {E01:Vector((1,1,0)), E02:Vector((1,0,1)), E21:Vector((0,1,1)),
44
+ E32:Vector((1,1,0)), E31:Vector((1,0,1)), E03:Vector((0,1,1))}
45
+
46
+ MeetsTri = {E01:Vector((1,1,0,0)), E02:Vector((1,0,1,0)), E21:Vector((0,1,1,0)),
47
+ E32:Vector((0,0,1,1)), E31:Vector((0,1,0,1)), E03:Vector((1,0,0,1))}
48
+
49
+ MeetsOct = {E01:Vector((1,1,2)), E02:Vector((1,2,1)), E21:Vector((2,1,1)),
50
+ E32:Vector((1,1,2)), E31:Vector((1,2,1)), E03:Vector((2,1,1))}
51
+
52
+ DisjointQuad = {E01:2, E02:1, E21:0,
53
+ E32:2, E31:1, E03:0}
54
+
55
+ QuadWeights = (Vector((1,0,0)), Vector((0,1,0)), Vector((0,0,1)) )
56
+
57
+ WeightVector = Vector([1,1,1])
58
+
59
+ TypeVector = Vector([0,1,2])
60
+
61
+ # Used for converting normal surface into tetrahedron edge-shift data.
62
+ # QuadShift[k] is the shifts induced by quad Qk3 along edges (E03, E13, E23).
63
+ # Note that this follows the convention that the order of the edges
64
+ # is the same as the order of the quads, and _not_ in order E01, E02, E03.
65
+
66
+ QuadShifts = ((0, 1, -1), (-1, 0, 1), (1, -1, 0))
67
+
68
+ # The format for a coefficient vector is [T0, T1, T2, T3, Q0, Q1, Q2, ...}
69
+
70
+ NonInteger = 'Error'
71
+
72
+ # NOTE: The convention is that the order of the quads is (Q03, Q13, Q23)
73
+
74
+
75
+ def gcd(x, y):
76
+ if x == 0:
77
+ if y == 0:
78
+ raise ValueError("gcd(0,0) is undefined.")
79
+ else:
80
+ return abs(y)
81
+ x = abs(x)
82
+ y = abs(y)
83
+ while y != 0:
84
+ r = x % y
85
+ x = y
86
+ y = r
87
+ return x
88
+
89
+
90
+ def reduce_slope( slope ):
91
+ a, b = slope
92
+ if a == b == 0:
93
+ return slope, 0
94
+ g = gcd(a,b)
95
+ a, b = a/g, b/g
96
+ return (a,b), g
97
+
98
+
99
+ class Surface:
100
+
101
+ def __init__(self, manifold, quadvector):
102
+ self.Size = len(manifold)
103
+ Q = Matrix(self.Size, 3, [min(x, 1) for x in quadvector])
104
+ A = Matrix(self.Size, 3, quadvector)
105
+ self.Quadvector = quadvector
106
+ self.Coefficients = A.dot(WeightVector)
107
+ self.Quadtypes = Q.dot(TypeVector)
108
+
109
+ def type(self):
110
+ if min(self.Coefficients) < 0:
111
+ return "almost-normal"
112
+ else:
113
+ return "normal"
114
+
115
+ # computes and records hexagon shift of surface along
116
+ # the edges of each tet. Order convention of edges in
117
+ # each tet is (E03, E13, E23) the same as the standard
118
+ # order of the quads, and _not_ (E01, E02, E03).
119
+
120
+ def add_shifts(self):
121
+ shifts = []
122
+ for i in range(self.Size):
123
+ shifts += [ self.Coefficients[i] * w for w in QuadShifts[self.Quadtypes[i]]]
124
+ self.Shifts = shifts
125
+
126
+ def find_edge_linking_annuli(self, manifold):
127
+ """
128
+ Surface.find_edge_linking_annuli(mcomplex) returns a list of the
129
+ indices of those edges for which the Surface contains an edge-linking
130
+ annulus (and hence has an obvious compression).
131
+ """
132
+ if self not in manifold.NormalSurfaces:
133
+ raise ValueError('That manifold does not contain the Surface!')
134
+ linked_edges = []
135
+ for edge in manifold.Edges:
136
+ is_linked = 1
137
+ for corner in edge.Corners:
138
+ quad = DisjointQuad[corner.Subsimplex]
139
+ if ( self.Coefficients[corner.Tetrahedron.Index] == 0 or
140
+ self.Quadtypes[corner.Tetrahedron.Index] != quad ):
141
+ is_linked = 0
142
+ break
143
+ if is_linked:
144
+ linked_edges.append(edge.Index)
145
+ return linked_edges
146
+
147
+ def info(self, out=sys.stdout):
148
+ if self.type() == "normal":
149
+ out.write("Normal surface\n")
150
+ for i in range(self.Size):
151
+ quad_weight = self.Coefficients[i]
152
+ if quad_weight == -1:
153
+ weight = " Quad Type Q%d3, weight: octagon" % self.Quadtypes[i]
154
+ elif quad_weight > 0:
155
+ weight = " Quad Type Q%d3, weight %d" % (self.Quadtypes[i], quad_weight)
156
+ else:
157
+ weight = "No quads"
158
+ out.write(weight + "\n")
159
+
160
+
161
+ class ClosedSurface(Surface):
162
+
163
+ def __init__(self, manifold, quadvector):
164
+ Surface.__init__(self, manifold, quadvector)
165
+ self.build_weights(manifold)
166
+ self.build_bounding_info(manifold)
167
+ self.find_euler_characteristic(manifold)
168
+
169
+ def build_weights(self, manifold):
170
+ """
171
+ Use self.QuadWeights self.QuadTypes vector to construct
172
+ self.Weights and self.EdgeWeights. The vector self.Weights has size
173
+ 7T and gives the weights of triangles and quads in each 3-simplex.
174
+ In each bank of 7 weights, the first 4 are triangle weights and the
175
+ last 3 are quad weights.
176
+ """
177
+
178
+ # Here is how it works. We use the system of normal surface
179
+ # equations defined as follows. For each edge e, and each face f
180
+ # containing e, let t1 and t2 be the two tetrahedra containing f.
181
+ # The weight of e can be expressed as the sum of two quad weights
182
+ # and two triangle weights in each of t1 and t2. Set these
183
+ # expressions equal to get one equation in the system. The
184
+ # resulting system can be written as Aw = Bq where w is the
185
+ # (unknown) vector of triangle weights and q is the (known) vector
186
+ # of quad weights. Note that this system does not have positive
187
+ # coefficients, and the matrix A is singular with null space
188
+ # spanned by the triangle weights of the vertex links, which of
189
+ # course have all quad weights equal to 0. We can make the system
190
+ # non-singular by restricting to the orthogonal complement of the
191
+ # null space, i.e. by adding an equation for each vertex v which
192
+ # sets the sum of the coefficients of triangles in the support of
193
+ # Link(v) equal to 0. The resulting system A'w = b is now
194
+ # non-singular, but not square. We solve it by using the
195
+ # "generalized inverse". We then adjust the solution vector by
196
+ # adding the unique linear combination of vertex links which
197
+ # produces a non-negative vector w' with a coefficient of 0 on
198
+ # some triangle in each vertex links. Now we can construct
199
+ # self.Weights by interleaving the vector w' and the vector q of
200
+ # quadweights. The vector self.EdgeWeights is constructed by
201
+ # simply multiplying the incidence matrix for edges meeting quads
202
+ # and triangles times the vector self.Weights.
203
+
204
+ self.Weights = Vector( 7*self.Size )
205
+ eqns = []
206
+ constants = []
207
+ edge_matrix = []
208
+ for edge in manifold.Edges:
209
+
210
+ # Build the row of the incidence matrix that records which quads
211
+ # and triangles meet this edge. We can use any tetrahedron that
212
+ # meets this edge to compute the row.
213
+
214
+ edge_row = Vector( 7*len(manifold) )
215
+ corner = edge.Corners[0]
216
+ j = corner.Tetrahedron.Index
217
+ edge_row[7*j:7*j+4] = MeetsTri[corner.Subsimplex]
218
+ if not self.Coefficients[j] == -1:
219
+ edge_row[7*j+4:7*j+7] = MeetsQuad[corner.Subsimplex]
220
+ else:
221
+ edge_row[7*j+4:7*j+7] = MeetsOct[corner.Subsimplex]
222
+ edge_matrix.append(edge_row)
223
+
224
+ # Build a row of A and a coefficient of the right hand side for
225
+ # each pair of adjacent 3-simplices that meet this edge.
226
+ for i in range(len(edge.Corners) - 1):
227
+ j = edge.Corners[i].Tetrahedron.Index
228
+ k = edge.Corners[i+1].Tetrahedron.Index
229
+ row = Vector(4*len(manifold))
230
+ row[4*j:4*j+4] = MeetsTri[edge.Corners[i].Subsimplex]
231
+ row[4*k:4*k+4] -= MeetsTri[edge.Corners[i+1].Subsimplex]
232
+ eqns.append(row)
233
+ c = 0
234
+ if self.Coefficients[k] == -1:
235
+ c = MeetsOct[edge.Corners[i+1].Subsimplex][self.Quadtypes[k]]
236
+ else:
237
+ if MeetsQuad[edge.Corners[i+1].Subsimplex][self.Quadtypes[k]]:
238
+ c = self.Coefficients[k]
239
+ if self.Coefficients[j] == -1:
240
+ c -= MeetsOct[edge.Corners[i].Subsimplex][self.Quadtypes[j]]
241
+ else:
242
+ if MeetsQuad[edge.Corners[i].Subsimplex][self.Quadtypes[j]]:
243
+ c -= self.Coefficients[j]
244
+ constants.append(c)
245
+ # Now add the extra equations to kill off the vertex links.
246
+ for vertex in manifold.Vertices:
247
+ eqns.append(vertex.IncidenceVector)
248
+ constants.append(0)
249
+
250
+ A = Matrix(eqns)
251
+ b = Vector(constants)
252
+ x = A.solve(b)
253
+ # Subtract off as many vertex links as possible.
254
+ for vertex in manifold.Vertices:
255
+ vert_vec = vertex.IncidenceVector
256
+ m = min([x[i] for i, w in enumerate(vert_vec) if w])
257
+ x -= Vector(m*vert_vec)
258
+
259
+ for i in range(len(manifold)):
260
+ for j in range(4):
261
+ v = x[4*i+j]
262
+ assert int(v) == v
263
+ self.Weights[7*i + j ] = int(v)
264
+ if not self.Coefficients[i] == -1:
265
+ self.Weights[7*i + 4: 7*i + 7] = (
266
+ self.Coefficients[i]*QuadWeights[int(self.Quadtypes[i])] )
267
+ else:
268
+ self.Weights[7*i + 4: 7*i + 7] = QuadWeights[int(self.Quadtypes[i])]
269
+
270
+ self.EdgeWeights = Matrix(edge_matrix).dot(self.Weights)
271
+
272
+ def find_euler_characteristic(self, manifold):
273
+ # An EdgeValence is the number of tetrahedra that meet the edge.
274
+ # The number of 2-simplices that meet the edge is larger by 1 in
275
+ # the case of a boundary edge.
276
+ valences = Vector(manifold.EdgeValences)
277
+ for edge in manifold.Edges:
278
+ if edge.IntOrBdry == 'bdry':
279
+ valences[edge.Index] += 1
280
+ V = sum(self.EdgeWeights)
281
+ E = (self.EdgeWeights*valences)/2
282
+ F = sum(abs(self.Weights))
283
+ self.EulerCharacteristic = V - E + F
284
+
285
+ # takes either a triangle given as the corresponding vertex
286
+ # or a quad given as an edge disjoint from it.
287
+
288
+ def get_weight(self, tet_number, subsimplex):
289
+ D = {V0: 0, V1:1, V2:2, V3:3, E03:4, E12:4, E13:5, E02:5, E23:6, E01:6}
290
+ return self.Weights[7*tet_number + D[subsimplex] ]
291
+
292
+ def has_quad(self, tet_number):
293
+ return max([self.get_weight(tet_number, e) for e in [E01, E02, E03]]) > 0
294
+
295
+ def get_edge_weight(self, edge):
296
+ j = edge.Index
297
+ return self.EdgeWeights[j]
298
+
299
+ # The next function decides if a normal surface bounds a subcomplex.
300
+ # The thing is to note is that given any surface, then there is a unique
301
+ # maximal subcomplex disjoint from it -- consisting of all simplices
302
+ # of any dimension disjoint from it. (For a normal surface, the boundary
303
+ # of a regular nbhd of this subcomplex is always normal.) It's not
304
+ # hard to see that a normal surface bounds a subcomplex iff all edge weights
305
+ # are 0 or 2. The function build_bounding_info sets self.BoundingInfo to:
306
+ #
307
+ # (bounds subcomplex, double bounds subcomplex, thick_or_thin)
308
+ #
309
+ # where thick_or_thin describes whether there is a tetrahedron contained
310
+ # in the subcomplex bounded by the surface or its double.
311
+
312
+ def build_bounding_info(self, manifold):
313
+ if self.type() != "normal":
314
+ return (0, 0, None)
315
+
316
+ bounds_subcomplex = 1
317
+ double_bounds_subcomplex = 1
318
+ for w in self.EdgeWeights:
319
+ if w != 0 and w != 2:
320
+ bounds_subcomplex = 0
321
+ if w != 0 and w != 1:
322
+ double_bounds_subcomplex = 0
323
+ if not (bounds_subcomplex or double_bounds_subcomplex):
324
+ break
325
+
326
+ if bounds_subcomplex or double_bounds_subcomplex:
327
+ thick_or_thin = "thin"
328
+ for tet in manifold.Tetrahedra:
329
+ inside = 1
330
+ for e in OneSubsimplices:
331
+ w = self.get_edge_weight(tet.Class[e])
332
+ if w != 0:
333
+ inside = 0
334
+ break
335
+
336
+ if inside:
337
+ thick_or_thin = "thick"
338
+ break
339
+
340
+ else:
341
+ thick_or_thin = None
342
+
343
+ self.BoundingInfo = (bounds_subcomplex, double_bounds_subcomplex, thick_or_thin)
344
+
345
+ # It is not a torus unless the edge is a loop!
346
+ # A surface is an edge linking torus iff all edge weights are 2 except one which
347
+ # is zero. Returns pair (is linking torus, edge it links around).
348
+
349
+ def is_edge_linking_torus(self):
350
+ zeroes = 0
351
+ zero_index = None
352
+ for i in range(len(self.EdgeWeights)):
353
+ w = self.EdgeWeights[i]
354
+ if w == 0:
355
+ if zeroes > 0:
356
+ return (0, None)
357
+ zeroes = 1
358
+ zero_index = i
359
+ elif w != 2:
360
+ return (0, None)
361
+
362
+ return (1, zero_index)
363
+
364
+ def info(self, manifold, out=sys.stdout):
365
+ if self.type() == "normal":
366
+ # check if really boring:
367
+ q, e = self.is_edge_linking_torus()
368
+ if q:
369
+ out.write("Normal surface #%d is thin linking torus of edge %s\n"
370
+ % (manifold.NormalSurfaces.index(self), manifold.Edges[e]))
371
+ return
372
+ out.write("Normal surface #%d of Euler characteristic %d\n"
373
+ % (manifold.NormalSurfaces.index(self), self.EulerCharacteristic))
374
+ # additional message about bounding subcomplex
375
+ b, d, t = self.BoundingInfo
376
+ if b == 1:
377
+ out.write(" Bounds %s subcomplex\n" % t)
378
+ elif d == 1:
379
+ out.write(" Double bounds %s subcomplex\n" % t)
380
+ else:
381
+ out.write(" doesn't bound subcomplex\n")
382
+ else:
383
+ out.write("Almost-normal surface #%d of Euler characteristic %d\n"
384
+ % (manifold.AlmostNormalSurfaces.index(self),
385
+ self.EulerCharacteristic))
386
+ out.write('\n')
387
+ for i in range(self.Size):
388
+ quad_weight = self.Coefficients[i]
389
+ if quad_weight == -1:
390
+ weight = " Quad Type Q%d3, weight: octagon" % self.Quadtypes[i]
391
+ elif quad_weight > 0:
392
+ weight = " Quad Type Q%d3, weight %d" % (self.Quadtypes[i], quad_weight)
393
+ else:
394
+ weight = "No quads"
395
+ out.write(" In tetrahedron %s : %s\n" %
396
+ (manifold.Tetrahedra[i], weight))
397
+ out.write("\tTri weights V0: %d V1: %d V2 : %d V3 : %d\n"
398
+ % (self.get_weight(i, V0),
399
+ self.get_weight(i, V1),
400
+ self.get_weight(i, V2),
401
+ self.get_weight(i, V3)))
402
+ out.write('\n')
403
+
404
+ for i in range(len(self.EdgeWeights)):
405
+ out.write(" Edge %s has weight %d\n"
406
+ % (manifold.Edges[i], self.EdgeWeights[i]))
407
+
408
+ def casson_split(self, manifold):
409
+ """
410
+
411
+ Returns the "Casson Split" of the manifold along the normal
412
+ surface. That is, splits the manifold open along the surface
413
+ and replaces the "combinatorial I-bundles" by I-bundles over
414
+ disks. Of course, doing so may change the topology of
415
+ complementary manifold.
416
+
417
+ """
418
+ M = manifold
419
+ have_quads = [self.has_quad(i) for i in range(len(M))]
420
+ new_tets = {}
421
+ for i in have_quads:
422
+ new_tets[i] = Tetrahedron()
423
+ for i in have_quads:
424
+ T = new_tets[i]
425
+
426
+ # -----------------end class ClosedSurface---------------------------------------
427
+
428
+
429
+ # -----------------begin class SpunSurface--------------------------------------
430
+
431
+ def dot_product(x,y):
432
+ assert len(x) == len(y)
433
+ dot = 0
434
+ for i in range(len(x)):
435
+ dot += x[i]*y[i]
436
+ return dot
437
+
438
+
439
+ class SpunSurface(Surface):
440
+
441
+ def __init__(self, manifold, quadvector):
442
+ Surface.__init__(self, manifold, quadvector)
443
+ self.Incompressible = None
444
+ self.BoundarySlope = None
445
+
446
+ def add_boundary_slope(surface, cusp_equations):
447
+ surface.BoundarySlope = (-dot_product(surface.Shifts, cusp_equations[1]),
448
+ dot_product(surface.Shifts, cusp_equations[0]) )
449
+
450
+ def find_euler_characteristic(self, manifold):
451
+ quadvector = array(self.Quadvector, 'd')
452
+ floatresult = dot(manifold.Anglevector, quadvector)
453
+ intresult = round(floatresult)
454
+ error = abs(floatresult - intresult)
455
+ if error > .0000001:
456
+ raise OverflowError('Yikes! A non-integral euler characteristic!')
457
+ return -int(intresult)
458
+
459
+ def info(self, manifold, out=sys.stdout):
460
+ out.write("SpunSurface.\n Slope: %s; Boundary components: %d; " %
461
+ reduce_slope(self.BoundarySlope))
462
+ out.write("Euler characteristic: %d\n" %
463
+ self.find_euler_characteristic(manifold))
464
+ out.write(" Incompressible: %s\n" % self.Incompressible)
465
+ for i in range(self.Size):
466
+ quad_weight = self.Coefficients[i]
467
+ if quad_weight > 0:
468
+ weight = (" Tet %d: Quad Type Q%d3, weight %d" %
469
+ (i, self.Quadtypes[i], quad_weight))
470
+ else:
471
+ weight = " Tet %d: no quads" % i
472
+ out.write(weight + "\n")
473
+
474
+
475
+ # -------------begin class ClosedSurfaceInCusped------------------------
476
+
477
+ class ClosedSurfaceInCusped(ClosedSurface):
478
+ def __init__(self, manifold, quadvector):
479
+ ClosedSurface.__init__(self, manifold, quadvector)
480
+ self.Incompressible = None
481
+ self.BoundarySlope = None
482
+
483
+ def info(self, manifold, out=sys.stdout):
484
+ out.write("ClosedSurfaceInCusped #%d: Euler %d; Incompressible %s\n" %
485
+ (manifold.ClosedSurfaces.index(self), self.EulerCharacteristic, self.Incompressible))
486
+ # check if really boring:
487
+ q, e = self.is_edge_linking_torus()
488
+ if q:
489
+ out.write(" is thin linking surface of edge %s\n" % manifold.Edges[e])
490
+ return
491
+
492
+ # additional message about bounding subcomplex
493
+ b, d, t = self.BoundingInfo
494
+ if b == 1:
495
+ out.write(" Bounds %s subcomplex\n" % t)
496
+ elif d == 1:
497
+ out.write(" Double bounds %s subcomplex\n" % t)
498
+ else:
499
+ out.write(" Doesn't bound subcomplex\n")
500
+
501
+ for i in range(self.Size):
502
+ quad_weight = self.Coefficients[i]
503
+ if quad_weight > 0:
504
+ weight = " Quad Type Q%d3, weight %d" % (self.Quadtypes[i], quad_weight)
505
+ else:
506
+ weight = "No quads"
507
+
508
+ out.write(" In tet %s : %s\n" %
509
+ (manifold.Tetrahedra[i], weight))
510
+ out.write("\tTri weights V0: %d V1: %d V2 : %d V3 : %d\n"
511
+ % (self.get_weight(i, V0),
512
+ self.get_weight(i, V1),
513
+ self.get_weight(i, V2),
514
+ self.get_weight(i, V3)))
515
+ out.write('\n')
516
+
517
+ for i in range(len(self.EdgeWeights)):
518
+ out.write(" Edge %s has weight %d\n"
519
+ % (manifold.Edges[i], self.EdgeWeights[i]))
@@ -0,0 +1,20 @@
1
+ import snappy
2
+ import snappy.snap.t3mlite as t3m
3
+
4
+
5
+ def closed_test():
6
+ for M in snappy.OrientableClosedCensus[:10]:
7
+ N = M.filled_triangulation()
8
+ T = t3m.Mcomplex(N)
9
+ T.find_normal_surfaces()
10
+ T.normal_surface_info()
11
+
12
+
13
+ def cusped_test():
14
+ for M in snappy.OrientableCuspedCensus[:10]:
15
+ T = t3m.Mcomplex(M)
16
+ T.find_normal_surfaces()
17
+
18
+
19
+ closed_test()
20
+ cusped_test()
@@ -0,0 +1,86 @@
1
+ import snappy
2
+ import regina
3
+ import snappy.snap.t3mlite as t3m
4
+ import snappy.snap.t3mlite.spun as spun
5
+
6
+
7
+ def hash_t3m_surface(surface):
8
+ ans = [surface.EulerCharacteristic]
9
+ ans += sorted(surface.EdgeWeights)
10
+ ans += sorted(surface.Quadvector)
11
+ return ans
12
+
13
+
14
+ def hash_regina_surface(S):
15
+ T = S.getTriangulation()
16
+ t = T.getNumberOfTetrahedra()
17
+ ans = [S.getEulerCharacteristic()]
18
+ ans += sorted([S.getEdgeWeight(i) for i in range(T.getNumberOfEdges())])
19
+ ans += sorted([S.getQuadCoord(i, j) for i in range(t) for j in range(3)])
20
+ return ans
21
+
22
+
23
+ def to_regina(snappy_manifold):
24
+ return regina.NTriangulation(snappy_manifold._to_string())
25
+
26
+
27
+ def vertex_surfaces(regina_triangulation):
28
+ """
29
+ Enumerate the vertex surfaces of the given triangulation
30
+ in quad coordinates.
31
+ """
32
+ surfaces = regina.NNormalSurfaceList.enumerate(
33
+ regina_triangulation, regina.NS_QUAD)
34
+ for i in range(surfaces.getNumberOfSurfaces()):
35
+ yield surfaces.getSurface(i)
36
+
37
+
38
+ def compare_closed(snappy_manifold):
39
+ N = snappy_manifold.filled_triangulation()
40
+
41
+ T = t3m.Mcomplex(N)
42
+ T.find_normal_surfaces()
43
+ t_hashes = sorted( hash_t3m_surface(S) for S in T.NormalSurfaces )
44
+
45
+ R = to_regina(N)
46
+ r_hashes = sorted( hash_regina_surface(S) for S in vertex_surfaces(R))
47
+
48
+ all_together = sum(t_hashes, [])
49
+ return t_hashes == r_hashes, len(all_together), sum(all_together)
50
+
51
+
52
+ def regina_boundary_slope(surface):
53
+ slope = surface.boundaryIntersections()
54
+ a = int(slope.entry(0,0).stringValue())
55
+ b = int(slope.entry(0,1).stringValue())
56
+ return (b, -a)
57
+
58
+
59
+ def compare_cusped(snappy_manifold):
60
+ tri_data = snappy_manifold._to_string()
61
+ T = spun.Manifold(tri_data)
62
+ t_hashes = sorted(sorted(S.quad_vector()) for S in T.normal_surfaces())
63
+ t_slopes = sorted(tuple(S.boundary_slopes()) for S in T.normal_surfaces())
64
+
65
+ R = regina.NSnapPeaTriangulation(tri_data)
66
+ t = R.getNumberOfTetrahedra()
67
+ regina_surfaces = list(vertex_surfaces(R))
68
+ r_hashes = sorted(
69
+ sorted(int(S.getQuadCoord(i, j).stringValue())
70
+ for i in range(t) for j in range(3))
71
+ for S in regina_surfaces)
72
+ r_slopes = sorted(map(regina_boundary_slope, regina_surfaces))
73
+
74
+ assert t_hashes == r_hashes and t_slopes == r_slopes
75
+
76
+
77
+ def closed_test(N=10):
78
+ for M in snappy.OrientableClosedCensus[:N]:
79
+ print(M, compare_closed(M))
80
+
81
+
82
+ def cusped_test(N=100):
83
+ for census in [snappy.CensusKnots, snappy.OrientableCuspedCensus(cusps=1)]:
84
+ for M in census:
85
+ print(M)
86
+ compare_cusped(M)