snappy 3.0.3__cp38-cp38-macosx_11_0_arm64.whl → 3.2__cp38-cp38-macosx_11_0_arm64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (401) hide show
  1. snappy/CyOpenGL.cpython-38-darwin.so +0 -0
  2. snappy/SnapPy.cpython-38-darwin.so +0 -0
  3. snappy/SnapPyHP.cpython-38-darwin.so +0 -0
  4. snappy/__init__.py +373 -426
  5. snappy/app.py +240 -75
  6. snappy/app_menus.py +93 -78
  7. snappy/browser.py +87 -63
  8. snappy/cache.py +5 -8
  9. snappy/canonical.py +249 -0
  10. snappy/{verify/cusp_shapes.py → cusps/__init__.py} +11 -19
  11. snappy/cusps/cusp_area_matrix.py +101 -0
  12. snappy/{verify/cusp_areas.py → cusps/cusp_areas_from_matrix.py} +39 -54
  13. snappy/cusps/maximal_cusp_area_matrix.py +136 -0
  14. snappy/cusps/test.py +21 -0
  15. snappy/cusps/trig_cusp_area_matrix.py +63 -0
  16. snappy/database.py +40 -31
  17. snappy/db_utilities.py +13 -14
  18. snappy/decorated_isosig.py +377 -133
  19. snappy/dev/extended_ptolemy/complexVolumesClosed.py +42 -9
  20. snappy/dev/extended_ptolemy/extended.py +32 -25
  21. snappy/dev/extended_ptolemy/giac_rur.py +23 -8
  22. snappy/dev/extended_ptolemy/phc_wrapper.py +10 -10
  23. snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +2 -1
  24. snappy/dev/vericlosed/gimbalLoopFinder.py +5 -5
  25. snappy/dev/vericlosed/hyperbolicStructure.py +3 -3
  26. snappy/dev/vericlosed/oneVertexTruncatedComplex.py +2 -2
  27. snappy/dev/vericlosed/truncatedComplex.py +3 -2
  28. snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +4 -3
  29. snappy/doc/_images/geodesics.jpg +0 -0
  30. snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
  31. snappy/doc/_images/m125_paper_plane.jpg +0 -0
  32. snappy/doc/_images/o9_00000_systole_paper_plane.jpg +0 -0
  33. snappy/doc/_images/o9_00000_systole_paper_plane_closer.jpg +0 -0
  34. snappy/doc/_sources/additional_classes.rst.txt +1 -0
  35. snappy/doc/_sources/credits.rst.txt +6 -1
  36. snappy/doc/_sources/development.rst.txt +69 -50
  37. snappy/doc/_sources/index.rst.txt +101 -66
  38. snappy/doc/_sources/installing.rst.txt +148 -165
  39. snappy/doc/_sources/news.rst.txt +136 -32
  40. snappy/doc/_sources/ptolemy.rst.txt +1 -1
  41. snappy/doc/_sources/ptolemy_examples1.rst.txt +9 -8
  42. snappy/doc/_sources/ptolemy_examples2.rst.txt +3 -3
  43. snappy/doc/_sources/ptolemy_examples3.rst.txt +14 -14
  44. snappy/doc/_sources/ptolemy_prelim.rst.txt +1 -1
  45. snappy/doc/_sources/snap.rst.txt +2 -2
  46. snappy/doc/_sources/snappy.rst.txt +1 -1
  47. snappy/doc/_sources/triangulation.rst.txt +3 -2
  48. snappy/doc/_sources/verify.rst.txt +89 -29
  49. snappy/doc/_sources/verify_internals.rst.txt +5 -16
  50. snappy/doc/_static/SnapPy-horizontal-128.png +0 -0
  51. snappy/doc/_static/SnapPy.ico +0 -0
  52. snappy/doc/_static/_sphinx_javascript_frameworks_compat.js +123 -0
  53. snappy/doc/_static/basic.css +47 -27
  54. snappy/doc/_static/css/badge_only.css +1 -0
  55. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  56. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  57. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  58. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  59. snappy/doc/_static/css/fonts/fontawesome-webfont.eot +0 -0
  60. snappy/doc/_static/css/fonts/fontawesome-webfont.svg +2671 -0
  61. snappy/doc/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  62. snappy/doc/_static/css/fonts/fontawesome-webfont.woff +0 -0
  63. snappy/doc/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  64. snappy/doc/_static/css/fonts/lato-bold-italic.woff +0 -0
  65. snappy/doc/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  66. snappy/doc/_static/css/fonts/lato-bold.woff +0 -0
  67. snappy/doc/_static/css/fonts/lato-bold.woff2 +0 -0
  68. snappy/doc/_static/css/fonts/lato-normal-italic.woff +0 -0
  69. snappy/doc/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  70. snappy/doc/_static/css/fonts/lato-normal.woff +0 -0
  71. snappy/doc/_static/css/fonts/lato-normal.woff2 +0 -0
  72. snappy/doc/_static/css/theme.css +4 -0
  73. snappy/doc/_static/doctools.js +107 -274
  74. snappy/doc/_static/documentation_options.js +6 -5
  75. snappy/doc/_static/fonts/Lato/lato-bold.eot +0 -0
  76. snappy/doc/_static/fonts/Lato/lato-bold.ttf +0 -0
  77. snappy/doc/_static/fonts/Lato/lato-bold.woff +0 -0
  78. snappy/doc/_static/fonts/Lato/lato-bold.woff2 +0 -0
  79. snappy/doc/_static/fonts/Lato/lato-bolditalic.eot +0 -0
  80. snappy/doc/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
  81. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff +0 -0
  82. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
  83. snappy/doc/_static/fonts/Lato/lato-italic.eot +0 -0
  84. snappy/doc/_static/fonts/Lato/lato-italic.ttf +0 -0
  85. snappy/doc/_static/fonts/Lato/lato-italic.woff +0 -0
  86. snappy/doc/_static/fonts/Lato/lato-italic.woff2 +0 -0
  87. snappy/doc/_static/fonts/Lato/lato-regular.eot +0 -0
  88. snappy/doc/_static/fonts/Lato/lato-regular.ttf +0 -0
  89. snappy/doc/_static/fonts/Lato/lato-regular.woff +0 -0
  90. snappy/doc/_static/fonts/Lato/lato-regular.woff2 +0 -0
  91. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
  92. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
  93. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
  94. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
  95. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
  96. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
  97. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
  98. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
  99. snappy/doc/_static/jquery.js +2 -2
  100. snappy/doc/_static/js/badge_only.js +1 -0
  101. snappy/doc/_static/js/theme.js +1 -0
  102. snappy/doc/_static/js/versions.js +228 -0
  103. snappy/doc/_static/language_data.js +3 -101
  104. snappy/doc/_static/pygments.css +1 -0
  105. snappy/doc/_static/searchtools.js +489 -398
  106. snappy/doc/_static/snappy_furo.css +33 -0
  107. snappy/doc/_static/snappy_sphinx_rtd_theme.css +42 -0
  108. snappy/doc/_static/sphinx_highlight.js +154 -0
  109. snappy/doc/additional_classes.html +688 -263
  110. snappy/doc/bugs.html +107 -94
  111. snappy/doc/censuses.html +155 -127
  112. snappy/doc/credits.html +115 -104
  113. snappy/doc/development.html +184 -146
  114. snappy/doc/genindex.html +287 -204
  115. snappy/doc/index.html +189 -150
  116. snappy/doc/installing.html +259 -266
  117. snappy/doc/manifold.html +1626 -592
  118. snappy/doc/manifoldhp.html +119 -105
  119. snappy/doc/news.html +198 -104
  120. snappy/doc/objects.inv +0 -0
  121. snappy/doc/other.html +117 -105
  122. snappy/doc/platonic_census.html +161 -114
  123. snappy/doc/plink.html +113 -105
  124. snappy/doc/ptolemy.html +131 -108
  125. snappy/doc/ptolemy_classes.html +242 -223
  126. snappy/doc/ptolemy_examples1.html +144 -130
  127. snappy/doc/ptolemy_examples2.html +141 -129
  128. snappy/doc/ptolemy_examples3.html +148 -132
  129. snappy/doc/ptolemy_examples4.html +131 -111
  130. snappy/doc/ptolemy_prelim.html +162 -138
  131. snappy/doc/py-modindex.html +104 -69
  132. snappy/doc/screenshots.html +117 -108
  133. snappy/doc/search.html +115 -84
  134. snappy/doc/searchindex.js +1 -1
  135. snappy/doc/snap.html +109 -96
  136. snappy/doc/snappy.html +134 -97
  137. snappy/doc/spherogram.html +259 -187
  138. snappy/doc/todo.html +107 -94
  139. snappy/doc/triangulation.html +1380 -111
  140. snappy/doc/tutorial.html +107 -94
  141. snappy/doc/verify.html +194 -125
  142. snappy/doc/verify_internals.html +248 -686
  143. snappy/drilling/__init__.py +456 -0
  144. snappy/drilling/barycentric.py +103 -0
  145. snappy/drilling/constants.py +5 -0
  146. snappy/drilling/crush.py +270 -0
  147. snappy/drilling/cusps.py +125 -0
  148. snappy/drilling/debug.py +242 -0
  149. snappy/drilling/epsilons.py +6 -0
  150. snappy/drilling/exceptions.py +55 -0
  151. snappy/drilling/moves.py +620 -0
  152. snappy/drilling/peripheral_curves.py +210 -0
  153. snappy/drilling/perturb.py +188 -0
  154. snappy/drilling/shorten.py +36 -0
  155. snappy/drilling/subdivide.py +274 -0
  156. snappy/drilling/test.py +23 -0
  157. snappy/drilling/test_cases.py +126 -0
  158. snappy/drilling/tracing.py +351 -0
  159. snappy/exceptions.py +23 -3
  160. snappy/export_stl.py +20 -14
  161. snappy/exterior_to_link/__init__.py +2 -0
  162. snappy/exterior_to_link/barycentric_geometry.py +463 -0
  163. snappy/exterior_to_link/exceptions.py +6 -0
  164. snappy/exterior_to_link/geodesic_map.json +14408 -0
  165. snappy/exterior_to_link/hyp_utils.py +112 -0
  166. snappy/exterior_to_link/link_projection.py +323 -0
  167. snappy/exterior_to_link/main.py +197 -0
  168. snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
  169. snappy/exterior_to_link/mcomplex_with_link.py +687 -0
  170. snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
  171. snappy/exterior_to_link/pl_utils.py +491 -0
  172. snappy/exterior_to_link/put_in_S3.py +156 -0
  173. snappy/exterior_to_link/rational_linear_algebra.py +123 -0
  174. snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
  175. snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
  176. snappy/exterior_to_link/stored_moves.py +475 -0
  177. snappy/exterior_to_link/test.py +31 -0
  178. snappy/geometric_structure/__init__.py +212 -0
  179. snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
  180. snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +697 -0
  181. snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +484 -0
  182. snappy/geometric_structure/cusp_neighborhood/exceptions.py +42 -0
  183. snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +298 -0
  184. snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +159 -0
  185. snappy/geometric_structure/cusp_neighborhood/vertices.py +32 -0
  186. snappy/geometric_structure/geodesic/__init__.py +0 -0
  187. snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
  188. snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
  189. snappy/geometric_structure/geodesic/canonical_keys.py +52 -0
  190. snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
  191. snappy/geometric_structure/geodesic/constants.py +6 -0
  192. snappy/geometric_structure/geodesic/exceptions.py +22 -0
  193. snappy/geometric_structure/geodesic/fixed_points.py +93 -0
  194. snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
  195. snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
  196. snappy/geometric_structure/geodesic/line.py +30 -0
  197. snappy/geometric_structure/geodesic/multiplicity.py +127 -0
  198. snappy/geometric_structure/geodesic/tiles_for_geodesic.py +101 -0
  199. snappy/geometric_structure/test.py +22 -0
  200. snappy/gui.py +36 -36
  201. snappy/horoviewer.py +50 -48
  202. snappy/hyperboloid/__init__.py +212 -0
  203. snappy/hyperboloid/distances.py +245 -0
  204. snappy/hyperboloid/horoball.py +19 -0
  205. snappy/hyperboloid/line.py +35 -0
  206. snappy/hyperboloid/point.py +9 -0
  207. snappy/hyperboloid/triangle.py +29 -0
  208. snappy/{infodialog.py → infowindow.py} +32 -33
  209. snappy/isometry_signature.py +382 -0
  210. snappy/len_spec/__init__.py +596 -0
  211. snappy/len_spec/geodesic_info.py +110 -0
  212. snappy/len_spec/geodesic_key_info_dict.py +117 -0
  213. snappy/len_spec/geodesic_piece.py +143 -0
  214. snappy/len_spec/geometric_structure.py +182 -0
  215. snappy/len_spec/geometry.py +80 -0
  216. snappy/len_spec/length_spectrum_geodesic_info.py +170 -0
  217. snappy/len_spec/spine.py +206 -0
  218. snappy/len_spec/test.py +24 -0
  219. snappy/len_spec/test_cases.py +69 -0
  220. snappy/len_spec/tile.py +275 -0
  221. snappy/len_spec/word.py +86 -0
  222. snappy/manifolds/__init__.py +1 -1
  223. snappy/math_basics.py +176 -0
  224. snappy/matrix.py +525 -0
  225. snappy/number.py +97 -21
  226. snappy/numeric_output_checker.py +37 -27
  227. snappy/pari.py +30 -69
  228. snappy/phone_home.py +25 -20
  229. snappy/polyviewer.py +39 -37
  230. snappy/ptolemy/__init__.py +4 -6
  231. snappy/ptolemy/component.py +14 -12
  232. snappy/ptolemy/coordinates.py +312 -295
  233. snappy/ptolemy/fieldExtensions.py +14 -12
  234. snappy/ptolemy/findLoops.py +43 -31
  235. snappy/ptolemy/geometricRep.py +24 -26
  236. snappy/ptolemy/homology.py +12 -7
  237. snappy/ptolemy/manifoldMethods.py +69 -70
  238. snappy/ptolemy/matrix.py +65 -26
  239. snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +18 -14
  240. snappy/ptolemy/polynomial.py +125 -119
  241. snappy/ptolemy/processComponents.py +36 -30
  242. snappy/ptolemy/processFileBase.py +79 -18
  243. snappy/ptolemy/processFileDispatch.py +13 -14
  244. snappy/ptolemy/processMagmaFile.py +44 -39
  245. snappy/ptolemy/processRurFile.py +18 -11
  246. snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +20 -17
  247. snappy/ptolemy/ptolemyObstructionClass.py +13 -17
  248. snappy/ptolemy/ptolemyVariety.py +190 -121
  249. snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +20 -19
  250. snappy/ptolemy/reginaWrapper.py +25 -29
  251. snappy/ptolemy/rur.py +6 -14
  252. snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +27 -22
  253. snappy/ptolemy/test.py +247 -188
  254. snappy/ptolemy/utilities.py +41 -43
  255. snappy/raytracing/__init__.py +64 -0
  256. snappy/raytracing/additional_horospheres.py +64 -0
  257. snappy/raytracing/additional_len_spec_choices.py +63 -0
  258. snappy/raytracing/cohomology_fractal.py +10 -6
  259. snappy/raytracing/eyeball.py +123 -0
  260. snappy/raytracing/finite_raytracing_data.py +48 -38
  261. snappy/raytracing/finite_viewer.py +218 -210
  262. snappy/raytracing/geodesic_tube_info.py +174 -0
  263. snappy/raytracing/geodesics.py +246 -0
  264. snappy/raytracing/geodesics_window.py +258 -0
  265. snappy/raytracing/gui_utilities.py +152 -40
  266. snappy/raytracing/hyperboloid_navigation.py +102 -52
  267. snappy/raytracing/hyperboloid_utilities.py +114 -261
  268. snappy/raytracing/ideal_raytracing_data.py +256 -179
  269. snappy/raytracing/inside_viewer.py +522 -253
  270. snappy/raytracing/pack.py +22 -0
  271. snappy/raytracing/raytracing_data.py +46 -34
  272. snappy/raytracing/raytracing_view.py +190 -109
  273. snappy/raytracing/shaders/Eye.png +0 -0
  274. snappy/raytracing/shaders/NonGeometric.png +0 -0
  275. snappy/raytracing/shaders/__init__.py +60 -4
  276. snappy/raytracing/shaders/fragment.glsl +575 -148
  277. snappy/raytracing/test.py +29 -0
  278. snappy/raytracing/tooltip.py +146 -0
  279. snappy/raytracing/upper_halfspace_utilities.py +98 -0
  280. snappy/raytracing/view_scale_controller.py +98 -0
  281. snappy/raytracing/zoom_slider/__init__.py +32 -29
  282. snappy/raytracing/zoom_slider/test.py +2 -0
  283. snappy/sage_helper.py +69 -123
  284. snappy/{preferences.py → settings.py} +167 -145
  285. snappy/shell.py +4 -0
  286. snappy/snap/__init__.py +12 -8
  287. snappy/snap/character_varieties.py +24 -18
  288. snappy/snap/find_field.py +35 -34
  289. snappy/snap/fundamental_polyhedron.py +99 -85
  290. snappy/snap/generators.py +6 -8
  291. snappy/snap/interval_reps.py +18 -6
  292. snappy/snap/kernel_structures.py +8 -3
  293. snappy/snap/mcomplex_base.py +1 -2
  294. snappy/snap/nsagetools.py +107 -53
  295. snappy/snap/peripheral/__init__.py +1 -1
  296. snappy/snap/peripheral/dual_cellulation.py +15 -7
  297. snappy/snap/peripheral/link.py +20 -16
  298. snappy/snap/peripheral/peripheral.py +22 -14
  299. snappy/snap/peripheral/surface.py +47 -50
  300. snappy/snap/peripheral/test.py +8 -8
  301. snappy/snap/polished_reps.py +65 -40
  302. snappy/snap/shapes.py +41 -22
  303. snappy/snap/slice_obs_HKL.py +64 -25
  304. snappy/snap/t3mlite/arrow.py +88 -51
  305. snappy/snap/t3mlite/corner.py +5 -6
  306. snappy/snap/t3mlite/edge.py +32 -21
  307. snappy/snap/t3mlite/face.py +7 -9
  308. snappy/snap/t3mlite/files.py +31 -23
  309. snappy/snap/t3mlite/homology.py +14 -10
  310. snappy/snap/t3mlite/linalg.py +158 -56
  311. snappy/snap/t3mlite/mcomplex.py +739 -291
  312. snappy/snap/t3mlite/perm4.py +236 -84
  313. snappy/snap/t3mlite/setup.py +9 -10
  314. snappy/snap/t3mlite/simplex.py +65 -48
  315. snappy/snap/t3mlite/spun.py +42 -30
  316. snappy/snap/t3mlite/surface.py +45 -45
  317. snappy/snap/t3mlite/test.py +3 -0
  318. snappy/snap/t3mlite/test_vs_regina.py +17 -13
  319. snappy/snap/t3mlite/tetrahedron.py +25 -24
  320. snappy/snap/t3mlite/vertex.py +8 -13
  321. snappy/snap/test.py +45 -52
  322. snappy/snap/utilities.py +66 -65
  323. snappy/test.py +155 -158
  324. snappy/test_cases.py +263 -0
  325. snappy/testing.py +131 -0
  326. snappy/tiling/__init__.py +2 -0
  327. snappy/tiling/canonical_key_dict.py +59 -0
  328. snappy/tiling/dict_based_set.py +79 -0
  329. snappy/tiling/floor.py +49 -0
  330. snappy/tiling/hyperboloid_dict.py +54 -0
  331. snappy/tiling/iter_utils.py +78 -0
  332. snappy/tiling/lifted_tetrahedron.py +22 -0
  333. snappy/tiling/lifted_tetrahedron_set.py +54 -0
  334. snappy/tiling/real_hash_dict.py +164 -0
  335. snappy/tiling/test.py +23 -0
  336. snappy/tiling/tile.py +215 -0
  337. snappy/tiling/triangle.py +33 -0
  338. snappy/tkterminal.py +313 -203
  339. snappy/twister/main.py +1 -8
  340. snappy/twister/twister_core.cpython-38-darwin.so +0 -0
  341. snappy/upper_halfspace/__init__.py +146 -0
  342. snappy/upper_halfspace/ideal_point.py +26 -0
  343. snappy/verify/__init__.py +4 -8
  344. snappy/verify/{verifyCanonical.py → canonical.py} +114 -97
  345. snappy/verify/complex_volume/__init__.py +3 -2
  346. snappy/verify/complex_volume/adjust_torsion.py +13 -11
  347. snappy/verify/complex_volume/closed.py +29 -24
  348. snappy/verify/complex_volume/compute_ptolemys.py +8 -6
  349. snappy/verify/complex_volume/cusped.py +10 -9
  350. snappy/verify/complex_volume/extended_bloch.py +14 -12
  351. snappy/verify/{cuspTranslations.py → cusp_translations.py} +15 -14
  352. snappy/verify/edge_equations.py +80 -0
  353. snappy/verify/exceptions.py +23 -56
  354. snappy/verify/{verifyHyperbolicity.py → hyperbolicity.py} +19 -15
  355. snappy/verify/interval_newton_shapes_engine.py +51 -211
  356. snappy/verify/interval_tree.py +27 -25
  357. snappy/verify/krawczyk_shapes_engine.py +47 -50
  358. snappy/verify/maximal_cusp_area_matrix/__init__.py +17 -86
  359. snappy/verify/maximal_cusp_area_matrix/cusp_tiling_engine.py +58 -48
  360. snappy/verify/maximal_cusp_area_matrix/cusp_translate_engine.py +53 -57
  361. snappy/verify/{realAlgebra.py → real_algebra.py} +26 -20
  362. snappy/verify/shapes.py +10 -7
  363. snappy/verify/short_slopes.py +41 -42
  364. snappy/verify/{squareExtensions.py → square_extensions.py} +96 -92
  365. snappy/verify/test.py +59 -57
  366. snappy/verify/upper_halfspace/extended_matrix.py +5 -5
  367. snappy/verify/upper_halfspace/finite_point.py +44 -31
  368. snappy/verify/upper_halfspace/ideal_point.py +69 -57
  369. snappy/verify/volume.py +15 -12
  370. snappy/version.py +2 -3
  371. {snappy-3.0.3.dist-info → snappy-3.2.dist-info}/METADATA +14 -12
  372. snappy-3.2.dist-info/RECORD +503 -0
  373. {snappy-3.0.3.dist-info → snappy-3.2.dist-info}/WHEEL +1 -1
  374. {snappy-3.0.3.dist-info → snappy-3.2.dist-info}/entry_points.txt +0 -1
  375. {snappy-3.0.3.dist-info → snappy-3.2.dist-info}/top_level.txt +10 -1
  376. snappy/doc/_sources/verify_canon.rst.txt +0 -90
  377. snappy/doc/_static/classic.css +0 -266
  378. snappy/doc/_static/jquery-3.5.1.js +0 -10872
  379. snappy/doc/_static/sidebar.js +0 -159
  380. snappy/doc/_static/underscore-1.13.1.js +0 -2042
  381. snappy/doc/_static/underscore.js +0 -6
  382. snappy/doc/verify_canon.html +0 -283
  383. snappy/ppm_to_png.py +0 -243
  384. snappy/togl/__init__.py +0 -3
  385. snappy/togl/darwin-tk8.6/Togl2.1/LICENSE +0 -28
  386. snappy/togl/darwin-tk8.6/Togl2.1/libTogl2.1.dylib +0 -0
  387. snappy/togl/darwin-tk8.6/Togl2.1/pkgIndex.tcl +0 -5
  388. snappy/togl/linux2-x86_64-tk8.6/Togl2.1/LICENSE +0 -28
  389. snappy/togl/linux2-x86_64-tk8.6/Togl2.1/libTogl2.1.so +0 -0
  390. snappy/togl/linux2-x86_64-tk8.6/Togl2.1/pkgIndex.tcl +0 -5
  391. snappy/togl/win32VC-tk8.6/Togl2.1/LICENSE +0 -28
  392. snappy/togl/win32VC-tk8.6/Togl2.1/Togl21.dll +0 -0
  393. snappy/togl/win32VC-tk8.6/Togl2.1/Togl21.lib +0 -0
  394. snappy/togl/win32VC-tk8.6/Togl2.1/pkgIndex.tcl +0 -6
  395. snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/LICENSE +0 -28
  396. snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/Togl21.dll +0 -0
  397. snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/Togl21.lib +0 -0
  398. snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/pkgIndex.tcl +0 -6
  399. snappy/verify/cuspCrossSection.py +0 -1413
  400. snappy/verify/mathHelpers.py +0 -64
  401. snappy-3.0.3.dist-info/RECORD +0 -360
