snappy 3.2__cp310-cp310-macosx_10_12_x86_64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (503) hide show
  1. snappy/CyOpenGL.cpython-310-darwin.so +0 -0
  2. snappy/SnapPy.cpython-310-darwin.so +0 -0
  3. snappy/SnapPy.ico +0 -0
  4. snappy/SnapPy.png +0 -0
  5. snappy/SnapPyHP.cpython-310-darwin.so +0 -0
  6. snappy/__init__.py +760 -0
  7. snappy/app.py +605 -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 +38 -0
  13. snappy/cusps/cusp_area_matrix.py +101 -0
  14. snappy/cusps/cusp_areas_from_matrix.py +173 -0
  15. snappy/cusps/maximal_cusp_area_matrix.py +136 -0
  16. snappy/cusps/test.py +21 -0
  17. snappy/cusps/trig_cusp_area_matrix.py +63 -0
  18. snappy/database.py +454 -0
  19. snappy/db_utilities.py +79 -0
  20. snappy/decorated_isosig.py +710 -0
  21. snappy/dev/__init__.py +0 -0
  22. snappy/dev/extended_ptolemy/__init__.py +8 -0
  23. snappy/dev/extended_ptolemy/closed.py +106 -0
  24. snappy/dev/extended_ptolemy/complexVolumesClosed.py +149 -0
  25. snappy/dev/extended_ptolemy/direct.py +42 -0
  26. snappy/dev/extended_ptolemy/extended.py +406 -0
  27. snappy/dev/extended_ptolemy/giac_helper.py +43 -0
  28. snappy/dev/extended_ptolemy/giac_rur.py +129 -0
  29. snappy/dev/extended_ptolemy/gluing.py +46 -0
  30. snappy/dev/extended_ptolemy/phc_wrapper.py +220 -0
  31. snappy/dev/extended_ptolemy/printMatrices.py +70 -0
  32. snappy/dev/vericlosed/__init__.py +1 -0
  33. snappy/dev/vericlosed/computeApproxHyperbolicStructureNew.py +159 -0
  34. snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +90 -0
  35. snappy/dev/vericlosed/computeVerifiedHyperbolicStructure.py +111 -0
  36. snappy/dev/vericlosed/gimbalLoopFinder.py +130 -0
  37. snappy/dev/vericlosed/hyperbolicStructure.py +313 -0
  38. snappy/dev/vericlosed/krawczykCertifiedEdgeLengthsEngine.py +165 -0
  39. snappy/dev/vericlosed/oneVertexTruncatedComplex.py +122 -0
  40. snappy/dev/vericlosed/orb/__init__.py +1 -0
  41. snappy/dev/vericlosed/orb/orb_solution_for_snappea_finite_triangulation_mac +0 -0
  42. snappy/dev/vericlosed/parseVertexGramMatrixFile.py +47 -0
  43. snappy/dev/vericlosed/polishApproxHyperbolicStructure.py +61 -0
  44. snappy/dev/vericlosed/test.py +54 -0
  45. snappy/dev/vericlosed/truncatedComplex.py +176 -0
  46. snappy/dev/vericlosed/verificationError.py +58 -0
  47. snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +177 -0
  48. snappy/doc/_images/SnapPy-196.png +0 -0
  49. snappy/doc/_images/geodesics.jpg +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 +51 -0
  61. snappy/doc/_sources/credits.rst.txt +75 -0
  62. snappy/doc/_sources/development.rst.txt +259 -0
  63. snappy/doc/_sources/index.rst.txt +182 -0
  64. snappy/doc/_sources/installing.rst.txt +247 -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 +355 -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 +925 -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 +156 -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 +199 -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 +620 -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 +427 -0
  152. snappy/doc/credits.html +181 -0
  153. snappy/doc/development.html +384 -0
  154. snappy/doc/genindex.html +1331 -0
  155. snappy/doc/index.html +262 -0
  156. snappy/doc/installing.html +346 -0
  157. snappy/doc/manifold.html +3452 -0
  158. snappy/doc/manifoldhp.html +180 -0
  159. snappy/doc/news.html +388 -0
  160. snappy/doc/objects.inv +0 -0
  161. snappy/doc/other.html +161 -0
  162. snappy/doc/platonic_census.html +375 -0
  163. snappy/doc/plink.html +210 -0
  164. snappy/doc/ptolemy.html +254 -0
  165. snappy/doc/ptolemy_classes.html +1144 -0
  166. snappy/doc/ptolemy_examples1.html +409 -0
  167. snappy/doc/ptolemy_examples2.html +471 -0
  168. snappy/doc/ptolemy_examples3.html +414 -0
  169. snappy/doc/ptolemy_examples4.html +195 -0
  170. snappy/doc/ptolemy_prelim.html +248 -0
  171. snappy/doc/py-modindex.html +165 -0
  172. snappy/doc/screenshots.html +141 -0
  173. snappy/doc/search.html +135 -0
  174. snappy/doc/searchindex.js +1 -0
  175. snappy/doc/snap.html +202 -0
  176. snappy/doc/snappy.html +181 -0
  177. snappy/doc/spherogram.html +1211 -0
  178. snappy/doc/todo.html +166 -0
  179. snappy/doc/triangulation.html +1584 -0
  180. snappy/doc/tutorial.html +159 -0
  181. snappy/doc/verify.html +330 -0
  182. snappy/doc/verify_internals.html +1235 -0
  183. snappy/drilling/__init__.py +456 -0
  184. snappy/drilling/barycentric.py +103 -0
  185. snappy/drilling/constants.py +5 -0
  186. snappy/drilling/crush.py +270 -0
  187. snappy/drilling/cusps.py +125 -0
  188. snappy/drilling/debug.py +242 -0
  189. snappy/drilling/epsilons.py +6 -0
  190. snappy/drilling/exceptions.py +55 -0
  191. snappy/drilling/moves.py +620 -0
  192. snappy/drilling/peripheral_curves.py +210 -0
  193. snappy/drilling/perturb.py +188 -0
  194. snappy/drilling/shorten.py +36 -0
  195. snappy/drilling/subdivide.py +274 -0
  196. snappy/drilling/test.py +23 -0
  197. snappy/drilling/test_cases.py +126 -0
  198. snappy/drilling/tracing.py +351 -0
  199. snappy/exceptions.py +26 -0
  200. snappy/export_stl.py +120 -0
  201. snappy/exterior_to_link/__init__.py +2 -0
  202. snappy/exterior_to_link/barycentric_geometry.py +463 -0
  203. snappy/exterior_to_link/exceptions.py +6 -0
  204. snappy/exterior_to_link/geodesic_map.json +14408 -0
  205. snappy/exterior_to_link/hyp_utils.py +112 -0
  206. snappy/exterior_to_link/link_projection.py +323 -0
  207. snappy/exterior_to_link/main.py +197 -0
  208. snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
  209. snappy/exterior_to_link/mcomplex_with_link.py +687 -0
  210. snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
  211. snappy/exterior_to_link/pl_utils.py +491 -0
  212. snappy/exterior_to_link/put_in_S3.py +156 -0
  213. snappy/exterior_to_link/rational_linear_algebra.py +123 -0
  214. snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
  215. snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
  216. snappy/exterior_to_link/stored_moves.py +475 -0
  217. snappy/exterior_to_link/test.py +31 -0
  218. snappy/filedialog.py +28 -0
  219. snappy/geometric_structure/__init__.py +212 -0
  220. snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
  221. snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +697 -0
  222. snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +484 -0
  223. snappy/geometric_structure/cusp_neighborhood/exceptions.py +42 -0
  224. snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +298 -0
  225. snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +159 -0
  226. snappy/geometric_structure/cusp_neighborhood/vertices.py +32 -0
  227. snappy/geometric_structure/geodesic/__init__.py +0 -0
  228. snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
  229. snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
  230. snappy/geometric_structure/geodesic/canonical_keys.py +52 -0
  231. snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
  232. snappy/geometric_structure/geodesic/constants.py +6 -0
  233. snappy/geometric_structure/geodesic/exceptions.py +22 -0
  234. snappy/geometric_structure/geodesic/fixed_points.py +93 -0
  235. snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
  236. snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
  237. snappy/geometric_structure/geodesic/line.py +30 -0
  238. snappy/geometric_structure/geodesic/multiplicity.py +127 -0
  239. snappy/geometric_structure/geodesic/tiles_for_geodesic.py +101 -0
  240. snappy/geometric_structure/test.py +22 -0
  241. snappy/gui.py +121 -0
  242. snappy/horoviewer.py +443 -0
  243. snappy/hyperboloid/__init__.py +212 -0
  244. snappy/hyperboloid/distances.py +245 -0
  245. snappy/hyperboloid/horoball.py +19 -0
  246. snappy/hyperboloid/line.py +35 -0
  247. snappy/hyperboloid/point.py +9 -0
  248. snappy/hyperboloid/triangle.py +29 -0
  249. snappy/info_icon.gif +0 -0
  250. snappy/infowindow.py +65 -0
  251. snappy/isometry_signature.py +382 -0
  252. snappy/len_spec/__init__.py +596 -0
  253. snappy/len_spec/geodesic_info.py +110 -0
  254. snappy/len_spec/geodesic_key_info_dict.py +117 -0
  255. snappy/len_spec/geodesic_piece.py +143 -0
  256. snappy/len_spec/geometric_structure.py +182 -0
  257. snappy/len_spec/geometry.py +80 -0
  258. snappy/len_spec/length_spectrum_geodesic_info.py +170 -0
  259. snappy/len_spec/spine.py +206 -0
  260. snappy/len_spec/test.py +24 -0
  261. snappy/len_spec/test_cases.py +69 -0
  262. snappy/len_spec/tile.py +275 -0
  263. snappy/len_spec/word.py +86 -0
  264. snappy/manifolds/HTWKnots/alternating.gz +0 -0
  265. snappy/manifolds/HTWKnots/nonalternating.gz +0 -0
  266. snappy/manifolds/__init__.py +3 -0
  267. snappy/math_basics.py +176 -0
  268. snappy/matrix.py +525 -0
  269. snappy/number.py +657 -0
  270. snappy/numeric_output_checker.py +345 -0
  271. snappy/pari.py +41 -0
  272. snappy/phone_home.py +57 -0
  273. snappy/polyviewer.py +259 -0
  274. snappy/ptolemy/__init__.py +17 -0
  275. snappy/ptolemy/component.py +103 -0
  276. snappy/ptolemy/coordinates.py +2290 -0
  277. snappy/ptolemy/fieldExtensions.py +153 -0
  278. snappy/ptolemy/findLoops.py +473 -0
  279. snappy/ptolemy/geometricRep.py +59 -0
  280. snappy/ptolemy/homology.py +165 -0
  281. snappy/ptolemy/magma/default.magma_template +229 -0
  282. snappy/ptolemy/magma/radicalsOfPrimaryDecomposition.magma_template +79 -0
  283. snappy/ptolemy/manifoldMethods.py +395 -0
  284. snappy/ptolemy/matrix.py +350 -0
  285. snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +113 -0
  286. snappy/ptolemy/polynomial.py +857 -0
  287. snappy/ptolemy/processComponents.py +173 -0
  288. snappy/ptolemy/processFileBase.py +247 -0
  289. snappy/ptolemy/processFileDispatch.py +46 -0
  290. snappy/ptolemy/processMagmaFile.py +392 -0
  291. snappy/ptolemy/processRurFile.py +150 -0
  292. snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +102 -0
  293. snappy/ptolemy/ptolemyObstructionClass.py +64 -0
  294. snappy/ptolemy/ptolemyVariety.py +1029 -0
  295. snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +140 -0
  296. snappy/ptolemy/reginaWrapper.py +698 -0
  297. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  298. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  299. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  300. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  301. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  302. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  303. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  304. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  305. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  306. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  307. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c0.magma_out.bz2 +0 -0
  308. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  309. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  310. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c1.magma_out.bz2 +0 -0
  311. snappy/ptolemy/rur.py +545 -0
  312. snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +277 -0
  313. snappy/ptolemy/test.py +1126 -0
  314. snappy/ptolemy/testing_files/3_1__sl2_c0.magma_out.bz2 +0 -0
  315. snappy/ptolemy/testing_files/3_1__sl2_c1.magma_out.bz2 +0 -0
  316. snappy/ptolemy/testing_files/4_1__sl2_c0.magma_out.bz2 +0 -0
  317. snappy/ptolemy/testing_files/4_1__sl2_c1.magma_out.bz2 +0 -0
  318. snappy/ptolemy/testing_files/4_1__sl3_c0.magma_out.bz2 +0 -0
  319. snappy/ptolemy/testing_files/4_1__sl4_c0.magma_out.bz2 +0 -0
  320. snappy/ptolemy/testing_files/4_1__sl4_c1.magma_out.bz2 +0 -0
  321. snappy/ptolemy/testing_files/5_2__sl2_c0.magma_out.bz2 +0 -0
  322. snappy/ptolemy/testing_files/5_2__sl2_c1.magma_out.bz2 +0 -0
  323. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  324. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  325. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  326. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  327. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  328. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  329. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  330. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  331. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c0.magma_out +95 -0
  332. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c1.magma_out +95 -0
  333. snappy/ptolemy/testing_files/m015__sl3_c0.magma_out.bz2 +0 -0
  334. snappy/ptolemy/testing_files/m135__sl2_c0.magma_out.bz2 +0 -0
  335. snappy/ptolemy/testing_files/m135__sl2_c1.magma_out.bz2 +0 -0
  336. snappy/ptolemy/testing_files/m135__sl2_c2.magma_out.bz2 +0 -0
  337. snappy/ptolemy/testing_files/m135__sl2_c3.magma_out.bz2 +0 -0
  338. snappy/ptolemy/testing_files/m135__sl2_c4.magma_out.bz2 +0 -0
  339. snappy/ptolemy/testing_files/m135__sl2_c5.magma_out.bz2 +0 -0
  340. snappy/ptolemy/testing_files/m135__sl2_c6.magma_out.bz2 +0 -0
  341. snappy/ptolemy/testing_files/m135__sl2_c7.magma_out.bz2 +0 -0
  342. snappy/ptolemy/testing_files/s000__sl2_c0.magma_out.bz2 +0 -0
  343. snappy/ptolemy/testing_files/s000__sl2_c1.magma_out.bz2 +0 -0
  344. snappy/ptolemy/testing_files/t00000__sl2_c0.magma_out.bz2 +0 -0
  345. snappy/ptolemy/testing_files/t00000__sl2_c1.magma_out.bz2 +0 -0
  346. snappy/ptolemy/testing_files/v0000__sl2_c0.magma_out.bz2 +0 -0
  347. snappy/ptolemy/testing_files/v0000__sl2_c1.magma_out.bz2 +0 -0
  348. snappy/ptolemy/testing_files/v0000__sl2_c2.magma_out.bz2 +0 -0
  349. snappy/ptolemy/testing_files/v0000__sl2_c3.magma_out.bz2 +0 -0
  350. snappy/ptolemy/testing_files_generalized/m003__sl2_c0.magma_out.bz2 +0 -0
  351. snappy/ptolemy/testing_files_generalized/m003__sl2_c1.magma_out.bz2 +0 -0
  352. snappy/ptolemy/testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  353. snappy/ptolemy/testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  354. snappy/ptolemy/testing_files_generalized/m004__sl2_c0.magma_out.bz2 +0 -0
  355. snappy/ptolemy/testing_files_generalized/m004__sl2_c1.magma_out.bz2 +0 -0
  356. snappy/ptolemy/testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  357. snappy/ptolemy/testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  358. snappy/ptolemy/testing_files_rur/m052__sl3_c0.rur.bz2 +0 -0
  359. snappy/ptolemy/utilities.py +236 -0
  360. snappy/raytracing/__init__.py +64 -0
  361. snappy/raytracing/additional_horospheres.py +64 -0
  362. snappy/raytracing/additional_len_spec_choices.py +63 -0
  363. snappy/raytracing/cohomology_fractal.py +197 -0
  364. snappy/raytracing/eyeball.py +123 -0
  365. snappy/raytracing/finite_raytracing_data.py +237 -0
  366. snappy/raytracing/finite_viewer.py +590 -0
  367. snappy/raytracing/geodesic_tube_info.py +174 -0
  368. snappy/raytracing/geodesics.py +246 -0
  369. snappy/raytracing/geodesics_window.py +258 -0
  370. snappy/raytracing/gui_utilities.py +293 -0
  371. snappy/raytracing/hyperboloid_navigation.py +556 -0
  372. snappy/raytracing/hyperboloid_utilities.py +234 -0
  373. snappy/raytracing/ideal_raytracing_data.py +592 -0
  374. snappy/raytracing/inside_viewer.py +974 -0
  375. snappy/raytracing/pack.py +22 -0
  376. snappy/raytracing/raytracing_data.py +126 -0
  377. snappy/raytracing/raytracing_view.py +454 -0
  378. snappy/raytracing/shaders/Eye.png +0 -0
  379. snappy/raytracing/shaders/NonGeometric.png +0 -0
  380. snappy/raytracing/shaders/__init__.py +101 -0
  381. snappy/raytracing/shaders/fragment.glsl +1744 -0
  382. snappy/raytracing/test.py +29 -0
  383. snappy/raytracing/tooltip.py +146 -0
  384. snappy/raytracing/upper_halfspace_utilities.py +98 -0
  385. snappy/raytracing/view_scale_controller.py +98 -0
  386. snappy/raytracing/zoom_slider/__init__.py +263 -0
  387. snappy/raytracing/zoom_slider/inward.png +0 -0
  388. snappy/raytracing/zoom_slider/inward18.png +0 -0
  389. snappy/raytracing/zoom_slider/outward.png +0 -0
  390. snappy/raytracing/zoom_slider/outward18.png +0 -0
  391. snappy/raytracing/zoom_slider/test.py +20 -0
  392. snappy/sage_helper.py +117 -0
  393. snappy/settings.py +409 -0
  394. snappy/shell.py +53 -0
  395. snappy/snap/__init__.py +114 -0
  396. snappy/snap/character_varieties.py +375 -0
  397. snappy/snap/find_field.py +372 -0
  398. snappy/snap/fundamental_polyhedron.py +569 -0
  399. snappy/snap/generators.py +39 -0
  400. snappy/snap/interval_reps.py +81 -0
  401. snappy/snap/kernel_structures.py +128 -0
  402. snappy/snap/mcomplex_base.py +18 -0
  403. snappy/snap/nsagetools.py +702 -0
  404. snappy/snap/peripheral/__init__.py +1 -0
  405. snappy/snap/peripheral/dual_cellulation.py +219 -0
  406. snappy/snap/peripheral/link.py +127 -0
  407. snappy/snap/peripheral/peripheral.py +159 -0
  408. snappy/snap/peripheral/surface.py +522 -0
  409. snappy/snap/peripheral/test.py +35 -0
  410. snappy/snap/polished_reps.py +335 -0
  411. snappy/snap/shapes.py +152 -0
  412. snappy/snap/slice_obs_HKL.py +668 -0
  413. snappy/snap/t3mlite/__init__.py +2 -0
  414. snappy/snap/t3mlite/arrow.py +243 -0
  415. snappy/snap/t3mlite/corner.py +22 -0
  416. snappy/snap/t3mlite/edge.py +172 -0
  417. snappy/snap/t3mlite/face.py +37 -0
  418. snappy/snap/t3mlite/files.py +211 -0
  419. snappy/snap/t3mlite/homology.py +53 -0
  420. snappy/snap/t3mlite/linalg.py +419 -0
  421. snappy/snap/t3mlite/mcomplex.py +1499 -0
  422. snappy/snap/t3mlite/perm4.py +320 -0
  423. snappy/snap/t3mlite/setup.py +12 -0
  424. snappy/snap/t3mlite/simplex.py +199 -0
  425. snappy/snap/t3mlite/spun.py +297 -0
  426. snappy/snap/t3mlite/surface.py +519 -0
  427. snappy/snap/t3mlite/test.py +20 -0
  428. snappy/snap/t3mlite/test_vs_regina.py +86 -0
  429. snappy/snap/t3mlite/tetrahedron.py +109 -0
  430. snappy/snap/t3mlite/vertex.py +42 -0
  431. snappy/snap/test.py +134 -0
  432. snappy/snap/utilities.py +288 -0
  433. snappy/test.py +209 -0
  434. snappy/test_cases.py +263 -0
  435. snappy/testing.py +131 -0
  436. snappy/tiling/__init__.py +2 -0
  437. snappy/tiling/canonical_key_dict.py +59 -0
  438. snappy/tiling/dict_based_set.py +79 -0
  439. snappy/tiling/floor.py +49 -0
  440. snappy/tiling/hyperboloid_dict.py +54 -0
  441. snappy/tiling/iter_utils.py +78 -0
  442. snappy/tiling/lifted_tetrahedron.py +22 -0
  443. snappy/tiling/lifted_tetrahedron_set.py +54 -0
  444. snappy/tiling/real_hash_dict.py +164 -0
  445. snappy/tiling/test.py +23 -0
  446. snappy/tiling/tile.py +215 -0
  447. snappy/tiling/triangle.py +33 -0
  448. snappy/tkterminal.py +920 -0
  449. snappy/twister/__init__.py +20 -0
  450. snappy/twister/main.py +646 -0
  451. snappy/twister/surfaces/S_0_1 +3 -0
  452. snappy/twister/surfaces/S_0_2 +3 -0
  453. snappy/twister/surfaces/S_0_4 +7 -0
  454. snappy/twister/surfaces/S_0_4_Lantern +8 -0
  455. snappy/twister/surfaces/S_1 +3 -0
  456. snappy/twister/surfaces/S_1_1 +4 -0
  457. snappy/twister/surfaces/S_1_2 +5 -0
  458. snappy/twister/surfaces/S_1_2_5 +6 -0
  459. snappy/twister/surfaces/S_2 +6 -0
  460. snappy/twister/surfaces/S_2_1 +8 -0
  461. snappy/twister/surfaces/S_2_heeg +10 -0
  462. snappy/twister/surfaces/S_3 +8 -0
  463. snappy/twister/surfaces/S_3_1 +10 -0
  464. snappy/twister/surfaces/S_4_1 +12 -0
  465. snappy/twister/surfaces/S_5_1 +14 -0
  466. snappy/twister/surfaces/heeg_fig8 +9 -0
  467. snappy/twister/twister_core.cpython-310-darwin.so +0 -0
  468. snappy/upper_halfspace/__init__.py +146 -0
  469. snappy/upper_halfspace/ideal_point.py +26 -0
  470. snappy/verify/__init__.py +13 -0
  471. snappy/verify/canonical.py +542 -0
  472. snappy/verify/complex_volume/__init__.py +18 -0
  473. snappy/verify/complex_volume/adjust_torsion.py +86 -0
  474. snappy/verify/complex_volume/closed.py +168 -0
  475. snappy/verify/complex_volume/compute_ptolemys.py +90 -0
  476. snappy/verify/complex_volume/cusped.py +56 -0
  477. snappy/verify/complex_volume/extended_bloch.py +201 -0
  478. snappy/verify/cusp_translations.py +85 -0
  479. snappy/verify/edge_equations.py +80 -0
  480. snappy/verify/exceptions.py +254 -0
  481. snappy/verify/hyperbolicity.py +224 -0
  482. snappy/verify/interval_newton_shapes_engine.py +523 -0
  483. snappy/verify/interval_tree.py +400 -0
  484. snappy/verify/krawczyk_shapes_engine.py +518 -0
  485. snappy/verify/maximal_cusp_area_matrix/__init__.py +46 -0
  486. snappy/verify/maximal_cusp_area_matrix/cusp_tiling_engine.py +419 -0
  487. snappy/verify/maximal_cusp_area_matrix/cusp_translate_engine.py +153 -0
  488. snappy/verify/real_algebra.py +286 -0
  489. snappy/verify/shapes.py +25 -0
  490. snappy/verify/short_slopes.py +200 -0
  491. snappy/verify/square_extensions.py +1005 -0
  492. snappy/verify/test.py +78 -0
  493. snappy/verify/upper_halfspace/__init__.py +9 -0
  494. snappy/verify/upper_halfspace/extended_matrix.py +100 -0
  495. snappy/verify/upper_halfspace/finite_point.py +283 -0
  496. snappy/verify/upper_halfspace/ideal_point.py +426 -0
  497. snappy/verify/volume.py +128 -0
  498. snappy/version.py +2 -0
  499. snappy-3.2.dist-info/METADATA +58 -0
  500. snappy-3.2.dist-info/RECORD +503 -0
  501. snappy-3.2.dist-info/WHEEL +5 -0
  502. snappy-3.2.dist-info/entry_points.txt +2 -0
  503. snappy-3.2.dist-info/top_level.txt +28 -0
