snappy 3.3__cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. snappy/CyOpenGL.cpython-310-aarch64-linux-gnu.so +0 -0
  2. snappy/SnapPy.cpython-310-aarch64-linux-gnu.so +0 -0
  3. snappy/SnapPy.ico +0 -0
  4. snappy/SnapPy.png +0 -0
  5. snappy/SnapPyHP.cpython-310-aarch64-linux-gnu.so +0 -0
  6. snappy/__init__.py +534 -0
  7. snappy/app.py +604 -0
  8. snappy/app_menus.py +372 -0
  9. snappy/browser.py +998 -0
  10. snappy/cache.py +25 -0
  11. snappy/canonical.py +249 -0
  12. snappy/cusps/__init__.py +280 -0
  13. snappy/cusps/cusp_area_matrix.py +98 -0
  14. snappy/cusps/cusp_areas_from_matrix.py +96 -0
  15. snappy/cusps/maximal_cusp_area_matrix.py +136 -0
  16. snappy/cusps/short_slopes_for_cusp.py +217 -0
  17. snappy/cusps/test.py +22 -0
  18. snappy/cusps/trig_cusp_area_matrix.py +63 -0
  19. snappy/database.py +454 -0
  20. snappy/db_utilities.py +79 -0
  21. snappy/decorated_isosig.py +717 -0
  22. snappy/dev/__init__.py +0 -0
  23. snappy/dev/extended_ptolemy/__init__.py +8 -0
  24. snappy/dev/extended_ptolemy/closed.py +106 -0
  25. snappy/dev/extended_ptolemy/complexVolumesClosed.py +149 -0
  26. snappy/dev/extended_ptolemy/direct.py +42 -0
  27. snappy/dev/extended_ptolemy/extended.py +406 -0
  28. snappy/dev/extended_ptolemy/giac_helper.py +43 -0
  29. snappy/dev/extended_ptolemy/giac_rur.py +129 -0
  30. snappy/dev/extended_ptolemy/gluing.py +46 -0
  31. snappy/dev/extended_ptolemy/phc_wrapper.py +220 -0
  32. snappy/dev/extended_ptolemy/printMatrices.py +70 -0
  33. snappy/dev/vericlosed/__init__.py +1 -0
  34. snappy/dev/vericlosed/computeApproxHyperbolicStructureNew.py +159 -0
  35. snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +90 -0
  36. snappy/dev/vericlosed/computeVerifiedHyperbolicStructure.py +111 -0
  37. snappy/dev/vericlosed/gimbalLoopFinder.py +130 -0
  38. snappy/dev/vericlosed/hyperbolicStructure.py +313 -0
  39. snappy/dev/vericlosed/krawczykCertifiedEdgeLengthsEngine.py +165 -0
  40. snappy/dev/vericlosed/oneVertexTruncatedComplex.py +122 -0
  41. snappy/dev/vericlosed/orb/__init__.py +1 -0
  42. snappy/dev/vericlosed/orb/orb_solution_for_snappea_finite_triangulation_mac +0 -0
  43. snappy/dev/vericlosed/parseVertexGramMatrixFile.py +47 -0
  44. snappy/dev/vericlosed/polishApproxHyperbolicStructure.py +61 -0
  45. snappy/dev/vericlosed/test.py +54 -0
  46. snappy/dev/vericlosed/truncatedComplex.py +176 -0
  47. snappy/dev/vericlosed/verificationError.py +58 -0
  48. snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +177 -0
  49. snappy/doc/_images/SnapPy-196.png +0 -0
  50. snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
  51. snappy/doc/_images/m125_paper_plane.jpg +0 -0
  52. snappy/doc/_images/mac.png +0 -0
  53. snappy/doc/_images/o9_00000_systole_paper_plane.jpg +0 -0
  54. snappy/doc/_images/o9_00000_systole_paper_plane_closer.jpg +0 -0
  55. snappy/doc/_images/plink-action.png +0 -0
  56. snappy/doc/_images/ubuntu.png +0 -0
  57. snappy/doc/_images/win7.png +0 -0
  58. snappy/doc/_sources/additional_classes.rst.txt +40 -0
  59. snappy/doc/_sources/bugs.rst.txt +14 -0
  60. snappy/doc/_sources/censuses.rst.txt +52 -0
  61. snappy/doc/_sources/credits.rst.txt +81 -0
  62. snappy/doc/_sources/development.rst.txt +261 -0
  63. snappy/doc/_sources/index.rst.txt +215 -0
  64. snappy/doc/_sources/installing.rst.txt +249 -0
  65. snappy/doc/_sources/manifold.rst.txt +6 -0
  66. snappy/doc/_sources/manifoldhp.rst.txt +46 -0
  67. snappy/doc/_sources/news.rst.txt +425 -0
  68. snappy/doc/_sources/other.rst.txt +25 -0
  69. snappy/doc/_sources/platonic_census.rst.txt +20 -0
  70. snappy/doc/_sources/plink.rst.txt +102 -0
  71. snappy/doc/_sources/ptolemy.rst.txt +66 -0
  72. snappy/doc/_sources/ptolemy_classes.rst.txt +42 -0
  73. snappy/doc/_sources/ptolemy_examples1.rst.txt +298 -0
  74. snappy/doc/_sources/ptolemy_examples2.rst.txt +363 -0
  75. snappy/doc/_sources/ptolemy_examples3.rst.txt +301 -0
  76. snappy/doc/_sources/ptolemy_examples4.rst.txt +61 -0
  77. snappy/doc/_sources/ptolemy_prelim.rst.txt +105 -0
  78. snappy/doc/_sources/screenshots.rst.txt +21 -0
  79. snappy/doc/_sources/snap.rst.txt +87 -0
  80. snappy/doc/_sources/snappy.rst.txt +28 -0
  81. snappy/doc/_sources/spherogram.rst.txt +103 -0
  82. snappy/doc/_sources/todo.rst.txt +47 -0
  83. snappy/doc/_sources/triangulation.rst.txt +11 -0
  84. snappy/doc/_sources/tutorial.rst.txt +49 -0
  85. snappy/doc/_sources/verify.rst.txt +210 -0
  86. snappy/doc/_sources/verify_internals.rst.txt +79 -0
  87. snappy/doc/_static/SnapPy-horizontal-128.png +0 -0
  88. snappy/doc/_static/SnapPy.ico +0 -0
  89. snappy/doc/_static/_sphinx_javascript_frameworks_compat.js +123 -0
  90. snappy/doc/_static/basic.css +906 -0
  91. snappy/doc/_static/css/badge_only.css +1 -0
  92. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  93. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  94. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  95. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  96. snappy/doc/_static/css/fonts/fontawesome-webfont.eot +0 -0
  97. snappy/doc/_static/css/fonts/fontawesome-webfont.svg +2671 -0
  98. snappy/doc/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  99. snappy/doc/_static/css/fonts/fontawesome-webfont.woff +0 -0
  100. snappy/doc/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  101. snappy/doc/_static/css/fonts/lato-bold-italic.woff +0 -0
  102. snappy/doc/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  103. snappy/doc/_static/css/fonts/lato-bold.woff +0 -0
  104. snappy/doc/_static/css/fonts/lato-bold.woff2 +0 -0
  105. snappy/doc/_static/css/fonts/lato-normal-italic.woff +0 -0
  106. snappy/doc/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  107. snappy/doc/_static/css/fonts/lato-normal.woff +0 -0
  108. snappy/doc/_static/css/fonts/lato-normal.woff2 +0 -0
  109. snappy/doc/_static/css/theme.css +4 -0
  110. snappy/doc/_static/doctools.js +149 -0
  111. snappy/doc/_static/documentation_options.js +13 -0
  112. snappy/doc/_static/file.png +0 -0
  113. snappy/doc/_static/fonts/Lato/lato-bold.eot +0 -0
  114. snappy/doc/_static/fonts/Lato/lato-bold.ttf +0 -0
  115. snappy/doc/_static/fonts/Lato/lato-bold.woff +0 -0
  116. snappy/doc/_static/fonts/Lato/lato-bold.woff2 +0 -0
  117. snappy/doc/_static/fonts/Lato/lato-bolditalic.eot +0 -0
  118. snappy/doc/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
  119. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff +0 -0
  120. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
  121. snappy/doc/_static/fonts/Lato/lato-italic.eot +0 -0
  122. snappy/doc/_static/fonts/Lato/lato-italic.ttf +0 -0
  123. snappy/doc/_static/fonts/Lato/lato-italic.woff +0 -0
  124. snappy/doc/_static/fonts/Lato/lato-italic.woff2 +0 -0
  125. snappy/doc/_static/fonts/Lato/lato-regular.eot +0 -0
  126. snappy/doc/_static/fonts/Lato/lato-regular.ttf +0 -0
  127. snappy/doc/_static/fonts/Lato/lato-regular.woff +0 -0
  128. snappy/doc/_static/fonts/Lato/lato-regular.woff2 +0 -0
  129. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
  130. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
  131. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
  132. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
  133. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
  134. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
  135. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
  136. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
  137. snappy/doc/_static/jquery.js +2 -0
  138. snappy/doc/_static/js/badge_only.js +1 -0
  139. snappy/doc/_static/js/theme.js +1 -0
  140. snappy/doc/_static/js/versions.js +228 -0
  141. snappy/doc/_static/language_data.js +192 -0
  142. snappy/doc/_static/minus.png +0 -0
  143. snappy/doc/_static/plus.png +0 -0
  144. snappy/doc/_static/pygments.css +75 -0
  145. snappy/doc/_static/searchtools.js +635 -0
  146. snappy/doc/_static/snappy_furo.css +33 -0
  147. snappy/doc/_static/snappy_sphinx_rtd_theme.css +42 -0
  148. snappy/doc/_static/sphinx_highlight.js +154 -0
  149. snappy/doc/additional_classes.html +1500 -0
  150. snappy/doc/bugs.html +132 -0
  151. snappy/doc/censuses.html +453 -0
  152. snappy/doc/credits.html +184 -0
  153. snappy/doc/development.html +385 -0
  154. snappy/doc/doc-latest/additional_classes.html +1500 -0
  155. snappy/doc/doc-latest/bugs.html +132 -0
  156. snappy/doc/doc-latest/censuses.html +453 -0
  157. snappy/doc/doc-latest/credits.html +184 -0
  158. snappy/doc/doc-latest/development.html +385 -0
  159. snappy/doc/doc-latest/genindex.html +1349 -0
  160. snappy/doc/doc-latest/index.html +287 -0
  161. snappy/doc/doc-latest/installing.html +346 -0
  162. snappy/doc/doc-latest/manifold.html +3632 -0
  163. snappy/doc/doc-latest/manifoldhp.html +180 -0
  164. snappy/doc/doc-latest/news.html +438 -0
  165. snappy/doc/doc-latest/objects.inv +0 -0
  166. snappy/doc/doc-latest/other.html +160 -0
  167. snappy/doc/doc-latest/platonic_census.html +376 -0
  168. snappy/doc/doc-latest/plink.html +210 -0
  169. snappy/doc/doc-latest/ptolemy.html +253 -0
  170. snappy/doc/doc-latest/ptolemy_classes.html +1144 -0
  171. snappy/doc/doc-latest/ptolemy_examples1.html +409 -0
  172. snappy/doc/doc-latest/ptolemy_examples2.html +471 -0
  173. snappy/doc/doc-latest/ptolemy_examples3.html +414 -0
  174. snappy/doc/doc-latest/ptolemy_examples4.html +195 -0
  175. snappy/doc/doc-latest/ptolemy_prelim.html +248 -0
  176. snappy/doc/doc-latest/py-modindex.html +165 -0
  177. snappy/doc/doc-latest/screenshots.html +141 -0
  178. snappy/doc/doc-latest/search.html +135 -0
  179. snappy/doc/doc-latest/searchindex.js +1 -0
  180. snappy/doc/doc-latest/snap.html +202 -0
  181. snappy/doc/doc-latest/snappy.html +181 -0
  182. snappy/doc/doc-latest/spherogram.html +1346 -0
  183. snappy/doc/doc-latest/todo.html +166 -0
  184. snappy/doc/doc-latest/triangulation.html +1676 -0
  185. snappy/doc/doc-latest/tutorial.html +159 -0
  186. snappy/doc/doc-latest/verify.html +330 -0
  187. snappy/doc/doc-latest/verify_internals.html +1235 -0
  188. snappy/doc/genindex.html +1349 -0
  189. snappy/doc/index.html +287 -0
  190. snappy/doc/installing.html +346 -0
  191. snappy/doc/manifold.html +3632 -0
  192. snappy/doc/manifoldhp.html +180 -0
  193. snappy/doc/news.html +438 -0
  194. snappy/doc/objects.inv +0 -0
  195. snappy/doc/other.html +160 -0
  196. snappy/doc/platonic_census.html +376 -0
  197. snappy/doc/plink.html +210 -0
  198. snappy/doc/ptolemy.html +253 -0
  199. snappy/doc/ptolemy_classes.html +1144 -0
  200. snappy/doc/ptolemy_examples1.html +409 -0
  201. snappy/doc/ptolemy_examples2.html +471 -0
  202. snappy/doc/ptolemy_examples3.html +414 -0
  203. snappy/doc/ptolemy_examples4.html +195 -0
  204. snappy/doc/ptolemy_prelim.html +248 -0
  205. snappy/doc/py-modindex.html +165 -0
  206. snappy/doc/screenshots.html +141 -0
  207. snappy/doc/search.html +135 -0
  208. snappy/doc/searchindex.js +1 -0
  209. snappy/doc/snap.html +202 -0
  210. snappy/doc/snappy.html +181 -0
  211. snappy/doc/spherogram.html +1346 -0
  212. snappy/doc/todo.html +166 -0
  213. snappy/doc/triangulation.html +1676 -0
  214. snappy/doc/tutorial.html +159 -0
  215. snappy/doc/verify.html +330 -0
  216. snappy/doc/verify_internals.html +1235 -0
  217. snappy/drilling/__init__.py +456 -0
  218. snappy/drilling/barycentric.py +103 -0
  219. snappy/drilling/constants.py +5 -0
  220. snappy/drilling/crush.py +270 -0
  221. snappy/drilling/cusps.py +125 -0
  222. snappy/drilling/debug.py +242 -0
  223. snappy/drilling/epsilons.py +6 -0
  224. snappy/drilling/exceptions.py +55 -0
  225. snappy/drilling/moves.py +620 -0
  226. snappy/drilling/peripheral_curves.py +210 -0
  227. snappy/drilling/perturb.py +188 -0
  228. snappy/drilling/shorten.py +36 -0
  229. snappy/drilling/subdivide.py +274 -0
  230. snappy/drilling/test.py +23 -0
  231. snappy/drilling/test_cases.py +132 -0
  232. snappy/drilling/tracing.py +351 -0
  233. snappy/exceptions.py +26 -0
  234. snappy/export_stl.py +120 -0
  235. snappy/exterior_to_link/__init__.py +2 -0
  236. snappy/exterior_to_link/barycentric_geometry.py +463 -0
  237. snappy/exterior_to_link/exceptions.py +6 -0
  238. snappy/exterior_to_link/geodesic_map.json +14408 -0
  239. snappy/exterior_to_link/hyp_utils.py +112 -0
  240. snappy/exterior_to_link/link_projection.py +323 -0
  241. snappy/exterior_to_link/main.py +198 -0
  242. snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
  243. snappy/exterior_to_link/mcomplex_with_link.py +687 -0
  244. snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
  245. snappy/exterior_to_link/pl_utils.py +491 -0
  246. snappy/exterior_to_link/put_in_S3.py +156 -0
  247. snappy/exterior_to_link/rational_linear_algebra.py +130 -0
  248. snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
  249. snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
  250. snappy/exterior_to_link/stored_moves.py +475 -0
  251. snappy/exterior_to_link/test.py +31 -0
  252. snappy/filedialog.py +28 -0
  253. snappy/geometric_structure/__init__.py +212 -0
  254. snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
  255. snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +691 -0
  256. snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +480 -0
  257. snappy/geometric_structure/cusp_neighborhood/exceptions.py +41 -0
  258. snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +294 -0
  259. snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +156 -0
  260. snappy/geometric_structure/cusp_neighborhood/vertices.py +35 -0
  261. snappy/geometric_structure/geodesic/__init__.py +0 -0
  262. snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
  263. snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
  264. snappy/geometric_structure/geodesic/canonical_representatives.py +52 -0
  265. snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
  266. snappy/geometric_structure/geodesic/constants.py +6 -0
  267. snappy/geometric_structure/geodesic/exceptions.py +22 -0
  268. snappy/geometric_structure/geodesic/fixed_points.py +106 -0
  269. snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
  270. snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
  271. snappy/geometric_structure/geodesic/line.py +30 -0
  272. snappy/geometric_structure/geodesic/multiplicity.py +127 -0
  273. snappy/geometric_structure/geodesic/tiles_for_geodesic.py +128 -0
  274. snappy/geometric_structure/test.py +22 -0
  275. snappy/gui.py +121 -0
  276. snappy/horoviewer.py +443 -0
  277. snappy/hyperboloid/__init__.py +212 -0
  278. snappy/hyperboloid/distances.py +259 -0
  279. snappy/hyperboloid/horoball.py +19 -0
  280. snappy/hyperboloid/line.py +35 -0
  281. snappy/hyperboloid/point.py +9 -0
  282. snappy/hyperboloid/triangle.py +29 -0
  283. snappy/info_icon.gif +0 -0
  284. snappy/infowindow.py +65 -0
  285. snappy/isometry_signature.py +389 -0
  286. snappy/len_spec/__init__.py +609 -0
  287. snappy/len_spec/geodesic_info.py +129 -0
  288. snappy/len_spec/geodesic_key_info_dict.py +116 -0
  289. snappy/len_spec/geodesic_piece.py +146 -0
  290. snappy/len_spec/geometric_structure.py +182 -0
  291. snappy/len_spec/geometry.py +136 -0
  292. snappy/len_spec/length_spectrum_geodesic_info.py +185 -0
  293. snappy/len_spec/spine.py +128 -0
  294. snappy/len_spec/test.py +24 -0
  295. snappy/len_spec/test_cases.py +69 -0
  296. snappy/len_spec/tile.py +276 -0
  297. snappy/len_spec/word.py +86 -0
  298. snappy/manifolds/HTWKnots/alternating.gz +0 -0
  299. snappy/manifolds/HTWKnots/nonalternating.gz +0 -0
  300. snappy/manifolds/__init__.py +3 -0
  301. snappy/margulis/__init__.py +332 -0
  302. snappy/margulis/cusp_neighborhood_neighborhood.py +66 -0
  303. snappy/margulis/geodesic_neighborhood.py +152 -0
  304. snappy/margulis/margulis_info.py +21 -0
  305. snappy/margulis/mu_from_neighborhood_pair.py +175 -0
  306. snappy/margulis/neighborhood.py +29 -0
  307. snappy/margulis/test.py +22 -0
  308. snappy/math_basics.py +187 -0
  309. snappy/matrix.py +525 -0
  310. snappy/number.py +657 -0
  311. snappy/numeric_output_checker.py +345 -0
  312. snappy/pari.py +41 -0
  313. snappy/phone_home.py +57 -0
  314. snappy/polyviewer.py +259 -0
  315. snappy/ptolemy/__init__.py +17 -0
  316. snappy/ptolemy/component.py +103 -0
  317. snappy/ptolemy/coordinates.py +2290 -0
  318. snappy/ptolemy/fieldExtensions.py +153 -0
  319. snappy/ptolemy/findLoops.py +473 -0
  320. snappy/ptolemy/geometricRep.py +59 -0
  321. snappy/ptolemy/homology.py +165 -0
  322. snappy/ptolemy/magma/default.magma_template +229 -0
  323. snappy/ptolemy/magma/radicalsOfPrimaryDecomposition.magma_template +79 -0
  324. snappy/ptolemy/manifoldMethods.py +395 -0
  325. snappy/ptolemy/matrix.py +350 -0
  326. snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +113 -0
  327. snappy/ptolemy/polynomial.py +856 -0
  328. snappy/ptolemy/processComponents.py +173 -0
  329. snappy/ptolemy/processFileBase.py +247 -0
  330. snappy/ptolemy/processFileDispatch.py +46 -0
  331. snappy/ptolemy/processMagmaFile.py +392 -0
  332. snappy/ptolemy/processRurFile.py +150 -0
  333. snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +102 -0
  334. snappy/ptolemy/ptolemyObstructionClass.py +64 -0
  335. snappy/ptolemy/ptolemyVariety.py +995 -0
  336. snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +140 -0
  337. snappy/ptolemy/reginaWrapper.py +698 -0
  338. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  339. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  340. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  341. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  342. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  343. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  344. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  345. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  346. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  347. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  348. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c0.magma_out.bz2 +0 -0
  349. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  350. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  351. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c1.magma_out.bz2 +0 -0
  352. snappy/ptolemy/rur.py +545 -0
  353. snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +277 -0
  354. snappy/ptolemy/test.py +1126 -0
  355. snappy/ptolemy/testing_files/3_1__sl2_c0.magma_out.bz2 +0 -0
  356. snappy/ptolemy/testing_files/3_1__sl2_c1.magma_out.bz2 +0 -0
  357. snappy/ptolemy/testing_files/4_1__sl2_c0.magma_out.bz2 +0 -0
  358. snappy/ptolemy/testing_files/4_1__sl2_c1.magma_out.bz2 +0 -0
  359. snappy/ptolemy/testing_files/4_1__sl3_c0.magma_out.bz2 +0 -0
  360. snappy/ptolemy/testing_files/4_1__sl4_c0.magma_out.bz2 +0 -0
  361. snappy/ptolemy/testing_files/4_1__sl4_c1.magma_out.bz2 +0 -0
  362. snappy/ptolemy/testing_files/5_2__sl2_c0.magma_out.bz2 +0 -0
  363. snappy/ptolemy/testing_files/5_2__sl2_c1.magma_out.bz2 +0 -0
  364. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  365. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  366. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  367. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  368. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  369. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  370. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  371. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  372. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c0.magma_out +95 -0
  373. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c1.magma_out +95 -0
  374. snappy/ptolemy/testing_files/m015__sl3_c0.magma_out.bz2 +0 -0
  375. snappy/ptolemy/testing_files/m135__sl2_c0.magma_out.bz2 +0 -0
  376. snappy/ptolemy/testing_files/m135__sl2_c1.magma_out.bz2 +0 -0
  377. snappy/ptolemy/testing_files/m135__sl2_c2.magma_out.bz2 +0 -0
  378. snappy/ptolemy/testing_files/m135__sl2_c3.magma_out.bz2 +0 -0
  379. snappy/ptolemy/testing_files/m135__sl2_c4.magma_out.bz2 +0 -0
  380. snappy/ptolemy/testing_files/m135__sl2_c5.magma_out.bz2 +0 -0
  381. snappy/ptolemy/testing_files/m135__sl2_c6.magma_out.bz2 +0 -0
  382. snappy/ptolemy/testing_files/m135__sl2_c7.magma_out.bz2 +0 -0
  383. snappy/ptolemy/testing_files/s000__sl2_c0.magma_out.bz2 +0 -0
  384. snappy/ptolemy/testing_files/s000__sl2_c1.magma_out.bz2 +0 -0
  385. snappy/ptolemy/testing_files/t00000__sl2_c0.magma_out.bz2 +0 -0
  386. snappy/ptolemy/testing_files/t00000__sl2_c1.magma_out.bz2 +0 -0
  387. snappy/ptolemy/testing_files/v0000__sl2_c0.magma_out.bz2 +0 -0
  388. snappy/ptolemy/testing_files/v0000__sl2_c1.magma_out.bz2 +0 -0
  389. snappy/ptolemy/testing_files/v0000__sl2_c2.magma_out.bz2 +0 -0
  390. snappy/ptolemy/testing_files/v0000__sl2_c3.magma_out.bz2 +0 -0
  391. snappy/ptolemy/testing_files_generalized/m003__sl2_c0.magma_out.bz2 +0 -0
  392. snappy/ptolemy/testing_files_generalized/m003__sl2_c1.magma_out.bz2 +0 -0
  393. snappy/ptolemy/testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  394. snappy/ptolemy/testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  395. snappy/ptolemy/testing_files_generalized/m004__sl2_c0.magma_out.bz2 +0 -0
  396. snappy/ptolemy/testing_files_generalized/m004__sl2_c1.magma_out.bz2 +0 -0
  397. snappy/ptolemy/testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  398. snappy/ptolemy/testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  399. snappy/ptolemy/testing_files_rur/m052__sl3_c0.rur.bz2 +0 -0
  400. snappy/ptolemy/utilities.py +236 -0
  401. snappy/raytracing/__init__.py +64 -0
  402. snappy/raytracing/additional_horospheres.py +64 -0
  403. snappy/raytracing/additional_len_spec_choices.py +63 -0
  404. snappy/raytracing/cohomology_fractal.py +197 -0
  405. snappy/raytracing/eyeball.py +124 -0
  406. snappy/raytracing/finite_raytracing_data.py +237 -0
  407. snappy/raytracing/finite_viewer.py +590 -0
  408. snappy/raytracing/geodesic_tube_info.py +174 -0
  409. snappy/raytracing/geodesics.py +246 -0
  410. snappy/raytracing/geodesics_window.py +258 -0
  411. snappy/raytracing/gui_utilities.py +293 -0
  412. snappy/raytracing/hyperboloid_navigation.py +556 -0
  413. snappy/raytracing/hyperboloid_utilities.py +234 -0
  414. snappy/raytracing/ideal_raytracing_data.py +592 -0
  415. snappy/raytracing/inside_viewer.py +974 -0
  416. snappy/raytracing/pack.py +22 -0
  417. snappy/raytracing/raytracing_data.py +126 -0
  418. snappy/raytracing/raytracing_view.py +454 -0
  419. snappy/raytracing/shaders/Eye.png +0 -0
  420. snappy/raytracing/shaders/NonGeometric.png +0 -0
  421. snappy/raytracing/shaders/__init__.py +101 -0
  422. snappy/raytracing/shaders/fragment.glsl +1744 -0
  423. snappy/raytracing/test.py +29 -0
  424. snappy/raytracing/tooltip.py +146 -0
  425. snappy/raytracing/upper_halfspace_utilities.py +98 -0
  426. snappy/raytracing/view_scale_controller.py +98 -0
  427. snappy/raytracing/zoom_slider/__init__.py +263 -0
  428. snappy/raytracing/zoom_slider/inward.png +0 -0
  429. snappy/raytracing/zoom_slider/inward18.png +0 -0
  430. snappy/raytracing/zoom_slider/outward.png +0 -0
  431. snappy/raytracing/zoom_slider/outward18.png +0 -0
  432. snappy/raytracing/zoom_slider/test.py +20 -0
  433. snappy/sage_helper.py +119 -0
  434. snappy/settings.py +407 -0
  435. snappy/shell.py +53 -0
  436. snappy/snap/__init__.py +117 -0
  437. snappy/snap/character_varieties.py +375 -0
  438. snappy/snap/find_field.py +372 -0
  439. snappy/snap/fox_milnor.py +271 -0
  440. snappy/snap/fundamental_polyhedron.py +569 -0
  441. snappy/snap/generators.py +39 -0
  442. snappy/snap/interval_reps.py +81 -0
  443. snappy/snap/kernel_structures.py +128 -0
  444. snappy/snap/mcomplex_base.py +18 -0
  445. snappy/snap/nsagetools.py +716 -0
  446. snappy/snap/peripheral/__init__.py +1 -0
  447. snappy/snap/peripheral/dual_cellulation.py +219 -0
  448. snappy/snap/peripheral/link.py +127 -0
  449. snappy/snap/peripheral/peripheral.py +159 -0
  450. snappy/snap/peripheral/surface.py +522 -0
  451. snappy/snap/peripheral/test.py +35 -0
  452. snappy/snap/polished_reps.py +335 -0
  453. snappy/snap/shapes.py +152 -0
  454. snappy/snap/slice_obs_HKL/__init__.py +194 -0
  455. snappy/snap/slice_obs_HKL/basics.py +236 -0
  456. snappy/snap/slice_obs_HKL/direct.py +217 -0
  457. snappy/snap/slice_obs_HKL/poly_norm.py +212 -0
  458. snappy/snap/slice_obs_HKL/rep_theory.py +424 -0
  459. snappy/snap/t3mlite/__init__.py +2 -0
  460. snappy/snap/t3mlite/arrow.py +243 -0
  461. snappy/snap/t3mlite/corner.py +22 -0
  462. snappy/snap/t3mlite/edge.py +172 -0
  463. snappy/snap/t3mlite/face.py +37 -0
  464. snappy/snap/t3mlite/files.py +211 -0
  465. snappy/snap/t3mlite/homology.py +53 -0
  466. snappy/snap/t3mlite/linalg.py +419 -0
  467. snappy/snap/t3mlite/mcomplex.py +1499 -0
  468. snappy/snap/t3mlite/perm4.py +320 -0
  469. snappy/snap/t3mlite/setup.py +12 -0
  470. snappy/snap/t3mlite/simplex.py +199 -0
  471. snappy/snap/t3mlite/spun.py +297 -0
  472. snappy/snap/t3mlite/surface.py +519 -0
  473. snappy/snap/t3mlite/test.py +20 -0
  474. snappy/snap/t3mlite/test_vs_regina.py +86 -0
  475. snappy/snap/t3mlite/tetrahedron.py +109 -0
  476. snappy/snap/t3mlite/vertex.py +42 -0
  477. snappy/snap/test.py +139 -0
  478. snappy/snap/utilities.py +288 -0
  479. snappy/test.py +213 -0
  480. snappy/test_cases.py +263 -0
  481. snappy/testing.py +131 -0
  482. snappy/tiling/__init__.py +2 -0
  483. snappy/tiling/dict_based_set.py +79 -0
  484. snappy/tiling/floor.py +49 -0
  485. snappy/tiling/hyperboloid_dict.py +54 -0
  486. snappy/tiling/iter_utils.py +78 -0
  487. snappy/tiling/lifted_tetrahedron.py +22 -0
  488. snappy/tiling/lifted_tetrahedron_set.py +54 -0
  489. snappy/tiling/quotient_dict.py +70 -0
  490. snappy/tiling/real_hash_dict.py +164 -0
  491. snappy/tiling/test.py +23 -0
  492. snappy/tiling/tile.py +224 -0
  493. snappy/tiling/triangle.py +33 -0
  494. snappy/tkterminal.py +920 -0
  495. snappy/twister/__init__.py +20 -0
  496. snappy/twister/main.py +646 -0
  497. snappy/twister/surfaces/S_0_1 +3 -0
  498. snappy/twister/surfaces/S_0_2 +3 -0
  499. snappy/twister/surfaces/S_0_4 +7 -0
  500. snappy/twister/surfaces/S_0_4_Lantern +8 -0
  501. snappy/twister/surfaces/S_1 +3 -0
  502. snappy/twister/surfaces/S_1_1 +4 -0
  503. snappy/twister/surfaces/S_1_2 +5 -0
  504. snappy/twister/surfaces/S_1_2_5 +6 -0
  505. snappy/twister/surfaces/S_2 +6 -0
  506. snappy/twister/surfaces/S_2_1 +8 -0
  507. snappy/twister/surfaces/S_2_heeg +10 -0
  508. snappy/twister/surfaces/S_3 +8 -0
  509. snappy/twister/surfaces/S_3_1 +10 -0
  510. snappy/twister/surfaces/S_4_1 +12 -0
  511. snappy/twister/surfaces/S_5_1 +14 -0
  512. snappy/twister/surfaces/heeg_fig8 +9 -0
  513. snappy/twister/twister_core.cpython-310-aarch64-linux-gnu.so +0 -0
  514. snappy/upper_halfspace/__init__.py +146 -0
  515. snappy/upper_halfspace/ideal_point.py +29 -0
  516. snappy/verify/__init__.py +13 -0
  517. snappy/verify/canonical.py +542 -0
  518. snappy/verify/complex_volume/__init__.py +18 -0
  519. snappy/verify/complex_volume/adjust_torsion.py +86 -0
  520. snappy/verify/complex_volume/closed.py +168 -0
  521. snappy/verify/complex_volume/compute_ptolemys.py +90 -0
  522. snappy/verify/complex_volume/cusped.py +56 -0
  523. snappy/verify/complex_volume/extended_bloch.py +201 -0
  524. snappy/verify/cusp_translations.py +85 -0
  525. snappy/verify/edge_equations.py +80 -0
  526. snappy/verify/exceptions.py +254 -0
  527. snappy/verify/hyperbolicity.py +224 -0
  528. snappy/verify/interval_newton_shapes_engine.py +523 -0
  529. snappy/verify/interval_tree.py +400 -0
  530. snappy/verify/krawczyk_shapes_engine.py +518 -0
  531. snappy/verify/real_algebra.py +286 -0
  532. snappy/verify/shapes.py +25 -0
  533. snappy/verify/square_extensions.py +1005 -0
  534. snappy/verify/test.py +72 -0
  535. snappy/verify/volume.py +128 -0
  536. snappy/version.py +2 -0
  537. snappy-3.3.dist-info/METADATA +58 -0
  538. snappy-3.3.dist-info/RECORD +541 -0
  539. snappy-3.3.dist-info/WHEEL +6 -0
  540. snappy-3.3.dist-info/entry_points.txt +2 -0
  541. snappy-3.3.dist-info/top_level.txt +28 -0