snappy/__init__.py CHANGED
@@ -1,17 +1,20 @@
1
- #from __future__ import print_function
2
1
  # import the SnapPy bindings
3
- #import logging
4
- #logging.basicConfig(filename='example.log',level=logging.DEBUG)
5
- #logging.debug('This message should go to the log file')
2
+ # import logging
3
+ # logging.basicConfig(filename='example.log',level=logging.DEBUG)
4
+ # logging.debug('This message should go to the log file')
6
5
  import sys
7
- from .SnapPy import (AbelianGroup, HolonomyGroup, FundamentalGroup,
8
- DirichletDomain, CuspNeighborhood, SymmetryGroup,
9
- AlternatingKnotExteriors, NonalternatingKnotExteriors,
6
+ from .SnapPy import (AbelianGroup,
7
+ FundamentalGroup,
8
+ SymmetryGroup,
9
+ Isometry,
10
+ AlternatingKnotExteriors,
11
+ NonalternatingKnotExteriors,
10
12
  pari)
11
- from .exceptions import SnapPeaFatalError
12
13
  from .SnapPy import DirichletDomain
13
14
  from .SnapPyHP import DirichletDomain as DirichletDomainHP
15
+ from .SnapPy import CuspNeighborhood
14
16
  from .SnapPyHP import CuspNeighborhood as CuspNeighborhoodHP
17
+ from .SnapPy import HolonomyGroup
15
18
  from .SnapPyHP import HolonomyGroup as HolonomyGroupHP
16
19
 
17
20
  from .SnapPy import Triangulation as _TriangulationLP
@@ -24,14 +27,56 @@ import time
24
27
  from .SnapPy import set_rand_seed
25
28
  set_rand_seed(int(time.time()))
26
29
 
30
+ from .exceptions import (SnapPeaFatalError,
31
+ InsufficientPrecisionError,
32
+ NonorientableManifoldError)
33
+
34
+ from typing import Union, Tuple, List, Optional
35
+
36
+ # Subclass to be able to monkey-patch
27
37
  class Triangulation(_TriangulationLP):
28
38
  __doc__ = _TriangulationLP.__doc__
29
-
39
+
40
+ # Subclass to be able to monkey-patch
30
41
  class TriangulationHP(_TriangulationHP):
31
42
  __doc__ = _TriangulationHP.__doc__
32
43
 
33
- class Manifold(_ManifoldLP):
44
+ # We want Manifold to be a subclass of Triangulation.
45
+ # Unfortunately, that introduces a diamond pattern here.
46
+ # Luckily, the python resolves methods and bases classes
47
+ # in the presence of a diamond pattern seem to work just
48
+ # fine. In particular, we do not double allocate the underlying
49
+ # C structures.
50
+ class Manifold(_ManifoldLP, Triangulation):
34
51
  __doc__ = _ManifoldLP.__doc__
52
+
53
+ def identify(self, extends_to_link=False):
54
+ """
55
+ Looks for the manifold in all of the SnapPy databases.
56
+ For hyperbolic manifolds this is done by searching for isometries:
57
+
58
+ >>> M = Manifold('m125')
59
+ >>> M.identify()
60
+ [m125(0,0)(0,0), L13n5885(0,0)(0,0), ooct01_00000(0,0)(0,0)]
61
+
62
+ By default, there is no restriction on the isometries. One can
63
+ require that the isometry take meridians to meridians. This
64
+ might return fewer results:
65
+
66
+ >>> M.identify(extends_to_link=True)
67
+ [m125(0,0)(0,0), ooct01_00000(0,0)(0,0)]
68
+
69
+ For closed manifolds, extends_to_link doesn't make sense
70
+ because of how the kernel code works:
71
+
72
+ >>> C = Manifold("m015(1,2)")
73
+ >>> C.identify()
74
+ [m006(-5,2)]
75
+ >>> C.identify(True)
76
+ []
77
+ """
78
+ return self._identify(extends_to_link)
79
+
35
80
  def high_precision(self):
36
81
  """
37
82
  Return a high precision version of this manifold.
@@ -56,8 +101,11 @@ class Manifold(_ManifoldLP):
56
101
  def low_precision(self):
57
102
  return self.copy()
58
103
 
59
- class ManifoldHP(_ManifoldHP):
104
+ # We want ManifoldHP to be a subclass of TriangulationHP.
105
+ # See comment about Manifold and the diamond pattern.
106
+ class ManifoldHP(_ManifoldHP, TriangulationHP):
60
107
  __doc__ = _ManifoldHP.__doc__
108
+
61
109
  def low_precision(self):
62
110
  """
63
111
  Return a low precision version of this high precision manifold.
@@ -65,6 +113,7 @@ class ManifoldHP(_ManifoldHP):
65
113
  >>> M = ManifoldHP('m004')
66
114
  >>> type(M.low_precision())
67
115
  <class 'snappy.Manifold'>
116
+
68
117
  """
69
118
  LP = Manifold('empty')
70
119
  LP._from_string(self._to_string(), initialize_structure=False)
@@ -84,27 +133,32 @@ class ManifoldHP(_ManifoldHP):
84
133
 
85
134
  def identify(self, extends_to_link=False):
86
135
  """
87
- Look for the manifold in all of the SnapPy databases:
136
+ Looks for the manifold in all of the SnapPy databases.
137
+ For hyperbolic manifolds this is done by searching for isometries:
88
138
 
89
139
  >>> M = ManifoldHP('m125')
90
140
  >>> M.identify()
91
141
  [m125(0,0)(0,0), L13n5885(0,0)(0,0), ooct01_00000(0,0)(0,0)]
92
-
93
- One can require that there be an isometry taking merdians
94
- to meridians:
142
+
143
+ By default, there is no restriction on the isometries. One can require
144
+ that the isometry take meridians to meridians. This might return
145
+ fewer results:
95
146
 
96
147
  >>> M.identify(extends_to_link=True)
97
148
  [m125(0,0)(0,0), ooct01_00000(0,0)(0,0)]
98
-
149
+
99
150
  For closed manifolds, extends_to_link doesn't make sense because
100
- of how the kernel code works:
151
+ of how the kernel code works:
152
+
101
153
  >>> C = Manifold("m015(1,2)")
102
154
  >>> C.identify()
103
155
  [m006(-5,2)]
104
156
  >>> C.identify(True)
105
157
  []
158
+
106
159
  """
107
- return self.low_precision().identify(extends_to_link)
160
+ return self.low_precision()._identify(extends_to_link)
161
+
108
162
 
109
163
  SnapPy._manifold_class = Manifold
110
164
  SnapPy._triangulation_class = Triangulation
@@ -116,449 +170,387 @@ __all__ = ['Triangulation', 'Manifold', 'ManifoldHP', 'AbelianGroup',
116
170
  'DirichletDomain', 'DirichletDomainHP', 'CuspNeighborhood',
117
171
  'CuspNeighborhoodHP', 'SymmetryGroup', 'AlternatingKnotExteriors',
118
172
  'NonalternatingKnotExteriors', 'SnapPeaFatalError',
173
+ 'InsufficientPrecisionError',
119
174
  'pari', 'twister', ]
120
175
 
121
- from .sage_helper import _within_sage
122
- if _within_sage:
123
- to_sage = lambda n : n.sage()
124
- Manifold.use_field_conversion(to_sage)
125
- ManifoldHP.use_field_conversion(to_sage)
176
+ def _symmetrize_high_precision_manifold(
177
+ mfd1 : Union[Manifold, ManifoldHP],
178
+ mfd2 : Union[Manifold, ManifoldHP]
179
+ ) -> Union[Tuple[Manifold, Manifold],
180
+ Tuple[ManifoldHP, ManifoldHP]]:
181
+ """
182
+ Given a (potential) mix of two Manifold and ManifoldHP,
183
+ promote one to high precision if necessary and return
184
+ the result as pair.
185
+ """
186
+ resolved_mfd1 = mfd1
187
+ resolved_mfd2 = mfd2
188
+ high1 = isinstance(mfd1, ManifoldHP)
189
+ high2 = isinstance(mfd2, ManifoldHP)
190
+ if high1 and not high2:
191
+ resolved_mfd2 = ManifoldHP(mfd2)
192
+ if high2 and not high1:
193
+ resolved_mfd1 = ManifoldHP(mfd1)
194
+ return (resolved_mfd1, resolved_mfd2)
195
+
196
+ def _symmetrize_low_precision_triangulation(
197
+ tri1 : Union[Triangulation, TriangulationHP],
198
+ tri2 : Union[Triangulation, TriangulationHP]
199
+ ) -> Union[Tuple[Triangulation, Triangulation],
200
+ Tuple[TriangulationHP, TriangulationHP]]:
201
+ """
202
+ Given a (potential) mix of two Triangulation and TriangulationHP,
203
+ demote one to low precision if necessary and return
204
+ the result as pair.
205
+ """
206
+ resolved_tri1 = tri1
207
+ resolved_tri2 = tri2
208
+ low1 = isinstance(tri1, Triangulation)
209
+ low2 = isinstance(tri2, Triangulation)
210
+ if low1 and not low2:
211
+ resolved_tri2 = Triangulation(tri2, remove_finite_vertices=False)
212
+ if low2 and not low1:
213
+ resolved_tri1 = Triangulation(tri1, remove_finite_vertices=False)
214
+ return (resolved_tri1, resolved_tri2)
215
+
216
+ def is_isometric_to(self,
217
+ other : Union[Manifold, ManifoldHP],
218
+ return_isometries : bool = False
219
+ ) -> Union[bool, List[Isometry]]:
220
+ resolved_self, resolved_other = (
221
+ _symmetrize_high_precision_manifold(
222
+ self, other))
223
+
224
+ return resolved_self._is_isometric_to(
225
+ resolved_other,
226
+ return_isometries=return_isometries)
227
+
228
+ is_isometric_to.__doc__ = _ManifoldLP._is_isometric_to.__doc__
229
+ Manifold.is_isometric_to = is_isometric_to
230
+ ManifoldHP.is_isometric_to = is_isometric_to
231
+
232
+ def isomorphisms_to(self,
233
+ other : Union[Triangulation, TriangulationHP]
234
+ ) -> List[Isometry]:
235
+ resolved_self, resolved_other = (
236
+ _symmetrize_low_precision_triangulation(
237
+ self, other))
238
+
239
+ return resolved_self._isomorphisms_to(
240
+ resolved_other)
241
+
242
+ isomorphisms_to.__doc__ = _TriangulationLP._isomorphisms_to.__doc__
243
+ Triangulation.isomorphisms_to = isomorphisms_to
244
+ TriangulationHP.isomorphisms_to = isomorphisms_to
126
245
 
127
246
  from . import snap
128
247
  snap.add_methods(Manifold)
129
248
  snap.add_methods(ManifoldHP)
130
249
  snap.add_methods(Triangulation, hyperbolic=False)
250
+ snap.add_methods(TriangulationHP, hyperbolic=False)
251
+
252
+ from . import exterior_to_link
253
+ Triangulation.exterior_to_link = exterior_to_link.exterior_to_link
254
+ TriangulationHP.exterior_to_link = exterior_to_link.exterior_to_link
255
+ Manifold.exterior_to_link = exterior_to_link.exterior_to_link
256
+ ManifoldHP.exterior_to_link = exterior_to_link.exterior_to_link
131
257
 
132
258
  from . import verify
133
259
  Manifold.verify_hyperbolicity = verify.verify_hyperbolicity
134
260
  ManifoldHP.verify_hyperbolicity = verify.verify_hyperbolicity
135
261
 
136
- def canonical_retriangulation(
137
- manifold, verified = False,
138
- interval_bits_precs = verify.default_interval_bits_precs,
139
- exact_bits_prec_and_degrees = verify.default_exact_bits_prec_and_degrees,
140
- verbose = False):
262
+ from . import len_spec
263
+ Manifold.length_spectrum_alt_gen = len_spec.length_spectrum_alt_gen
264
+ ManifoldHP.length_spectrum_alt_gen = len_spec.length_spectrum_alt_gen
265
+ Manifold.length_spectrum_alt = len_spec.length_spectrum_alt
266
+ ManifoldHP.length_spectrum_alt = len_spec.length_spectrum_alt
141
267
 
142
- """
143
- The canonical retriangulation which is closely related to the canonical
144
- cell decomposition and described in more detail `here
145
- <verify.html#the-canonical-retriangulation-and-the-isometry-signature>`_::
146
-
147
- >>> M = Manifold("m412")
148
- >>> K = M.canonical_retriangulation()
149
- >>> len(K.isomorphisms_to(K)) # Unverified size of the isometry group.
150
- 8
151
-
152
- When used inside `Sage <http://sagemath.org/>`_ and ``verified = True`` is
153
- passed as argument, the verify module will certify the result to be
154
- correct::
155
-
156
- sage: M = Manifold("m412")
157
- sage: K = M.canonical_retriangulation(verified = True)
158
- sage: len(K.isomorphisms_to(K)) # Verified size of the isometry group.
159
- 8
160
-
161
- See :py:meth:`verify.verified_canonical_retriangulation` for the
162
- additional options.
163
- """
164
- if False in manifold.cusp_info('complete?'):
165
- raise ValueError('Canonical retriangulation needs all cusps to be complete')
166
-
167
- if verified:
168
- return verify.verified_canonical_retriangulation(
169
- manifold,
170
- interval_bits_precs = interval_bits_precs,
171
- exact_bits_prec_and_degrees = exact_bits_prec_and_degrees,
172
- verbose = verbose)
173
- else:
174
- return manifold._canonical_retriangulation()
175
-
176
- Manifold.canonical_retriangulation = canonical_retriangulation
177
- ManifoldHP.canonical_retriangulation = canonical_retriangulation
268
+ from . import canonical
269
+ Manifold.canonical_retriangulation = canonical.canonical_retriangulation
270
+ ManifoldHP.canonical_retriangulation = canonical.canonical_retriangulation_hp
178
271
 
179
- def isometry_signature(
180
- manifold, of_link = False, verified = False,
181
- interval_bits_precs = verify.default_interval_bits_precs,
182
- exact_bits_prec_and_degrees = verify.default_exact_bits_prec_and_degrees,
183
- verbose = False):
272
+ from . import isometry_signature
184
273
 
185
- """
186
- The isomorphism signature of the canonical retriangulation. This is a
187
- complete invariant of the isometry type of a hyperbolic 3-manifold and
188
- described in more detail `here
189
- <verify.html#the-canonical-retriangulation-and-the-isometry-signature>`_::
190
-
191
- >>> M = Manifold("m125")
192
- >>> M.isometry_signature() # Unverified isometry signature
193
- 'gLLPQccdefffqffqqof'
194
-
195
- When used inside `Sage <http://sagemath.org/>`_ and ``verified = True`` is
196
- passed as argument, the verify module will certify the result to be
197
- correct::
198
-
199
- sage: M = Manifold("m125")
200
- sage: M.isometry_signature(verified = True) # Verified isometry signature
201
- 'gLLPQccdefffqffqqof'
202
-
203
- When ``of_link = True`` is specified, the peripheral curves are included in
204
- such a way that the result is a complete invariant of a link. In particular,
205
- ``isometry_signature(of_link=True)`` is invariant under changing the
206
- ordering or orientations of the components or flipping all crossings of a
207
- link simultaneously (it passes ``ignore_cusp_order = True,
208
- ignore_curve_orientations = True`` to
209
- :py:meth:`Manifold.triangulation_isosig`)::
210
-
211
- >>> Manifold("5^2_1").isometry_signature(of_link = True)
212
- 'eLPkbdcddhgggb_baCbbaCb'
213
- >>> Manifold("7^2_8").isometry_signature(of_link = True)
214
- 'eLPkbdcddhgggb_bBcBbaCb'
215
-
216
- See :py:meth:`verify.verified_canonical_retriangulation` for the
217
- additional options.
218
-
219
- Note that interval methods cannot verify a canonical retriangulation
220
- with non-tetrahedral cells such as in the cas of ``m412``, so the following
221
- call returns ``None``::
222
-
223
- sage: M = Manifold("m412")
224
- sage: M.isometry_signature(verified = True, exact_bits_prec_and_degrees = None)
274
+ Manifold.isometry_signature = isometry_signature.isometry_signature
275
+ ManifoldHP.isometry_signature = isometry_signature.isometry_signature
225
276
 
226
- """
227
- if False in manifold.cusp_info('complete?'):
228
- raise ValueError('isometry_signature needs all cusps to be complete')
277
+ from .cusps import cusp_area_matrix
229
278
 
230
- retrig = manifold.canonical_retriangulation(
231
- verified = verified,
232
- interval_bits_precs = interval_bits_precs,
233
- exact_bits_prec_and_degrees = exact_bits_prec_and_degrees,
234
- verbose = verbose)
279
+ Manifold.cusp_area_matrix = cusp_area_matrix.cusp_area_matrix
280
+ ManifoldHP.cusp_area_matrix = cusp_area_matrix.cusp_area_matrix
235
281
 
236
- if not retrig:
237
- return None
238
-
239
- return retrig.triangulation_isosig(decorated = of_link,
240
- ignore_cusp_ordering = True,
241
- ignore_curve_orientations = True)
242
-
243
- Manifold.isometry_signature = isometry_signature
244
- ManifoldHP.isometry_signature = isometry_signature
245
-
246
-
247
- def cusp_area_matrix(manifold, method='trigDependentTryCanonize',
248
- verified=False, bits_prec=None):
249
- r"""
250
- This function returns a matrix that can be used to check whether
251
- cusp neighborhoods of areas a\ :sub:`0`\ , ..., a\ :sub:`m-1` are
252
- disjoint: the cusp neighborhoods about cusp i and j are
253
- disjoint (respectively, the cusp neighborhood embeds if i and j
254
- are equal) if a\ :sub:`i` * a\ :sub:`j` is less than or equal to
255
- the entry (i,j) of the cusp area matrix. Note that the "if"
256
- becomes "if and only if" if we pick the "maximal cusp area
257
- matrix".
258
-
259
- This function can operate in different ways (determined by
260
- ``method``). By default (``method='trigDependentTryCanonize'``),
261
- it returns a result which can be suboptimal and non-deterministic
262
- but is quicker to compute and sufficies for many applications::
263
-
264
- >>> M = Manifold("s776")
265
- >>> M.cusp_area_matrix() # doctest: +NUMERIC12
266
- [28.0000000000000 7.00000000000000 6.99999999999999]
267
- [7.00000000000000 21.4375000000000 7.00000000000000]
268
- [6.99999999999999 7.00000000000000 21.4375000000000]
269
-
270
- If ``method='maximal'`` is specified, the result is the "maximal
271
- cusp area matrix", thus it is optimal and an invariant of the
272
- manifold with labeled cusps. Note that the "maximal cusp area
273
- matrix" is only available as verified computation and thus
274
- requires passing ``verified = True``::
275
-
276
- sage: M.cusp_area_matrix(method = 'maximal', verified=True) # doctest: +NUMERIC6
277
- [28.0000000000? 7.0000000000? 7.0000000000?]
278
- [ 7.0000000000? 28.000000000? 7.00000000000?]
279
- [ 7.0000000000? 7.00000000000? 28.00000000?]
280
-
281
- If ``verified = True`` is specified and ``method`` is not
282
- ``maximal``, the entries are all guaranteed to be less than the
283
- corresponding ones in the maximal cusp area matrix (more
284
- precisely, the lower end point of the interval is guaranteed to be
285
- less than the true value of the corresponding maximal cusp area
286
- matrix entry)::
287
-
288
- sage: M.cusp_area_matrix(verified=True, bits_prec=70) # doctest: +NUMERIC15
289
- [ 28.000000000000000? 7.0000000000000000? 7.0000000000000000?]
290
- [ 7.0000000000000000? 21.4375000000000000? 7.0000000000000000?]
291
- [ 7.0000000000000000? 7.0000000000000000? 21.4375000000000000?]
292
-
293
- For expert users:
294
-
295
- Besides the two values above, ``method`` can be ``trigDependent``:
296
- this result is also fast to compute by making the assumption that
297
- cusp neighborhoods are not only disjoint but also in "standard
298
- form" with respect to the triangulation (i.e., when lifting of a
299
- cusp neighborhood to a horoball in the universal cover, it
300
- intersects a geodesic tetrahedron in three but not four
301
- faces). ``trigDependentTryCanonize`` is similar to
302
- ``trigDependent`` but tries to "proto-canonize" (a copy of) the
303
- triangulation first since this often produces a matrix that is
304
- closer to the maximal cusp area matrix, for example::
305
-
306
- >>> M = Manifold("o9_35953")
307
- >>> M.cusp_area_matrix(method = 'trigDependent') # doctest: +NUMERIC9
308
- [72.9848715318467 12.7560424258060]
309
- [12.7560424258060 6.65567118002656]
310
- >>> M.cusp_area_matrix(method = 'trigDependentTryCanonize') # doctest: +NUMERIC9
311
- [72.9848715318466 12.7560424258060]
312
- [12.7560424258060 62.1043047674605]
313
-
314
- Compare to maximal area matrix::
315
-
316
- sage: M.cusp_area_matrix(method = 'maximal', verified = True, bits_prec = 100) # doctest: +NUMERIC15
317
- [ 72.984871531846664? 12.7560424258059765562778?]
318
- [12.7560424258059765562778? 62.104304767460978078?]
282
+ from .cusps import cusp_areas_from_matrix
319
283
 
