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,20 @@
1
+ ''' Twister is a program by Mark Bell, Tracy Hall and Saul Schleimer for
2
+ constructing triangulations of surface bundles and Heegaard splittings from
3
+ a description of a mapping class of a surface.
4
+
5
+ Twister is available from:
6
+ https://github.com/MarkCBell/twister
7
+
8
+ See the included users guide ./docs/Twister.pdf for instructions for installing,
9
+ testing and using Twister.
10
+
11
+ Provides:
12
+ Surface - A class representing a squared surface with curves drawn on it.
13
+ DT_drilling_surface - A function returning a standard surface from a knots
14
+ Dowker--Thistlethwaite code.
15
+ DT_handles_surface - A function returning a standard surface from a knots
16
+ Dowker--Thistlethwaite code.
17
+ surface_database - A set of all surfaces in Twister's surface database.
18
+ version - A string containing the version number of the Twister kernel. '''
19
+
20
+ from .main import Surface, DT_drilling_surface, DT_handles_surface, surface_database, version
snappy/twister/main.py ADDED
@@ -0,0 +1,646 @@
1
+ ### Required modules:
2
+ # Some standard modules.
3
+ import os
4
+ from random import choice
5
+ from itertools import combinations
6
+ # Some custom modules.
7
+ import snappy
8
+ from plink import LinkManager
9
+ from .twister_core import build_bundle, build_splitting, twister_version
10
+
11
+ surface_database_path = os.path.join(os.path.dirname(__file__), 'surfaces')
12
+ surface_database = set(os.listdir(surface_database_path))
13
+ version = twister_version()
14
+
15
+ def _get_surface(surface):
16
+ if isinstance(surface, tuple) and len(surface) == 2 and isinstance(surface[0], int) and isinstance(surface[1], int):
17
+ return LP_surface(surface[0], surface[1])
18
+
19
+ if isinstance(surface, str):
20
+ # If surface is actually the contents of a surface file.
21
+ if surface.startswith('# A Twister surface file'):
22
+ return surface
23
+
24
+ # If surface is in the database.
25
+ if surface in surface_database:
26
+ surface = os.path.join(surface_database_path, surface)
27
+
28
+ try:
29
+ lines = open(surface, 'r').readlines()
30
+ except IOError:
31
+ raise IOError('Unable to open %s' % surface)
32
+
33
+ contents = ''.join(lines)
34
+ if contents.startswith('% Virtual Link Projection\n'):
35
+ # We use PLink to handle virtual link projections.
36
+ LM = LinkManager()
37
+ LM._from_string(contents)
38
+ return LM.Twister_surface_file()
39
+ if contents.startswith('# A Twister surface file'):
40
+ return contents
41
+
42
+ raise TypeError('Not a Twister surface file.')
43
+
44
+ raise TypeError('Surfaces can only be loaded from a string or pair of integers (genus,boundary).')
45
+
46
+ def _parse_line(line):
47
+ data = line.split('#')
48
+ if data[0] == '': return None
49
+ return data[0].split(',')
50
+
51
+ def _parse_surface(surface_contents):
52
+ # We now compute some properties of the surface. These are useful for error checking.
53
+ # We could do more error checking to make sure that the surface is valid. But this
54
+ # would just be repeating code in twister_core.
55
+ curves = {'annulus':[], 'rectangle':[], 'macro':[]}
56
+ num_squares = 0;
57
+ for line in surface_contents.split('\n'):
58
+ data = _parse_line(line)
59
+ if data is not None:
60
+ if len(data) > 2:
61
+ curves[data[0]].append((data[1], data[2], data[3:]))
62
+ if data[3:] != []:
63
+ largest_num = max(map(lambda x: abs(int(x)) + 1, data[3:]))
64
+ if largest_num > num_squares:
65
+ num_squares = largest_num
66
+
67
+ vertices = [set([str(i) + d]) for i in range(num_squares) for d in ['NE', 'NW', 'SE', 'SW']]
68
+
69
+ def join(v, a, b):
70
+ X = [s for s in v if a in s or b in s]
71
+ if len(X) == 2:
72
+ v.remove(X[0])
73
+ v.remove(X[1])
74
+ v.append(X[0] | X[1])
75
+
76
+ for annulus in curves['annulus']:
77
+ data = annulus[2]
78
+ for i in range(len(data)):
79
+ j = (i+1) % len(data)
80
+ sign1 = data[i][0] == '-'
81
+ sign2 = data[j][0] == '-'
82
+ square1 = str(abs(int(data[i])))
83
+ square2 = str(abs(int(data[j])))
84
+ corner1a = 'NW' if data[i][0] == '-' else 'NE'
85
+ corner2a = 'SW' if data[j][0] == '-' else 'NW'
86
+ corner1b = 'NE' if data[i][0] == '-' else 'SE'
87
+ corner2b = 'SE' if data[j][0] == '-' else 'SW'
88
+
89
+ join(vertices, square1 + corner1a, square2 + corner2a)
90
+ join(vertices, square1 + corner1b, square2 + corner2b)
91
+
92
+ for rectangle in curves['rectangle']:
93
+ data = rectangle[2]
94
+ for i in range(len(data)-1):
95
+ j = (i+1) % len(data)
96
+ square1 = str(abs(int(data[i])))
97
+ square2 = str(abs(int(data[j])))
98
+ corner1a = 'NW' if data[i][0] == '-' else 'NE'
99
+ corner2a = 'SW' if data[j][0] == '-' else 'NW'
100
+ corner1b = 'NE' if data[i][0] == '-' else 'SE'
101
+ corner2b = 'SE' if data[j][0] == '-' else 'SW'
102
+
103
+ join(vertices, square1 + corner1a, square2 + corner2a)
104
+ join(vertices, square1 + corner1b, square2 + corner2b)
105
+
106
+ end_edges = []
107
+ for rectangle in curves['rectangle']:
108
+ data = rectangle[2]
109
+
110
+ square1 = str(abs(int(data[0])))
111
+ corner1a = 'SW' if data[0][0] == '-' else 'SW'
112
+ corner1b = 'SE' if data[0][0] == '-' else 'NW'
113
+ end_edges.append((square1 + corner1a, square1 + corner1b))
114
+
115
+ square2 = str(abs(int(data[-1])))
116
+ corner2a = 'NW' if data[0][0] == '-' else 'NE'
117
+ corner2b = 'NE' if data[0][0] == '-' else 'SE'
118
+ end_edges.append((square2 + corner2a, square2 + corner2b))
119
+
120
+ boundary_components = [set([e]) for e in end_edges]
121
+ for e1, e2 in combinations(end_edges, r=2):
122
+ if any(v1 in v and v2 in v for v in vertices for v1 in e1 for v2 in e2):
123
+ join(boundary_components, e1, e2)
124
+
125
+ return num_squares, curves, vertices, boundary_components
126
+
127
+ def _compute_intersections(curves):
128
+ curve_names = [name for (name, inverse_name, data) in curves['annulus']] + [name for (name, inverse_name, data) in curves['rectangle']]
129
+ data = dict((name, set([abs(int(x)) for x in data])) for (name, inverse_name, data) in curves['annulus'] + curves['rectangle'])
130
+
131
+ rows = [[''] + curve_names]
132
+ for name in curve_names:
133
+ row = [name]
134
+ for name2 in curve_names:
135
+ row.append(len(data[name].intersection(data[name2])) if name != name2 else 0)
136
+ rows.append(row)
137
+
138
+ return rows
139
+
140
+ class Surface:
141
+ ''' Represents a squared surface with a collection of curves on it. '''
142
+ def __init__(self, surface):
143
+ ''' Creates a new surface from either:
144
+ - the name of a surface in the surface database,
145
+ - a path to a surface file,
146
+ - a path to a plink virtual knot file,
147
+ - the contents of a surface file, or
148
+ - the pair (genus, boundary). For information about how this surface
149
+ \t is created see the doc string of twister.LP_surface(). '''
150
+ self.surface_contents = _get_surface(surface)
151
+ self.num_squares, self.curves, vertices, self.boundary_components = _parse_surface(self.surface_contents)
152
+
153
+ self.num_boundary = len(self.boundary_components)
154
+ self.num_edges = sum(len(x[2]) for x in self.curves['annulus']) + sum(len(x[2]) + 1 for x in self.curves['rectangle'])
155
+ self.num_vertices = len(vertices)
156
+ self.Euler_characteristic = self.num_vertices - self.num_edges + self.num_squares
157
+ self.genus = (2 - self.num_boundary - self.Euler_characteristic) // 2
158
+ self.intersection_matrix = _compute_intersections(self.curves)
159
+
160
+ def info(self, verbose=False):
161
+ annuli = ', '.join(a[0] for a in self.curves['annulus'])
162
+ inv_annuli = ', '.join(a[1] for a in self.curves['annulus'])
163
+ rectangles = ', '.join(r[0] for r in self.curves['rectangle'])
164
+ inv_rectangles = ', '.join(r[1] for r in self.curves['rectangle'])
165
+ macros = ', '.join('%s:%s' % (r[0], r[1]) for r in self.curves['macro'])
166
+ matrix = '\n'.join(str(row) for row in self.intersection_matrix)
167
+ print('A Twister surface of genus %d with %d boundary component(s)' % (self.genus, self.num_boundary))
168
+ print('Loops: %s' % annuli)
169
+ if verbose: print('Inverse names: %s' % inv_annuli)
170
+ print('Arcs: %s' % rectangles)
171
+ if verbose: print('Inverse names: %s' % inv_rectangles)
172
+ if verbose: print('Macros: %s' % macros)
173
+ if verbose: print('Intersection matrix:\n%s' % matrix)
174
+
175
+ def random_word(self, n, twists=True, half_twists=True, macros=True, inverses=True):
176
+ ''' Returns a random word of length n in the generators of Mod(S). Setting twists, half_twists or macros to False
177
+ prevents them from appearing in the word. If all generators are disallowed then the empty word is returned. If
178
+ inverses is set to False then no inverse of a generator will be used. '''
179
+
180
+ generators = []
181
+ if twists: generators += [curve[0] for curve in self.curves['annulus']]
182
+ if twists and inverses: generators += [curve[1] for curve in self.curves['annulus']]
183
+ if half_twists: generators += [curve[0] for curve in self.curves['rectangle']]
184
+ if half_twists and inverses: generators += [curve[1] for curve in self.curves['rectangle']]
185
+ if macros: generators += [curve[0] for curve in self.curves['macro']]
186
+
187
+ if generators == []: return ''
188
+
189
+ return ''.join([choice(generators) for i in range(n)])
190
+
191
+ def bundle(self, monodromy, name=None, optimize=True, warnings=True, debugging_level=0, return_type='manifold'):
192
+ ''' Generate a surface bundle over a circle with fibre this surface from mapping class group data using the Twister
193
+ program of Bell, Hall and Schleimer.
194
+
195
+ Arguments:
196
+ Required:
197
+ monodromy - build a surface bundle with specified monodromy
198
+ Optional:
199
+ name - name of the resulting manifold
200
+ optimize - try to reduce the number of tetrahedra (default True)
201
+ warnings - print Twister warnings (default True)
202
+ debugging_level - specifies the amount of debugging information to be shown (default 0)
203
+ return_type - specifies how to return the manifold, either as a 'manifold' (default), 'triangulation' or 'string'
204
+
205
+ Monodromy is a word of annulus and rectangle names (or
206
+ their inverses). These are read from left to right and determine a
207
+ sequence of (half) Dehn twists. When prefixed with an "!" the name
208
+ specifies a drilling. For example, "a*B*a*B*A*A*!a*!b" will perform 6
209
+ twists and then drill twice.
210
+
211
+ Examples:
212
+
213
+ The figure eight knot complement:
214
+ >>> M = twister.Surface((1,1)).bundle(monodromy='a_0*B1')
215
+
216
+ The minimally twisted six chain link:
217
+ >>> M = twister.Surface('S_1_1').bundles(monodromy='!a*!b*!a*!b*!a*!b')
218
+ >>> M.set_peripheral_curves('shortest_meridians', 0)
219
+ >>> M.dehn_fill((1,0),0) '''
220
+
221
+ if name is None: name = monodromy
222
+ tri, messages = build_bundle(name, self.surface_contents, monodromy, optimize, True, warnings, debugging_level)
223
+
224
+ # You might want to change what is done with any warning / error messages.
225
+ # Perhaps they should be returned in the next block?
226
+ if messages != '': print(messages)
227
+
228
+ if tri is None:
229
+ return None
230
+
231
+ return_type = return_type.lower()
232
+ if return_type == 'manifold':
233
+ return snappy.Manifold(tri)
234
+ if return_type == 'triangulation':
235
+ return snappy.Triangulation(tri)
236
+ if return_type == 'string':
237
+ return tri
238
+
239
+ raise TypeError('Return type must be \'manifold\', \'triangulation\' or \'string\'.')
240
+
241
+ def splitting(self, gluing, handles, name=None, optimize=True, warnings=True, debugging_level=0, return_type='manifold'):
242
+ ''' Generate a manifold with Heegaard splitting this surface from mapping class group data using the Twister
243
+ program of Bell, Hall and Schleimer.
244
+
245
+ Arguments:
246
+ Required:
247
+ gluing - the gluing used to join the upper and lower compression bodies
248
+ handles - where to attach 2-handles
249
+ Optional:
250
+ name - name of the resulting manifold
251
+ optimize - try to reduce the number of tetrahedra (default True)
252
+ warnings - print Twister warnings (default True)
253
+ debugging_level - specifies the amount of debugging information to be shown (default 0)
254
+ return_type - specifies how to return the manifold, either as a 'manifold' (default), 'triangulation' or 'string'
255
+
256
+ Gluing is a word of annulus and rectangle names (or
257
+ their inverses). These are read from left to right and determine a
258
+ sequence of (half) Dehn twists. When prefixed with an "!" the name
259
+ specifies a drilling. For example, "a*B*a*B*A*A*!a*!b" will perform 6
260
+ twists and then drill twice.
261
+
262
+ Handles is again a word of annulus names (or inverses). For example,
263
+ 'a*c*A' means attach three 2-handles, two above and one below.
264
+
265
+ Examples:
266
+
267
+ The genus two splitting of the solid torus:
268
+ >>> M = twister.Surface('S_2').splitting(gluing='', handles='a*B*c') '''
269
+
270
+ if name is None: name = gluing + ' ' + handles
271
+ tri, messages = build_splitting(name, self.surface_contents, gluing, handles, optimize, True, warnings, debugging_level)
272
+
273
+ # You might want to change what is done with any warning / error messages.
274
+ # Perhaps they should be returned in the next block?
275
+ if messages != '': print(messages)
276
+
277
+ if tri is None:
278
+ return None
279
+
280
+ return_type = return_type.lower()
281
+ if return_type == 'manifold':
282
+ return snappy.Manifold(tri)
283
+ if return_type == 'triangulation':
284
+ return snappy.Triangulation(tri)
285
+ if return_type == 'string':
286
+ return tri
287
+
288
+ raise TypeError('Return type must be \'manifold\', \'triangulation\' or \'string\'.')
289
+
290
+ ### Some standard types of surface that can be automatically generated.
291
+
292
+ def LP_surface(genus, boundary, make_prefix_unique=True):
293
+ ''' Returns the contents of a surface file for the surface S_{genus, boundary}.
294
+ We generally follow the naming convention given in Figure 13
295
+ of the Labruere and Paris paper "Presentations for the punctured
296
+ mapping class groups in terms of Artin groups".
297
+
298
+ When genus == 1, the loop a_n is dropped as it is isotopic to the
299
+ loop a_0.
300
+
301
+ The case of genus == 0, given here, is a small modification of
302
+ Figure 11 in [LP].
303
+
304
+ You should not use this function directly, rather just call
305
+ Surface((genus, boundary)). '''
306
+
307
+ contents = ['# A Twister surface file produced by LP_surface.']
308
+ contents.append('# with generating set for MCG(S_{%d,%d}) following Figure 13 of Labruere and' % (genus, boundary))
309
+ contents.append('# Paris paper "Presentations for the punctured mapping class groups')
310
+ contents.append('# in terms of Artin groups".')
311
+ contents.append('#')
312
+
313
+ padded_length = len(str(max(2*genus, boundary))) if make_prefix_unique else 0
314
+
315
+ square_count = 0
316
+
317
+ if genus == 0:
318
+ if boundary == 0:
319
+ square_count += 1
320
+ contents.append('annulus,a1,A1,-0,+1#')
321
+ contents.append('annulus,a2,A2,-1,+0#')
322
+ else:
323
+ for i in range(boundary):
324
+ square_count += 1
325
+ start = 'rectangle,t' + str(i + 1).zfill(padded_length) + ',T' + str(i + 1).zfill(padded_length)
326
+ connections = ',-' + str(square_count - 1) + ',+' + str(square_count)
327
+ contents.append(start + connections + '#')
328
+
329
+ if i == boundary - 1:
330
+ start = 'annulus,a' + str(i + 1).zfill(padded_length) + ',A' + str(i + 1).zfill(padded_length)
331
+ connections = ',-' + str(square_count) + ',+' + '0'
332
+ contents.append(start + connections + '#')
333
+ else:
334
+ square_count += 1
335
+ start = 'annulus,a' + str(i + 1).zfill(padded_length) + ',A' + str(i + 1).zfill(padded_length)
336
+ connections = ',-' + str(square_count - 1) + ',+' + str(square_count)
337
+ contents.append(start + connections + '#')
338
+ else:
339
+ c_loop = -1 # Just a marker.
340
+
341
+ # Start with the a0 loop.
342
+ next_line = 'annulus,a' + '0'.zfill(padded_length) + ',A' + '0'.zfill(padded_length) + ',+0'
343
+ contents.append(next_line + '#')
344
+
345
+ # And the b1 loop.
346
+ start = 'annulus,b' + '1'.zfill(padded_length) + ',B' + '1'.zfill(padded_length)
347
+ connections = ',-0'
348
+
349
+ if boundary > 1:
350
+ for i in range(boundary - 1):
351
+ square_count += 1
352
+ connections = connections + ',-' + str(square_count)
353
+
354
+ square_count += 1
355
+
356
+ start2 = 'annulus,a' + str(i + 1).zfill(padded_length) + ',A' + str(i + 1).zfill(padded_length)
357
+ connections2 = ',+' + str(square_count - 1) + ',+' + str(square_count)
358
+ contents.append(start2 + connections2 + '#')
359
+
360
+ start3 = 'rectangle,t' + str(i + 1).zfill(padded_length) + ',T' + str(i + 1).zfill(padded_length)
361
+ connections3 = ',-' + str(square_count)
362
+ contents.append(start3 + connections3 + '#')
363
+
364
+ elif boundary == 1:
365
+ square_count += 1
366
+ connections = connections + ',-' + str(square_count)
367
+
368
+ start2 = 'rectangle,t' + '1'.zfill(padded_length) + ',T' + '1'.zfill(padded_length)
369
+ connections2 = ',+' + str(square_count)
370
+ contents.append(start2 + connections2 + '#')
371
+
372
+ elif boundary == 0 and genus > 1:
373
+ square_count += 1
374
+ connections = connections + ',+' + str(square_count)
375
+
376
+ # Add in an extra a loop (if needed) to isolate the half-twists from the rest of the surface.
377
+ if genus > 1 and boundary > 0:
378
+ square_count += 1
379
+ connections = connections + ',-' + str(square_count)
380
+
381
+ start2 = 'annulus,a' + str(boundary).zfill(padded_length) + ',A' + str(boundary).zfill(padded_length)
382
+ connections2 = ',+' + str(square_count)
383
+ contents.append(start2 + connections2 + '#')
384
+
385
+ # Add in the start point for the b2 ... chain.
386
+ square_count += 1
387
+ connections = connections + ',+' + str(square_count)
388
+
389
+ contents.append(start + connections + '#')
390
+
391
+ # Now construct the rest of the b loops.
392
+ for i in range(2, 2 * genus - 1):
393
+ square_count += 1
394
+ start = 'annulus,b' + str(i).zfill(padded_length) + ',B' + str(i).zfill(padded_length)
395
+ connections = ',-' + str(square_count - 1) + ',+' + str(square_count)
396
+ contents.append(start + connections + '#')
397
+ if i == 2: c_loop = len(contents)
398
+
399
+ # Don't forget, the last one is different.
400
+ if genus > 1:
401
+ square_count += 1
402
+ start = 'annulus,b' + str(2 * genus - 1).zfill(padded_length) + ',B' + str(2 * genus - 1).zfill(padded_length)
403
+ connections = ',-' + str(square_count - 1)
404
+ contents.append(start + connections + '#')
405
+
406
+ # Modify the 3rd b loop to add in the c loop (if needed).
407
+ if c_loop > -1:
408
+ next_line = 'annulus,c,C,-' + str(square_count)
409
+ contents.append(next_line + '#')
410
+ contents[c_loop] = contents[c_loop][:-1] + ',+' + str(square_count) + '#'
411
+
412
+ return '\n'.join(contents)
413
+
414
+ def code_to_sign_sequence(code):
415
+ ''' Produces a sign sequence for a given Dowker code. '''
416
+
417
+ def first_non_zero(L): return min(i for i in range(len(L)) if L[i])
418
+
419
+ N = len(code)
420
+ signs = [abs(n) - 1 for n in code]
421
+
422
+ pairs = list(zip(range(0, 2*N, 2), signs))
423
+ pairs_dict = dict([(x, y) for x, y in pairs] + [(y, x) for x, y in pairs])
424
+ full_code = [pairs_dict[i] for i in range(2*N)]
425
+
426
+ seq = full_code * 2 # seq is two copies of full DT involution on crossings numbered 0 to 2N-1.
427
+ emb, A = [0] * 2*N, [0] * 2*N # zero emb and A. A will only ever contain zeroes and ones.
428
+
429
+ # Set initial conditions.
430
+ A[0], A[seq[0]] = 1, 1
431
+ emb[0], emb[seq[0]] = 1, -1
432
+
433
+ # Determine the possible phi's
434
+ all_phi = [[0] * 2*N for i in range(2*N)]
435
+ for i in range(2*N):
436
+ all_phi[i][i] = 1
437
+ for j in range(i, i+2*N):
438
+ all_phi[i][j % (2*N)] = 1 if i == j else -all_phi[i][(j-1) % (2*N)] if i <= seq[j] <= seq[i] else all_phi[i][(j-1) % (2*N)]
439
+
440
+ while any(A):
441
+ i = first_non_zero(A) # let i be the index of the first non-zero member of A
442
+
443
+ D = [1] * 2*N
444
+ D[i:seq[i]+1] = [0] * (seq[i] - i + 1)
445
+ while any(D):
446
+ x = first_non_zero(D) # let x be the index of the first non-zero member of D
447
+ D[x] = 0
448
+
449
+ if ((i <= seq[x] <= seq[i] and emb[x] != 0 and all_phi[i][x] * all_phi[i][seq[x]] * emb[i] != emb[x]) or ((seq[x] < i or seq[i] < seq[x]) and all_phi[i][x] * all_phi[i][seq[x]] != 1)) and x < i: # This extra AND conditions shouldn't be needed.
450
+ raise ValueError('Not a realisable DT-code.')
451
+
452
+ if seq[i] < seq[x] or seq[x] < i:
453
+ D[seq[x]] = 0
454
+ elif emb[x] == 0: # emb[x] is already defined
455
+ assert D[seq[x]] == 0
456
+ emb[x] = all_phi[i][x] * all_phi[i][seq[x]] * emb[i]
457
+ emb[seq[x]] = -emb[x]
458
+ if abs(seq[x]-seq[x-1]) % (2*N) != 1:
459
+ A[x] = 1
460
+ A[seq[x]] = 1
461
+
462
+ A[i], A[seq[i]] = 0, 0
463
+
464
+ return [emb[i] for i in range(0, 2*N, 2)] # Note [emb[pairs_dict[i]] for i in range(0, 2*N, 2)] is also a valid code.
465
+
466
+ def DT_drilling_surface(code, make_prefix_unique=True):
467
+ ''' Returns a Surface which can be used to construct a triangulation of the
468
+ complement of the knot with Dowker--Thistlethwaite code 'code'.
469
+
470
+ Example: DT_drilling_surface([6,10,8,12,4,2]) returns a Surface that can be
471
+ used to construct the 6_1 knot complement. '''
472
+
473
+ # Note: There are smaller surface files that can be constructed to do this,
474
+ # but they are significantly more complicated and have less symmetry.
475
+ code = list(code)
476
+ signs = code_to_sign_sequence(code)
477
+
478
+ contents = ['# A Twister surface file']
479
+ contents.append('#')
480
+ contents.append('# Surface file for knot with Dowker code:')
481
+ contents.append('# ' + ','.join(map(str, code)))
482
+ contents.append('#')
483
+ contents.append('# To build this knot complement, make a Heegaard splitting with a 2-handle attached above')
484
+ contents.append('# and below every annulus and drill every rectangle exactly once, making sure to drill all')
485
+ contents.append('# of the "x" rectangles before drilling ANY of the "y" rectangles.')
486
+ contents.append('#')
487
+
488
+ num_crossings = len(code)
489
+ padded_length = len(str(2*num_crossings)) if make_prefix_unique else 0
490
+ num_squares = num_crossings * 5
491
+
492
+ pairs = list(zip(range(1, 2*num_crossings+1, 2), code))
493
+ pairs_dict = dict([(x, abs(y)) for (x, y) in pairs] + [(abs(y), x) for (x, y) in pairs])
494
+ signs_dict = dict([(x, y > 0) for (x, y) in pairs] + [(abs(y), y > 0) for (x, y) in pairs])
495
+
496
+ drill_names = []
497
+ handle_names = []
498
+
499
+ # First build all the rectangles.
500
+ for i in range(1, 2*num_crossings+1):
501
+ if i % 2 == 1:
502
+ k = i // 2
503
+ cells = ['-' + str(k * 5 + 1), '+' + str(k * 5 + 2), '+' + str(k * 5 + 3)]
504
+ else:
505
+ k = pairs_dict[i] // 2
506
+ if signs[k] == 1:
507
+ cells = ['-' + str(k * 5 + 4), '-' + str(k * 5 + 2), '+' + str(k * 5 + 0)]
508
+ else:
509
+ cells = ['-' + str(k * 5 + 0), '-' + str(k * 5 + 2), '+' + str(k * 5 + 4)]
510
+
511
+ over = (i % 2 == 0) ^ signs_dict[i]
512
+ name = ('y' if (i % 2 == 0) ^ signs_dict[i] else 'x') + str(i).zfill(padded_length)
513
+ inverse_name = name.swapcase()
514
+ contents.append(','.join(['rectangle', name, inverse_name] + cells) + '#')
515
+ drill_names.append('!' + name)
516
+
517
+ # Then the required annuli.
518
+ for i in range(1, 2*num_crossings+1):
519
+ j = i % (2*num_crossings) + 1
520
+ if i % 2 == 1:
521
+ k = i // 2
522
+ l = pairs_dict[j] // 2
523
+ if signs[l] == 1:
524
+ cells = ['-' + str(k * 5 + 3), '+' + str(l * 5 + 4)]
525
+ else:
526
+ cells = ['-' + str(k * 5 + 3), '-' + str(l * 5 + 4)]
527
+ else:
528
+ k = pairs_dict[i] // 2
529
+ l = j // 2
530
+ if signs[k] == 1:
531
+ cells = ['-' + str(k * 5 + 0), '+' + str(l * 5 + 1)]
532
+ else:
533
+ cells = ['+' + str(k * 5 + 0), '+' + str(l * 5 + 1)]
534
+
535
+ name = 'a' + '_' + str(i).zfill(padded_length)
536
+ inverse_name = name.swapcase()
537
+ contents.append(','.join(['annulus', name, inverse_name] + cells) + '#')
538
+ handle_names.append(name)
539
+ handle_names.append(inverse_name)
540
+
541
+ contents.append('# We also give a macro to drill all of the rectangles in an acceptable order.')
542
+ contents.append('# And one for attaching all handles too.')
543
+ drill_names.sort() # Make sure to sort the rectangle drill names so that all of the "x"'s appear before ANY of the "y"'s.
544
+ contents.append('macro,s,' + '*'.join(drill_names) + '#')
545
+ contents.append('macro,h,' + '*'.join(handle_names) + '#')
546
+
547
+ return Surface('\n'.join(contents))
548
+
549
+ def DT_handles_surface(code, make_prefix_unique=True):
550
+ ''' Returns a Surface which can be used to construct a triangulation of the
551
+ complement of the knot with Dowker code 'code'.
552
+
553
+ Example: DT_handles_surface([6,10,8,12,4,2]) returns a Surface that can be
554
+ used to construct the 6_1 knot complement. '''
555
+
556
+ # Note: There are smaller surface files that can be constructed to do this,
557
+ # but they are significantly more complicated and have less symmetry.
558
+ code = list(code)
559
+ signs = code_to_sign_sequence(code) # Get the orientation of each intersection
560
+
561
+ contents = ['# A Twister surface file']
562
+ contents.append('#')
563
+ contents.append('# Surface file for knot with Dowker code:')
564
+ contents.append('# ' + ','.join(map(str, code)))
565
+ contents.append('#')
566
+ contents.append('# To build this knot complement, make a Heegaard splitting with a 2-handle attached above')
567
+ contents.append('# and below the sequence of annuli specified in the macro "h".')
568
+ contents.append('#')
569
+
570
+ num_crossings = len(code)
571
+
572
+ pairs = list(zip(range(1, 2*num_crossings+1, 2), code))
573
+ pairs_dict = dict([(x, abs(y)) for (x, y) in pairs] + [(abs(y), x) for (x, y) in pairs])
574
+ signs_dict = dict([(x, y > 0) for (x, y) in pairs] + [(abs(y), y > 0) for (x, y) in pairs])
575
+
576
+ overcrossing = [signs_dict[i+1] ^ (i % 2 == 1) for i in range(2*num_crossings)]
577
+ where_switch = list(filter(lambda i: not signs_dict[i+1] ^ signs_dict[((i+1) % (2*num_crossings)) + 1], range(2*num_crossings)))
578
+ last_true = max(where_switch) + 1
579
+
580
+ num_annuli = len(where_switch)
581
+ squares_in_crossings = 4 * num_crossings
582
+ squares_in_links = 2 * num_annuli
583
+ squares_in_rectangles = 2 * num_annuli
584
+
585
+ num_squares = squares_in_crossings + squares_in_links + squares_in_rectangles
586
+ padded_length = len(str(num_annuli)) if make_prefix_unique else 0
587
+
588
+ annuli_count = 0
589
+ squares = []
590
+ back_squares = []
591
+ handle_names = []
592
+ for j in range(2*num_crossings):
593
+ i = ((j + last_true) % (2*num_crossings))
594
+ if i % 2 == 0:
595
+ k = i // 2
596
+ squares.append('-' + str(4*k+0))
597
+ squares.append('+' + str(4*k+1))
598
+ back_squares.append('+' + str(4*k+3))
599
+ back_squares.append('-' + str(4*k+2))
600
+ else:
601
+ k = pairs_dict[i+1] // 2
602
+ if signs[k] == +1:
603
+ squares.append('-' + str(4*k+3))
604
+ squares.append('+' + str(4*k+0))
605
+ back_squares.append('+' + str(4*k+2))
606
+ back_squares.append('-' + str(4*k+1))
607
+ else:
608
+ squares.append('-' + str(4*k+1))
609
+ squares.append('+' + str(4*k+2))
610
+ back_squares.append('+' + str(4*k+0))
611
+ back_squares.append('-' + str(4*k+3))
612
+
613
+ if i in where_switch:
614
+ row = 'annulus,a' + str(annuli_count).zfill(padded_length) + ',A' + str(annuli_count).zfill(padded_length) + ','
615
+ row += '+' + str(squares_in_crossings + 2*annuli_count) + ','
616
+ row += ','.join(squares) + ','
617
+ row += '-' + str(squares_in_crossings + 2*((annuli_count+1) % num_annuli)) + ','
618
+ row += '-' + str(squares_in_crossings + squares_in_links + 2*annuli_count) + ','
619
+ row += '+' + str(squares_in_crossings + squares_in_links + 2*annuli_count + 1) + ','
620
+ row += '+' + str(squares_in_crossings + 2*((annuli_count+1) % num_annuli) + 1) + ','
621
+ row += ','.join(back_squares[::-1]) + ','
622
+ row += '-' + str(squares_in_crossings + 2*annuli_count + 1)
623
+ row += '#'
624
+
625
+ contents.append(row)
626
+
627
+ handle_names.append(('a' if overcrossing[i] else 'A') + str(annuli_count).zfill(padded_length))
628
+
629
+ annuli_count += 1
630
+ squares = []
631
+ back_squares = []
632
+
633
+ for i in range(num_annuli):
634
+ row = 'rectangle,t' + str(i).zfill(padded_length) + ',T' + str(i).zfill(padded_length) + ','
635
+ row += '+' + str(squares_in_crossings + squares_in_links + 2*i) + ','
636
+ row += '-' + str(squares_in_crossings + squares_in_links + 2*i + 1)
637
+ row += '#'
638
+ contents.append(row)
639
+
640
+
641
+ num_squares = num_crossings * 5
642
+
643
+ contents.append('# We also give a macro for attaching the required handles.')
644
+ contents.append('macro,h,' + '*'.join(handle_names) + '#')
645
+
646
+ return Surface('\n'.join(contents))
@@ -0,0 +1,3 @@
1
+ # A Twister surface file
2
+ rectangle,x,X,-0#
3
+ rectangle,y,Y,+0#
@@ -0,0 +1,3 @@
1
+ # A Twister surface file
2
+ annulus,a,A,+0#
3
+ rectangle,x,X,-0#
@@ -0,0 +1,7 @@
1
+ # A Twister surface file
2
+ annulus,a,A,+0,-1,+2,+3#
3
+ annulus,b,B,+1,-4,-3,-5#
4
+ rectangle,w,W,+4#
5
+ rectangle,x,X,-0#
6
+ rectangle,y,Y,+5#
7
+ rectangle,z,Z,-2#