snappy 3.3__cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. snappy/CyOpenGL.cpython-310-aarch64-linux-gnu.so +0 -0
  2. snappy/SnapPy.cpython-310-aarch64-linux-gnu.so +0 -0
  3. snappy/SnapPy.ico +0 -0
  4. snappy/SnapPy.png +0 -0
  5. snappy/SnapPyHP.cpython-310-aarch64-linux-gnu.so +0 -0
  6. snappy/__init__.py +534 -0
  7. snappy/app.py +604 -0
  8. snappy/app_menus.py +372 -0
  9. snappy/browser.py +998 -0
  10. snappy/cache.py +25 -0
  11. snappy/canonical.py +249 -0
  12. snappy/cusps/__init__.py +280 -0
  13. snappy/cusps/cusp_area_matrix.py +98 -0
  14. snappy/cusps/cusp_areas_from_matrix.py +96 -0
  15. snappy/cusps/maximal_cusp_area_matrix.py +136 -0
  16. snappy/cusps/short_slopes_for_cusp.py +217 -0
  17. snappy/cusps/test.py +22 -0
  18. snappy/cusps/trig_cusp_area_matrix.py +63 -0
  19. snappy/database.py +454 -0
  20. snappy/db_utilities.py +79 -0
  21. snappy/decorated_isosig.py +717 -0
  22. snappy/dev/__init__.py +0 -0
  23. snappy/dev/extended_ptolemy/__init__.py +8 -0
  24. snappy/dev/extended_ptolemy/closed.py +106 -0
  25. snappy/dev/extended_ptolemy/complexVolumesClosed.py +149 -0
  26. snappy/dev/extended_ptolemy/direct.py +42 -0
  27. snappy/dev/extended_ptolemy/extended.py +406 -0
  28. snappy/dev/extended_ptolemy/giac_helper.py +43 -0
  29. snappy/dev/extended_ptolemy/giac_rur.py +129 -0
  30. snappy/dev/extended_ptolemy/gluing.py +46 -0
  31. snappy/dev/extended_ptolemy/phc_wrapper.py +220 -0
  32. snappy/dev/extended_ptolemy/printMatrices.py +70 -0
  33. snappy/dev/vericlosed/__init__.py +1 -0
  34. snappy/dev/vericlosed/computeApproxHyperbolicStructureNew.py +159 -0
  35. snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +90 -0
  36. snappy/dev/vericlosed/computeVerifiedHyperbolicStructure.py +111 -0
  37. snappy/dev/vericlosed/gimbalLoopFinder.py +130 -0
  38. snappy/dev/vericlosed/hyperbolicStructure.py +313 -0
  39. snappy/dev/vericlosed/krawczykCertifiedEdgeLengthsEngine.py +165 -0
  40. snappy/dev/vericlosed/oneVertexTruncatedComplex.py +122 -0
  41. snappy/dev/vericlosed/orb/__init__.py +1 -0
  42. snappy/dev/vericlosed/orb/orb_solution_for_snappea_finite_triangulation_mac +0 -0
  43. snappy/dev/vericlosed/parseVertexGramMatrixFile.py +47 -0
  44. snappy/dev/vericlosed/polishApproxHyperbolicStructure.py +61 -0
  45. snappy/dev/vericlosed/test.py +54 -0
  46. snappy/dev/vericlosed/truncatedComplex.py +176 -0
  47. snappy/dev/vericlosed/verificationError.py +58 -0
  48. snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +177 -0
  49. snappy/doc/_images/SnapPy-196.png +0 -0
  50. snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
  51. snappy/doc/_images/m125_paper_plane.jpg +0 -0
  52. snappy/doc/_images/mac.png +0 -0
  53. snappy/doc/_images/o9_00000_systole_paper_plane.jpg +0 -0
  54. snappy/doc/_images/o9_00000_systole_paper_plane_closer.jpg +0 -0
  55. snappy/doc/_images/plink-action.png +0 -0
  56. snappy/doc/_images/ubuntu.png +0 -0
  57. snappy/doc/_images/win7.png +0 -0
  58. snappy/doc/_sources/additional_classes.rst.txt +40 -0
  59. snappy/doc/_sources/bugs.rst.txt +14 -0
  60. snappy/doc/_sources/censuses.rst.txt +52 -0
  61. snappy/doc/_sources/credits.rst.txt +81 -0
  62. snappy/doc/_sources/development.rst.txt +261 -0
  63. snappy/doc/_sources/index.rst.txt +215 -0
  64. snappy/doc/_sources/installing.rst.txt +249 -0
  65. snappy/doc/_sources/manifold.rst.txt +6 -0
  66. snappy/doc/_sources/manifoldhp.rst.txt +46 -0
  67. snappy/doc/_sources/news.rst.txt +425 -0
  68. snappy/doc/_sources/other.rst.txt +25 -0
  69. snappy/doc/_sources/platonic_census.rst.txt +20 -0
  70. snappy/doc/_sources/plink.rst.txt +102 -0
  71. snappy/doc/_sources/ptolemy.rst.txt +66 -0
  72. snappy/doc/_sources/ptolemy_classes.rst.txt +42 -0
  73. snappy/doc/_sources/ptolemy_examples1.rst.txt +298 -0
  74. snappy/doc/_sources/ptolemy_examples2.rst.txt +363 -0
  75. snappy/doc/_sources/ptolemy_examples3.rst.txt +301 -0
  76. snappy/doc/_sources/ptolemy_examples4.rst.txt +61 -0
  77. snappy/doc/_sources/ptolemy_prelim.rst.txt +105 -0
  78. snappy/doc/_sources/screenshots.rst.txt +21 -0
  79. snappy/doc/_sources/snap.rst.txt +87 -0
  80. snappy/doc/_sources/snappy.rst.txt +28 -0
  81. snappy/doc/_sources/spherogram.rst.txt +103 -0
  82. snappy/doc/_sources/todo.rst.txt +47 -0
  83. snappy/doc/_sources/triangulation.rst.txt +11 -0
  84. snappy/doc/_sources/tutorial.rst.txt +49 -0
  85. snappy/doc/_sources/verify.rst.txt +210 -0
  86. snappy/doc/_sources/verify_internals.rst.txt +79 -0
  87. snappy/doc/_static/SnapPy-horizontal-128.png +0 -0
  88. snappy/doc/_static/SnapPy.ico +0 -0
  89. snappy/doc/_static/_sphinx_javascript_frameworks_compat.js +123 -0
  90. snappy/doc/_static/basic.css +906 -0
  91. snappy/doc/_static/css/badge_only.css +1 -0
  92. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  93. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  94. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  95. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  96. snappy/doc/_static/css/fonts/fontawesome-webfont.eot +0 -0
  97. snappy/doc/_static/css/fonts/fontawesome-webfont.svg +2671 -0
  98. snappy/doc/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  99. snappy/doc/_static/css/fonts/fontawesome-webfont.woff +0 -0
  100. snappy/doc/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  101. snappy/doc/_static/css/fonts/lato-bold-italic.woff +0 -0
  102. snappy/doc/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  103. snappy/doc/_static/css/fonts/lato-bold.woff +0 -0
  104. snappy/doc/_static/css/fonts/lato-bold.woff2 +0 -0
  105. snappy/doc/_static/css/fonts/lato-normal-italic.woff +0 -0
  106. snappy/doc/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  107. snappy/doc/_static/css/fonts/lato-normal.woff +0 -0
  108. snappy/doc/_static/css/fonts/lato-normal.woff2 +0 -0
  109. snappy/doc/_static/css/theme.css +4 -0
  110. snappy/doc/_static/doctools.js +149 -0
  111. snappy/doc/_static/documentation_options.js +13 -0
  112. snappy/doc/_static/file.png +0 -0
  113. snappy/doc/_static/fonts/Lato/lato-bold.eot +0 -0
  114. snappy/doc/_static/fonts/Lato/lato-bold.ttf +0 -0
  115. snappy/doc/_static/fonts/Lato/lato-bold.woff +0 -0
  116. snappy/doc/_static/fonts/Lato/lato-bold.woff2 +0 -0
  117. snappy/doc/_static/fonts/Lato/lato-bolditalic.eot +0 -0
  118. snappy/doc/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
  119. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff +0 -0
  120. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
  121. snappy/doc/_static/fonts/Lato/lato-italic.eot +0 -0
  122. snappy/doc/_static/fonts/Lato/lato-italic.ttf +0 -0
  123. snappy/doc/_static/fonts/Lato/lato-italic.woff +0 -0
  124. snappy/doc/_static/fonts/Lato/lato-italic.woff2 +0 -0
  125. snappy/doc/_static/fonts/Lato/lato-regular.eot +0 -0
  126. snappy/doc/_static/fonts/Lato/lato-regular.ttf +0 -0
  127. snappy/doc/_static/fonts/Lato/lato-regular.woff +0 -0
  128. snappy/doc/_static/fonts/Lato/lato-regular.woff2 +0 -0
  129. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
  130. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
  131. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
  132. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
  133. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
  134. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
  135. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
  136. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
  137. snappy/doc/_static/jquery.js +2 -0
  138. snappy/doc/_static/js/badge_only.js +1 -0
  139. snappy/doc/_static/js/theme.js +1 -0
  140. snappy/doc/_static/js/versions.js +228 -0
  141. snappy/doc/_static/language_data.js +192 -0
  142. snappy/doc/_static/minus.png +0 -0
  143. snappy/doc/_static/plus.png +0 -0
  144. snappy/doc/_static/pygments.css +75 -0
  145. snappy/doc/_static/searchtools.js +635 -0
  146. snappy/doc/_static/snappy_furo.css +33 -0
  147. snappy/doc/_static/snappy_sphinx_rtd_theme.css +42 -0
  148. snappy/doc/_static/sphinx_highlight.js +154 -0
  149. snappy/doc/additional_classes.html +1500 -0
  150. snappy/doc/bugs.html +132 -0
  151. snappy/doc/censuses.html +453 -0
  152. snappy/doc/credits.html +184 -0
  153. snappy/doc/development.html +385 -0
  154. snappy/doc/doc-latest/additional_classes.html +1500 -0
  155. snappy/doc/doc-latest/bugs.html +132 -0
  156. snappy/doc/doc-latest/censuses.html +453 -0
  157. snappy/doc/doc-latest/credits.html +184 -0
  158. snappy/doc/doc-latest/development.html +385 -0
  159. snappy/doc/doc-latest/genindex.html +1349 -0
  160. snappy/doc/doc-latest/index.html +287 -0
  161. snappy/doc/doc-latest/installing.html +346 -0
  162. snappy/doc/doc-latest/manifold.html +3632 -0
  163. snappy/doc/doc-latest/manifoldhp.html +180 -0
  164. snappy/doc/doc-latest/news.html +438 -0
  165. snappy/doc/doc-latest/objects.inv +0 -0
  166. snappy/doc/doc-latest/other.html +160 -0
  167. snappy/doc/doc-latest/platonic_census.html +376 -0
  168. snappy/doc/doc-latest/plink.html +210 -0
  169. snappy/doc/doc-latest/ptolemy.html +253 -0
  170. snappy/doc/doc-latest/ptolemy_classes.html +1144 -0
  171. snappy/doc/doc-latest/ptolemy_examples1.html +409 -0
  172. snappy/doc/doc-latest/ptolemy_examples2.html +471 -0
  173. snappy/doc/doc-latest/ptolemy_examples3.html +414 -0
  174. snappy/doc/doc-latest/ptolemy_examples4.html +195 -0
  175. snappy/doc/doc-latest/ptolemy_prelim.html +248 -0
  176. snappy/doc/doc-latest/py-modindex.html +165 -0
  177. snappy/doc/doc-latest/screenshots.html +141 -0
  178. snappy/doc/doc-latest/search.html +135 -0
  179. snappy/doc/doc-latest/searchindex.js +1 -0
  180. snappy/doc/doc-latest/snap.html +202 -0
  181. snappy/doc/doc-latest/snappy.html +181 -0
  182. snappy/doc/doc-latest/spherogram.html +1346 -0
  183. snappy/doc/doc-latest/todo.html +166 -0
  184. snappy/doc/doc-latest/triangulation.html +1676 -0
  185. snappy/doc/doc-latest/tutorial.html +159 -0
  186. snappy/doc/doc-latest/verify.html +330 -0
  187. snappy/doc/doc-latest/verify_internals.html +1235 -0
  188. snappy/doc/genindex.html +1349 -0
  189. snappy/doc/index.html +287 -0
  190. snappy/doc/installing.html +346 -0
  191. snappy/doc/manifold.html +3632 -0
  192. snappy/doc/manifoldhp.html +180 -0
  193. snappy/doc/news.html +438 -0
  194. snappy/doc/objects.inv +0 -0
  195. snappy/doc/other.html +160 -0
  196. snappy/doc/platonic_census.html +376 -0
  197. snappy/doc/plink.html +210 -0
  198. snappy/doc/ptolemy.html +253 -0
  199. snappy/doc/ptolemy_classes.html +1144 -0
  200. snappy/doc/ptolemy_examples1.html +409 -0
  201. snappy/doc/ptolemy_examples2.html +471 -0
  202. snappy/doc/ptolemy_examples3.html +414 -0
  203. snappy/doc/ptolemy_examples4.html +195 -0
  204. snappy/doc/ptolemy_prelim.html +248 -0
  205. snappy/doc/py-modindex.html +165 -0
  206. snappy/doc/screenshots.html +141 -0
  207. snappy/doc/search.html +135 -0
  208. snappy/doc/searchindex.js +1 -0
  209. snappy/doc/snap.html +202 -0
  210. snappy/doc/snappy.html +181 -0
  211. snappy/doc/spherogram.html +1346 -0
  212. snappy/doc/todo.html +166 -0
  213. snappy/doc/triangulation.html +1676 -0
  214. snappy/doc/tutorial.html +159 -0
  215. snappy/doc/verify.html +330 -0
  216. snappy/doc/verify_internals.html +1235 -0
  217. snappy/drilling/__init__.py +456 -0
  218. snappy/drilling/barycentric.py +103 -0
  219. snappy/drilling/constants.py +5 -0
  220. snappy/drilling/crush.py +270 -0
  221. snappy/drilling/cusps.py +125 -0
  222. snappy/drilling/debug.py +242 -0
  223. snappy/drilling/epsilons.py +6 -0
  224. snappy/drilling/exceptions.py +55 -0
  225. snappy/drilling/moves.py +620 -0
  226. snappy/drilling/peripheral_curves.py +210 -0
  227. snappy/drilling/perturb.py +188 -0
  228. snappy/drilling/shorten.py +36 -0
  229. snappy/drilling/subdivide.py +274 -0
  230. snappy/drilling/test.py +23 -0
  231. snappy/drilling/test_cases.py +132 -0
  232. snappy/drilling/tracing.py +351 -0
  233. snappy/exceptions.py +26 -0
  234. snappy/export_stl.py +120 -0
  235. snappy/exterior_to_link/__init__.py +2 -0
  236. snappy/exterior_to_link/barycentric_geometry.py +463 -0
  237. snappy/exterior_to_link/exceptions.py +6 -0
  238. snappy/exterior_to_link/geodesic_map.json +14408 -0
  239. snappy/exterior_to_link/hyp_utils.py +112 -0
  240. snappy/exterior_to_link/link_projection.py +323 -0
  241. snappy/exterior_to_link/main.py +198 -0
  242. snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
  243. snappy/exterior_to_link/mcomplex_with_link.py +687 -0
  244. snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
  245. snappy/exterior_to_link/pl_utils.py +491 -0
  246. snappy/exterior_to_link/put_in_S3.py +156 -0
  247. snappy/exterior_to_link/rational_linear_algebra.py +130 -0
  248. snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
  249. snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
  250. snappy/exterior_to_link/stored_moves.py +475 -0
  251. snappy/exterior_to_link/test.py +31 -0
  252. snappy/filedialog.py +28 -0
  253. snappy/geometric_structure/__init__.py +212 -0
  254. snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
  255. snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +691 -0
  256. snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +480 -0
  257. snappy/geometric_structure/cusp_neighborhood/exceptions.py +41 -0
  258. snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +294 -0
  259. snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +156 -0
  260. snappy/geometric_structure/cusp_neighborhood/vertices.py +35 -0
  261. snappy/geometric_structure/geodesic/__init__.py +0 -0
  262. snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
  263. snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
  264. snappy/geometric_structure/geodesic/canonical_representatives.py +52 -0
  265. snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
  266. snappy/geometric_structure/geodesic/constants.py +6 -0
  267. snappy/geometric_structure/geodesic/exceptions.py +22 -0
  268. snappy/geometric_structure/geodesic/fixed_points.py +106 -0
  269. snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
  270. snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
  271. snappy/geometric_structure/geodesic/line.py +30 -0
  272. snappy/geometric_structure/geodesic/multiplicity.py +127 -0
  273. snappy/geometric_structure/geodesic/tiles_for_geodesic.py +128 -0
  274. snappy/geometric_structure/test.py +22 -0
  275. snappy/gui.py +121 -0
  276. snappy/horoviewer.py +443 -0
  277. snappy/hyperboloid/__init__.py +212 -0
  278. snappy/hyperboloid/distances.py +259 -0
  279. snappy/hyperboloid/horoball.py +19 -0
  280. snappy/hyperboloid/line.py +35 -0
  281. snappy/hyperboloid/point.py +9 -0
  282. snappy/hyperboloid/triangle.py +29 -0
  283. snappy/info_icon.gif +0 -0
  284. snappy/infowindow.py +65 -0
  285. snappy/isometry_signature.py +389 -0
  286. snappy/len_spec/__init__.py +609 -0
  287. snappy/len_spec/geodesic_info.py +129 -0
  288. snappy/len_spec/geodesic_key_info_dict.py +116 -0
  289. snappy/len_spec/geodesic_piece.py +146 -0
  290. snappy/len_spec/geometric_structure.py +182 -0
  291. snappy/len_spec/geometry.py +136 -0
  292. snappy/len_spec/length_spectrum_geodesic_info.py +185 -0
  293. snappy/len_spec/spine.py +128 -0
  294. snappy/len_spec/test.py +24 -0
  295. snappy/len_spec/test_cases.py +69 -0
  296. snappy/len_spec/tile.py +276 -0
  297. snappy/len_spec/word.py +86 -0
  298. snappy/manifolds/HTWKnots/alternating.gz +0 -0
  299. snappy/manifolds/HTWKnots/nonalternating.gz +0 -0
  300. snappy/manifolds/__init__.py +3 -0
  301. snappy/margulis/__init__.py +332 -0
  302. snappy/margulis/cusp_neighborhood_neighborhood.py +66 -0
  303. snappy/margulis/geodesic_neighborhood.py +152 -0
  304. snappy/margulis/margulis_info.py +21 -0
  305. snappy/margulis/mu_from_neighborhood_pair.py +175 -0
  306. snappy/margulis/neighborhood.py +29 -0
  307. snappy/margulis/test.py +22 -0
  308. snappy/math_basics.py +187 -0
  309. snappy/matrix.py +525 -0
  310. snappy/number.py +657 -0
  311. snappy/numeric_output_checker.py +345 -0
  312. snappy/pari.py +41 -0
  313. snappy/phone_home.py +57 -0
  314. snappy/polyviewer.py +259 -0
  315. snappy/ptolemy/__init__.py +17 -0
  316. snappy/ptolemy/component.py +103 -0
  317. snappy/ptolemy/coordinates.py +2290 -0
  318. snappy/ptolemy/fieldExtensions.py +153 -0
  319. snappy/ptolemy/findLoops.py +473 -0
  320. snappy/ptolemy/geometricRep.py +59 -0
  321. snappy/ptolemy/homology.py +165 -0
  322. snappy/ptolemy/magma/default.magma_template +229 -0
  323. snappy/ptolemy/magma/radicalsOfPrimaryDecomposition.magma_template +79 -0
  324. snappy/ptolemy/manifoldMethods.py +395 -0
  325. snappy/ptolemy/matrix.py +350 -0
  326. snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +113 -0
  327. snappy/ptolemy/polynomial.py +856 -0
  328. snappy/ptolemy/processComponents.py +173 -0
  329. snappy/ptolemy/processFileBase.py +247 -0
  330. snappy/ptolemy/processFileDispatch.py +46 -0
  331. snappy/ptolemy/processMagmaFile.py +392 -0
  332. snappy/ptolemy/processRurFile.py +150 -0
  333. snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +102 -0
  334. snappy/ptolemy/ptolemyObstructionClass.py +64 -0
  335. snappy/ptolemy/ptolemyVariety.py +995 -0
  336. snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +140 -0
  337. snappy/ptolemy/reginaWrapper.py +698 -0
  338. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  339. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  340. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  341. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  342. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  343. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  344. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  345. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  346. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  347. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  348. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c0.magma_out.bz2 +0 -0
  349. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  350. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  351. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c1.magma_out.bz2 +0 -0
  352. snappy/ptolemy/rur.py +545 -0
  353. snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +277 -0
  354. snappy/ptolemy/test.py +1126 -0
  355. snappy/ptolemy/testing_files/3_1__sl2_c0.magma_out.bz2 +0 -0
  356. snappy/ptolemy/testing_files/3_1__sl2_c1.magma_out.bz2 +0 -0
  357. snappy/ptolemy/testing_files/4_1__sl2_c0.magma_out.bz2 +0 -0
  358. snappy/ptolemy/testing_files/4_1__sl2_c1.magma_out.bz2 +0 -0
  359. snappy/ptolemy/testing_files/4_1__sl3_c0.magma_out.bz2 +0 -0
  360. snappy/ptolemy/testing_files/4_1__sl4_c0.magma_out.bz2 +0 -0
  361. snappy/ptolemy/testing_files/4_1__sl4_c1.magma_out.bz2 +0 -0
  362. snappy/ptolemy/testing_files/5_2__sl2_c0.magma_out.bz2 +0 -0
  363. snappy/ptolemy/testing_files/5_2__sl2_c1.magma_out.bz2 +0 -0
  364. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  365. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  366. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  367. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  368. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  369. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  370. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  371. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  372. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c0.magma_out +95 -0
  373. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c1.magma_out +95 -0
  374. snappy/ptolemy/testing_files/m015__sl3_c0.magma_out.bz2 +0 -0
  375. snappy/ptolemy/testing_files/m135__sl2_c0.magma_out.bz2 +0 -0
  376. snappy/ptolemy/testing_files/m135__sl2_c1.magma_out.bz2 +0 -0
  377. snappy/ptolemy/testing_files/m135__sl2_c2.magma_out.bz2 +0 -0
  378. snappy/ptolemy/testing_files/m135__sl2_c3.magma_out.bz2 +0 -0
  379. snappy/ptolemy/testing_files/m135__sl2_c4.magma_out.bz2 +0 -0
  380. snappy/ptolemy/testing_files/m135__sl2_c5.magma_out.bz2 +0 -0
  381. snappy/ptolemy/testing_files/m135__sl2_c6.magma_out.bz2 +0 -0
  382. snappy/ptolemy/testing_files/m135__sl2_c7.magma_out.bz2 +0 -0
  383. snappy/ptolemy/testing_files/s000__sl2_c0.magma_out.bz2 +0 -0
  384. snappy/ptolemy/testing_files/s000__sl2_c1.magma_out.bz2 +0 -0
  385. snappy/ptolemy/testing_files/t00000__sl2_c0.magma_out.bz2 +0 -0
  386. snappy/ptolemy/testing_files/t00000__sl2_c1.magma_out.bz2 +0 -0
  387. snappy/ptolemy/testing_files/v0000__sl2_c0.magma_out.bz2 +0 -0
  388. snappy/ptolemy/testing_files/v0000__sl2_c1.magma_out.bz2 +0 -0
  389. snappy/ptolemy/testing_files/v0000__sl2_c2.magma_out.bz2 +0 -0
  390. snappy/ptolemy/testing_files/v0000__sl2_c3.magma_out.bz2 +0 -0
  391. snappy/ptolemy/testing_files_generalized/m003__sl2_c0.magma_out.bz2 +0 -0
  392. snappy/ptolemy/testing_files_generalized/m003__sl2_c1.magma_out.bz2 +0 -0
  393. snappy/ptolemy/testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  394. snappy/ptolemy/testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  395. snappy/ptolemy/testing_files_generalized/m004__sl2_c0.magma_out.bz2 +0 -0
  396. snappy/ptolemy/testing_files_generalized/m004__sl2_c1.magma_out.bz2 +0 -0
  397. snappy/ptolemy/testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  398. snappy/ptolemy/testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  399. snappy/ptolemy/testing_files_rur/m052__sl3_c0.rur.bz2 +0 -0
  400. snappy/ptolemy/utilities.py +236 -0
  401. snappy/raytracing/__init__.py +64 -0
  402. snappy/raytracing/additional_horospheres.py +64 -0
  403. snappy/raytracing/additional_len_spec_choices.py +63 -0
  404. snappy/raytracing/cohomology_fractal.py +197 -0
  405. snappy/raytracing/eyeball.py +124 -0
  406. snappy/raytracing/finite_raytracing_data.py +237 -0
  407. snappy/raytracing/finite_viewer.py +590 -0
  408. snappy/raytracing/geodesic_tube_info.py +174 -0
  409. snappy/raytracing/geodesics.py +246 -0
  410. snappy/raytracing/geodesics_window.py +258 -0
  411. snappy/raytracing/gui_utilities.py +293 -0
  412. snappy/raytracing/hyperboloid_navigation.py +556 -0
  413. snappy/raytracing/hyperboloid_utilities.py +234 -0
  414. snappy/raytracing/ideal_raytracing_data.py +592 -0
  415. snappy/raytracing/inside_viewer.py +974 -0
  416. snappy/raytracing/pack.py +22 -0
  417. snappy/raytracing/raytracing_data.py +126 -0
  418. snappy/raytracing/raytracing_view.py +454 -0
  419. snappy/raytracing/shaders/Eye.png +0 -0
  420. snappy/raytracing/shaders/NonGeometric.png +0 -0
  421. snappy/raytracing/shaders/__init__.py +101 -0
  422. snappy/raytracing/shaders/fragment.glsl +1744 -0
  423. snappy/raytracing/test.py +29 -0
  424. snappy/raytracing/tooltip.py +146 -0
  425. snappy/raytracing/upper_halfspace_utilities.py +98 -0
  426. snappy/raytracing/view_scale_controller.py +98 -0
  427. snappy/raytracing/zoom_slider/__init__.py +263 -0
  428. snappy/raytracing/zoom_slider/inward.png +0 -0
  429. snappy/raytracing/zoom_slider/inward18.png +0 -0
  430. snappy/raytracing/zoom_slider/outward.png +0 -0
  431. snappy/raytracing/zoom_slider/outward18.png +0 -0
  432. snappy/raytracing/zoom_slider/test.py +20 -0
  433. snappy/sage_helper.py +119 -0
  434. snappy/settings.py +407 -0
  435. snappy/shell.py +53 -0
  436. snappy/snap/__init__.py +117 -0
  437. snappy/snap/character_varieties.py +375 -0
  438. snappy/snap/find_field.py +372 -0
  439. snappy/snap/fox_milnor.py +271 -0
  440. snappy/snap/fundamental_polyhedron.py +569 -0
  441. snappy/snap/generators.py +39 -0
  442. snappy/snap/interval_reps.py +81 -0
  443. snappy/snap/kernel_structures.py +128 -0
  444. snappy/snap/mcomplex_base.py +18 -0
  445. snappy/snap/nsagetools.py +716 -0
  446. snappy/snap/peripheral/__init__.py +1 -0
  447. snappy/snap/peripheral/dual_cellulation.py +219 -0
  448. snappy/snap/peripheral/link.py +127 -0
  449. snappy/snap/peripheral/peripheral.py +159 -0
  450. snappy/snap/peripheral/surface.py +522 -0
  451. snappy/snap/peripheral/test.py +35 -0
  452. snappy/snap/polished_reps.py +335 -0
  453. snappy/snap/shapes.py +152 -0
  454. snappy/snap/slice_obs_HKL/__init__.py +194 -0
  455. snappy/snap/slice_obs_HKL/basics.py +236 -0
  456. snappy/snap/slice_obs_HKL/direct.py +217 -0
  457. snappy/snap/slice_obs_HKL/poly_norm.py +212 -0
  458. snappy/snap/slice_obs_HKL/rep_theory.py +424 -0
  459. snappy/snap/t3mlite/__init__.py +2 -0
  460. snappy/snap/t3mlite/arrow.py +243 -0
  461. snappy/snap/t3mlite/corner.py +22 -0
  462. snappy/snap/t3mlite/edge.py +172 -0
  463. snappy/snap/t3mlite/face.py +37 -0
  464. snappy/snap/t3mlite/files.py +211 -0
  465. snappy/snap/t3mlite/homology.py +53 -0
  466. snappy/snap/t3mlite/linalg.py +419 -0
  467. snappy/snap/t3mlite/mcomplex.py +1499 -0
  468. snappy/snap/t3mlite/perm4.py +320 -0
  469. snappy/snap/t3mlite/setup.py +12 -0
  470. snappy/snap/t3mlite/simplex.py +199 -0
  471. snappy/snap/t3mlite/spun.py +297 -0
  472. snappy/snap/t3mlite/surface.py +519 -0
  473. snappy/snap/t3mlite/test.py +20 -0
  474. snappy/snap/t3mlite/test_vs_regina.py +86 -0
  475. snappy/snap/t3mlite/tetrahedron.py +109 -0
  476. snappy/snap/t3mlite/vertex.py +42 -0
  477. snappy/snap/test.py +139 -0
  478. snappy/snap/utilities.py +288 -0
  479. snappy/test.py +213 -0
  480. snappy/test_cases.py +263 -0
  481. snappy/testing.py +131 -0
  482. snappy/tiling/__init__.py +2 -0
  483. snappy/tiling/dict_based_set.py +79 -0
  484. snappy/tiling/floor.py +49 -0
  485. snappy/tiling/hyperboloid_dict.py +54 -0
  486. snappy/tiling/iter_utils.py +78 -0
  487. snappy/tiling/lifted_tetrahedron.py +22 -0
  488. snappy/tiling/lifted_tetrahedron_set.py +54 -0
  489. snappy/tiling/quotient_dict.py +70 -0
  490. snappy/tiling/real_hash_dict.py +164 -0
  491. snappy/tiling/test.py +23 -0
  492. snappy/tiling/tile.py +224 -0
  493. snappy/tiling/triangle.py +33 -0
  494. snappy/tkterminal.py +920 -0
  495. snappy/twister/__init__.py +20 -0
  496. snappy/twister/main.py +646 -0
  497. snappy/twister/surfaces/S_0_1 +3 -0
  498. snappy/twister/surfaces/S_0_2 +3 -0
  499. snappy/twister/surfaces/S_0_4 +7 -0
  500. snappy/twister/surfaces/S_0_4_Lantern +8 -0
  501. snappy/twister/surfaces/S_1 +3 -0
  502. snappy/twister/surfaces/S_1_1 +4 -0
  503. snappy/twister/surfaces/S_1_2 +5 -0
  504. snappy/twister/surfaces/S_1_2_5 +6 -0
  505. snappy/twister/surfaces/S_2 +6 -0
  506. snappy/twister/surfaces/S_2_1 +8 -0
  507. snappy/twister/surfaces/S_2_heeg +10 -0
  508. snappy/twister/surfaces/S_3 +8 -0
  509. snappy/twister/surfaces/S_3_1 +10 -0
  510. snappy/twister/surfaces/S_4_1 +12 -0
  511. snappy/twister/surfaces/S_5_1 +14 -0
  512. snappy/twister/surfaces/heeg_fig8 +9 -0
  513. snappy/twister/twister_core.cpython-310-aarch64-linux-gnu.so +0 -0
  514. snappy/upper_halfspace/__init__.py +146 -0
  515. snappy/upper_halfspace/ideal_point.py +29 -0
  516. snappy/verify/__init__.py +13 -0
  517. snappy/verify/canonical.py +542 -0
  518. snappy/verify/complex_volume/__init__.py +18 -0
  519. snappy/verify/complex_volume/adjust_torsion.py +86 -0
  520. snappy/verify/complex_volume/closed.py +168 -0
  521. snappy/verify/complex_volume/compute_ptolemys.py +90 -0
  522. snappy/verify/complex_volume/cusped.py +56 -0
  523. snappy/verify/complex_volume/extended_bloch.py +201 -0
  524. snappy/verify/cusp_translations.py +85 -0
  525. snappy/verify/edge_equations.py +80 -0
  526. snappy/verify/exceptions.py +254 -0
  527. snappy/verify/hyperbolicity.py +224 -0
  528. snappy/verify/interval_newton_shapes_engine.py +523 -0
  529. snappy/verify/interval_tree.py +400 -0
  530. snappy/verify/krawczyk_shapes_engine.py +518 -0
  531. snappy/verify/real_algebra.py +286 -0
  532. snappy/verify/shapes.py +25 -0
  533. snappy/verify/square_extensions.py +1005 -0
  534. snappy/verify/test.py +72 -0
  535. snappy/verify/volume.py +128 -0
  536. snappy/version.py +2 -0
  537. snappy-3.3.dist-info/METADATA +58 -0
  538. snappy-3.3.dist-info/RECORD +541 -0
  539. snappy-3.3.dist-info/WHEEL +6 -0
  540. snappy-3.3.dist-info/entry_points.txt +2 -0
  541. snappy-3.3.dist-info/top_level.txt +28 -0