284
+ def cusp_areas(manifold,
285
+ policy : str = 'unbiased',
286
+ method : str = 'maximal',
287
+ verified : bool = False,
288
+ bits_prec : Optional[int] = None,
289
+ first_cusps : List[int] = []):
320
290
  """
291
+ Returns a list of areas, one for each cusp. The cusp neighborhoods
292
+ defined by these areas are embedded and disjoint. Furthermore, these
293
+ neighborhoods are maximal in that they fail to be embedded or
294
+ disjoint if any cusp neighborhood is enlarged (unless :attr:`method`
295
+ is set to a value different from the default).
321
296
 
322
- if method == 'maximal':
323
- if not verified:
324
- raise NotImplementedError("Maximal cusp area matrix only "
325
- "available as verified computation. "
326
- "Pass verified = True.")
327
- return verify.verified_maximal_cusp_area_matrix(
328
- manifold, bits_prec = bits_prec)
329
- if method in ['trigDependent', 'trigDependentTryCanonize']:
330
- if method == 'trigDependentTryCanonize':
331
- manifold = manifold.copy()
332
- manifold.canonize()
297
+ There are different policies how these cusp neighborhoods are found.
333
298
 
334
- return verify.triangulation_dependent_cusp_area_matrix(
335
- manifold, verified = verified, bits_prec = bits_prec)
336
-
337
- raise RuntimeError("method passed to cusp_area_matrix must be "
338
- "'trigDependent', 'trigDependentTryCanonize', "
339
- "or 'maximal'.")
340
-
341
- Manifold.cusp_area_matrix = cusp_area_matrix
342
- ManifoldHP.cusp_area_matrix = cusp_area_matrix
343
-
344
- from .verify import cusp_areas as verify_cusp_areas
345
-
346
- def cusp_areas(manifold, policy = 'unbiased',
347
- method = 'trigDependentTryCanonize',
348
- verified = False, bits_prec = None, first_cusps=[]):
349
-
350
- """
351
- Picks areas for the cusps such that the corresponding cusp
352
- neighborhoods are disjoint. By default, the ``policy`` is
353
- ``unbiased`` which means that the cusp neighborhoods are blown up
354
- simultaneously with a cusp neighborhood stopping to grow when it
355
- touches another cusp neighborhood or itself::
299
+ The default :attr:`policy` is ``unbiased``. This means that the
300
+ cusp neighborhoods are blown up simultaneously and a cusp neighborhood
301
+ stops growing when it touches any cusp neighborhood including itself::
356
302
 