@@ -0,0 +1,136 @@
1
+ from ..geometric_structure.cusp_neighborhood.tiles_for_cusp_neighborhood import (
2
+ mcomplex_for_tiling_cusp_neighborhoods)
3
+ from ..tiling.tile import Tile
4
+
5
+ from ..matrix import make_matrix
6
+ from ..sage_helper import _within_sage
7
+ from ..math_basics import correct_min, is_RealIntervalFieldElement, lower
8
+
9
+ from ..hyperboloid.distances import distance_r13_horoballs
10
+
11
+ if _within_sage:
12
+ from ..sage_helper import Infinity
13
+
14
+ def maximal_cusp_area_matrix(manifold, bits_prec, verified):
15
+ """
16
+ A test case that hits both the tiling case and the early bail case
17
+ (using v.exp_self_distance_along_edges):
18
+
19
+ >>> from snappy import Manifold
20
+ >>> M = Manifold("o9_44206")
21
+ >>> maximal_cusp_area_matrix(M, bits_prec=53, verified=False) # doctest: +NUMERIC9
22
+ [88.4588035788544 14.3590180492058 11.4136568679715 9.67661682098105]
23
+ [14.3590180492058 88.4588035788533 9.67661682098102 11.4136568679705]
24
+ [11.4136568679715 9.67661682098102 88.4588035788541 14.3590180492042]
25
+ [9.67661682098105 11.4136568679705 14.3590180492042 88.4588035788038]
26
+
27
+ sage: from snappy import Manifold
28
+ sage: M = Manifold("o9_44206")
29
+ sage: maximal_cusp_area_matrix(M, bits_prec=80, verified=True) # doctest: +NUMERIC6
30
+ [ 88.458803578854197094? 14.3590180492058335371? 11.4136568679715291317? 9.6766168209810445566?]
31
+ [14.3590180492058335371? 88.4588035789? 9.676616820981044? 11.4136568680?]
32
+ [11.4136568679715291317? 9.676616820981044? 88.45880357885420? 14.35901804921?]
33
+ [ 9.6766168209810445566? 11.4136568680? 14.35901804921? 88.458803578?]
34
+ """
35
+
36
+ mcomplex = mcomplex_for_tiling_cusp_neighborhoods(
37
+ manifold, bits_prec=bits_prec, verified=verified)
38
+
39
+ n = len(mcomplex.Vertices)
40
+
41
+ lower_entries = [
42
+ [ _entry(mcomplex, i, j) for j in range(i + 1) ]
43
+ for i in range(n) ]
44
+
45
+ return make_matrix(
46
+ [[ lower_entries[i][j] if j < i else lower_entries[j][i]
47
+ for j in range(n) ]
48
+ for i in range(n) ])
49
+
50
+ def _entry(mcomplex, i, j):
51
+ p = mcomplex.Vertices[i].cusp_area * mcomplex.Vertices[j].cusp_area
52
+
53
+ if i == j:
54
+ return p * _diagonal_scale(mcomplex, i)
55
+ else:
56
+ return p * _non_diagonal_scale(mcomplex, i, j)
57
+
58
+ def _diagonal_scale(mcomplex, i):
59
+ v = mcomplex.Vertices[i]
60
+ e = v.exp_self_distance_along_edges
61
+ if not e is None:
62
+ if e < v.scale_for_std_form ** 2:
63
+ return e ** 2
64
+
65
+ if mcomplex.verified:
66
+ d = mcomplex.RF(Infinity)
67
+ else:
68
+ d = mcomplex.RF(1e20)
69
+
70
+ tet_to_lifts = [ [] for tet in mcomplex.Tetrahedra ]
71
+
72
+ for tile in v.tiles():
73
+ if tile.lower_bound_distance > d / 2:
74
+ return (2 * d).exp() # Area, so need square
75
+
76
+ new_lift = tile.inverse_lifted_geometric_object.defining_vec
77
+
78
+ tet_index = tile.lifted_tetrahedron.tet.Index
79
+
80
+ lifts = tet_to_lifts[tet_index]
81
+ for lift in lifts:
82
+ d = correct_min([d,
83
+ distance_r13_horoballs(new_lift, lift)])
84
+ lifts.append(new_lift)
85
+
86
+ def _non_diagonal_scale(mcomplex, i, j):
87
+ v0 = mcomplex.Vertices[i]
88
+ v1 = mcomplex.Vertices[j]
89
+ c = mcomplex.real_cusp_cross_section
90
+ e = c.exp_distance_neighborhoods_measured_along_edges(i, j)
91
+ if not e is None:
92
+ if e < v0.scale_for_std_form * v1.scale_for_std_form:
93
+ return e ** 2
94
+
95
+ if mcomplex.verified:
96
+ d = mcomplex.RF(Infinity)
97
+ else:
98
+ d = mcomplex.RF(1e20)
99
+
100
+ obj_to_tet_to_lifts = [ [ [] for tet in mcomplex.Tetrahedra ]
101
+ for i in range(2) ]
102
+
103
+ for tile in _merge_tiles([v0.tiles(), v1.tiles()]):
104
+ if tile.lower_bound_distance > d:
105
+ return (2 * d).exp()
106
+
107
+ new_lift = tile.inverse_lifted_geometric_object.defining_vec
108
+ tet_index = tile.lifted_tetrahedron.tet.Index
109
+
110
+ for lift in obj_to_tet_to_lifts[1 - tile.object_index][tet_index]:
111
+ d = correct_min([d,
112
+ distance_r13_horoballs(new_lift, lift)])
113
+ obj_to_tet_to_lifts[tile.object_index][tet_index].append(new_lift)
114
+
115
+ def _merge_tiles(streams_of_tiles):
116
+
117
+ iters = [ iter(s) for s in streams_of_tiles ]
118
+ tiles = [ next(iter) for iter in iters ]
119
+
120
+ while True:
121
+ i = _argmin(*(lower(tile.lower_bound_distance) for tile in tiles))
122
+ tile = tiles[i]
123
+ yield Tile(
124
+ # Relying on -inf + x = -inf
125
+ sum(t.lower_bound_distance for t in tiles),
126
+ tile.inverse_lifted_geometric_object,
127
+ tile.lifted_tetrahedron,
128
+ i)
129
+
130
+ tiles[i] = next(iters[i])
131
+
132
+ def _argmin(v0, v1):
133
+ if v0 < v1:
134
+ return 0
135
+ else:
136
+ return 1
snappy/cusps/test.py ADDED
@@ -0,0 +1,21 @@
1
+ from snappy import testing
2
+ import snappy
3
+
4
+ from snappy import cusps
5
+
6
+ modules = [
7
+ cusps.maximal_cusp_area_matrix,
8
+ cusps.cusp_areas_from_matrix
9
+ ]
10
+
11
+ def run_doctests(verbose=False, print_info=True):
12
+ globs = {'Manifold': snappy.Manifold}
13
+ return testing.doctest_modules(modules,
14
+ verbose=verbose,
15
+ print_info=print_info,
16
+ extraglobs=globs)
17
+
18
+ run_doctests.__name__ = cusps.__name__
19
+
20
+ if __name__ == '__main__':
21
+ testing.run_doctests_as_main(run_doctests)
@@ -0,0 +1,63 @@
1
+ from ..geometric_structure.cusp_neighborhood.real_cusp_cross_section import RealCuspCrossSection
2
+ from ..math_basics import correct_min
3
+ from ..verify.shapes import compute_hyperbolic_shapes
4
+ from ..matrix import make_matrix
5
+
6
+ __all__ = ['triangulation_dependent_cusp_area_matrix',
7
+ 'triangulation_dependent_cusp_area_matrix_from_cusp_cross_section']
8
+
9
+ def triangulation_dependent_cusp_area_matrix(
10
+ snappy_manifold, bits_prec, verified):
11
+ """
12
+ Interesting case: t12521
13
+
14
+ Maximal cusp area matrix:
15
+
16
+ [ 77.5537626509970512653317518641810890989543820290380458409? 11.40953140648583915022197187043644048603871960228564151087?]
17
+ [11.40953140648583915022197187043644048603871960228564151087? 91.1461442179608339668518063027198489593908228325190920?]
18
+
19
+ This result:
20
+
21
+ [ 77.553762651? 11.409531407?]
22
+ [ 11.409531407? 5.508968850234?]
23
+
24
+ After M.canonize:
25
+
26
+ [ 62.42018359? 11.409531407?]
27
+ [ 11.409531407? 15.1140644993?]
28
+ """
29
+ # Get shapes, as intervals if requested
30
+ shapes = compute_hyperbolic_shapes(
31
+ snappy_manifold, verified=verified, bits_prec=bits_prec)
32
+
33
+ # Compute cusp cross section, the code is agnostic about whether
34
+ # the numbers are floating-point or intervals.
35
+ #
36
+ # Note that the constructed cusp cross section will always be too "large"
37
+ # and we need to scale them down (since during construction the
38
+ # cross-section of each cusp will have one edge of length 1, the
39
+ # corresponding tetrahedron does not intersect in "standard" form.)
40
+
41
+ return triangulation_dependent_cusp_area_matrix_from_cusp_cross_section(
42
+ RealCuspCrossSection.fromManifoldAndShapes(snappy_manifold, shapes))
43
+
44
+ def triangulation_dependent_cusp_area_matrix_from_cusp_cross_section(c):
45
+
46
+ # Scale (up or down) all the cusps so that they are in standard form.
47
+ c.ensure_std_form(allow_scaling_up=True)
48
+
49
+ areas = c.cusp_areas()
50
+ RIF = areas[0].parent()
51
+
52
+ def entry(i, j):
53
+ result = areas[i] * areas[j]
54
+
55
+ d = c.exp_distance_neighborhoods_measured_along_edges(i, j)
56
+ if d is not None:
57
+ result *= correct_min([ RIF(1), d ]) ** 2
58
+ return result
59
+
60
+ n = len(areas)
61
+
62
+ return make_matrix([[entry(i, j) for i in range(n)]
63
+ for j in range(n)])
snappy/database.py ADDED
@@ -0,0 +1,454 @@
1
+ """
2
+ This module uses the Manifold class from the SnapPy extension
3
+ module. After the Manifold class has been defined, the "__init__.py"
4
+ module for "snappy" itself sets::
5
+
6
+ database.Manifold = Manifold
7
+
8
+ This file simply defines the ManifoldTable class. The ManifoldTables
9
+ that come with actual data are defined in external packages, such as
10
+ the required "snappy_manifolds". Such a package must provide a
11
+ "get_tables" function that accepts the below "ManifoldTable" as input
12
+ and returns a list of subclasses of "ManifoldTable".
13
+ """
14
+ from .db_utilities import decode_torsion, decode_matrices, db_hash
15
+ from .sage_helper import _within_sage
16
+ from spherogram.codecs import DTcodec
17
+ import sys
18
+ import sqlite3
19
+ import re
20
+ import random
21
+ import importlib
22
+ import collections
23
+
24
+ if _within_sage:
25
+ from .sage_helper import Integer, RealDoubleElement, RealNumber
26
+
27
+ def is_int(slice):
28
+ return isinstance(slice, (Integer, int))
29
+
30
+ def is_int_or_none(slice):
31
+ return isinstance(slice, (Integer, int, type(None)))
32
+
33
+ def is_float_or_none(slice):
34
+ return isinstance(slice, (float, RealDoubleElement,
35
+ RealNumber, type(None)))
36
+ else:
37
+ def is_int(slice):
38
+ return isinstance(slice, int)
39
+
40
+ def is_int_or_none(slice):
41
+ return isinstance(slice, (int, type(None)))
42
+
43
+ def is_float_or_none(slice):
44
+ return isinstance(slice, (float, type(None)))
45
+
46
+ split_filling_info = re.compile(r'(.*?)((?:\([0-9 .+-]+,[0-9 .+-]+\))*$)')
47
+
48
+
49
+ def connect_to_db(db_path):
50
+ """
51
+ Open the given sqlite database, ideally in read-only mode.
52
+ """
53
+ if sys.version_info >= (3,4):
54
+ uri = 'file:' + db_path + '?mode=ro'
55
+ return sqlite3.connect(uri, uri=True)
56
+ elif sys.platform.startswith('win'):
57
+ try:
58
+ import apsw
59
+ return apsw.Connection(db_path, flags=apsw.SQLITE_OPEN_READONLY)
60
+ except ImportError:
61
+ return sqlite3.connect(db_path)
62
+ else:
63
+ return sqlite3.connect(db_path)
64
+
65
+
66
+ def mfld_hash(manifold):
67
+ """
68
+ We cache the hash to speed up searching for one manifold in
69
+ multiple tables.
70
+ """
71
+ if 'db_hash' not in manifold._cache:
72
+ manifold._cache['db_hash'] = db_hash(manifold)
73
+ return manifold._cache['db_hash']
74
+
75
+
76
+ class ManifoldTable():
77
+ """
78
+ Iterator for cusped manifolds in an sqlite3 table of manifolds.
79
+
80
+ Initialize with the table name. The table schema is required to
81
+ include a text field called 'name' and a text field called
82
+ 'triangulation'. The text holds the result of
83
+ M.triangulation_isosig(), M.triangulation_isosig(decorated = True), or
84
+ M._to_string().
85
+
86
+ Both mapping from the manifold name, and lookup by index are
87
+ supported. Slicing can be done either by numerical index or by
88
+ volume.
89
+
90
+ The __contains__ method is supported, so M in T returns True if M
91
+ is isometric to a manifold in the table T. The method
92
+ T.identify(M) will return the matching manifold from the table.
93
+ """
94
+ # basic select clause. Can be overridden, e.g. to add additional columns
95
+ _select = 'select name, triangulation from %s '
96
+
97
+ def __init__(self, table='', db_path=None,
98
+ mfld_hash=mfld_hash, **filter_args):
99
+ self._table = table
100
+ self.mfld_hash = mfld_hash
101
+ self._db_path = db_path
102
+ self._connection = connect_to_db(db_path)
103
+ self._cursor = self._connection.cursor()
104
+ self._set_schema()
105
+ self._check_schema()
106
+ self._configure(**filter_args)
107
+ self._get_length()
108
+ self._get_max_volume()
109
+ self._select = self._select % table
110
+
111
+ def _set_schema(self):
112
+ cursor, table = self._cursor, self._table
113
+ rows = cursor.execute("pragma table_info('%s')" % table).fetchall()
114
+ self.schema = {row[1]: row[2].lower() for row in rows}
115
+
116
+ def _check_schema(self):
117
+ assert (self.schema['name'] == 'text' and
118
+ self.schema['triangulation'] == 'text'
119
+ ), 'Not a valid Manifold table.'
120
+
121
+ @property
122
+ def filter(self):
123
+ return self._filter
124
+
125
+ def _get_length(self):
126
+ where_clause = 'where ' + self._filter if self._filter else ''
127
+ length_query = 'select count(*) from %s %s' % (self._table,
128
+ where_clause)
129
+ cursor = self._cursor.execute(length_query)
130
+ self._length = cursor.fetchone()[0]
131
+
132
+ min_id_query = 'select min(id) from %s %s' % (self._table, where_clause)
133
+ cursor = self._cursor.execute(min_id_query)
134
+ self._min_id = cursor.fetchone()[0]
135
+
136
+ max_id_query = 'select max(id) from %s %s' % (self._table, where_clause)
137
+ cursor = self._cursor.execute(max_id_query)
138
+ self._max_id = cursor.fetchone()[0]
139
+
140
+ if self._length > 0:
141
+ self._ids_contiguous = self._length == (self._max_id - self._min_id + 1)
142
+
143
+ def _get_max_volume(self):
144
+ where_clause = 'where ' + self._filter if self._filter else ''
145
+ vol_query = 'select max(volume) from %s %s' % (self._table,
146
+ where_clause)
147
+ cursor = self._cursor.execute(vol_query)
148
+ self._max_volume = cursor.fetchone()[0]
149
+
150
+ def _configure(self, **kwargs):
151
+ """
152
+ Set up the filter.
153
+ """
154
+ conditions = []
155
+
156
+ if 'filter' in kwargs:
157
+ conditions.append(kwargs['filter'])
158
+ if 'betti' in kwargs:
159
+ conditions.append('betti=%d ' % kwargs['betti'])
160
+ if 'num_cusps' in kwargs:
161
+ conditions.append('cusps=%d ' % kwargs['num_cusps'])
162
+ if 'cusps' in kwargs:
163
+ conditions.append('cusps=%d ' % kwargs['cusps'])
164
+ if 'num_tets' in kwargs:
165
+ conditions.append('tets=%d ' % kwargs['num_tets'])
166
+ if 'tets' in kwargs:
167
+ conditions.append('tets=%d ' % kwargs['tets'])
168
+ self._filter = ' and '.join(conditions)
169
+
170
+ def __repr__(self):
171
+ class_name = self.__class__.__name__
172
+ if self._filter == '':
173
+ return '%s without filters' % class_name
174
+ else:
175
+ return '%s with filter: %s' % (class_name, self._filter)
176
+
177
+ def __call__(self, **kwargs):
178
+ return self.__class__(**kwargs)
179
+
180
+ def __len__(self):
181
+ return self._length
182
+
183
+ def __iter__(self):
184
+ query = self._select
185
+ if self._filter:
186
+ query += ' where %s order by id' % self._filter
187
+ cursor = self._connection.cursor()
188
+ for row in cursor.execute(query):
189
+ yield self._manifold_factory(row)
190
+
191
+ def __contains__(self, mfld):
192
+ try:
193
+ M = self.identify(mfld)
194
+ # duck test
195
+ return M.num_tetrahedra() > 0
196
+ except:
197
+ return False
198
+
199
+ def __getitem__(self, index):
200
+ if isinstance(index, slice):
201
+ if index.step:
202
+ raise IndexError('Slices with steps are not supported.')
203
+ start, stop = index.start, index.stop
204
+ if is_float_or_none(start) and is_float_or_none(stop):
205
+ # Slice by volume.
206
+ conditions = []
207
+ if self._filter:
208
+ conditions.append(self._filter)
209
+ if start:
210
+ conditions.append('volume >= %f' % start)
211
+ if stop:
212
+ conditions.append('volume < %f' % stop)
213
+ filter = ' and '.join(conditions)
214
+ return self.__class__(filter=filter)
215
+ elif (is_int_or_none(start) and is_int_or_none(stop)):
216
+ if start is None:
217
+ start = 0
218
+ elif start < 0:
219
+ start = int(self._length + start)
220
+ if stop is None:
221
+ stop = self._length
222
+ elif stop < 0:
223
+ stop = int(self._length + stop)
224
+ conditions = []
225
+ base_query = 'select id from %s ' % self._table
226
+ if self._filter:
227
+ base_query += 'where %s ' % self._filter
228
+ query = base_query + 'order by id limit 1 offset %d' % start
229
+ start_id = self._cursor.execute(query).fetchone()
230
+ if start_id is not None:
231
+ conditions.append('id >= %d' % start_id[0])
232
+ query = base_query + 'order by id limit 1 offset %d' % stop
233
+ stop_id = self._cursor.execute(query).fetchone()
234
+ if stop_id is not None:
235
+ conditions.append('id < %d' % stop_id[0])
236
+ if self._filter:
237
+ conditions.append(self._filter)
238
+ return self.__class__(filter=' and '.join(conditions))
239
+ else:
240
+ raise IndexError(
241
+ 'Use two ints or two floats for start and stop.')
242
+ elif is_int(index):
243
+ if index < 0:
244
+ index = self._length + index
245
+ matches = self.find(limit=1, offset=index)
246
+ if len(matches) != 1:
247
+ raise IndexError('Manifold index is out of bounds')
248
+ elif isinstance(index, str):
249
+ matches = self.find("name='%s'" % index)
250
+ if len(matches) != 1:
251
+ raise KeyError('The manifold %s was not found.' % index)
252
+ else:
253
+ raise IndexError('%s is not a valid index type for manifolds.' %
254
+ type(index))
255
+ return matches[0]
256
+
257
+ def _manifold_factory(self, row, M=None):
258
+ """
259
+ Factory for "select name, triangulation" queries.
260
+ Returns a Manifold.
261
+ """
262
+
263
+ if M is None:
264
+ M = Manifold('empty')
265
+
266
+ # Get fillings, if any
267
+ m = split_filling_info.match(row[1])
268
+ isosig = m.group(1)
269
+ M._from_isosig(isosig)
270
+
271
+ fillings = eval( '[' + m.group(2).replace(')(', '),(') + ']', {})
272
+
273
+ if fillings:
274
+ M.dehn_fill(fillings)
275
+
276
+ self._finalize(M, row)
277
+ return M
278
+
279
+ def _finalize(self, M, row):
280
+ """
281
+ Give the manifold a name. Override this method for custom
282
+ manifold production.
283
+ """
284
+ M.set_name(row[0])
285
+
286
+ def _one_manifold(self, name, M):
287
+ """
288
+ Inflates the given empty Manifold with the table manifold
289
+ with the specified name.
290
+ """
291
+ if hasattr(self, '_regex'):
292
+ if self._regex.match(name) is None:
293
+ raise KeyError('The manifold %s was not found.' % name)
294
+ cursor = self._cursor.execute(self._select + "where name='" + name + "'")
295
+ rows = cursor.fetchall()
296
+ if len(rows) != 1:
297
+ raise KeyError('The manifold %s was not found.' % name)
298
+ return self._manifold_factory(rows[0], M)
299
+
300
+ def keys(self):
301
+ """
302
+ Return the list of column names for this manifold table.
303
+ """
304
+ return self.schema.keys()
305
+
306
+ def find(self, where=None, order_by='id', limit=None, offset=None):
307
+ """
308
+ Return a list of up to limit manifolds stored in this table,
309
+ satisfying the where clause, and ordered by the order_by
310
+ clause. If limit is None, all matching manifolds are
311
+ returned. If the offset parameter is set, the first offset
312
+ matches are skipped.
313
+ """
314
+ conditions = [cond for cond in [self._filter, where] if cond]
315
+ suffix = ' where ' if conditions else ' '
316
+ suffix += ' and '.join(conditions)
317
+ suffix += ' order by %s' % order_by
318
+ if limit is not None:
319
+ suffix += ' limit %d' % limit
320
+ if offset is not None:
321
+ suffix += ' offset %d' % offset
322
+ cursor = self._cursor.execute(self._select + suffix)
323
+ return [self._manifold_factory(row) for row in cursor.fetchall()]
324
+
325
+ def siblings(self, mfld):
326
+ """
327
+ Return all manifolds in the census which have the same hash value.
328
+ """
329
+ vol = mfld.volume()
330
+ epsilon = vol / 1e5
331
+ v_lower, v_upper = vol - epsilon, vol + epsilon
332
+ cusps = mfld.cusp_info('is_complete').count(True)
333
+ H = mfld.homology()
334
+ betti = H.betti_number()
335
+ torsion = [c for c in H.elementary_divisors() if c != 0]
336
+ txt = "volume between %f and %f and cusps=%d and betti=%d and torsion='%s'"
337
+ initial_candidates = self.find(txt % (v_lower, v_upper, cusps,
338
+ betti, torsion))
339
+ if not initial_candidates:
340
+ return []
341
+ return self.find("hash = '%s'" % self.mfld_hash(mfld))
342
+
343
+ def identify(self, mfld, extends_to_link=False):
344
+ """
345
+ Look for a manifold in this table which is isometric to the
346
+ argument.
347
+
348
+ Return the matching manifold, if there is one which SnapPea
349
+ declares to be isometric.
350
+
351
+ Return False if no manifold in the table has the same hash.
352
+
353
+ Return None in all other cases (for now).
354
+
355
+ If the flag "extends_to_link" is True, requires that the isometry
356
+ sends meridians to meridians. If the input manifold is closed
357
+ this will result in no matches being returned.
358
+ """
359
+ if hasattr(mfld, 'volume'):
360
+ bad_types = ['no solution found', 'not attempted']
361
+ if mfld.solution_type() in bad_types:
362
+ return False
363
+ if mfld.volume() > self._max_volume + 0.1:
364
+ return False
365
+
366
+ if extends_to_link and not (True in mfld.cusp_info('complete?')):
367
+ return False
368
+
369
+ sibs = self.siblings(mfld)
370
+ if len(sibs) == 0:
371
+ return False # No hash values match
372
+
373
+ mfld = mfld.copy()
374
+ mflds = [mfld]
375
+ for i in range(4):
376
+ mfld = mfld.copy()
377
+ mfld.randomize()
378
+ mflds.append(mfld)
379
+
380
+ # Check for isometry
381
+ for mfld in mflds:
382
+ for N in sibs:
383
+ try:
384
+ if not extends_to_link:
385
+ if mfld.is_isometric_to(N):
386
+ return N
387
+ else:
388
+ isoms = mfld.is_isometric_to(N, True)
389
+ if True in [i.extends_to_link() for i in isoms]:
390
+ return N
391
+ except RuntimeError:
392
+ pass
393
+
394
+ mfld = Triangulation(mflds[0]) # Drop the hyperbolic structure
395
+ # Check for identical triangulations.
396
+ if (False not in mfld.cusp_info('is_complete')) and not extends_to_link:
397
+ for n in range(100):
398
+ for N in sibs:
399
+ if mfld == N:
400
+ return N
401
+ mfld.randomize()
402
+
403
+ return None
404
+
405
+ def random(self):
406
+ if self._length == 0:
407
+ raise ValueError('ManifoldTable is empty')
408
+ if self._ids_contiguous:
409
+ rand_id = random.randrange(self._min_id, self._max_id + 1)
410
+ query = self._select + ' where id = %d limit 1' % rand_id
411
+ cursor = self._cursor.execute(query)
412
+ return self._manifold_factory(cursor.fetchone())
413
+ return self[random.randrange(len(self))]
414
+
415
+ # The below function is used to add ManifoldTables defined in external
416
+ # packages.
417
+
418
+
419
+ this_module = sys.modules[__name__]
420
+ __all_tables__ = collections.OrderedDict()
421
+
422
+
423
+ def add_tables_from_package(package_name, must_succeed=True):
424
+ """
425
+ Given a string with the name of an importable Python package that
426
+ implements a "get_tables" function, load all the tables provided
427
+ and put the results where the rest of SnapPy can find them.
428
+ Returns an ordered dictionary of pairs (table_name, table).
429
+ """
430
+
431
+ try:
432
+ package = importlib.import_module(package_name)
433
+ except ImportError:
434
+ if not must_succeed:
435
+ return {}
436
+ else:
437
+ raise ImportError('ManifoldTable package %s not found'
438
+ % package_name)
439
+
440
+ new_tables = collections.OrderedDict()
441
+ for table in package.get_tables(ManifoldTable):
442
+ name = table.__class__.__name__
443
+ new_tables[name] = table
444
+ __all_tables__[name] = table
445
+ setattr(this_module, name, table)
446
+
447
+ # We also store the tables here so that their doctests can be
448
+ # checked.
449
+ if not hasattr(this_module, '__test__'):
450
+ this_module.__test__ = {}
451
+ for name, table in new_tables.items():
452
+ this_module.__test__[name] = table.__class__
453
+
454
+ return new_tables