@@ -0,0 +1,995 @@
1
+ from . import matrix
2
+ from . import homology
3
+ from .polynomial import Polynomial
4
+ from .ptolemyObstructionClass import PtolemyObstructionClass
5
+ from .ptolemyGeneralizedObstructionClass import PtolemyGeneralizedObstructionClass
6
+ from .ptolemyVarietyPrimeIdealGroebnerBasis import PtolemyVarietyPrimeIdealGroebnerBasis
7
+ from . import processFileBase, processFileDispatch, processMagmaFile
8
+ from .processFileBase import PtolemyPrecomputedObstructionClassMismatchError
9
+ from . import utilities
10
+ from ..sage_helper import _within_sage, sage_method
11
+ from string import Template
12
+ import signal
13
+ import re
14
+ import os
15
+ import sys
16
+
17
+ if _within_sage:
18
+ from sage.rings.rational_field import RationalField
19
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
20
+ from sage.rings.ideal import Ideal
21
+
22
+ from urllib.request import Request, urlopen
23
+ from urllib.request import quote as urlquote
24
+ from urllib.error import HTTPError
25
+
26
+
27
+ class PtolemyFileMissingError(Exception):
28
+ """
29
+ An exception indicating that a requested solution file was missing.
30
+ """
31
+
32
+ def __init__(self, message):
33
+ Exception.__init__(self, message)
34
+
35
+ class PtolemyMissingFileForObstructionClass(Exception):
36
+ def __init__(self, index):
37
+
38
+ msg = (
39
+ "Pari's implementation of the Smith normal form has changed "
40
+ "affecting the order in which the cohomology classes are listed "
41
+ "and the cocycles used to represent them. Unfortunately, the "
42
+ "pre-computed file uses a cocycle that no longer matches and "
43
+ "a file matching the new cocycle has not yet been produced. "
44
+ "Please report the manifold and index (%d)." % index)
45
+ Exception.__init__(self, msg)
46
+ self.index = index
47
+
48
+ class PtolemyVariety():
49
+ """
50
+ Holds a reduced Ptolemy variety.
51
+
52
+ === Examples ===
53
+
54
+ To generate such a variety, call:
55
+
56
+ >>> from snappy import Manifold
57
+ >>> p = Manifold("4_1").ptolemy_variety(2, obstruction_class = 1)
58
+
59
+ Show the equations and variables:
60
+
61
+ >>> for e in p.equations: print(e)
62
+ - c_0011_0 * c_0101_0 + c_0011_0^2 + c_0101_0^2
63
+ c_0011_0 * c_0101_0 - c_0011_0^2 - c_0101_0^2
64
+ - 1 + c_0011_0
65
+ >>> p.variables
66
+ ['c_0011_0', 'c_0101_0']
67
+
68
+ Show as an ideal (sage object):
69
+
70
+ >>> p.ideal #doctest: +SKIP
71
+ Ideal (-c_0011_0^2 + c_0011_0*c_0101_0 + c_0101_0^2, -c_0011_0^2 - c_0011_0*c_0101_0 + c_0101_0^2, c_0011_0 - 1) of Multivariate Polynomial Ring in c_0011_0, c_0101_0 over Rational Field
72
+ (skip doctest because example only works in sage and not plain python)
73
+
74
+
75
+ Produce magma input:
76
+
77
+ >>> s = p.to_magma()
78
+ >>> print(s.split('ring and ideal')[1].strip()) #doctest: +ELLIPSIS
79
+ R<c_0011_0, c_0101_0> := PolynomialRing(RationalField(), 2, "grevlex");
80
+ MyIdeal := ideal<R |
81
+ - c_0011_0 * c_0101_0 + c_0011_0^2 + c_0101_0^2,
82
+ ...
83
+
84
+ Call ``p.compute_solutions()`` to automatically compute solutions!
85
+
86
+ Show canonical representatives:
87
+
88
+ (The Ptolemy coordinates c_0110_0 and c_0101_0 are identified, this
89
+ information is needed to recover all Ptolemy coordinates from the solutions
90
+ of a simplified Ptolemy variety. The information is also packaged into a
91
+ python section by py_eval_variable_dict().)
92
+
93
+ >>> p.canonical_representative["c_0110_0"]
94
+ (1, 0, 'c_0101_0')
95
+
96
+ """
97
+
98
+ def __init__(self, manifold, N, obstruction_class,
99
+ simplify, eliminate_fixed_ptolemys):
100
+ self._manifold = manifold
101
+ self._N = N
102
+ self._obstruction_class = obstruction_class
103
+
104
+ if obstruction_class:
105
+ obstruction_class._checkManifoldAndN(manifold, N)
106
+
107
+ if isinstance(obstruction_class, PtolemyObstructionClass):
108
+ self._identified_variables_from_obstruction = (
109
+ obstruction_class.identified_variables)
110
+ else:
111
+ self._identified_variables_from_obstruction = [ ]
112
+
113
+ H2_class = None
114
+
115
+ if isinstance(obstruction_class, PtolemyGeneralizedObstructionClass):
116
+ H2_class = obstruction_class.H2_class
117
+
118
+ self._identified_coordinates = (
119
+ manifold._ptolemy_equations_identified_coordinates(N, H2_class))
120
+
121
+ self._action_by_decoration_change = (
122
+ manifold._ptolemy_equations_action_by_decoration_change(N))
123
+
124
+ # find enough Ptolemy variables to set to one so that the
125
+ # decoration is fixed
126
+ self._fixed_ptolemy_coordinates = (
127
+ _fix_decoration(N, self._action_by_decoration_change))
128
+
129
+ self._identified_variables = (
130
+ self._identified_coordinates +
131
+ self._identified_variables_from_obstruction)
132
+
133
+ self._ptolemy_relations = (
134
+ _generate_ptolemy_relations(
135
+ N, manifold.num_tetrahedra(),
136
+ isinstance(obstruction_class, PtolemyObstructionClass)))
137
+
138
+ self.equations = list(self._ptolemy_relations)
139
+
140
+ order_of_u = 1
141
+
142
+ if isinstance(obstruction_class, PtolemyGeneralizedObstructionClass):
143
+ order_of_u, equations = (
144
+ obstruction_class._get_equation_for_u(N))
145
+ self.equations += equations
146
+
147
+ if eliminate_fixed_ptolemys:
148
+
149
+ # each ptolemy set to 1 for fixing decoration is eliminated by
150
+ # being replace by 1
151
+ self._identified_variables += (
152
+ [ (+1, 0, ptolemy_coord, 1)
153
+ for ptolemy_coord in self._fixed_ptolemy_coordinates])
154
+
155
+ else:
156
+ one = Polynomial.constant_polynomial(1)
157
+
158
+ # we add an equation c_XXXX_X - 1 for enough ptolemy's
159
+ # to fix the decoration
160
+ self.equations += (
161
+ [ Polynomial.from_variable_name(ptolemy_coord) - one
162
+ for ptolemy_coord in self._fixed_ptolemy_coordinates])
163
+
164
+ variables = _union(eqn.variables() for eqn in self.equations)
165
+
166
+ if simplify:
167
+
168
+ self.canonical_representative = _identified_variables_canonize(
169
+ self._identified_variables)
170
+
171
+ substitution = (
172
+ _canonical_representative_to_polynomial_substituition(
173
+ self.canonical_representative, order_of_u))
174
+
175
+ self.equations = [eqn.substitute(substitution)
176
+ for eqn in self.equations]
177
+
178
+ else:
179
+
180
+ self.canonical_representative = { }
181
+
182
+ for sign, power, var1, var2 in self._identified_variables:
183
+
184
+ self.canonical_representative[var1] = (+1, 0, var1)
185
+ if var2 != 1:
186
+ self.canonical_representative[var2] = (+1, 0, var2)
187
+
188
+ if order_of_u == 2:
189
+ u = Polynomial.constant_polynomial(-1)
190
+ else:
191
+ u = Polynomial.from_variable_name('u')
192
+
193
+ firstTerm = (
194
+ Polynomial.from_variable_name(var1) *
195
+ u ** (power % order_of_u))
196
+
197
+ if var2 == 1:
198
+ secondTerm = (
199
+ Polynomial.constant_polynomial(sign))
200
+ else:
201
+ secondTerm = (
202
+ Polynomial.constant_polynomial(sign) *
203
+ Polynomial.from_variable_name(var2))
204
+ self.equations.append(firstTerm - secondTerm)
205
+
206
+ self.variables = _union(eqn.variables() for eqn in self.equations)
207
+
208
+ # Process interior Ptolemy coordinates such as c_1111_x
209
+ # Only invoked for N >= 4
210
+ for var in self.variables:
211
+ if var[0:2] == 'c_':
212
+ if var not in self.canonical_representative:
213
+ self.canonical_representative[var] = (+1, 0, var)
214
+
215
+ self.variables_with_non_zero_condition = [ "t" ] + self.variables
216
+
217
+ # take out u, the root of unity
218
+ vars_without_u = [ var
219
+ for var in self.variables_with_non_zero_condition
220
+ if not var == 'u']
221
+
222
+ self._non_zero_condition = (
223
+ _non_zero_condition(vars_without_u))
224
+
225
+ self.equations_with_non_zero_condition = (
226
+ self.equations + [ self._non_zero_condition ])
227
+
228
+ if _within_sage:
229
+ self.ideal = _sage_ideal(
230
+ self.variables,
231
+ self.equations)
232
+
233
+ self.ideal_with_non_zero_condition = _sage_ideal(
234
+ self.variables_with_non_zero_condition,
235
+ self.equations_with_non_zero_condition)
236
+
237
+ def py_eval_variable_dict(self):
238
+
239
+ def create_dict_entry(var1, val):
240
+ sign, power, var2 = val
241
+
242
+ assert sign in [+1, -1]
243
+
244
+ p = ""
245
+ if self._N == 2:
246
+ sign *= (-1) ** power
247
+ else:
248
+ if power % self._N:
249
+ p = " * d['u'] ** %d" % (power % self._N)
250
+
251
+ if sign == +1:
252
+ return "'%s' : d['%s']%s" % (var1, var2, p)
253
+ else:
254
+ return "'%s' : - d['%s']%s" % (var1, var2, p)
255
+
256
+ format_str = "(lambda d: {\n %s})"
257
+
258
+ return (
259
+ format_str % ',\n '.join(
260
+ [create_dict_entry(key, val)
261
+ for key, val
262
+ in list(self.canonical_representative.items())
263
+ if not key == 1]))
264
+
265
+ def py_eval_section(self):
266
+ """
267
+ Returns a string that can be evaluated in python and contains extra
268
+ information needed to recover solutions from a simplified Ptolemy
269
+ variety.
270
+
271
+ >>> from snappy import Manifold, pari
272
+ >>> M = Manifold('4_1')
273
+ >>> p = M.ptolemy_variety(2, obstruction_class = 1)
274
+
275
+ Get extra information
276
+
277
+ >>> eval_section = p.py_eval_section()
278
+ >>> print(eval_section) #doctest: +ELLIPSIS
279
+ {'variable_dict' :
280
+ (lambda d: {
281
+ ...
282
+
283
+ Turn it into a python object by evaluation.
284
+
285
+ >>> obj = eval(eval_section)
286
+
287
+ Access the function that expands a solution to the simplified
288
+ Ptolemy variety to a full solution.
289
+
290
+ >>> variable_dict = obj['variable_dict']
291
+
292
+ Setup a solution and expand it to a full solution, '1' must map to 1
293
+
294
+ >>> simplified_solution = {'c_0101_0' : pari('0.5 - 0.866025403784439*I'), '1' : pari(1), 'c_0011_0' : pari(1)}
295
+ >>> full_solution = variable_dict(simplified_solution)
296
+
297
+ Full solution is a dictionary with a key for every Ptolemy coordinate
298
+
299
+ >>> full_solution['c_1010_1']
300
+ 1
301
+ >>> for tet in range(2):
302
+ ... for i in utilities.quadruples_with_fixed_sum_iterator(2, skipVertices = True):
303
+ ... c = "c_%d%d%d%d" % i + "_%d" % tet
304
+ ... assert c in full_solution
305
+ """
306
+
307
+ result = "{"
308
+ result += "'variable_dict' :\n %s" % self.py_eval_variable_dict()
309
+
310
+ # If we have a non-trivial generalized obstruction class,
311
+ # add an extra key to the dictionary to mark it.
312
+
313
+ # This will prevent PtolemyCoordinates to compute the ill-defined
314
+ # flattenings and complex volume.
315
+
316
+ if isinstance(self._obstruction_class,
317
+ PtolemyGeneralizedObstructionClass):
318
+ if self._obstruction_class._is_non_trivial(self._N):
319
+ result += (
320
+ ",\n "
321
+ "'non_trivial_generalized_obstruction_class' : True")
322
+
323
+ result += "}"
324
+
325
+ return result
326
+
327
+ def to_magma_file(
328
+ self, filename,
329
+ template_path="magma/default.magma_template"):
330
+ """
331
+ >>> import os, tempfile
332
+ >>> from snappy import Manifold
333
+ >>> handle, name = tempfile.mkstemp()
334
+ >>> p = Manifold("4_1").ptolemy_variety(2, obstruction_class=1)
335
+ >>> p.to_magma_file(name)
336
+ >>> os.close(handle); os.remove(name)
337
+ """
338
+ with open(filename, 'wb') as output:
339
+ output.write(bytes(self.to_magma(template_path=template_path).encode('ascii')))
340
+
341
+ def to_magma(
342
+ self,
343
+ template_path="magma/default.magma_template"):
344
+ """
345
+ Returns a string with the ideal that can be used as input for magma.
346
+
347
+ The advanced user can provide a template string to write own magma
348
+ code to process the equations.
349
+
350
+ >>> from snappy import *
351
+ >>> p = Manifold("4_1").ptolemy_variety(2, obstruction_class = 1)
352
+
353
+ Magma input to compute radical Decomposition
354
+ >>> s = p.to_magma()
355
+ >>> print(s.split('ring and ideal')[1].strip()) #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
356
+ R<c_0011_0, c_0101_0> := PolynomialRing(RationalField(), 2, "grevlex");
357
+ MyIdeal := ideal<R | - c_0011_0 * c_0101_0 + c_0011_0^2 + c_0101_0^2,
358
+ ...
359
+ >>> "RadicalDecomposition" in p.to_magma()
360
+ True
361
+ """
362
+
363
+ if os.path.isfile(template_path):
364
+ template = open(template_path, 'r').read()
365
+ else:
366
+ from snappy.ptolemy import __path__ as base_paths
367
+ abs_path = os.path.join(base_paths[0], template_path)
368
+ if os.path.isfile(abs_path):
369
+ template = open(abs_path, 'r').read()
370
+ else:
371
+ raise Exception("No file at template_path %s" % template_path)
372
+
373
+ PREAMBLE = (
374
+ "==TRIANGULATION=BEGINS==\n" +
375
+ self._manifold._to_string() + "\n"
376
+ "==TRIANGULATION=ENDS==\n" +
377
+ "PY=EVAL=SECTION=BEGINS=HERE\n" +
378
+ self.py_eval_section() + "\n"
379
+ "PY=EVAL=SECTION=ENDS=HERE\n")
380
+
381
+ # magma will wrap long lines and we potentially lose some information
382
+ # that way when retrieving the ASCII text encoding the triangulation
383
+ # and the py_eval dictionary.
384
+ # To prevent this, we already break long lines here in such a way that
385
+ # join_long_lines gives exactly back the same ASCII text.
386
+
387
+ # Next, we quote the text so that we can give it to magma's print.
388
+
389
+ QUOTED_PREAMBLE = utilities.quote_ascii_text(
390
+ utilities.break_long_lines(PREAMBLE))
391
+
392
+ return Template(template).safe_substitute(
393
+ PREAMBLE=PREAMBLE,
394
+ QUOTED_PREAMBLE=QUOTED_PREAMBLE,
395
+
396
+ VARIABLES=(
397
+ ", ".join(self.variables)),
398
+ VARIABLES_QUOTED=(
399
+ ", ".join(['"%s"' % v for v in self.variables])),
400
+ VARIABLE_NUMBER=(
401
+ len(self.variables)),
402
+
403
+ VARIABLES_WITH_NON_ZERO_CONDITION=(
404
+ ", ".join(self.variables_with_non_zero_condition)),
405
+ VARIABLES_WITH_NON_ZERO_CONDITION_QUOTED=(
406
+ ", ".join(['"%s"' % v
407
+ for v in self.variables_with_non_zero_condition])),
408
+ VARIABLE_WITH_NON_ZERO_CONDITION_NUMBER=(
409
+ len(self.variables_with_non_zero_condition)),
410
+
411
+ EQUATIONS=(
412
+ ',\n '.join(
413
+ [str(eqn)
414
+ for eqn in self.equations])),
415
+ EQUATIONS_WITH_NON_ZERO_CONDITION=(
416
+ ',\n '.join(
417
+ [str(eqn)
418
+ for eqn in self.equations_with_non_zero_condition])))
419
+
420
+ def filename_base(self):
421
+ """
422
+ Preferred filename base for writing out this Ptolemy variety
423
+
424
+ >>> from snappy import *
425
+ >>> M = Manifold('4_1')
426
+ >>> p = M.ptolemy_variety(2, obstruction_class = 1)
427
+ >>> p.filename_base()
428
+ '4_1__sl2_c1'
429
+
430
+ >>> p = M.ptolemy_variety(2)
431
+ >>> p.filename_base()
432
+ '4_1__sl2_c0'
433
+ """
434
+
435
+ obstruction_class = "NoIndex"
436
+
437
+ if self._obstruction_class is None:
438
+ obstruction_class = "0"
439
+ elif self._obstruction_class._index is not None:
440
+ obstruction_class = "%d" % self._obstruction_class._index
441
+ # filenames which contain regex special characters cause
442
+ # trouble with PyInstaller's globbing module.
443
+ name = self._manifold.name().replace('[', '_').replace(']', '')
444
+ return '%s__sl%d_c%s' % (name, self._N, obstruction_class)
445
+
446
+ def path_to_file(self):
447
+
448
+ name = self._manifold.name()
449
+
450
+ if re.match(r'([msvt]|o9_)[0-9]+$', name):
451
+ dir = 'OrientableCuspedCensus'
452
+ elif re.match(r'[0-9]+([\^][0-9]+)?[_][0-9]+$', name):
453
+ dir = 'LinkExteriors'
454
+ elif re.match(r'[KL][0-9]+[an][0-9]+$', name):
455
+ dir = 'HTLinkExteriors'
456
+ else:
457
+ raise Exception('No canonical path for manifold')
458
+
459
+ tets = self._manifold.num_tetrahedra()
460
+
461
+ return '/'.join(['data',
462
+ 'pgl%d' % self._N,
463
+ dir,
464
+ '%02d_tetrahedra' % tets])
465
+
466
+ def _solution_file_url(self, alt=0, ext='magma_out', data_url=None):
467
+
468
+ if data_url is None:
469
+ from . import DATA_URL as data_url
470
+
471
+ if '://' not in data_url:
472
+ # No schema in url, assume file
473
+ if not data_url[0] == '/':
474
+ data_url = '/' + data_url
475
+ data_url = 'file://' + data_url
476
+
477
+ # Make it end in /
478
+ if not data_url[-1] == '/':
479
+ data_url = data_url + '/'
480
+
481
+ if alt > 0:
482
+ suffix = '_alt%d' % alt
483
+ else:
484
+ suffix = ''
485
+
486
+ filename = self.filename_base() + suffix + "." + ext
487
+
488
+ return data_url + self.path_to_file() + '/' + urlquote(filename)
489
+
490
+ def _retrieve_solution_file_alt(self,
491
+ alt=0,
492
+ data_url=None,
493
+ exts=['magma_out', 'rur'],
494
+ verbose=False):
495
+ for i, ext in enumerate(exts):
496
+ url = self._solution_file_url(alt=alt,
497
+ data_url=data_url,
498
+ ext=ext)
499
+ if verbose:
500
+ print("Trying to retrieve solutions from %s ..." % url)
501
+
502
+ try:
503
+ return _retrieve_url(url)
504
+ except PtolemyFileMissingError as e:
505
+ if i == len(exts) - 1:
506
+ raise
507
+
508
+ def _retrieve_solution_file(self,
509
+ data_url=None,
510
+ exts=['magma_out', 'rur'],
511
+ verbose=False):
512
+
513
+ num_alts = 3
514
+
515
+ for alt in range(num_alts):
516
+ try:
517
+ text = self._retrieve_solution_file_alt(alt=alt,
518
+ data_url=data_url,
519
+ exts=exts,
520
+ verbose=verbose)
521
+ self._check_obstruction_class_for_precomputed_file(text)
522
+ return text
523
+ except PtolemyPrecomputedObstructionClassMismatchError as e:
524
+ if alt == num_alts - 1:
525
+ raise
526
+ except PtolemyFileMissingError as e:
527
+ if alt == 0:
528
+ raise
529
+ else:
530
+ raise PtolemyMissingFileForObstructionClass(
531
+ self._obstruction_class._index if self._obstruction_class else 0)
532
+
533
+ def _check_obstruction_class_for_precomputed_file(
534
+ self, text):
535
+
536
+ # Grab the PY=EVAL=SECTION
537
+ # Note that this will be evaluated again later.
538
+ # But it is cheap enough that the double evaluation should not matter.
539
+ py_eval = processFileBase.get_py_eval(text)
540
+
541
+ # Now get the function that takes a dictionary-like object with
542
+ # the solutions to the variety and expands it to a dictionary
543
+ # assigning a value to all Ptolemy coordinates and obstruction class
544
+ # variables.
545
+ variable_dict_function = py_eval['variable_dict']
546
+
547
+ # As noticed by Nathan, the obstruction classes used for producing
548
+ # the pre-computed solutions do not match the obstruction classes
549
+ # we compute now.
550
+ # This is due to pari changing the code for computing the
551
+ # Smith normal form in version 2.13 (see
552
+ # http://pari.math.u-bordeaux.fr/archives/pari-announce-20/msg00006.html)
553
+ #
554
+ # We thus check here explicitly that the obstruction class still
555
+ # matches.
556
+ #
557
+ processFileBase.check_obstruction_class_for_variable_dict_function(
558
+ variable_dict_function,
559
+ self._obstruction_class)
560
+
561
+ def retrieve_decomposition(self, data_url=None, verbose=True):
562
+
563
+ text = self._retrieve_solution_file(data_url,
564
+ exts=['magma_out'],
565
+ verbose=verbose)
566
+
567
+ if verbose:
568
+ print("Parsing...")
569
+
570
+ M = processFileBase.get_manifold(text)
571
+ assert M._to_bytes() == self._manifold._to_bytes(), (
572
+ "Manifold does not match census manifold")
573
+
574
+ return processMagmaFile.decomposition_from_magma(text)
575
+
576
+ def retrieve_solutions(self, numerical=False,
577
+ prefer_rur=False,
578
+ data_url=None,
579
+ verbose=True):
580
+
581
+ exts = ['magma_out.gz', 'magma_out', 'rur']
582
+ if prefer_rur:
583
+ exts = exts[::-1]
584
+
585
+ text = self._retrieve_solution_file(data_url=data_url,
586
+ exts=exts,
587
+ verbose=verbose)
588
+
589
+ if verbose:
590
+ print("Parsing...")
591
+
592
+ M = processFileBase.get_manifold(text)
593
+ assert M._to_bytes() == self._manifold._to_bytes(), (
594
+ "Manifold does not match census manifold")
595
+
596
+ return processFileDispatch.parse_solutions(text, numerical=numerical)
597
+
598
+ def __repr__(self):
599
+
600
+ res = "Ptolemy Variety for %s, N = %d" % (self._manifold.name(),
601
+ self._N)
602
+ if self._obstruction_class is not None:
603
+ res += ", obstruction_class = "
604
+ if self._obstruction_class._index is not None:
605
+ res += "%d" % self._obstruction_class._index
606
+ if isinstance(self._obstruction_class,
607
+ PtolemyGeneralizedObstructionClass):
608
+ res += " (generalized)"
609
+ elif isinstance(self._obstruction_class,
610
+ PtolemyGeneralizedObstructionClass):
611
+ res += "%s" % self._obstruction_class.H2_class
612
+ else:
613
+ res += "..."
614
+
615
+ res += "\n" + "\n".join([' %s' % e for e in self.equations])
616
+
617
+ return res
618
+
619
+ def compute_decomposition(
620
+ self,
621
+ engine=None,
622
+ memory_limit=750000000,
623
+ directory=None,
624
+ verbose=False,
625
+ template_path="magma/default.magma_template"):
626
+ """
627
+ Starts an engine such as magma to compute the
628
+ radical decomposition of the Ptolemy variety.
629
+
630
+ If started in sage, uses sage, otherwise, uses magma.
631
+
632
+ === Arguments ===
633
+
634
+ engine --- engine to use, currently, only support magma and sage
635
+ memory_limit --- maximal allowed memory in bytes
636
+ directory --- location for input and output files, temporary directory used if not specified
637
+ verbose --- print extra information
638
+ """
639
+
640
+ if engine is None:
641
+ if _within_sage:
642
+ engine = 'sage'
643
+ else:
644
+ engine = 'magma'
645
+
646
+ if engine == 'magma':
647
+ return processMagmaFile.run_magma(
648
+ self.to_magma(template_path=template_path),
649
+ filename_base=self.filename_base(),
650
+ memory_limit=memory_limit,
651
+ directory=directory,
652
+ verbose=verbose)
653
+
654
+ if engine == 'sage':
655
+
656
+ M = self._manifold.copy()
657
+
658
+ radical = self.ideal_with_non_zero_condition.radical()
659
+
660
+ sage_radical_decomp = radical.primary_decomposition()
661
+
662
+ def process_component(component):
663
+
664
+ dimension = component.dimension()
665
+
666
+ if dimension == 0:
667
+ sage_gb = component.groebner_basis()
668
+ polys = [ Polynomial.parse_string(str(p)) for p in sage_gb ]
669
+ else:
670
+ polys = []
671
+
672
+ return PtolemyVarietyPrimeIdealGroebnerBasis(
673
+ polys=polys,
674
+ term_order='lex',
675
+ size=None,
676
+ dimension=dimension,
677
+ is_prime=component.is_prime(),
678
+ free_variables=None,
679
+ py_eval=eval(self.py_eval_section()),
680
+ manifold_thunk=lambda :M)
681
+
682
+ return utilities.MethodMappingList(
683
+ [ process_component(component)
684
+ for component in sage_radical_decomp
685
+ if not component.is_one()])
686
+
687
+ def compute_solutions(self,
688
+ engine=None,
689
+ numerical=False,
690
+ template_path="magma/default.magma_template",
691
+ memory_limit=750000000,
692
+ directory=None,
693
+ verbose=False):
694
+ """
695
+ Starts an engine such as magma to compute the
696
+ radical decomposition of the ideal and computes exact solutions.
697
+
698
+ If started in sage, uses sage, otherwise, uses magma.
699
+
700
+ === Arguments ===
701
+
702
+ engine --- engine to use, currently, only support magma and sage
703
+ numerical --- get numerical solutions from magma instead of exact ones
704
+ memory_limit --- maximal allowed memory in bytes
705
+ directory --- location for input and output files, temporary directory used if not specified
706
+ verbose --- print extra information
707
+ """
708
+
709
+ decomposition = self.compute_decomposition(
710
+ engine=engine,
711
+ memory_limit=memory_limit,
712
+ template_path=template_path,
713
+ directory=directory,
714
+ verbose=verbose)
715
+
716
+ return utilities.MethodMappingList(
717
+ [ component.solutions(numerical=numerical)
718
+ for component in decomposition ])
719
+
720
+ def degree_to_shapes(self):
721
+ """
722
+ In general, there can be d different solutions to the (reduced) Ptolemy
723
+ variety for each solution to the gluing equations (with peripheral
724
+ equations). This method computes d which is also the number of elements
725
+ in H^1(Mhat; Z/N) where Mhat is the non-manifold cell comples obtained
726
+ by gluing together the tetrahedra as non-ideal tetrahedra.
727
+
728
+
729
+ For example, the Ptolemy variety for m009 has 4 points but there are
730
+ only 2 distinct boundary-unipotent PSL(2,C) representations.
731
+ Thus the following call returns 2 = 4 / 2
732
+
733
+ >>> from snappy import Manifold
734
+ >>> Manifold("m009").ptolemy_variety(2,1).degree_to_shapes()
735
+ 2
736
+
737
+ >>> Manifold("m010").ptolemy_variety(2,1).degree_to_shapes()
738
+ 2
739
+ >>> Manifold("m011").ptolemy_variety(2,1).degree_to_shapes()
740
+ 1
741
+
742
+ >>> Manifold("m009").ptolemy_variety(3,1).degree_to_shapes()
743
+ 1
744
+ >>> Manifold("m010").ptolemy_variety(3,1).degree_to_shapes()
745
+ 3
746
+ >>> Manifold("m011").ptolemy_variety(3,1).degree_to_shapes()
747
+ 1
748
+
749
+ """
750
+
751
+ # Boundary maps for chain complex
752
+ d2 = self._manifold._ptolemy_equations_boundary_map_2()[0]
753
+ d1 = self._manifold._ptolemy_equations_boundary_map_1()[0]
754
+
755
+ # Boundary maps for dual chain complex
756
+ co_d1 = matrix.matrix_transpose(d2)
757
+ co_d0 = matrix.matrix_transpose(d1)
758
+
759
+ # All cohomology classes
760
+ cohomology_classes = homology.homology_representatives(
761
+ co_d1, co_d0, self._N)
762
+
763
+ # Number of classes
764
+ return len(list(cohomology_classes))
765
+
766
+ def _fix_decoration(N, action_by_decoration_change):
767
+
768
+ action_matrix, ptolemy_coords, decorations_to_be_fixed = (
769
+ action_by_decoration_change)
770
+
771
+ return matrix.get_independent_rows(
772
+ action_matrix, ptolemy_coords, desired_determinant=N)
773
+
774
+
775
+ def _generate_ptolemy_relations(N, num_tet,
776
+ has_obstruction_class):
777
+
778
+ def generate_ptolemy_relation(tet, index):
779
+
780
+ def generate_Ptolemy_coordinate(addl_index):
781
+ total_index = matrix.vector_add(index, addl_index)
782
+ return Polynomial.from_variable_name(
783
+ "c_%d%d%d%d" % tuple(total_index) + "_%d" % tet)
784
+
785
+ def generate_obstruction_variable(face):
786
+ if has_obstruction_class:
787
+ return Polynomial.from_variable_name(
788
+ "s_%d_%d" % (face, tet))
789
+ else:
790
+ return Polynomial.constant_polynomial(1)
791
+
792
+ # implements equation 5.8 from paper
793
+
794
+ return (
795
+ generate_obstruction_variable(0) *
796
+ generate_obstruction_variable(1) *
797
+ generate_Ptolemy_coordinate((1,1,0,0)) *
798
+ generate_Ptolemy_coordinate((0,0,1,1))
799
+ - generate_obstruction_variable(0) *
800
+ generate_obstruction_variable(2) *
801
+ generate_Ptolemy_coordinate((1,0,1,0)) *
802
+ generate_Ptolemy_coordinate((0,1,0,1))
803
+ + generate_obstruction_variable(0) *
804
+ generate_obstruction_variable(3) *
805
+ generate_Ptolemy_coordinate((1,0,0,1)) *
806
+ generate_Ptolemy_coordinate((0,1,1,0)))
807
+
808
+ return [generate_ptolemy_relation(tet, index)
809
+ for tet in range(num_tet)
810
+ for index in utilities.quadruples_with_fixed_sum_iterator(N-2)]
811
+
812
+
813
+ def _non_zero_condition(variables):
814
+ one = Polynomial.constant_polynomial(1)
815
+
816
+ polynomial = one
817
+
818
+ for var in variables:
819
+ polynomial = polynomial * Polynomial.from_variable_name(var)
820
+
821
+ polynomial = polynomial - one
822
+
823
+ return polynomial
824
+
825
+
826
+ def _union(lists):
827
+ return sorted(set(e for l in lists for e in l))
828
+
829
+ def _identified_variables_canonize(identified_variables):
830
+
831
+ def merge_two_dicts(sign, power, var1, var2, dict1, dict2):
832
+
833
+ sign1, power1 = dict1[var1]
834
+ sign2, power2 = dict2[var2]
835
+
836
+ new_sign = sign1 * sign * sign2
837
+ new_power = power1 - power - power2
838
+
839
+ for v2, (s2, p2) in dict2.items():
840
+ dict1[v2] = (s2 * new_sign, p2 + new_power)
841
+
842
+ return dict1
843
+
844
+ all_variables = {}
845
+
846
+ for sign, power, var1, var2 in identified_variables:
847
+ all_variables[var1] = { var1 : (+1, 0) }
848
+ all_variables[var2] = { var2 : (+1, 0) }
849
+
850
+ for sign, power, var1, var2 in identified_variables:
851
+ if not all_variables[var1] is all_variables[var2]:
852
+ new_dict = merge_two_dicts(sign, power, var1, var2,
853
+ all_variables[var1],
854
+ all_variables[var2])
855
+ for var in new_dict:
856
+ all_variables[var] = new_dict
857
+
858
+ result = {}
859
+
860
+ for variable, variable_dict in all_variables.items():
861
+ if variable not in result:
862
+ vars = list(variable_dict.keys())
863
+ if 1 in vars:
864
+ canonical_rep = 1
865
+ else:
866
+ vars.sort()
867
+ canonical_rep = vars[0]
868
+
869
+ canonical_rep_sign, canonical_rep_power = (
870
+ variable_dict[canonical_rep])
871
+
872
+ for (var, (sign, power)) in variable_dict.items():
873
+ result[var] = (canonical_rep_sign * sign,
874
+ canonical_rep_power - power,
875
+ canonical_rep)
876
+
877
+ return result
878
+
879
+
880
+ def _canonical_representative_to_polynomial_substituition(
881
+ canonical_representative, order_of_u):
882
+
883
+ result = {}
884
+
885
+ for var1, signed_var2 in canonical_representative.items():
886
+ sign, power, var2 = signed_var2
887
+ if not var1 == var2:
888
+
889
+ if order_of_u == 2:
890
+ u = Polynomial.constant_polynomial(-1)
891
+ else:
892
+ u = Polynomial.from_variable_name('u')
893
+
894
+ sign_and_power = (
895
+ Polynomial.constant_polynomial(sign) *
896
+ u ** (power % order_of_u))
897
+
898
+ if var2 == 1:
899
+ result[var1] = sign_and_power
900
+ else:
901
+ result[var1] = (sign_and_power *
902
+ Polynomial.from_variable_name(var2))
903
+
904
+ return result
905
+
906
+
907
+ def _retrieve_url(url):
908
+
909
+ overview_url = "https://ptolemy.unhyperbolic.org/data/overview.html"
910
+
911
+ try:
912
+ # Remember SnapPy's SIGALRM handler (defined in app.py)
913
+ # And temporarily disable it (except under windows which does not
914
+ # have SIGALRM)
915
+ sigalrm_handler = None
916
+ if hasattr(signal, 'SIGALRM'):
917
+ sigalrm_handler = signal.signal(signal.SIGALRM, signal.SIG_IGN)
918
+ r = Request(url,
919
+ headers={'User-Agent': 'Wget/1.20.3'})
920
+ s = urlopen(r)
921
+
922
+ except HTTPError as e:
923
+ if e.code in [404, 406]:
924
+ raise PtolemyFileMissingError(
925
+ "The ptolemy variety has probably not been computed "
926
+ "yet, see %s (%s)" % (overview_url, e))
927
+ else:
928
+ raise PtolemyFileMissingError(
929
+ "The ptolemy variety has probably not been computed "
930
+ "yet or the given data_url or environment variable "
931
+ "PTOLEMY_DATA_URL "
932
+ "is not configured correctly: %s. Also see %s" % (
933
+ e, overview_url))
934
+
935
+ except OSError as e:
936
+ # IOError: this means the file wasn't there or we couldn't connect
937
+ # to the server
938
+ if url.startswith('http:') or url.startswith('https'):
939
+ # IOError for http means we could not connect to server
940
+ raise RuntimeError(
941
+ "Problem connecting to server while retrieving %s: "
942
+ "%s" % (url, e))
943
+ else:
944
+ # Otherwise, it probably means the file wasn't there
945
+ raise PtolemyFileMissingError(
946
+ "The ptolemy variety has probably not been computed "
947
+ "yet or the given data_url or environment variable "
948
+ "PTOLEMY_DATA_URL "
949
+ "is not configured correctly: %s. Also see %s" % (
950
+ e, overview_url))
951
+ finally:
952
+ # Always restore the original signal handler
953
+ if sigalrm_handler: # Not supported under windows
954
+ signal.signal(signal.SIGALRM, sigalrm_handler)
955
+
956
+ text = s.read()
957
+
958
+ if url.endswith('.gz'):
959
+ import gzip
960
+ text = gzip.decompress(text)
961
+
962
+ # Read the text
963
+ text = text.decode('ascii').replace('\r\n', '\n')
964
+
965
+ if not (url.startswith('http:') or url.startswith('https')):
966
+ # If this is a normal file, we are done
967
+ return text
968
+
969
+ # For http, we need to check that this isn't an error message
970
+ # by checking the HTTP code
971
+ code = s.getcode()
972
+ if code == 200:
973
+ # HTTP code 200 means alright
974
+ return text
975
+
976
+ # Otherwise we have an error
977
+ httpErr = "(HTTP Error %d while accessing %s)" % (code, url)
978
+
979
+ if code in [404, 406]:
980
+ # 404 means file not found
981
+ raise PtolemyFileMissingError(
982
+ "The ptolemy variety has probably not been computed "
983
+ "yet, see %s (%s)" % (overview_url, httpErr))
984
+
985
+ # Everything else means something is wrong with the server
986
+ # configuration or the connection to the server
987
+ raise RuntimeError(
988
+ "Problem retrieving file from server, please report to "
989
+ "enischte@gmail.com: %s" % httpErr)
990
+
991
+ @sage_method
992
+ def _sage_ideal(vars, polynomials, order='lex'):
993
+ polynomialRing = PolynomialRing(RationalField(), vars, order=order)
994
+
995
+ return Ideal(polynomialRing, [ p.sage() for p in polynomials ])