357
303
  >>> M = Manifold("s776")
358
304
  >>> M.cusp_areas() # doctest: +NUMERIC9
359
305
  [2.64575131106459, 2.64575131106459, 2.64575131106459]
360
306
 
361
- Alternatively, ``policy='greedy'`` means that the first cusp
362
- neighborhood is blown up until it touches itself, then the second
363
- cusp neighborhood is blown up until it touches itself or the first
364
- cusp neighborhood, ...::
307
+ Alternatively, :attr:`policy='greedy'` can be specified. This means
308
+ that the first cusp neighborhood is blown up until it touches itself,
309
+ then the second cusp neighborhood is blown up until it touches itself
310
+ or the first cusp neighborhood, and so on::
365
311
 
366
312
  >>> M.cusp_areas(policy='greedy') # doctest: +NUMERIC9
367
313
  [5.29150262212918, 1.32287565553230, 1.32287565553229]
368
314
 
369
- To specify cusps to be blown up first, and in which order to blow
370
- them up, set ``first_cusps`` to the appropriate list of cusps.
315
+ Use :attr:`first_cusps` to specify the order in which the cusp
316
+ neighborhoods are blown up::
371
317
 
372
- >>> M = Manifold('o9_44210')
373
- >>> M.cusp_areas(policy='greedy') # doctest: +NUMERIC9
374
- [7.053940530873898, 3.2712450270, 2.7091590087]
375
- >>> M.cusp_areas(policy='greedy', first_cusps=[]) # doctest: +NUMERIC9
376
- [7.053940530873898, 3.2712450270, 2.7091590087]
377
- >>> M.cusp_areas(policy='greedy', first_cusps=[0,]) # doctest: +NUMERIC9
378
- [7.053940530873898, 3.2712450270, 2.7091590087]
379
- >>> M.cusp_areas(policy='greedy', first_cusps=[0,1]) # doctest: +NUMERIC9
380
- [7.053940530873898, 3.2712450270, 2.7091590087]
381
- >>> M.cusp_areas(policy='greedy', first_cusps=[0,1,2]) # doctest: +NUMERIC9
382
- [7.053940530873898, 3.2712450270, 2.7091590087]
383
- >>> M.cusp_areas(policy='greedy', first_cusps=[0,2,1]) # doctest: +NUMERIC9
384
- [7.053940530873898, 2.3513135103, 3.7690945490]
385
- >>> M.cusp_areas(policy='greedy', first_cusps=[1,]) # doctest: +NUMERIC9
386
- [4.0302253322, 5.725527974287718, 1.5478612583]
387
-
388
- ``cusp_areas`` is implemented using
389
- :py:meth:`Manifold.cusp_area_matrix` and the same arguments
390
- (``method``, ``verified``, ``bits_prec``) are accepted. For
391
- example, verified computations are supported::
318
+ >>> M.cusp_areas(policy='greedy', first_cusps=[1,0,2]) # doctest: +NUMERIC9
319
+ [1.32287565553230, 5.29150262212918, 1.32287565553229]
392
320
 
