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,522 @@
1
+ from collections import OrderedDict
2
+ from ... import sage_helper
3
+
4
+ if sage_helper._within_sage:
5
+ from ...sage_helper import ZZ, matrix, vector, cached_method, ChainComplex
6
+ from sage.plot.all import line, arrow, text
7
+ else:
8
+ def cached_method(func):
9
+ return func
10
+
11
+
12
+ class Triangle():
13
+ """
14
+ The vertices are numbered 0, 1, 2 in an anti-clockwise
15
+ orientation.
16
+
17
+ Edges of the triangle are specified by the vertex that they
18
+ *don't* contain.
19
+ """
20
+ def __init__(self, edges=None, vertices=None):
21
+ self.edges = edges if edges else EdgeList([None, None, None])
22
+ self.vertices = vertices if vertices else [None, None, None]
23
+ self.index = None
24
+
25
+ def __repr__(self):
26
+ return "<Tri: %s>" % self.index
27
+
28
+ def oriented_sides(self):
29
+ return [Side(self, e) for e in oriented_edges_of_triangle]
30
+
31
+
32
+ def opposite_vertex_from_edge_function( vertices ):
33
+ other = [v for v in range(3) if v not in vertices]
34
+ assert len(vertices) == 2 and len(other) == 1
35
+ return other[0]
36
+
37
+
38
+ opposite_vertex_from_edge_dict = {(i,j):opposite_vertex_from_edge_function((i,j))
39
+ for i in range(3) for j in range(3) if i != j}
40
+
41
+ oriented_edges_of_triangle = [ (1,2), (2,0), (0, 1)]
42
+
43
+
44
+ class Edge():
45
+ """
46
+ An oriented edge 0 -> 1.
47
+ """
48
+ def __init__(self, sides=None, vertices=None):
49
+ self.sides, self.vertices = sides, vertices
50
+ self.index = None
51
+
52
+ def glued_to(self, side):
53
+ for sides in ( list(self.sides), [-S for S in self.sides] ):
54
+ if side in sides:
55
+ sides.remove(side)
56
+ return sides[0]
57
+
58
+ raise IndexError("Given side does not appear in this edge")
59
+
60
+ def orientation_with_respect_to(self, side):
61
+ """
62
+ Returns +1 if the orientation of the given side matches the
63
+ edges, -1 otherwise.
64
+ """
65
+ if side in self.sides:
66
+ return 1
67
+ elif -side in self.sides:
68
+ return -1
69
+ raise IndexError("Given side does not appear in this edge")
70
+
71
+ def __repr__(self):
72
+ return "<Edge %s: %s : %s>" % (self.index, [v.index for v in self.vertices], self.sides)
73
+
74
+ def reverse(self):
75
+ self.vertices = (self.vertices[1], self.vertices[0])
76
+ self.sides = tuple( [-s for s in self.sides] )
77
+
78
+
79
+ class EdgeList():
80
+ """
81
+ A list with one item for each edge in a Triangle. The contents
82
+ can be accessed either by a pair of vertices or by the opposite
83
+ vertex.
84
+ """
85
+ def __init__(self, items):
86
+ self.data = {}
87
+ for i, x in enumerate(items):
88
+ self[i] = x
89
+
90
+ def __getitem__(self, index):
91
+ return self.data[index]
92
+
93
+ def __setitem__(self, index, value):
94
+ if not hasattr(index, "__iter__"):
95
+ index = oriented_edges_of_triangle[index]
96
+ self.data[index] = value
97
+ self.data[(index[1], index[0])] = value
98
+ self.data[opposite_vertex_from_edge_dict[index]] = value
99
+
100
+ def __repr__(self):
101
+ return '[%s, %s, %s]' % (self.data[0], self.data[1], self.data[2])
102
+
103
+
104
+ class Vertex():
105
+ def __init__(self, corners=None):
106
+ self.corners = corners
107
+ self.index = None
108
+ self.incoming, self.outgoing = [], []
109
+
110
+ def __repr__(self):
111
+ return "<Vertex %s: %s %s : %s>" % (self.index, [e.index for e in self.incoming], [e.index for e in self.outgoing], self.corners)
112
+
113
+
114
+ class Side():
115
+ """
116
+ A neighborhood of an oriented edge in a triangle
117
+ """
118
+ def __init__(self, triangle=None, vertices=None):
119
+ self.triangle, self.vertices = triangle, vertices
120
+ self.index = None
121
+
122
+ def __neg__(self):
123
+ v, w = self.vertices
124
+ S = Side(self.triangle, (w, v) )
125
+ return S
126
+
127
+ def __repr__(self):
128
+ v, w = self.vertices
129
+ return "<Side %s : %d -> %d>" % (self.triangle.index, v, w)
130
+
131
+ def __eq__(self, other):
132
+ if isinstance(other, Side):
133
+ t, T = self.triangle, other.triangle
134
+ v, w = self.vertices
135
+ V, W = other.vertices
136
+ return t == T and v == V and w == W
137
+
138
+ def __ne__(self, other):
139
+ return not self.__eq__(other)
140
+
141
+ def corners(self):
142
+ v, w = self.vertices
143
+ T = self.triangle
144
+ return Corner(T, v), Corner(T, w)
145
+
146
+ def edge(self):
147
+ return self.triangle.edges[ self.vertices ]
148
+
149
+ def opposite_vertex(self):
150
+ return opposite_vertex_from_edge_dict[self.vertices]
151
+
152
+
153
+ class Corner():
154
+ """
155
+ A neighborhood of a vertex V in a triangle T.
156
+ """
157
+ def __init__(self, triangle=None, vertex=None):
158
+ self.triangle, self.vertex = triangle, vertex
159
+
160
+ def next_corner(self):
161
+ v = self.vertex
162
+ w = [2, 0, 1][v]
163
+ E = self.triangle.edges[ (v, w) ]
164
+ S = Side( self.triangle, (v, w) )
165
+ OS = E.glued_to(S)
166
+ return Corner(OS.triangle, OS.vertices[0])
167
+
168
+ def edge_with_orientation(self):
169
+ v = self.vertex
170
+ w = [2, 0, 1][v]
171
+ E = self.triangle.edges[ (v, w) ]
172
+ S = Side(self.triangle, (v,w) )
173
+ return E, E.orientation_with_respect_to(S)
174
+
175
+ def __repr__(self):
176
+ return "<Corner %s %d>" % (self.triangle.index, self.vertex)
177
+
178
+ def __eq__(self, other):
179
+ if isinstance(other, Corner):
180
+ return (self.triangle == other.triangle) and (self.vertex == other.vertex)
181
+
182
+ def __ne__(self, other):
183
+ return not self.__eq__(other)
184
+
185
+
186
+ class Surface():
187
+ """
188
+ An oriented surface.
189
+ """
190
+ def __init__(self, triangles=None):
191
+ self.triangles, self.edges, self.vertices = triangles, [], []
192
+
193
+ def glue_triangles(self, T0, e0, T1, e1):
194
+ """
195
+ T0, T1 are triangles, and e0, e1 specify a gluing in one of two
196
+ ways: as a list of vertices of the triangle, or as the vertex
197
+ opposite the edge being glued. In the latter case, the assumption
198
+ is that the gluing preserves orientation.
199
+
200
+ Returns the newly created edge.
201
+ """
202
+
203
+ if not hasattr(e0, "__iter__"):
204
+ e0 = oriented_edges_of_triangle[e0]
205
+ a,b = oriented_edges_of_triangle[e1]
206
+ e1 = (b, a)
207
+
208
+ S0, S1 = Side(T0, e0), Side(T1, e1)
209
+ E = Edge( sides=(S0,S1) )
210
+
211
+ T0.edges[opposite_vertex_from_edge_dict[e0]] = E
212
+ T1.edges[opposite_vertex_from_edge_dict[e1]] = E
213
+
214
+ self.edges.append(E)
215
+ return E
216
+
217
+ def build_vertices(self):
218
+ """
219
+ Build the 0 skeleton.
220
+ """
221
+ vertices = []
222
+ corners = OrderedDict(
223
+ [ [(T, v), Corner(T, v)] for T in self.triangles for v in range(3) ] )
224
+ while corners:
225
+ C0 = next(iter(corners.values()))
226
+ vertex = [C0]
227
+ C = C0.next_corner()
228
+ while C != C0:
229
+ vertex.append(C)
230
+ C = C.next_corner()
231
+
232
+ V = Vertex(vertex)
233
+ for C in vertex:
234
+ corners.pop( (C.triangle, C.vertex) )
235
+ C.triangle.vertices[C.vertex] = V
236
+
237
+ vertices.append(V)
238
+
239
+ self.vertices = vertices
240
+ self._vertex_containing_corner = {(C.triangle, C.vertex): V for V in vertices for C in V.corners}
241
+
242
+ def build(self):
243
+ """
244
+ Build the overall cell structure and label all the cells
245
+ """
246
+ self.build_vertices()
247
+
248
+ for E in self.edges:
249
+ S = E.sides[0]
250
+ C0, C1 = S.corners()
251
+ V0, V1 = self.vertex_containing_corner(C0), self.vertex_containing_corner(C1)
252
+ E.vertices = (V0, V1)
253
+ V0.outgoing.append(E), V1.incoming.append(E)
254
+
255
+ self.index()
256
+
257
+ def vertex_containing_corner(self, corner):
258
+ return self._vertex_containing_corner[ (corner.triangle, corner.vertex) ]
259
+
260
+ def index(self):
261
+ for objects in [self.triangles, self.edges, self.vertices]:
262
+ for i, x in enumerate(objects):
263
+ x.index = i
264
+
265
+ @cached_method
266
+ def B1(self):
267
+ """
268
+ The matrix describing the boundary map C_1 -> C_0
269
+ """
270
+ V, E = len(self.vertices), len(self.edges)
271
+ vert_indices = sorted((v.index, v) for v in self.vertices)
272
+ vertex_to_row = {v:i for i, (j, v) in enumerate(vert_indices)}
273
+ assert list(range(V)) == sorted(vertex_to_row.values())
274
+ assert list(range(E)) == sorted(e.index for e in self.edges)
275
+
276
+ D = matrix(ZZ, V, E, sparse=True)
277
+ for e in self.edges:
278
+ v_init = vertex_to_row[e.vertices[0]]
279
+ v_term = vertex_to_row[e.vertices[1]]
280
+ D[v_term, e.index] += 1
281
+ D[v_init, e.index] += -1
282
+
283
+ return D
284
+
285
+ @cached_method
286
+ def B2(self):
287
+ """
288
+ The matrix describing the boundary map C_2 -> C_1
289
+ """
290
+
291
+ E, F = len(self.edges), len(self.triangles)
292
+ assert list(range(E)) == sorted(e.index for e in self.edges)
293
+ assert list(range(F)) == sorted(v.index for v in self.triangles)
294
+ D = matrix(ZZ, E, F, sparse=True)
295
+ for T in self.triangles:
296
+ for S in T.oriented_sides():
297
+ E = S.edge()
298
+ D[E.index, T.index] += E.orientation_with_respect_to(S)
299
+
300
+ return D
301
+
302
+ @cached_method
303
+ def d0(self):
304
+ """
305
+ The matrix describing the coboundary map C^0 -> C^1.
306
+ """
307
+ return self.B1().transpose()
308
+
309
+ @cached_method
310
+ def d1(self):
311
+ """
312
+ The matrix describing the coboundary map C^1 -> C^2.
313
+ """
314
+ return self.B2().transpose()
315
+
316
+ def euler(self):
317
+ return len(self.vertices) - len(self.edges) + len(self.triangles)
318
+
319
+ def homology_test(self):
320
+ B1, B2 = self.B1(), self.B2()
321
+ assert B1 * B2 == 0
322
+ b0 = len(self.vertices) - B1.rank()
323
+ b1 = B1.right_kernel().dimension() - B2.rank()
324
+ b2 = B2.right_kernel().dimension()
325
+ assert b0 - b1 + b2 == self.euler()
326
+
327
+ @cached_method
328
+ def chain_complex(self):
329
+ return ChainComplex({1: self.B1(), 2: self.B2()}, degree=-1)
330
+
331
+ @cached_method
332
+ def cochain_complex(self):
333
+ return self.chain_complex().dual()
334
+
335
+ @cached_method
336
+ def betti(self, dimension=1):
337
+ C = self.chain_complex()
338
+ return C.betti(dimension)
339
+
340
+ @cached_method
341
+ def integral_cohomology_basis(self, dimension=1):
342
+ # Removed use of Chomp per https://trac.sagemath.org/ticket/33777
343
+ C = self.cochain_complex()
344
+ homology = C.homology(generators=True)[dimension]
345
+ ans = [factor[1].vector(dimension) for factor in homology]
346
+
347
+ if dimension == 1:
348
+ assert len(ans) == 2 - self.euler()
349
+ ans = [OneCocycle(self, a) for a in ans]
350
+ return ans
351
+
352
+ @cached_method
353
+ def integral_homology_basis(self, dimension=1):
354
+ # Removed use of Chomp per https://trac.sagemath.org/ticket/33777
355
+ C = self.chain_complex()
356
+ homology = C.homology(generators=True)[dimension]
357
+ ans = [factor[1].vector(dimension) for factor in homology]
358
+
359
+ if dimension == 1:
360
+ assert len(ans) == 2 - self.euler()
361
+ ans = [OneCycle(self, a) for a in ans]
362
+ return ans
363
+
364
+
365
+ def first_pair_differing_in_first_component(L):
366
+ for i in range(len(L)):
367
+ a, b = L[i : i + 2]
368
+ if a[0] != b[0]:
369
+ return a, b
370
+
371
+
372
+ def segments_into_components(L):
373
+ components = []
374
+ while L:
375
+ s0 = L[0]
376
+ component = [s0]
377
+ s = s0.next
378
+ L.remove(s0)
379
+ while s != s0:
380
+ component.append(s)
381
+ L.remove(s)
382
+ s = s.next
383
+
384
+ components.append(component)
385
+
386
+ return components
387
+
388
+
389
+ def component_to_cycle(surface, component):
390
+ w = len(surface.edges)*[0,]
391
+ for s in component:
392
+ w[s.edge.index] += s.orientation_agrees
393
+ return OneCycle(surface, w)
394
+
395
+
396
+ class OneCycleSegment:
397
+ def __init__(self, edge, orientation_agrees, family_index, next=None, previous=None):
398
+ self.edge, self.orientation_agrees = edge, orientation_agrees
399
+ self.next, self.previous = next, previous
400
+ self.family_index = family_index
401
+
402
+ def __repr__(self):
403
+ return "<OCSeg: %d %d>" % (self.edge.index, self.family_index)
404
+
405
+
406
+ class Cycle:
407
+ """
408
+ Base class of OneCycle and OneCocycle. The get/setitem allows one to
409
+ access the weights both by edge index and also via a Side. The
410
+ latter incorporates the orientations in the way you would expect.
411
+
412
+ Please note that the weights are just a list, not a vector.
413
+ """
414
+ def __init__(self, surface, weights=None, check=True):
415
+ self.surface, self.weights = surface, weights
416
+ if weights is None:
417
+ self.weights = len(surface.edges) * [None]
418
+ else:
419
+ if check:
420
+ self.check()
421
+
422
+ def check(self):
423
+ if len(self.weights) != len(self.surface.edges):
424
+ raise ValueError('Weights do not match the number of edges')
425
+
426
+ def __getitem__(self, edge):
427
+ if isinstance(edge, Side):
428
+ side = edge
429
+ E = side.edge()
430
+ weight = self.weights[E.index]
431
+ orient = E.orientation_with_respect_to(side)
432
+ return orient*weight
433
+ else:
434
+ return self.weights[edge]
435
+
436
+ def __setitem__(self, edge, weight):
437
+ if isinstance(edge, Side):
438
+ side = edge
439
+ E = side.edge()
440
+ edge = E.index
441
+ orient = E.orientation_with_respect_to(side)
442
+ weight = orient*weight
443
+ if self.weights[edge] is None:
444
+ self.weights[edge] = weight
445
+ else:
446
+ assert self.weights[edge] == weight
447
+
448
+ def __add__(self, other):
449
+ if isinstance(other, type(self)):
450
+ return self.__class__(self.surface, [s + o for s, o in zip(self.weights, other.weights)],
451
+ check=False)
452
+
453
+
454
+ class OneCycle(Cycle):
455
+ def check(self):
456
+ w = vector(self.weights)
457
+ B1 = self.surface.B1()
458
+ if B1*w != 0:
459
+ raise ValueError('OneCycle not in kernel of boundary map')
460
+
461
+ def is_zero_in_homology(self):
462
+ B2 = self.surface.B2().transpose()
463
+ r1 = B2.rank()
464
+ r2 = matrix(list(B2) + [self.weights]).rank()
465
+ return r1 == r2
466
+
467
+ def components(self):
468
+ """
469
+ Returns a list of the connected components of the multicurve
470
+ corresponding to the 1-cycle, each given as a OneCycle.
471
+ """
472
+ S, W = self.surface, self.weights
473
+ support = [i for i, w in enumerate(W) if w != 0]
474
+ segments = {}
475
+ for i in support:
476
+ E = S.edges[i]
477
+ w = self.weights[i]
478
+ o = 1 if w > 0 else -1
479
+ segments[i] = [OneCycleSegment(E, o, a) for a in range(abs(w))]
480
+
481
+ for V in S.vertices:
482
+ segs_at_vertex = [] # a cyclically ordered list of arcs of the multicurve
483
+ for C in V.corners:
484
+ E, o_edge = C.edge_with_orientation() # o_edge = +1 means *outgoing*.
485
+ i = E.index
486
+ if i in support:
487
+ segs = segments[E.index]
488
+ o_strands = o_edge * segs[0].orientation_agrees
489
+ if o_strands > 0:
490
+ segs_at_vertex += [ (o_strands, s) for s in segs]
491
+ else:
492
+ segs_at_vertex += [ (o_strands, s) for s in reversed(segs)]
493
+
494
+ assert sum([s[0] for s in segs_at_vertex]) == 0
495
+
496
+ while segs_at_vertex:
497
+ s0, s1 = first_pair_differing_in_first_component( segs_at_vertex )
498
+ # want s0 to be incoming, s1 outgoing.
499
+ if s0[0] > 0:
500
+ s0, s1 = s1, s0
501
+ s0[1].next, s1[1].prev = s1[1], s0[1]
502
+ segs_at_vertex.remove(s0), segs_at_vertex.remove(s1)
503
+
504
+ components = segments_into_components( sum( segments.values(), [] ) )
505
+ return [component_to_cycle(S, c) for c in components]
506
+
507
+ def __repr__(self):
508
+ return '<Cycle: %s>' % self.weights
509
+
510
+
511
+ class OneCocycle(Cycle):
512
+ def check(self):
513
+ if self.surface.d1() * vector(self.weights) != 0:
514
+ raise ValueError('Not in the kernel of d1')
515
+
516
+ def __repr__(self):
517
+ return '<Cocycle: %s>' % self.weights
518
+
519
+ def __call__(self, cycle):
520
+ if isinstance(cycle, OneCycle):
521
+ cycle = cycle.weights
522
+ return sum(c*z for c, z in zip(self.weights, cycle))
@@ -0,0 +1,35 @@
1
+ import sys
2
+ import getopt
3
+ import doctest
4
+
5
+ from . import dual_cellulation, link, peripheral, surface
6
+ modules = [dual_cellulation, link, peripheral, surface]
7
+
8
+
9
+ def verbose():
10
+ try:
11
+ optlist, args = getopt.getopt(sys.argv[1:], 'v', ['verbose'])
12
+ opts = [o[0] for o in optlist]
13
+ verbose = '-v' in opts
14
+ except getopt.GetoptError:
15
+ verbose = False
16
+ return verbose
17
+
18
+
19
+ def doctest_globals(module):
20
+ if hasattr(module, 'doctest_globals'):
21
+ return module.doctest_globals()
22
+ return {}
23
+
24
+
25
+ if __name__ == '__main__':
26
+ failed, attempted = 0, 0
27
+ for module in modules:
28
+ print(module.__name__)
29
+ result = doctest.testmod(module,
30
+ extraglobs=doctest_globals(module),
31
+ verbose=verbose())
32
+ print(4 * ' ' + repr(result))
33
+ failed += result.failed
34
+ attempted += result.attempted
35
+ print('\nAll doctests:\n %s failures out of %s tests.' % (failed, attempted))