snappy/ptolemy/test.py ADDED
@@ -0,0 +1,1126 @@
1
+ # Tests the ptolemy module
2
+ ###
3
+ # Test in sage with precomputed results in testing_files_directory:
4
+ # sage -python test.py
5
+ ###
6
+ # Test in python with precomputed results:
7
+ # python test.py
8
+ ###
9
+ # Test in sage computing the results:
10
+ # sage -python test.py --compute
11
+ ###
12
+ # Test in python computing the results using magma:
13
+ # python test.py --compute
14
+
15
+ from snappy import Manifold, pari, ptolemy
16
+ from snappy import ptolemy
17
+ from snappy.ptolemy import solutions_from_magma, Flattenings, parse_solutions
18
+ from snappy.ptolemy.processFileBase import get_manifold
19
+ from snappy.ptolemy import __path__ as ptolemy_paths
20
+ from snappy.ptolemy.coordinates import PtolemyCannotBeCheckedError
21
+ from snappy.sage_helper import _within_sage
22
+ from snappy.testing import doctest_modules
23
+ from snappy.pari import pari
24
+ import bz2
25
+ import os
26
+ import sys
27
+ import doctest
28
+ import traceback
29
+
30
+ if _within_sage:
31
+ from sage.misc.sage_eval import sage_eval
32
+
33
+ test_regina = '--regina' in sys.argv
34
+ compute_solutions = '--compute' in sys.argv
35
+
36
+ base_path = ptolemy_paths[0]
37
+ if test_regina:
38
+ base_path = os.path.join(base_path, 'regina_')
39
+
40
+ testing_files_directory = os.path.join(base_path,'testing_files')
41
+ testing_files_generalized_directory = os.path.join(base_path,
42
+ 'testing_files_generalized')
43
+ testing_files_rur_directory = os.path.join(base_path, 'testing_files_rur')
44
+
45
+ if test_regina:
46
+ from regina import NTriangulation
47
+ from snappy.ptolemy.reginaWrapper import *
48
+
49
+ def ManifoldGetter(name):
50
+ return NTriangulationForPtolemy(
51
+ NTriangulation(Manifold(name)._to_string()))
52
+ else:
53
+ def ManifoldGetter(name):
54
+ return Manifold(name)
55
+
56
+ vol_tet = pari('1.014941606409653625021202554274520285941689307530299792017489106776597476258244022136470354228256695')
57
+
58
+
59
+ def check_volumes(complex_volumes, baseline_complex_volumes,
60
+ check_real_part_only=False,
61
+ torsion_imaginary_part=6, epsilon=1e-80):
62
+
63
+ # add complex volumes from complex conjugation to baseline
64
+
65
+ conjugates = [ -cvol.conj() for cvol in baseline_complex_volumes ]
66
+
67
+ baseline_complex_volumes = baseline_complex_volumes + conjugates
68
+
69
+ # real parts need to be equal
70
+ # imaginary parts need to be equal up to pi^2/torstion
71
+ p = pari('Pi * Pi') / torsion_imaginary_part
72
+
73
+ def is_close(cvol1, cvol2):
74
+ diff = cvol1 - cvol2
75
+
76
+ if diff.real().abs() > epsilon:
77
+ return False
78
+
79
+ if check_real_part_only:
80
+ return True
81
+
82
+ return ((( diff.imag()) % p) < epsilon or
83
+ ((-diff.imag()) % p) < epsilon)
84
+
85
+ # check that every base line volume appears in computed volumes
86
+ for cvol1 in baseline_complex_volumes:
87
+
88
+ if not any(is_close(cvol1, cvol2) for cvol2 in complex_volumes):
89
+ print("Missing base line volume:", cvol1)
90
+
91
+ print("Volumes:")
92
+ for i in complex_volumes:
93
+ print(" ", i)
94
+
95
+ raise Exception
96
+
97
+ # check that every computed volume is a base line volume
98
+ for cvol2 in complex_volumes:
99
+ if not any(is_close(cvol1, cvol2)
100
+ for cvol1 in baseline_complex_volumes):
101
+ print("Extra volume:", cvol2)
102
+
103
+ print("Volumes:")
104
+ for i in complex_volumes:
105
+ print(" ", i)
106
+
107
+ raise Exception
108
+
109
+
110
+ def testSolutionsForManifold(M, N, solutions, baseline_cvolumes=None,
111
+ expect_non_zero_dimensional=None,
112
+ against_geometric=True):
113
+
114
+ old_precision = pari.set_real_precision(100)
115
+
116
+ # check solutions exactly
117
+
118
+ found_non_zero_dimensional = False
119
+
120
+ numerical_solutions = [ ]
121
+ numerical_cross_ratios = [ ]
122
+
123
+ numerical_cross_ratios_alt = [ ]
124
+
125
+ for solution in solutions:
126
+
127
+ if isinstance(solution,
128
+ ptolemy.component.NonZeroDimensionalComponent):
129
+ # encountered non-zero dimensional component
130
+
131
+ found_non_zero_dimensional = True
132
+ else:
133
+
134
+ assert solution.N() == N
135
+ assert solution.num_tetrahedra() == M.num_tetrahedra()
136
+
137
+ # check exact solutions
138
+ solution.check_against_manifold(M)
139
+
140
+ # compute numerical solutions and cross ratios
141
+ for numerical_solution in solution.numerical():
142
+ numerical_solutions.append(numerical_solution)
143
+ numerical_cross_ratios.append(numerical_solution.cross_ratios())
144
+
145
+ # check exact cross ratios
146
+ cross_ratios = solution.cross_ratios()
147
+ if not test_regina:
148
+ cross_ratios.check_against_manifold(M)
149
+
150
+ assert cross_ratios.N() == N
151
+
152
+ # compute numerical cross ratios alternatively
153
+ # (above we converted exact Ptolemy's to numerical and then
154
+ # converted to cross ratio, here we first compute cross ratios
155
+ # exactly and then convert to numerical)
156
+ numerical_cross_ratios_alt += cross_ratios.numerical()
157
+
158
+ # check we encountered non-zero dimensional component if that's
159
+ # expected
160
+ if expect_non_zero_dimensional is not None:
161
+ assert expect_non_zero_dimensional == found_non_zero_dimensional
162
+
163
+ # check the numerical solutions against the manifold
164
+ for s in numerical_solutions:
165
+ s.check_against_manifold(M, epsilon=1e-80)
166
+
167
+ # check that they make a flattening
168
+ if not test_regina:
169
+ s.flattenings_numerical().check_against_manifold(M, epsilon=1e-80)
170
+
171
+ if not test_regina:
172
+ for s in numerical_cross_ratios:
173
+ s.check_against_manifold(M, epsilon=1e-80)
174
+
175
+ for s in numerical_cross_ratios_alt:
176
+ s.check_against_manifold(M, epsilon=1e-80)
177
+
178
+ # compute complex volumes and volumes
179
+ complex_volumes = [s.complex_volume_numerical() for s in numerical_solutions]
180
+ volumes = [s.volume_numerical() for s in numerical_cross_ratios]
181
+
182
+ # there should be equally many
183
+ assert len(complex_volumes) == len(volumes)
184
+
185
+ # and real part of cvol should be equal to vol
186
+ for vol, cvol in zip(volumes, complex_volumes):
187
+ diff = vol - cvol.real()
188
+ assert diff.abs() < 1e-80
189
+
190
+ # volumes from cross ratios computed the different way
191
+ volumes_alt = [s.volume_numerical() for s in numerical_cross_ratios_alt]
192
+
193
+ # volumes should be equal
194
+ assert len(volumes) == len(volumes_alt)
195
+ volumes.sort(key=float)
196
+ volumes_alt.sort(key=float)
197
+ for vol1, vol2 in zip(volumes, volumes_alt):
198
+ assert (vol1 - vol2).abs() < 1e-80
199
+
200
+ if against_geometric and not test_regina:
201
+ if M.solution_type() == 'all tetrahedra positively oriented':
202
+ geom_vol = M.volume() * (N-1) * N * (N+1) / 6
203
+ assert True in [
204
+ abs(geom_vol - vol) < 1e-11 for vol in volumes]
205
+
206
+ # check that complex volumes match baseline volumes
207
+ if baseline_cvolumes is not None:
208
+ check_volumes(complex_volumes, baseline_cvolumes)
209
+
210
+ pari.set_real_precision(old_precision)
211
+
212
+
213
+ def testComputeSolutionsForManifold(manifold, N,
214
+ compute_solutions=False,
215
+ baseline_cvolumes=None,
216
+ expect_non_zero_dimensional=None,
217
+ print_info=True):
218
+
219
+ varieties = manifold.ptolemy_variety(N, obstruction_class="all_original")
220
+
221
+ if compute_solutions:
222
+ def compute(variety):
223
+ return variety.compute_solutions()
224
+
225
+ else:
226
+ def compute(variety):
227
+ return compute_using_precomputed_magma(variety)
228
+
229
+ solutions = sum([compute(variety) for variety in varieties], [])
230
+
231
+ testSolutionsForManifold(manifold, N, solutions,
232
+ baseline_cvolumes, expect_non_zero_dimensional)
233
+
234
+ if manifold.name() == 't00000':
235
+ testMatrixMethods(manifold, solutions, print_info=print_info)
236
+
237
+
238
+ def testMatrixMethods(manifold, solutions, print_info=True):
239
+
240
+ def matrix_is_diagonal(m):
241
+ return (
242
+ m[0][0] - m[1][1] == 0 and
243
+ m[0][1] == 0 and
244
+ m[1][0] == 0)
245
+
246
+ def matrix_is_pm_identity(m):
247
+ return matrix_is_diagonal(m) and (
248
+ m[0][0] + 1 == 0 or m[0][0] - 1 == 0)
249
+
250
+ if print_info:
251
+ print("Testing matrix methods...")
252
+
253
+ G = manifold.fundamental_group(simplify_presentation=True)
254
+ Graw = manifold.fundamental_group(simplify_presentation=False)
255
+
256
+ for solution in solutions:
257
+ if solution.dimension == 0:
258
+
259
+ solution._testing_check_cocycles()
260
+
261
+ cross_ratios = solution.cross_ratios()
262
+
263
+ for gen in G.generators():
264
+ assert not matrix_is_diagonal(
265
+ solution.evaluate_word(gen, G))
266
+ assert not matrix_is_diagonal(
267
+ cross_ratios.evaluate_word(gen, G))
268
+
269
+ for gen in Graw.generators():
270
+ assert not matrix_is_diagonal(
271
+ solution.evaluate_word(gen, Graw))
272
+ assert not matrix_is_diagonal(
273
+ cross_ratios.evaluate_word(gen, Graw))
274
+ assert not matrix_is_diagonal(
275
+ solution.evaluate_word(gen))
276
+ assert not matrix_is_diagonal(
277
+ cross_ratios.evaluate_word(gen))
278
+
279
+ for rel in G.relators():
280
+ assert matrix_is_pm_identity(
281
+ solution.evaluate_word(rel, G))
282
+ assert matrix_is_diagonal(
283
+ solution.evaluate_word(rel, G))
284
+
285
+ for rel in Graw.relators():
286
+ assert matrix_is_pm_identity(
287
+ solution.evaluate_word(rel, Graw))
288
+ assert matrix_is_diagonal(
289
+ solution.evaluate_word(rel, Graw))
290
+ assert matrix_is_pm_identity(
291
+ solution.evaluate_word(rel))
292
+ assert matrix_is_diagonal(
293
+ solution.evaluate_word(rel))
294
+
295
+
296
+ def test_flattenings_from_tetrahedra_shapes_of_manifold():
297
+
298
+ old_precision = pari.set_real_precision(100)
299
+
300
+ # real parts need to be equal
301
+ # imaginary parts need to be equal up to pi^2/6
302
+ p = pari('Pi * Pi / 6')
303
+
304
+ def is_close(cvol1, cvol2, epsilon):
305
+ diff = cvol1 - cvol2
306
+ return diff.real().abs() < epsilon and (
307
+ ( diff.imag() % p) < epsilon or
308
+ (-diff.imag() % p) < epsilon)
309
+
310
+ from snappy import OrientableCuspedCensus
311
+
312
+ for M_database in (list(OrientableCuspedCensus()[0:10]) +
313
+ list(OrientableCuspedCensus()[10000:10010])):
314
+
315
+ # The manifold returned by OrientableCuspedCensus is
316
+ # a SnapPy.Manifold, not a snappy.Manifold (as is overridden
317
+ # in python/test.py).
318
+ M = Manifold(M_database)
319
+
320
+ flattening = Flattenings.from_tetrahedra_shapes_of_manifold(M)
321
+ flattening.check_against_manifold(M, epsilon=1e-80)
322
+
323
+ if not is_close(flattening.complex_volume(),
324
+ M.complex_volume(), # returns only double precision
325
+ epsilon=1e-13):
326
+ raise Exception("Wrong volume")
327
+
328
+ # test high precision
329
+
330
+ M = ManifoldGetter("5_2")
331
+ flattening = Flattenings.from_tetrahedra_shapes_of_manifold(M)
332
+ flattening.check_against_manifold(M, epsilon=1e-80)
333
+
334
+ if not is_close(flattening.complex_volume(),
335
+ pari('2.828122088330783162763898809276634942770981317300649477043520327258802548322471630936947017929999108 - 3.024128376509301659719951221694600993984450242270735312503300643508917708286193746506469158300472966*I'),
336
+ epsilon=1e-80):
337
+ raise Exception("Wrong volume")
338
+
339
+ pari.set_real_precision(old_precision)
340
+
341
+
342
+ def checkSolutionsForManifoldGeneralizedObstructionClass(
343
+ solutions_trivial, solutions_non_trivial,
344
+ manifold, N, baseline_volumes, baseline_dimensions):
345
+
346
+ torsionTrivial = pari('Pi^2/6 * I')
347
+ torsionNonTrivial = pari('Pi^2/18 * I')
348
+
349
+ solutions = (
350
+ [ (s, False) for s in solutions_trivial ] +
351
+ [ (s, True) for s in solutions_non_trivial ])
352
+
353
+ # Dimensions and volumes encountered
354
+ dimensions = set()
355
+ volumes = []
356
+ volumes_2 = []
357
+
358
+ for solution, sol_is_non_trivial in solutions:
359
+ # Add the dimension
360
+ dimensions.add(solution.dimension)
361
+ if solution.dimension == 0:
362
+
363
+ if sol_is_non_trivial:
364
+ got_exception = False
365
+ try:
366
+ solution.check_against_manifold(manifold)
367
+ except PtolemyCannotBeCheckedError:
368
+ got_exception = True
369
+
370
+ assert got_exception, (
371
+ "check_against_manifold should not have passed")
372
+ else:
373
+ solution.check_against_manifold(manifold)
374
+
375
+ fl = solution.flattenings_numerical()
376
+ for f in fl:
377
+ if not test_regina:
378
+ # Not supported yet in regina
379
+ f.check_against_manifold(epsilon=1e-80)
380
+
381
+ cvol, modulo = f.complex_volume(with_modulo=True)
382
+
383
+ if sol_is_non_trivial and N == 3:
384
+ assert (modulo - torsionNonTrivial).abs() < 1e-80, (
385
+ "Wrong modulo returned non-trivial case")
386
+ else:
387
+ assert (modulo - torsionTrivial).abs() < 1e-80, (
388
+ "Wrong modulo returned trivial case")
389
+
390
+ volumes_2.append(cvol.real())
391
+
392
+ # Add the volumes
393
+ volumes += solution.volume_numerical()
394
+
395
+ # Check that the resulting cross ratios full fill
396
+ # the gluing equations
397
+ cross_ratios = solution.cross_ratios()
398
+ if not test_regina:
399
+ cross_ratios.check_against_manifold(manifold)
400
+
401
+ def is_close(a, b):
402
+ return (a - b).abs() < 1e-80
403
+
404
+ def make_unique(L):
405
+ L.sort()
406
+ result = L[:1]
407
+
408
+ for i in L:
409
+ if not is_close(result[-1], i):
410
+ result.append(i)
411
+ return result
412
+
413
+ volumes = make_unique(volumes)
414
+ volumes_2 = make_unique(volumes_2)
415
+ all_expected_volumes = make_unique(baseline_volumes +
416
+ [-vol for vol in baseline_volumes])
417
+
418
+ assert len(all_expected_volumes) >= 2 * len(baseline_volumes) - 1
419
+
420
+ for volume, expected_volume in zip(volumes, all_expected_volumes):
421
+ assert is_close(volume, expected_volume)
422
+
423
+ for volume, expected_volume in zip(volumes_2,all_expected_volumes):
424
+ assert is_close(volume, expected_volume)
425
+
426
+ assert dimensions == set(baseline_dimensions)
427
+
428
+
429
+ def testComputeSolutionsForManifoldGeneralizedObstructionClass(
430
+ manifold, N, compute_solutions, baseline_volumes, baseline_dimensions):
431
+
432
+ varieties = manifold.ptolemy_variety(N,
433
+ obstruction_class="all_generalized"
434
+ # , simplify = False
435
+ # , eliminate_fixed_ptolemys = True
436
+ )
437
+
438
+ assert len(varieties) == 2
439
+
440
+ if compute_solutions:
441
+ def compute(variety):
442
+ return variety.compute_solutions()
443
+
444
+ else:
445
+ def compute(variety):
446
+ return compute_using_precomputed_magma(
447
+ variety, dir=testing_files_generalized_directory)
448
+
449
+ # Solutions for the trivial obstruction class
450
+ solutions_trivial = compute(varieties[0])
451
+
452
+ # Solutions for the non-trivial obstruction class
453
+ solutions_non_trivial = sum([compute(variety)
454
+ for variety in varieties[1:]],
455
+ [])
456
+
457
+ checkSolutionsForManifoldGeneralizedObstructionClass(
458
+ solutions_trivial, solutions_non_trivial,
459
+ manifold, N, baseline_volumes, baseline_dimensions)
460
+
461
+
462
+ def testGeneralizedObstructionClass(compute_solutions, print_info = True):
463
+
464
+ vols = [
465
+ pari('0'),
466
+ 2 * vol_tet
467
+ ]
468
+ test__m003__2 = (ManifoldGetter("m003"), # Manifold
469
+ 2, # N = 2
470
+ vols, # expected volumes
471
+ [0]) # expected dimensions
472
+
473
+ vols = [
474
+ 2 * vol_tet
475
+ ]
476
+ test__m004__2 = (ManifoldGetter("m004"), # Manifold
477
+ 2, # N = 2
478
+ vols, # expected volumes
479
+ [0]) # expected dimensions
480
+
481
+ vols = [
482
+ pari('0'),
483
+ pari('2.595387593686742138301993834077989475956329764530314161212797242812715071384508096863829303251915501'),
484
+ 2 * 4 * vol_tet,
485
+ ]
486
+ test__m003__3 = (ManifoldGetter("m003"), # Manifold
487
+ 3, # N = 3
488
+ vols, # expected volumes
489
+ [0,1]) # expected dimensions
490
+
491
+ test_cases = [ test__m003__2,
492
+ test__m004__2]
493
+
494
+ if (not _within_sage) or (not compute_solutions):
495
+ test_cases += [test__m003__3]
496
+
497
+ for manifold, N, vols, dims in test_cases:
498
+
499
+ if print_info:
500
+ print("Checking for", manifold.name(), "N = %d" % N)
501
+
502
+ testComputeSolutionsForManifoldGeneralizedObstructionClass(
503
+ manifold, N, compute_solutions, vols, dims)
504
+
505
+
506
+ def testMapleLikeRur():
507
+
508
+ M = ManifoldGetter("m052")
509
+ p = M.ptolemy_variety(3, 0)
510
+
511
+ sols = parse_solutions(
512
+ bz2.BZ2File(os.path.join(testing_files_rur_directory,
513
+ p.filename_base() + '.rur.bz2'),
514
+ 'r').read().decode('ascii'))
515
+ assert len(sols) == 4
516
+ assert [sol.dimension for sol in sols] == [0, 0, 0, 1]
517
+
518
+ sols.check_against_manifold()
519
+ cross_ratios = sols.cross_ratios()
520
+ cross_ratios.check_against_manifold()
521
+
522
+ assert sols.number_field()[0:3] == [
523
+ pari('3*x^5 - 3*x^4 + 7*x^3 - 11*x^2 + 6*x - 1'),
524
+ pari('x^5 - 3*x^4 + x^3 + x^2 + 2*x - 1'),
525
+ pari('29987478321*x^50 + 79088110854*x^49 + 146016538609*x^48 + 168029123283*x^47 + 195292402206*x^46 + 249251168329*x^45 + 342446347782*x^44 + 342999865332*x^43 + 169423424001*x^42 - 273623428749*x^41 - 913797131672*x^40 - 1673817412888*x^39 - 2346916788229*x^38 - 2864053668977*x^37 - 3089416575581*x^36 - 3067233025932*x^35 - 2754270808082*x^34 - 2290714735763*x^33 - 1691408820544*x^32 - 1128722560267*x^31 - 616892765351*x^30 - 264545491200*x^29 - 28918206196*x^28 + 65364520067*x^27 + 95427288700*x^26 + 68490651548*x^25 + 40427041992*x^24 + 8765319150*x^23 - 5368633716*x^22 - 14060382008*x^21 - 12638294169*x^20 - 10728252922*x^19 - 6615567685*x^18 - 4275928015*x^17 - 2168416333*x^16 - 1279131210*x^15 - 627103252*x^14 - 403508975*x^13 - 222568645*x^12 - 147840406*x^11 - 81185759*x^10 - 46353128*x^9 - 21481295*x^8 - 9738710*x^7 - 3418080*x^6 - 1145883*x^5 - 254870*x^4 - 44273*x^3 - 565*x^2 + 2925*x + 487')]
526
+
527
+ sols[0].multiply_terms_in_RUR().check_against_manifold()
528
+ sols[0].multiply_and_simplify_terms_in_RUR().check_against_manifold()
529
+ sol_pur = sols[0].to_PUR()
530
+ sol_pur.check_against_manifold()
531
+
532
+ cross_ratios[0].multiply_terms_in_RUR().check_against_manifold()
533
+ cross_ratios[0].multiply_and_simplify_terms_in_RUR().check_against_manifold()
534
+ cross_ratio_pur = cross_ratios[0].to_PUR()
535
+
536
+ old_precision = pari.set_real_precision(60)
537
+
538
+ sols.numerical().check_against_manifold(epsilon=1e-50)
539
+ sols.numerical().cross_ratios().check_against_manifold(epsilon=1e-50)
540
+ cross_ratios.numerical().check_against_manifold(epsilon=1e-50)
541
+ sol_pur.numerical().check_against_manifold(epsilon=1e-50)
542
+ cross_ratio_pur.numerical().check_against_manifold(epsilon=1e-50)
543
+
544
+ expected_cvols = [
545
+ pari('-0.78247122081308825152609555186377860994691907952043*I'),
546
+ pari('-0.72702516069067618470921136741414357709195254197557*I'),
547
+ pari('-0.68391161907531103571619313072177855528960855942240*I'),
548
+ pari('-0.56931748709124386099667356226108260894423337722116*I'),
549
+ pari('-0.51896820855866930434990357344936169357239176536016*I'),
550
+ pari('-0.51572066892431201326839038002795162651553325964817*I'),
551
+ pari('-0.43203716183360487568405407399314603426109522825732*I'),
552
+ pari('-0.36010613661069069469455670342059458401551240819467*I'),
553
+ pari('-0.30859303742385031407330927444373574273739067157054*I'),
554
+ pari('-0.026277944917886842767978680898127354858352285383691*I'),
555
+ pari('0.0248303748672046904847696634069363554930433748091423*I'),
556
+ pari('0.099321499468818761939078653627745421972173499236569*I'),
557
+ pari('0.10014328074298669302370298811922885078531513167037*I'),
558
+ pari('0.26650486587884614841887735378855648561147071193673*I'),
559
+ pari('0.28149146457238928303062789829916587391163953396165*I'),
560
+ pari('0.31647148942727816629296211895022802382665885673450*I'),
561
+ pari('0.43039483620012844786769013182478937263427654168349*I'),
562
+ pari('0.69353686619303521491910998831602468798059163569136*I'),
563
+ pari('0.54467996179900207437301145027949601489757288486931 - 0.63094967104322016076042058145264363658770535751782*I'),
564
+ pari('2.01433658377684250427882647709079550884158567943161 - 0.49992935281631459421725377501106345869263727223108*I'),
565
+ pari('2.5032821968844998826603550693091792509880846739036 - 0.26075155111137757913541371074811175755130345738250*I'),
566
+ pari('2.9278315480495821855974883510454022661942898386197 + 0.19505171376983273645226251276721729342140990274561*I'),
567
+ pari('3.3588310807753976907039310005151876035685073404636 - 0.59541514146929793136574297969820009572263815053647*I'),
568
+ pari('3.5588560966663108341691237279801529977950803397723 - 0.65837426652607617086885854703688633418948363301344*I'),
569
+ pari('4.3805052030906555151826572095707468309691641904106 - 0.53144574794454652850763996164828079301339638663719*I'),
570
+ pari('5.2749826604398957699736902920967737019972675833349 + 0.72096167973012423863761073630614422902154219296456*I'),
571
+ pari('5.5615522795375430947143486065492921841179004148132 - 0.28072986489486989042244876551205538542949560983728*I'),
572
+ pari('8.0573463351073700171153059083631820353663427177264 - 0.35478334441703194039659993339822864555159918771765*I'),
573
+ pari('13.232966218921677854715244009824382732164844146922 + 0.13989736389653471530824083989755826875684215156147*I')
574
+ ]
575
+
576
+ expected_cvols = expected_cvols + [ -a.conj() for a in expected_cvols ]
577
+
578
+ cvols = sols.complex_volume_numerical().flatten(2) # Include witnesses
579
+
580
+ check_volumes(cvols, expected_cvols, epsilon=1e-40)
581
+
582
+ vols = sols.volume_numerical().flatten(2) # Include witnesses
583
+
584
+ check_volumes(vols, expected_cvols, check_real_part_only=True, epsilon=1e-40)
585
+
586
+ pari.set_real_precision(old_precision)
587
+
588
+
589
+ def testNumericalSolutions():
590
+
591
+ M = ManifoldGetter("m003")
592
+ N = 3
593
+
594
+ varieties = M.ptolemy_variety(N, obstruction_class='all')
595
+
596
+ solutions = [
597
+ solutions_from_magma(
598
+ get_precomputed_magma(variety,
599
+ dir=testing_files_generalized_directory),
600
+ numerical=True)
601
+ for variety in varieties ]
602
+
603
+ for obstruction_index, obstruction in enumerate(solutions):
604
+ for component in obstruction:
605
+ for solution in component:
606
+ flattenings = solution.flattenings_numerical()
607
+ if not test_regina:
608
+ flattenings.check_against_manifold(epsilon=1e-80)
609
+ order = flattenings.get_order()
610
+
611
+ if obstruction_index:
612
+ assert order == 6
613
+ else:
614
+ assert order == 2
615
+
616
+ cross_ratios = solution.cross_ratios()
617
+ is_cr = cross_ratios.is_pu_2_1_representation(epsilon=1e-80,
618
+ epsilon2=1e-10)
619
+
620
+ if cross_ratios.volume_numerical().abs() < 1e-10:
621
+ # Every volume 0 representation of m003 happens to be
622
+ # cr
623
+ assert is_cr
624
+ else:
625
+ assert not is_cr
626
+
627
+ number_one_dimensional = 0
628
+
629
+ allComponents = sum(solutions, [])
630
+
631
+ dimension_dict = {}
632
+ degree_dict = {}
633
+
634
+ for component in allComponents:
635
+
636
+ dim = component.dimension
637
+ deg = len(component)
638
+
639
+ dimension_dict[dim] = 1 + dimension_dict.get(dim, 0)
640
+ degree_dict[deg] = 1 + degree_dict.get(deg, 0)
641
+
642
+ assert (dim == 0) ^ (deg == 0)
643
+
644
+ assert dimension_dict == {0: 4, 1: 2}
645
+ assert degree_dict == {0 :2, 2: 2, 8: 2}
646
+
647
+ allSolutions = sum(allComponents, [])
648
+
649
+ allCVolumes = [s.complex_volume_numerical() for s in allSolutions]
650
+
651
+ expected_cvolume = pari('2.595387593686742138301993834077989475956329764530314161212797242812715071384508096863829303251915501 + 0.1020524924166561605528051801006522147774827678324290664524996742369032819581086580383974219370194645*I')
652
+
653
+ expected_cvolumes = [
654
+ pari(0),
655
+ expected_cvolume,
656
+ expected_cvolume.conj(),
657
+ 2 * 4 * vol_tet
658
+ ]
659
+
660
+ check_volumes(allCVolumes, expected_cvolumes)
661
+
662
+
663
+ def testGeometricRep(compute_solutions, print_info=False):
664
+
665
+ from snappy.ptolemy import geometricRep
666
+
667
+ M = Manifold("m019")
668
+ if compute_solutions:
669
+ sol = geometricRep.compute_geometric_solution(M)
670
+ else:
671
+ from pathlib import Path
672
+ url = Path(os.path.abspath(testing_files_directory)).as_uri()
673
+ sol = geometricRep.retrieve_geometric_solution(
674
+ M, data_url=url, verbose = print_info)
675
+
676
+ # Make sure this is of type Ptolemy
677
+ sol['c_0011_2']
678
+
679
+ assert any(
680
+ abs(vol - 2.9441064867) < 1e-9 for vol in sol.volume_numerical())
681
+
682
+
683
+ def testSageCommandLine():
684
+
685
+ sage_eval('Manifold("m004").ptolemy_variety(3,0).compute_solutions().check_against_manifold()',
686
+ { 'Manifold' : ManifoldGetter })
687
+
688
+
689
+ def get_precomputed_magma(variety, dir):
690
+ magma_file_name = os.path.join(dir,
691
+ variety.filename_base() + '.magma_out.bz2')
692
+ return bz2.BZ2File(magma_file_name,'r').read().decode('ascii')
693
+
694
+
695
+ def compute_using_precomputed_magma(variety, dir=testing_files_directory):
696
+ return solutions_from_magma(get_precomputed_magma(variety, dir))
697
+
698
+
699
+ def test_induced_representation():
700
+
701
+ M = ManifoldGetter("m015")
702
+ variety__sl2_c1 = M.ptolemy_variety(2, obstruction_class=1)
703
+ variety__sl3_c0 = M.ptolemy_variety(3, obstruction_class=0)
704
+
705
+ solutions__sl2_c1 = compute_using_precomputed_magma(
706
+ variety__sl2_c1, dir=testing_files_generalized_directory)
707
+ solutions__sl3_c0 = compute_using_precomputed_magma(
708
+ variety__sl3_c0, dir=testing_files_generalized_directory)
709
+
710
+ # Check that is_real
711
+
712
+ got_exception = False
713
+ try:
714
+ solutions__sl3_c0[0].cross_ratios().is_real(epsilon=1e-80)
715
+ except:
716
+ got_exception = True
717
+ assert got_exception, (
718
+ "Expected error when calling is_real on exact solution")
719
+
720
+ # For each component of sl3 c0, determine the number
721
+ # of solutions which are real vs number of all solutions
722
+
723
+ numbers_all_and_real = []
724
+ for component in solutions__sl3_c0:
725
+ number_real = 0
726
+ number_all = 0
727
+ for z in component.cross_ratios_numerical():
728
+ if z.is_real(epsilon=1e-80):
729
+ number_real += 1
730
+ number_all += 1
731
+ numbers_all_and_real.append((number_all, number_real))
732
+
733
+ # Bring into canonical form
734
+ numbers_all_and_real.sort()
735
+
736
+ expected_numbers = [
737
+ (3, 1), # component has 3 solutions, 1 of them has real cross ratios
738
+ (4, 2),
739
+ (6, 0) ]
740
+
741
+ assert numbers_all_and_real == expected_numbers, (
742
+ "Order of components and number of real solutions is off")
743
+
744
+ # Check is_induced_from_psl2
745
+
746
+ number_psl2 = 0
747
+
748
+ for component in solutions__sl3_c0:
749
+ if component.cross_ratios().is_induced_from_psl2():
750
+ number_psl2 += 1
751
+
752
+ assert number_psl2 == 1, "Only one component can come from psl2"
753
+
754
+ number_psl2 = 0
755
+
756
+ for component in solutions__sl3_c0:
757
+ is_induced_from_psl2 = [z.is_induced_from_psl2(epsilon=1e-80)
758
+ for z in component.cross_ratios_numerical()]
759
+ if any(is_induced_from_psl2):
760
+ number_psl2 += 1
761
+ assert all(is_induced_from_psl2), "Mixed up is_induced_from_psl2"
762
+
763
+ assert number_psl2 == 1, (
764
+ "Only one component can come from psl2 (numerically)")
765
+
766
+ # Check that induced_representation for sl3 throws error
767
+ got_exception = False
768
+ try:
769
+ solutions__sl3_c0[0].cross_ratios().induced_representation(3)
770
+ except:
771
+ got_exception = True
772
+ assert got_exception, (
773
+ "Expected error when calling induced_representation on sl3")
774
+
775
+ # Check that induced_representation(3) works for m015
776
+
777
+ m015_volume = pari("2.828122088330783162763898809276634942770981317300649477043520327258802548322471630936947017929999108")
778
+
779
+ z = solutions__sl2_c1[0].cross_ratios().induced_representation(3)
780
+ assert z.is_induced_from_psl2(), (
781
+ "induced_representation failed to be detected as being induced")
782
+
783
+ assert z.check_against_manifold, (
784
+ "induced_representation fails to be valid")
785
+
786
+ for v in z.volume_numerical():
787
+ assert v.abs() < 1e-80 or (v.abs() - 4 * m015_volume).abs() < 1e-80, (
788
+ "Did not get expected voluem for induced representation")
789
+
790
+ for z in solutions__sl2_c1[0].cross_ratios_numerical():
791
+ v = z.induced_representation(3).volume_numerical()
792
+ assert v.abs() < 1e-80 or (v.abs() - 4 * m015_volume).abs() < 1e-80, (
793
+ "Did not get expected voluem for induced representation")
794
+
795
+
796
+ def test_induced_sl4_representation():
797
+ M = Manifold("m004")
798
+
799
+ z_gl2 = ptolemy.CrossRatios.from_snappy_manifold(M)
800
+ z_gl4 = z_gl2.induced_representation(4)
801
+
802
+ G = M.fundamental_group()
803
+
804
+ mat = z_gl4.evaluate_word(G.relators()[0], G)
805
+
806
+ for i, row in enumerate(mat):
807
+ for j, entry in enumerate(row):
808
+ if i == j:
809
+ assert abs(entry - 1) < 1e-9
810
+ else:
811
+ assert abs(entry) < 1e-9
812
+
813
+
814
+ def test_num_obstruction_class_match():
815
+ from snappy import OrientableCuspedCensus
816
+
817
+ for M in (list(OrientableCuspedCensus()[0:5]) +
818
+ list(OrientableCuspedCensus()[10000:10005])):
819
+ N = NTriangulationForPtolemy(M._to_string())
820
+
821
+ assert len(M.ptolemy_obstruction_classes()) == len(N.ptolemy_obstruction_classes())
822
+
823
+ for i in range(2,6):
824
+ assert len(M.ptolemy_generalized_obstruction_classes(i)) == len(N.ptolemy_generalized_obstruction_classes(i))
825
+
826
+ def run_ptolemy_tests_raising_exceptions(print_info=True):
827
+ if print_info:
828
+ print("Testing in sage:", _within_sage)
829
+
830
+ print("Testing in regina:", test_regina)
831
+
832
+ if test_regina:
833
+ if print_info:
834
+ print("Testing that regina agrees with snappy obstruction classes")
835
+ test_num_obstruction_class_match()
836
+
837
+ if not test_regina:
838
+ if print_info:
839
+ print("Testing Flattenings.from_tetrahedra_shapes_of_manifold...")
840
+
841
+ test_flattenings_from_tetrahedra_shapes_of_manifold()
842
+
843
+ if test_regina and not compute_solutions:
844
+ print("regina testing requires --compute")
845
+ sys.exit(1)
846
+
847
+ old_precision = pari.set_real_precision(100)
848
+
849
+ if print_info:
850
+ print("Testing induced representation...")
851
+
852
+ test_induced_representation()
853
+
854
+ if print_info:
855
+ print("Testing induced SL(4,C) representation...")
856
+
857
+ test_induced_sl4_representation()
858
+
859
+ if print_info:
860
+ print("Running manifold tests for generalized obstruction class...")
861
+
862
+ testGeneralizedObstructionClass(compute_solutions, print_info=print_info)
863
+
864
+ if not test_regina:
865
+ if print_info:
866
+ print("Testing RUR for m052__sl3_c0.rur")
867
+
868
+ testMapleLikeRur()
869
+
870
+ if print_info:
871
+ print("Testing numerical solution retrieval method...")
872
+
873
+ testNumericalSolutions()
874
+
875
+ if print_info:
876
+ print("Testing geometricRep...")
877
+ testGeometricRep(compute_solutions, print_info=print_info)
878
+
879
+ if _within_sage:
880
+ if print_info:
881
+ print("Testing in sage command line...")
882
+ testSageCommandLine()
883
+
884
+ if print_info:
885
+ print("Running manifold tests...")
886
+
887
+ # Test for a non-hyperbolic manifold
888
+
889
+ cvols = [ # Expected Complex volumes
890
+ pari('0') ]
891
+ test__3_1__2 = (ManifoldGetter("3_1"), # Manifold
892
+ 2, # N = 2
893
+ cvols, # expected complex volumes
894
+ False) # No non-zero dimensional components
895
+
896
+ # Test for 4_1, amphichiral, expect zero CS
897
+
898
+ cvols = [ # Expected Complex volumes
899
+ 2 * vol_tet
900
+ ]
901
+ test__4_1__2 = (ManifoldGetter("4_1"), # Manifold
902
+ 2, # N = 2
903
+ cvols, # expected complex volumes
904
+ False) # expect non-zero dimensional components
905
+
906
+ # N = 3
907
+
908
+ cvols = [ # Expected Complex volumes
909
+ pari(0),
910
+ 2 * 4 * vol_tet
911
+ ]
912
+ test__4_1__3 = (ManifoldGetter("4_1"), # Manifold
913
+ 3, # N = 3
914
+ cvols, # expected complex volumes
915
+ False) # expect non-zero dimensional components
916
+
917
+ # N = 4
918
+
919
+ cvols = [ # Expected Complex volumes
920
+ 2 * 10 * vol_tet,
921
+ pari('8.355502146379565994303773768814775354386025704336131822255670190659042090899812770381061831431114740 - 0.7836375483069721973241186952472609466029570462055317453592429525294418326815666413123016980810744089*I'),
922
+ pari('7.327724753417752120436828119459072886193194994253377074131984956974104158210038155834852103408920850'),
923
+ pari('4.260549384199988638895626360783795200167603461491438308495654794999595513880915593832371886868625127 + 0.1361281655780504266700965891301086052404492485996004213292764928775628027210816440355745847599247091*I'),
924
+ pari('3.276320849776062968038680855240250653840691843746753028019901828179320044237305241434903501877259688 + 0.03882948511714102091208888807575164800651790439786747350853616215556190252003379560451275222880494392*I'),
925
+ pari('3.230859569867059515989136707781810556962637199799080875515780771251800351524537196576706995730457048')
926
+ ]
927
+
928
+ # amphicheiral, so complex volumes should appear in pairs
929
+
930
+ cvols = cvols + [cvol.conj() for cvol in cvols]
931
+
932
+ test__4_1__4 = (ManifoldGetter("4_1"), # Manifold
933
+ 4, # N = 2
934
+ cvols, # expected complex volumes
935
+ True) # expect non-zero dimensional components
936
+
937
+ # Test for 5_2, expect non-trivial CS
938
+ # Number field has one real embedding with non-trival CS
939
+ # And one pair of complex embeddings with non-trivial CS
940
+
941
+ cvols = [ # Expected Complex volumes
942
+ pari('+ 1.113454552473924010022656943451126420312050780921075311799926598907813005362784871512051614741669817*I'),
943
+ pari('2.828122088330783162763898809276634942770981317300649477043520327258802548322471630936947017929999108 - 3.024128376509301659719951221694600993984450242270735312503300643508917708286193746506469158300472966*I')
944
+ ]
945
+ test__5_2__2 = (ManifoldGetter("5_2"), # Manifold
946
+ 2, # N = 2
947
+ cvols, # expected complex volumes
948
+ False) # expect no non-zero dimensional components
949
+
950
+ # m015 which is isometric to 5_2
951
+ # This example is also appearing on the website
952
+
953
+ cvols = [ # Expected Complex volumes
954
+ pari('+ 0.4033353624187061319128390413376061001062613536896471642214173008084760853375773296525240139108027276*I'),
955
+ pari('- 0.4809839906489832693266177261335698864086465799360940660069682924787703897584631354526802428925968492*I'),
956
+ pari('+ 0.6579736267392905745889660666584100756875799604827193750942232917480029881612803495334515602479034826*I'),
957
+ pari('- 0.6579736267392905745889660666584100756875799604827193750942232917480029881612803495334515602479034826*I'),
958
+ pari('6.332666642499251344664115407516762513592210378740462564820401485540596854320653136703448734707430999 + 0.6207993522147601522797880626542095445563442737585756367570704642807656925328117720905524433544779886*I'),
959
+ pari('11.31248835332313265105559523710653977108392526920259790817408130903521019328988652374778807171999643 - 0.5819750380996215835728987202562276514051516606353521858642949684456185403223688691904743288635809278*I')
960
+ ]
961
+
962
+ test__m015__3 = (ManifoldGetter("m015"), # Manifold
963
+ 3, # N = 3
964
+ cvols, # expected volumes
965
+ False) # expect no non-zero dimensional components
966
+
967
+ # Test for m135
968
+ # Ptolemy Variety has one non-zero dimensional component
969
+
970
+ cvols = [ # Expected Complex volumes
971
+ pari('3.66386237670887606021841405972953644309659749712668853706599247848705207910501907791742605170446042499429769047678479831614359521330343623772637894992 + 4.93480220054467930941724549993807556765684970362039531320667468811002241120960262150088670185927611591201295688701157203888617406101502336380530883900*I')
972
+ ]
973
+
974
+ test__m135__2 = (ManifoldGetter("m135"), # Manifold
975
+ 2, # N = 2
976
+ cvols, # expected volumes
977
+ True) # expect a non-zero dimensional component
978
+
979
+ # Test for s000
980
+ # Number field has one real embedding with non-trival CS
981
+ # And two complex embeddings with non-trivial CS
982
+
983
+ cvols = [ # Expected Complex volumes
984
+ pari('3.296902414326637335562593088559162089146991699269941951875989849869324250860299302482577730785960256 + 0.4908671850777469648812718224097607532197026477625119178645010117072332396428578681905186509136879130*I'),
985
+ pari('2.270424126345803402614201085375714538056567876339790536089272218685353247084791707534069624462050547 - 0.4107712000441024931074403997367404299427214514732528671142771778838924102954454212055598588991237349*I'),
986
+ pari('0.8061270618942289713279174295562193428686541442399728535727328789432842090598108984711933183445551654 - 0.08009598503364447177383142267302032327698119628925905075022383382334082934741244698495879201456417902*I')
987
+ ]
988
+
989
+ test__s000__2 = (ManifoldGetter("s000"), # Manifold
990
+ 2, # N = 2
991
+ cvols, # expected complex volumes
992
+ False) # expect non-zero dimensional components
993
+
994
+ # Test for v0000
995
+ # This also tests the case of having more than one (here two)
996
+ # cusps
997
+
998
+ cvols = [ # Expected Complex volumes
999
+ pari('3.377597408231442496961257171798882829176020069714519460350380851901055794392493960110119513942153791 + 0.3441889979504813554136570264352067044809511501367282461849580661783699588789118851518262199077361427*I'),
1000
+ pari('1.380586178282342062845519278761524817753278777803238623999221385504661588501960339341800843520223671 + 0.06704451876157525370444676522629959282378632516497136324893149116413190872188833330658100524720353406*I')
1001
+ ]
1002
+
1003
+ test__v0000__2 = (ManifoldGetter("v0000"), # Manifold
1004
+ 2, # N = 2
1005
+ cvols, # expected complex volumes
1006
+ False) # expect non-zero dimensional components
1007
+
1008
+ # Test for t00000
1009
+ # This also tests the case of having more than one (here two)
1010
+ # cusps
1011
+
1012
+ cvols = [ # Expected Complex volumes
1013
+ pari('1.801231981344929412976326011175173926741195258454700704383597306674496002389749200442131507334117933 - 0.5490336239273931479260463113980794374780078424892352183284248305887346671477869107359071072271699046*I'),
1014
+ pari('3.434540885902563701250335473165274495380101665474171663779718033441916041515556280543077990039279103 - 0.2258335622748003900958464044389939976977579115267501160859900439335840118881246299028850924706341411*I'),
1015
+ pari('2.781430316400743786576311128801205534982324055570742403430395886754122643539081915302290955978507418 - 0.1135489194824466736456241002458946823709871812077727407261274931826622024508518397031626436088171650*I'),
1016
+ pari('0.6223401945262803853426860070209275705147832620602921139947907237662088851273537136119288228151713940 + 0.06594907226052699343130923275995552293727798462035885627276325301997714628516294342514039299674185799*I')
1017
+ ]
1018
+
1019
+ test__t00000__2 = (ManifoldGetter("t00000"), # Manifold
1020
+ 2, # N = 2
1021
+ cvols, # expected complex volumes
1022
+ False) # expect non-zero dimensional components
1023
+
1024
+ # Check a big link
1025
+ # Also an example from the website
1026
+
1027
+ magma_file_name = os.path.join(testing_files_directory,
1028
+ 'DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2')
1029
+ magma_file = bz2.BZ2File(magma_file_name, 'r').read().decode('ascii')
1030
+ M = get_manifold(magma_file)
1031
+
1032
+ cvols = [ # Expected complex volumes
1033
+ pari('+ 0.7322614121694386973039290771667413108310290182470824825342304051284154933661673470336385959164416421*I'),
1034
+ pari('+ 0.6559698855197901194421542799077526971594537987318704612418448259078988296037785866985260815280619566*I'),
1035
+ pari('+ 0.2247361398283578756297647616373802721002644994163825408181485469244129408530290519698535075998585820*I'),
1036
+ pari('- 0.2027422644881176424634704044404281277501368039784045126270573672316679046996639567741375438621581585*I'),
1037
+ pari('- 0.5165804080147074827389022895582362309867052040022748905555220755792330887283843134684241943604049933*I'),
1038
+ pari('- 0.6947370811282851128538476965898593866158843479399924653138487625940910866865914821776342801425993440*I'),
1039
+ pari('0.5540930202692745891960825388466975825977590423995169588735760161940190344506116205300980253997539517 + 0.4068295289298811130481298436200768517194764143946539028521976313233755795250413907401491036923026977*I'),
1040
+ pari('1.107573735539315638081527574351339252286206152514359620788778723352858972530297840033883810630372795 - 0.5969698437345460065934215233692845699554045087887375026603956452869723823599605032061849791769108861*I'),
1041
+ pari('2.930037687027569312623189945781681052278144410906236798293622026086427321638842320557907595726492995 + 0.3289208659101980133472847400704889056725461985759517831954390384444124055329869355087545294359968288*I'),
1042
+ pari('3.125178220789358723184584053682215536632004045535766511323850625359539915401419555941250425818672532 - 0.3045460696329709194663539414577718771554887499547088593863438059068830455709928110292357447645590516*I'),
1043
+ pari('4.421889017241566419690868074785716366646707154662264036268588279252613543336245268108457201245088608 + 0.6139898590804745843458673335891956572719167936270349811550161917334120397060146434004694625036091183*I'),
1044
+ pari('5.114841460302400721438106628468470523914735245629326811523719108779649554034504844499930511307337652 - 0.05922105399342951023220969900445652084832276940306885833938997476066822991673855494231393721309130829*I'),
1045
+ pari('6.222431566185758097679258799420253341029081314309961806975091338751806200485840320374430035873760649 - 0.4263260019368806638768168211894976779995931712761356294379973306148491137274105197747275282097587014*I'),
1046
+ pari('9.266495487232495996324305783134684559241087943387258046228284813849170601366096263130956023317432143 + 0.03172800820055749085258729263585301130211316529809616828980203075096987437740390637996179595789268661*I'),
1047
+ pari('11.33736073062520808632824769184286601589152410942391317127856679767752551409389094871647937428783709 - 0.5767482750608833159526763068340021498631801513808564565980389960163842898485087439099502988183940450*I'),
1048
+ pari('12.48005937399413830153052941177305767103579608241815594942757035041902652992672347868089986739774396 + 0.4828891402943609873677952178777231024869262986704386628808130740557195704279966401921665132533128189*I')
1049
+ ]
1050
+
1051
+ test__morwen_link__2 = (M , # Manifold
1052
+ 2, # N = 2
1053
+ cvols, # expected complex volumes
1054
+ False) # expect no non-zero dimensional components
1055
+
1056
+ test_cases = [ test__3_1__2,
1057
+ test__4_1__2,
1058
+ test__5_2__2,
1059
+ test__m135__2,
1060
+ test__s000__2,
1061
+ test__v0000__2,
1062
+ test__t00000__2,
1063
+ test__morwen_link__2,
1064
+ test__4_1__3,
1065
+ test__m015__3,
1066
+ test__4_1__4]
1067
+
1068
+ pari.set_real_precision(old_precision)
1069
+
1070
+ for manifold, N, cvols, expect_non_zero_dim in test_cases:
1071
+
1072
+ if print_info:
1073
+ print("Checking for", manifold.name(), "N = %d" % N)
1074
+
1075
+ testComputeSolutionsForManifold(
1076
+ manifold, N,
1077
+ compute_solutions=compute_solutions,
1078
+ baseline_cvolumes=cvols,
1079
+ expect_non_zero_dimensional=expect_non_zero_dim,
1080
+ print_info=print_info)
1081
+
1082
+ def run_ptolemy_tests(verbose=False, print_info=True):
1083
+ try:
1084
+ run_ptolemy_tests_raising_exceptions(
1085
+ print_info=print_info)
1086
+ return doctest.TestResults(failed=0, attempted=1)
1087
+ except Exception as e:
1088
+ print()
1089
+ print("FAILED TEST in Ptolemy. Exception is:")
1090
+ traceback.print_exc()
1091
+ print()
1092
+ return doctest.TestResults(failed=1, attempted=1)
1093
+
1094
+ run_ptolemy_tests.__name__ = ptolemy.__name__ + ' (non-doc tests)'
1095
+
1096
+ modules = [ptolemy.component,
1097
+ ptolemy.coordinates,
1098
+ ptolemy.manifoldMethods,
1099
+ ptolemy.matrix,
1100
+ ptolemy.polynomial,
1101
+ ptolemy.processFileBase,
1102
+ ptolemy.processMagmaFile,
1103
+ ptolemy.processRurFile,
1104
+ ptolemy.ptolemyObstructionClass,
1105
+ ptolemy.ptolemyVariety,
1106
+ ptolemy.rur,
1107
+ ptolemy.utilities]
1108
+ if test_regina:
1109
+ modules.append(ptolemy.reginaWrapper)
1110
+
1111
+ def run_doctests(verbose=False, print_info=True):
1112
+ return doctest_modules(
1113
+ modules,
1114
+ verbose=verbose, print_info=print_info)
1115
+
1116
+ run_doctests.__name__ = ptolemy.__name__
1117
+
1118
+ if __name__ == '__main__':
1119
+ verbose = '-v' in sys.argv[1:] or '--verbose' in sys.argv[1:]
1120
+
1121
+ result = run_doctests(verbose=verbose, print_info=True)
1122
+ if result.failed:
1123
+ sys.exit(result.failed)
1124
+
1125
+ result = run_ptolemy_tests(verbose=verbose, print_info=True)
1126
+ sys.exit(result.failed)