393
- sage: M=Manifold("v2854")
394
- sage: M.cusp_areas(verified=True) # doctest: +NUMERIC9
395
- [3.6005032476?, 3.6005032476?]
321
+ An incomplete list can be given to :attr:`first_cusps`. In this case,
322
+ the list is automatically completed by appending the remaining cusps in
323
+ order. Thus, the above call is equivalent to::
396
324
 
397
- If ``method='maximal'``, ``policy='unbiased'`` and
398
- ``verified=True``, the result is an invariant of the manifold with
399
- labeled cusps and the corresponding cusp neighborhoods are maximal
400
- in that every cusp neighborhood is touching some (not necessarily
401
- distinct) cusp neighborhood.
325
+ >>> M.cusp_areas(policy='greedy', first_cusps=[1]) # doctest: +NUMERIC9
326
+ [1.32287565553230, 5.29150262212918, 1.32287565553229]
402
327
 
403
- Area of the cusp neighborhood touching itself for a one-cusped
404
- manifold::
328
+ Under the hood, this method is using
329
+ :meth:`~snappy.Manifold.cusp_area_matrix`.
405
330
 
406
- sage: M=Manifold("v1959")
407
- sage: M.cusp_areas(method='maximal', verified=True, bits_prec=100) # doctest: +NUMERIC15
408
- [7.15679216175810579?]
331
+ **Verified computation**
409
332
 
333
+ If :attr:`verified = False`, floating-point issues can arise resulting in
334
+ incorrect values. The method can be made
335
+ :ref:`verified <verify-primer>` by passing :attr:`verified = True`::
336
+
337
+ sage: M=Manifold("s776")
338
+ sage: M.cusp_areas(verified=True) # doctest: +NUMERIC9
339
+ [2.64575131107?, 2.64575131107?, 2.64575131107?]
340
+
341
+ :param verified:
342
+ Use :ref:`verified computation <verify-primer>`.
343
+ :param bits_prec:
344
+ Precision used for computation. Increase if computation
345
+ did not succeed or a more precise result is desired.
346
+ :param method:
347
+ Passed to :meth:`~snappy.Manifold.cusp_area_matrix`. If set
348
+ to a value different from the default ``maximal``, the cusp
349
+ neighborhoods stop growing when the corresponding value
350
+ in the computed cusp area matrix is exceeded. At this point,
351
+ the cusp neighborhood might not necessarily touch any other
352
+ cusp neighborhood since we do not use the maximal cusp area
353
+ matrix.
354
+ :param policy:
355
+ Specifies process of choosing cusp neighborhoods.
356
+ Either ``unbiased`` or ``greedy``, see above.
357
+ :param first_cusps:
358
+ Preference order of cusps.
359
+ Only relevant if :attr:`policy='greedy'`, see above.
360
+ :return:
361
+ Areas of maximal embedded and disjoint cusp neighborhoods
362
+ (default). Or areas of some embedded and disjoint cusp
363
+ neighborhoods (if :attr:`method` switches to older algorithm).
410
364
  """
411
365
  if policy not in ['unbiased', 'greedy']:
412
- raise RuntimeError("policy passed to cusp_areas must be 'unbiased' "
366
+ raise ValueError("policy passed to cusp_areas must be 'unbiased' "
413
367
  "or 'greedy'.")
414
368
 
415
369
  m = manifold.cusp_area_matrix(
416
370
  method=method, verified=verified, bits_prec=bits_prec)
417
371
 
418
372
  if policy == 'unbiased':
419
- return verify_cusp_areas.unbiased_cusp_areas_from_cusp_area_matrix(m)
373
+ return cusp_areas_from_matrix.unbiased_cusp_areas_from_cusp_area_matrix(m)
420
374
  else:
421
- return verify_cusp_areas.greedy_cusp_areas_from_cusp_area_matrix(m, first_cusps=first_cusps)
375
+ return cusp_areas_from_matrix.greedy_cusp_areas_from_cusp_area_matrix(m, first_cusps=first_cusps)
422
376
 
423
377
  Manifold.cusp_areas = cusp_areas
424
378
  ManifoldHP.cusp_areas = cusp_areas
425
379
 
426
380
  from .verify import short_slopes as verify_short_slopes
427
381
 
382
+
428
383
  def short_slopes(manifold,
429
- length = 6,
430
- policy = 'unbiased', method = 'trigDependentTryCanonize',
431
- verified = False, bits_prec = None, first_cusps=[]):
384
+ length=6,
385
+ policy : str = 'unbiased',
386
+ method : str = 'maximal',
387
+ verified : bool = False,
388
+ bits_prec : Optional[int] = None,
389
+ first_cusps : List[int] = []):
432
390
  """
433
- Picks disjoint cusp neighborhoods (using
434
- :py:meth:`Manifold.cusp_areas`, thus the same arguments can be
435
- used) and returns for each cusp the slopes that have length less
436
- or equal to given ``length`` (defaults to 6) when measured on the
437
- boundary of the cusp neighborhood::
391
+ Returns a list of short slopes (for Dehn-fillings) for each cusp.
392
+
393
+ That is, the method uses :meth:`~snappy.Manifold.cusp_areas` to find
394
+ (maximal) embedded and disjoint cusp neighborhoods. It uses the boundaries
395
+ of these cusp neighborhoods to measure the length of a peripheral curve.
396
+ For each cusp, it determines all simple peripheral curves shorter than
397
+ the given :attr:`length` (which defaults to 6). The result is a list
398
+ of the corresponding slopes for each cusp::
438
399
 
439
400
  >>> M = Manifold("otet20_00022")
440
401
  >>> M.short_slopes()
441
402
  [[(1, 0), (-1, 1), (0, 1)], [(1, 0)]]
442
-
443
- When ``verified=True``, the result is guaranteed
444
- to contain all slopes of length less or equal to given ``length``
445
- (and could contain additional slopes if precision is not high
446
- enough)::
447
403
 
448
- sage: M.short_slopes(verified = True)
449
- [[(1, 0), (-1, 1), (0, 1)], [(1, 0)]]
450
-
404
+ It takes the same arguments as :meth:`~snappy.Manifold.cusp_areas`::
405
+
406
+ >>> M.short_slopes(policy = 'greedy')
407
+ [[(1, 0)], [(1, 0)]]
408
+
451
409
  The ten exceptional slopes of the figure-eight knot::
452
410
 
453
411
  >>> M = Manifold("4_1")
454
412
  >>> M.short_slopes()
455
413
  [[(1, 0), (-4, 1), (-3, 1), (-2, 1), (-1, 1), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1)]]
456
414
 
457
- Two more slopes appear when increasing length to 2 pi::
458
-
415
+ Two more slopes appear when increasing length to :math:`2\\pi`::
416
+
459
417
  >>> M.short_slopes(length = 6.283185307179586)
460
418
  [[(1, 0), (-5, 1), (-4, 1), (-3, 1), (-2, 1), (-1, 1), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1)]]
461
419
 
462
- When using verified computations, ``length`` is converted into the ``RealIntervalField`` of requested precision::
420
+ **Verified computation**
421
+
422
+ If :attr:`verified = False`, floating-point issues can arise resulting in
423
+ incorrect values. The method can be made
424
+ :ref:`verified <verify-primer>` by passing :attr:`verified = True`::
425
+
426
+ sage: M = Manifold("4_1")
427
+ sage: M.short_slopes(verified = True)
428
+ [[(1, 0), (-4, 1), (-3, 1), (-2, 1), (-1, 1), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1)]]
429
+
430
+ If :attr:`verified = True`, the result is guaranteed to contain all short
431
+ slopes and might contain additional slopes (with lengths slightly longer
432
+ than the given :attr:`length` but this could not be proven using the
433
+ interval estimates).
434
+
435
+ The given :attr:`length` is cast to a SageMath ``RealIntervalField`` of the
436
+ given precision if :attr:`verified = True`::
463
437
 
464
438
  sage: from sage.all import pi
465
- sage: M.short_slopes(length = 2 * pi, verified = True, bits_prec = 100)
439
+ sage: M.short_slopes(length = 2 * pi, verified = True, bits_prec = 100)
466
440
  [[(1, 0), (-5, 1), (-4, 1), (-3, 1), (-2, 1), (-1, 1), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1)]]
467
441
 
468
442
  """
469
443
 
470
444
  return [
471
445
  verify_short_slopes.short_slopes_from_cusp_shape_and_area(
472
- shape, area, length = length)
446
+ shape, area, length=length)
473
447
  for shape, area
474
448
  in zip(manifold.cusp_info(
475
- 'shape', verified = verified, bits_prec = bits_prec),
449
+ 'shape', verified=verified, bits_prec=bits_prec),
476
450
  manifold.cusp_areas(
477
- policy = policy, method = method,
478
- verified = verified, bits_prec = bits_prec, first_cusps=first_cusps)) ]
451
+ policy=policy, method=method,
452
+ verified=verified, bits_prec=bits_prec, first_cusps=first_cusps)) ]
453
+
479
454
 
480
455
  Manifold.short_slopes = short_slopes
481
456
  ManifoldHP.short_slopes = short_slopes
482
457
 
483
- def cusp_translations(manifold, policy = 'unbiased',
484
- method = 'trigDependentTryCanonize',
485
- verified = False, bits_prec = None, first_cusps=[]):
458
+
459
+ def cusp_translations(manifold,
460
+ policy : str = 'unbiased',
461
+ method : str = 'maximal',
462
+ verified : bool = False,
463
+ bits_prec : Optional[int] = None,
464
+ first_cusps : List[int] = []):
486
465
  """
487
- Picks disjoint cusp neighborhoods and returns the respective
488
- (complex) Euclidean translations of the meridian and longitude for
489
- each cusp. The method takes the same arguments as
490
- :py:meth:`Manifold.cusp_areas` and uses that method to pick the
491
- cusp neighborhood. The result is a list of pairs, the second entry
492
- corresponding to a longitude is always real::
466
+ Returns a list of the (complex) Euclidean translations corresponding to the
467
+ meridian and longitude of each cusp.
468
+
469
+ That is, the method uses :meth:`~snappy.Manifold.cusp_areas` to find
470
+ (maximal) embedded and disjoint cusp neighborhoods. It then uses the
471
+ boundaries of these cusp neighborhoods to measure the meridian and
472
+ longitude of each cusp. The result is a pair for each cusp. The first
473
+ entry of the pair corresponds to the meridian and is complex. The
474
+ second entry corresponds to the longitude and is always real::
493
475
 
494
476
  >>> M = Manifold("s776")
495
477
  >>> M.cusp_translations() # doctest: +NUMERIC9
496
478
  [(0.500000000000000 + 1.32287565553230*I, 2.00000000000000), (0.500000000000000 + 1.32287565553230*I, 2.00000000000000), (0.499999999999999 + 1.32287565553230*I, 2.00000000000000)]
497
479
 
498
- Arguments such as ``policy='greedy'`` are interpreted the same way as
499
- for :py:meth:`Manifold.cusp_areas`::
480
+ It takes the same arguments as :meth:`~snappy.Manifold.cusp_areas`::
500
481
 
501
- >>> M.cusp_translations(policy = 'greedy', first_cusps = [], bits_prec = 100) # doctest: +NUMERIC21
482
+ >>> M.cusp_translations(policy = 'greedy') # doctest: +NUMERIC9
502
483
  [(0.70710678118654752440084436210 + 1.8708286933869706927918743662*I, 2.8284271247461900976033774484), (0.35355339059327376220042218105 + 0.93541434669348534639593718308*I, 1.4142135623730950488016887242), (0.35355339059327376220042218105 + 0.93541434669348534639593718308*I, 1.4142135623730950488016887242)]
503
484
 
504
- and can return verified intervals::
505
-
506
- sage: M.cusp_translations(method = 'maximal', verified = True) # doctest: +NUMERIC9
507
- [(0.50000000000? + 1.32287565553?*I, 2.00000000000?), (0.500000000000? + 1.32287565554?*I, 2.00000000000?), (0.500000000000? + 1.32287565554?*I, 2.00000000000?)]
485
+ **Verified computations**
508
486
 
509
- that are guaranteed to contain the true translations of cusp neighborhoods
510
- verified to be disjoint (the element corresponding to a longitude
511
- is always in a ``RealIntervalField``).
487
+ If :attr:`verified = False`, floating-point issues can arise resulting in
488
+ incorrect values. The method can be made
489
+ :ref:`verified <verify-primer>` by passing :attr:`verified = True`::
512
490
 
513
- **Remark:** The default ``method = 'trigDependentTryCanonize'`` is
514
- (potentially) non-deterministic and thus the result of
515
-
516
- [ M.cusp_translations()[i] for i in range(M.num_cusps()) ]
491
+ sage: M.cusp_translations(verified = True) # doctest: +NUMERIC9
492
+ [(0.50000000000? + 1.32287565553?*I, 2.00000000000?), (0.500000000000? + 1.32287565554?*I, 2.00000000000?), (0.500000000000? + 1.32287565554?*I, 2.00000000000?)]
517
493
 
518
- might not correspond to disjoint cusp neighborhoods.
494
+ Note that the first element of each pair is a SageMath ``ComplexIntervalField`` and
495
+ the second element a ``RealIntervalField``.
519
496
  """
520
497
 
521
498
  return [
522
499
  verify_short_slopes.translations_from_cusp_shape_and_area(
523
- shape, area, kernel_convention = True)
500
+ shape, area, kernel_convention=True)
524
501
  for shape, area
525
502
  in zip(manifold.cusp_info(
526
- 'shape', verified = verified, bits_prec = bits_prec),
503
+ 'shape', verified=verified, bits_prec=bits_prec),
527
504
  manifold.cusp_areas(
528
- policy = policy, method = method,
529
- verified = verified, bits_prec = bits_prec, first_cusps=first_cusps)) ]
505
+ policy=policy, method=method,
506
+ verified=verified, bits_prec=bits_prec, first_cusps=first_cusps)) ]
507
+
530
508
 
531
509
  Manifold.cusp_translations = cusp_translations
532
510
  ManifoldHP.cusp_translations = cusp_translations
533
511
 
534
- def complex_volume(manifold, verified_modulo_2_torsion = False,
535
- bits_prec = None):
512
+
513
+ def complex_volume(manifold, verified_modulo_2_torsion=False,
514
+ bits_prec=None):
536
515
  """
537
- Returns the complex volume, i.e.
538
- volume + i 2 pi^2 (chern simons)
539
-
540
- >>> M = Manifold('5_2')
541
- >>> M.complex_volume() # doctest: +NUMERIC6
542
- 2.82812209 - 3.02412838*I
543
- >>> c = M.chern_simons()
544
- >>> M.dehn_fill((1,2))
545
- >>> M.complex_volume() # doctest: +NUMERIC6
546
- 2.22671790 + 1.52619361*I
547
- >>> M = Manifold("3_1")
548
- >>> cvol = M.complex_volume()
549
- >>> cvol.real() # doctest: +NUMERIC6
550
- 0
551
- >>> cvol.imag() # doctest: +NUMERIC6
552
- -1.64493407
516
+ Returns the complex volume modulo :math:`i \\pi^2` which is given by
517
+
518
+ .. math::
519
+ \\text{vol} + i \\text{CS}
520
+
521
+ where :math:`\\text{CS}` is the (unnormalized) Chern-Simons invariant.
522
+
523
+ >>> M = Manifold('5_2')
524
+ >>> M.complex_volume() # doctest: +NUMERIC6
525
+ 2.82812209 - 3.02412838*I
526
+
527
+ Note that :meth:`chern_simons <snappy.Manifold.chern_simons>`
528
+ normalizes the Chern-Simons invariant by dividing it by
529
+ :math:`2 \\pi^2 = 19.7392...` ::
530
+
531
+ >>> M.chern_simons() # doctest: +NUMERIC6
532
+ -0.153204133297152
533
+
534
+ More examples::
535
+
536
+ >>> M.dehn_fill((1,2))
537
+ >>> M.complex_volume() # doctest: +NUMERIC6
538
+ 2.22671790 + 1.52619361*I
539
+ >>> M = Manifold("3_1") # A non-hyperbolic example.
540
+ >>> cvol = M.complex_volume()
541
+ >>> cvol.real() # doctest: +NUMERIC6
542
+ 0
543
+ >>> cvol.imag() # doctest: +NUMERIC6
544
+ -1.64493407
553
545
 
554
546
  If no cusp is filled or there is only one cusped (filled or
555
547
  unfilled), the complex volume can be verified up to multiples
556
- of i pi^2 / 2 by passing `verified_modulo_2_torsion = True`
557
- when inside SageMath (and higher precision can be requested
558
- with `bits_prec`)::
548
+ of :math:`i \\pi^2 /2` by passing ``verified_modulo_2_torsion = True``
549
+ when inside SageMath. Higher precision can be requested
550
+ with ``bits_prec``::
559
551
 
560
552
  sage: M = Manifold("m015")
561
- sage: M.complex_volume(verified_modulo_2_torsion=True, bits_prec = 90) # doctest: +NUMERIC24
553
+ sage: M.complex_volume(verified_modulo_2_torsion=True, bits_prec = 93) # doctest: +NUMERIC21
562
554
  2.828122088330783162764? + 1.910673824035377649698?*I
563
555
  sage: M = Manifold("m015(3,4)")
564
556
  sage: M.complex_volume(verified_modulo_2_torsion=True) # doctest: +NUMERIC6
@@ -567,76 +559,29 @@ def complex_volume(manifold, verified_modulo_2_torsion = False,
567
559
  """
568
560
  if verified_modulo_2_torsion:
569
561
  return verify.verified_complex_volume_torsion(
570
- manifold, bits_prec = bits_prec)
562
+ manifold, bits_prec=bits_prec)
571
563
 
572
564
  if bits_prec:
573
565
  raise Exception("Arbitrary precision for complex volume only "
574
566
  "supported for verified computations and cusped "
575
567
  "manifolds.")
576
-
568
+
577
569
  return manifold._complex_volume()
578
570
 
579
571
  Manifold.complex_volume = complex_volume
580
572
  ManifoldHP.complex_volume = complex_volume
581
573
 
582
- try:
583
- from .gui import ViewerWindow
584
- from .raytracing.inside_viewer import InsideViewer
585
- from .raytracing.inside_viewer import NonorientableUnsupportedError
586
- from .raytracing import cohomology_fractal
587
- except ImportError as e:
588
- InsideViewer = None
589
- _importErrorRaytracing = str(e)
590
-
591
- def manifold_inside_view(self, cohomology_class = None):
592
- """
593
- Show raytraced inside view of hyperbolic manifold:
594
-
595
- >>> M = Manifold("m004")
596
- >>> M.inside_view() #doctest: +CYMODERNOPENGL
597
-
598
- Or show the cohomology fractal:
599
-
600
- >>> M = Manifold("m004")
601
- >>> M.inside_view(cohomology_class = 0) #doctest: +CYMODERNOPENGL
602
-
603
- The cohomology class in H^2(M, bd M; R) producing the cohomology
604
- fractal can be specified as a cocycle or using an automatically computed
605
- basis (of, say, length ``n``). Thus, ``cohomology_class`` can be one of
606
- the following.
607
-
608
- - An integer ``i`` between 0 and ``n`` - 1 to pick the ``i``-th basis
609
- vector.
610
- - An array of length ``n`` specifying the cohomology class as linear
611
- combination of basis vectors.
612
- - A weight for each face of each tetrahedron.
613
-
614
- """
615
-
616
- if InsideViewer is None:
617
- raise RuntimeError("Raytraced inside view not imported; "
618
- "Tk or CyOpenGL is probably missing "
619
- "(original error : %s)" % _importErrorRaytracing)
620
-
621
- if not self.is_orientable():
622
- raise NonorientableUnsupportedError(self)
574
+ from . import drilling
575
+ drilling._add_methods(Manifold)
576
+ drilling._add_methods(ManifoldHP, high_precision=True)
623
577
 
624
- weights, cohomology_basis, cohomology_class = (
625
- cohomology_fractal.compute_weights_basis_class(
626
- self, cohomology_class))
578
+ from . import raytracing
627
579
 
628
- return ViewerWindow(
629
- InsideViewer,
630
- self,
631
- title = "Inside view of %s" % self.name(),
632
- weights = weights,
633
- cohomology_basis = cohomology_basis,
634
- cohomology_class = cohomology_class)
580
+ Manifold.inside_view = raytracing.inside_view
581
+ ManifoldHP.inside_view = raytracing.inside_view
635
582
 
636
- Manifold.inside_view = manifold_inside_view
637
- ManifoldHP.inside_view = manifold_inside_view
638
583
 
639
- def all_translations(self, verified = False, bits_prec = None):
584
+ def all_translations(self, verified=False, bits_prec=None):
640
585
  """
641
586
  Returns the (complex) Euclidean translations of the meridian
642
587
  and longitude for each cusp measured with respect to the cusp neighborhood.
@@ -656,10 +601,10 @@ def all_translations(self, verified = False, bits_prec = None):
656
601
  >>> N.set_displacement(100,2)
657
602
  >>> N.all_translations() # doctest: +NUMERIC9
658
603
  [(-0.477656250512815 + 2.33461303362557*I, 2.71240613125259), (-0.259696455247511 + 1.26930345526993*I, 1.47470541152065), (0.131389112265699 + 0.991330873713731*I, 1.22318540718077)]
659
-
604
+
660
605
  This can also be achieved by :py:meth:`Manifold.cusp_translations` which
661
606
  would have made a different choice of disjoint cusp neighborhoods though::
662
-
607
+
663
608
  >>> M.cusp_translations() # doctest: +NUMERIC6
664
609
  [(-0.315973594129651 + 1.54436599614183*I, 1.79427928161946), (-0.315973594129649 + 1.54436599614182*I, 1.79427928161946), (0.198620491993677 + 1.49859164484929*I, 1.84908538602825)]
665
610
 
@@ -691,16 +636,17 @@ def all_translations(self, verified = False, bits_prec = None):
691
636
 
692
637
  is not verified to correspond to disjoint cusp neighborhoods.
693
638
  """
694
-
639
+
695
640
  if verified or bits_prec:
696
- # Use the implementation in verify.cuspTranslations that uses
641
+ # Use the implementation in verify.cusp_translations that uses
697
642
  # tetrahedra_shapes and ComplexCuspNeighborhood
698
643
  return verify.cusp_translations_for_neighborhood(
699
- self, verified = verified, bits_prec = bits_prec)
644
+ self, verified=verified, bits_prec=bits_prec)
700
645
 
701
646
  # Use the implementation in the SnapPea kernel
702
647
  return [ self.translations(i) for i in range(self.num_cusps()) ]
703
648
 
649
+
704
650
  CuspNeighborhood.all_translations = all_translations
705
651
  CuspNeighborhoodHP.all_translations = all_translations
706
652
 
@@ -711,6 +657,7 @@ from . import twister
711
657
 
712
658
  from . import database
713
659
  database.Manifold = Manifold
660
+ database.Triangulation = Triangulation
714
661
  snappy_module = sys.modules[__name__]
715
662
  database_objects = []
716
663
  known_manifold_packages = [('snappy_manifolds', True),
@@ -730,11 +677,12 @@ __all__ += database_objects
730
677
 
731
678
  from spherogram.codecs import DTcodec
732
679
 
680
+
733
681
  def _link_exterior(self, with_hyperbolic_structure=True,
734
682
  remove_finite_vertices=True):
735
683
  """
736
684
  The exterior or complement of the link L, that is, S^3 minus L.
737
-
685
+
738
686
  >>> K = Link('4_1')
739
687
  >>> M = K.exterior()
740
688
  >>> M.volume() # doctest: +NUMERIC6
@@ -749,7 +697,7 @@ def _link_exterior(self, with_hyperbolic_structure=True,
749
697
  >>> M = K.exterior(False, False)
750
698
  >>> (M.num_cusps(), M._num_fake_cusps())
751
699
  (1, 2)
752
-
700
+
753
701
  """
754
702
  M = Triangulation('empty')
755
703
  M._get_from_link_data(self.KLPProjection(), remove_finite_vertices)
@@ -761,6 +709,7 @@ def _link_exterior(self, with_hyperbolic_structure=True,
761
709
  M.set_name(self.name)
762
710
  return M
763
711
 
712
+
764
713
  link_objects = []
765
714
 
766
715
  from spherogram.links import (Crossing, Strand, Link, Tangle,
@@ -787,27 +736,25 @@ for mfld_class in [Triangulation, Manifold, ManifoldHP]:
787
736
  'normal_boundary_slopes']:
788
737
  setattr(mfld_class, method, getattr(_spun, method))
789
738
 
739
+ import textwrap
740
+
790
741
  # Documentation for the module:
791
- SnapPy_doc = """
742
+ __doc__ = """
792
743
  SnapPy is a Cython wrapping of Jeff Weeks' SnapPea kernel.
793
744
 
794
745
  The module defines the following classes:
795
- Triangulation, Manifold,
796
- AbelianGroup, FundamentalGroup, HolonomyGroup,
797
- DirichletDomain, CuspNeighborhood, SymmetryGroup,
798
- OrientableCuspedCensus, NonorientableCuspedCensus,
799
- OrientableClosedCensus, NonorientableClosedCensus,
800
- AlternatingKnotExteriors, NonalternatingKnotExteriors,
801
- SnapPeaFatalError, pari, twister,
802
- %s
803
- %s.
804
-
805
- """%(', '.join(database_objects), ', '.join(link_objects))
806
-
807
- # Add easy way to get the version info
746
+ %s""" % textwrap.fill(
747
+ ', '.join(__all__) + '.',
748
+ width=78,
749
+ initial_indent=' ',
750
+ subsequent_indent=' ')
751
+
752
+ # Add easy way to get the version info
808
753
  from .version import version as release_info
809
754
 
755
+
810
756
  def version():
811
757
  return release_info
812
758
 
759
+
813
760
  __version__ = version()