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.
- snappy/CyOpenGL.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/SnapPy.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/SnapPy.ico +0 -0
- snappy/SnapPy.png +0 -0
- snappy/SnapPyHP.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/__init__.py +534 -0
- snappy/app.py +604 -0
- snappy/app_menus.py +372 -0
- snappy/browser.py +998 -0
- snappy/cache.py +25 -0
- snappy/canonical.py +249 -0
- snappy/cusps/__init__.py +280 -0
- snappy/cusps/cusp_area_matrix.py +98 -0
- snappy/cusps/cusp_areas_from_matrix.py +96 -0
- snappy/cusps/maximal_cusp_area_matrix.py +136 -0
- snappy/cusps/short_slopes_for_cusp.py +217 -0
- snappy/cusps/test.py +22 -0
- snappy/cusps/trig_cusp_area_matrix.py +63 -0
- snappy/database.py +454 -0
- snappy/db_utilities.py +79 -0
- snappy/decorated_isosig.py +717 -0
- snappy/dev/__init__.py +0 -0
- snappy/dev/extended_ptolemy/__init__.py +8 -0
- snappy/dev/extended_ptolemy/closed.py +106 -0
- snappy/dev/extended_ptolemy/complexVolumesClosed.py +149 -0
- snappy/dev/extended_ptolemy/direct.py +42 -0
- snappy/dev/extended_ptolemy/extended.py +406 -0
- snappy/dev/extended_ptolemy/giac_helper.py +43 -0
- snappy/dev/extended_ptolemy/giac_rur.py +129 -0
- snappy/dev/extended_ptolemy/gluing.py +46 -0
- snappy/dev/extended_ptolemy/phc_wrapper.py +220 -0
- snappy/dev/extended_ptolemy/printMatrices.py +70 -0
- snappy/dev/vericlosed/__init__.py +1 -0
- snappy/dev/vericlosed/computeApproxHyperbolicStructureNew.py +159 -0
- snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +90 -0
- snappy/dev/vericlosed/computeVerifiedHyperbolicStructure.py +111 -0
- snappy/dev/vericlosed/gimbalLoopFinder.py +130 -0
- snappy/dev/vericlosed/hyperbolicStructure.py +313 -0
- snappy/dev/vericlosed/krawczykCertifiedEdgeLengthsEngine.py +165 -0
- snappy/dev/vericlosed/oneVertexTruncatedComplex.py +122 -0
- snappy/dev/vericlosed/orb/__init__.py +1 -0
- snappy/dev/vericlosed/orb/orb_solution_for_snappea_finite_triangulation_mac +0 -0
- snappy/dev/vericlosed/parseVertexGramMatrixFile.py +47 -0
- snappy/dev/vericlosed/polishApproxHyperbolicStructure.py +61 -0
- snappy/dev/vericlosed/test.py +54 -0
- snappy/dev/vericlosed/truncatedComplex.py +176 -0
- snappy/dev/vericlosed/verificationError.py +58 -0
- snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +177 -0
- snappy/doc/_images/SnapPy-196.png +0 -0
- snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
- snappy/doc/_images/m125_paper_plane.jpg +0 -0
- snappy/doc/_images/mac.png +0 -0
- snappy/doc/_images/o9_00000_systole_paper_plane.jpg +0 -0
- snappy/doc/_images/o9_00000_systole_paper_plane_closer.jpg +0 -0
- snappy/doc/_images/plink-action.png +0 -0
- snappy/doc/_images/ubuntu.png +0 -0
- snappy/doc/_images/win7.png +0 -0
- snappy/doc/_sources/additional_classes.rst.txt +40 -0
- snappy/doc/_sources/bugs.rst.txt +14 -0
- snappy/doc/_sources/censuses.rst.txt +52 -0
- snappy/doc/_sources/credits.rst.txt +81 -0
- snappy/doc/_sources/development.rst.txt +261 -0
- snappy/doc/_sources/index.rst.txt +215 -0
- snappy/doc/_sources/installing.rst.txt +249 -0
- snappy/doc/_sources/manifold.rst.txt +6 -0
- snappy/doc/_sources/manifoldhp.rst.txt +46 -0
- snappy/doc/_sources/news.rst.txt +425 -0
- snappy/doc/_sources/other.rst.txt +25 -0
- snappy/doc/_sources/platonic_census.rst.txt +20 -0
- snappy/doc/_sources/plink.rst.txt +102 -0
- snappy/doc/_sources/ptolemy.rst.txt +66 -0
- snappy/doc/_sources/ptolemy_classes.rst.txt +42 -0
- snappy/doc/_sources/ptolemy_examples1.rst.txt +298 -0
- snappy/doc/_sources/ptolemy_examples2.rst.txt +363 -0
- snappy/doc/_sources/ptolemy_examples3.rst.txt +301 -0
- snappy/doc/_sources/ptolemy_examples4.rst.txt +61 -0
- snappy/doc/_sources/ptolemy_prelim.rst.txt +105 -0
- snappy/doc/_sources/screenshots.rst.txt +21 -0
- snappy/doc/_sources/snap.rst.txt +87 -0
- snappy/doc/_sources/snappy.rst.txt +28 -0
- snappy/doc/_sources/spherogram.rst.txt +103 -0
- snappy/doc/_sources/todo.rst.txt +47 -0
- snappy/doc/_sources/triangulation.rst.txt +11 -0
- snappy/doc/_sources/tutorial.rst.txt +49 -0
- snappy/doc/_sources/verify.rst.txt +210 -0
- snappy/doc/_sources/verify_internals.rst.txt +79 -0
- snappy/doc/_static/SnapPy-horizontal-128.png +0 -0
- snappy/doc/_static/SnapPy.ico +0 -0
- snappy/doc/_static/_sphinx_javascript_frameworks_compat.js +123 -0
- snappy/doc/_static/basic.css +906 -0
- snappy/doc/_static/css/badge_only.css +1 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.eot +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.svg +2671 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.ttf +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.woff +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-bold-italic.woff +0 -0
- snappy/doc/_static/css/fonts/lato-bold-italic.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-bold.woff +0 -0
- snappy/doc/_static/css/fonts/lato-bold.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-normal-italic.woff +0 -0
- snappy/doc/_static/css/fonts/lato-normal-italic.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-normal.woff +0 -0
- snappy/doc/_static/css/fonts/lato-normal.woff2 +0 -0
- snappy/doc/_static/css/theme.css +4 -0
- snappy/doc/_static/doctools.js +149 -0
- snappy/doc/_static/documentation_options.js +13 -0
- snappy/doc/_static/file.png +0 -0
- snappy/doc/_static/fonts/Lato/lato-bold.eot +0 -0
- snappy/doc/_static/fonts/Lato/lato-bold.ttf +0 -0
- snappy/doc/_static/fonts/Lato/lato-bold.woff +0 -0
- snappy/doc/_static/fonts/Lato/lato-bold.woff2 +0 -0
- snappy/doc/_static/fonts/Lato/lato-bolditalic.eot +0 -0
- snappy/doc/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
- snappy/doc/_static/fonts/Lato/lato-bolditalic.woff +0 -0
- snappy/doc/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
- snappy/doc/_static/fonts/Lato/lato-italic.eot +0 -0
- snappy/doc/_static/fonts/Lato/lato-italic.ttf +0 -0
- snappy/doc/_static/fonts/Lato/lato-italic.woff +0 -0
- snappy/doc/_static/fonts/Lato/lato-italic.woff2 +0 -0
- snappy/doc/_static/fonts/Lato/lato-regular.eot +0 -0
- snappy/doc/_static/fonts/Lato/lato-regular.ttf +0 -0
- snappy/doc/_static/fonts/Lato/lato-regular.woff +0 -0
- snappy/doc/_static/fonts/Lato/lato-regular.woff2 +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
- snappy/doc/_static/jquery.js +2 -0
- snappy/doc/_static/js/badge_only.js +1 -0
- snappy/doc/_static/js/theme.js +1 -0
- snappy/doc/_static/js/versions.js +228 -0
- snappy/doc/_static/language_data.js +192 -0
- snappy/doc/_static/minus.png +0 -0
- snappy/doc/_static/plus.png +0 -0
- snappy/doc/_static/pygments.css +75 -0
- snappy/doc/_static/searchtools.js +635 -0
- snappy/doc/_static/snappy_furo.css +33 -0
- snappy/doc/_static/snappy_sphinx_rtd_theme.css +42 -0
- snappy/doc/_static/sphinx_highlight.js +154 -0
- snappy/doc/additional_classes.html +1500 -0
- snappy/doc/bugs.html +132 -0
- snappy/doc/censuses.html +453 -0
- snappy/doc/credits.html +184 -0
- snappy/doc/development.html +385 -0
- snappy/doc/doc-latest/additional_classes.html +1500 -0
- snappy/doc/doc-latest/bugs.html +132 -0
- snappy/doc/doc-latest/censuses.html +453 -0
- snappy/doc/doc-latest/credits.html +184 -0
- snappy/doc/doc-latest/development.html +385 -0
- snappy/doc/doc-latest/genindex.html +1349 -0
- snappy/doc/doc-latest/index.html +287 -0
- snappy/doc/doc-latest/installing.html +346 -0
- snappy/doc/doc-latest/manifold.html +3632 -0
- snappy/doc/doc-latest/manifoldhp.html +180 -0
- snappy/doc/doc-latest/news.html +438 -0
- snappy/doc/doc-latest/objects.inv +0 -0
- snappy/doc/doc-latest/other.html +160 -0
- snappy/doc/doc-latest/platonic_census.html +376 -0
- snappy/doc/doc-latest/plink.html +210 -0
- snappy/doc/doc-latest/ptolemy.html +253 -0
- snappy/doc/doc-latest/ptolemy_classes.html +1144 -0
- snappy/doc/doc-latest/ptolemy_examples1.html +409 -0
- snappy/doc/doc-latest/ptolemy_examples2.html +471 -0
- snappy/doc/doc-latest/ptolemy_examples3.html +414 -0
- snappy/doc/doc-latest/ptolemy_examples4.html +195 -0
- snappy/doc/doc-latest/ptolemy_prelim.html +248 -0
- snappy/doc/doc-latest/py-modindex.html +165 -0
- snappy/doc/doc-latest/screenshots.html +141 -0
- snappy/doc/doc-latest/search.html +135 -0
- snappy/doc/doc-latest/searchindex.js +1 -0
- snappy/doc/doc-latest/snap.html +202 -0
- snappy/doc/doc-latest/snappy.html +181 -0
- snappy/doc/doc-latest/spherogram.html +1346 -0
- snappy/doc/doc-latest/todo.html +166 -0
- snappy/doc/doc-latest/triangulation.html +1676 -0
- snappy/doc/doc-latest/tutorial.html +159 -0
- snappy/doc/doc-latest/verify.html +330 -0
- snappy/doc/doc-latest/verify_internals.html +1235 -0
- snappy/doc/genindex.html +1349 -0
- snappy/doc/index.html +287 -0
- snappy/doc/installing.html +346 -0
- snappy/doc/manifold.html +3632 -0
- snappy/doc/manifoldhp.html +180 -0
- snappy/doc/news.html +438 -0
- snappy/doc/objects.inv +0 -0
- snappy/doc/other.html +160 -0
- snappy/doc/platonic_census.html +376 -0
- snappy/doc/plink.html +210 -0
- snappy/doc/ptolemy.html +253 -0
- snappy/doc/ptolemy_classes.html +1144 -0
- snappy/doc/ptolemy_examples1.html +409 -0
- snappy/doc/ptolemy_examples2.html +471 -0
- snappy/doc/ptolemy_examples3.html +414 -0
- snappy/doc/ptolemy_examples4.html +195 -0
- snappy/doc/ptolemy_prelim.html +248 -0
- snappy/doc/py-modindex.html +165 -0
- snappy/doc/screenshots.html +141 -0
- snappy/doc/search.html +135 -0
- snappy/doc/searchindex.js +1 -0
- snappy/doc/snap.html +202 -0
- snappy/doc/snappy.html +181 -0
- snappy/doc/spherogram.html +1346 -0
- snappy/doc/todo.html +166 -0
- snappy/doc/triangulation.html +1676 -0
- snappy/doc/tutorial.html +159 -0
- snappy/doc/verify.html +330 -0
- snappy/doc/verify_internals.html +1235 -0
- snappy/drilling/__init__.py +456 -0
- snappy/drilling/barycentric.py +103 -0
- snappy/drilling/constants.py +5 -0
- snappy/drilling/crush.py +270 -0
- snappy/drilling/cusps.py +125 -0
- snappy/drilling/debug.py +242 -0
- snappy/drilling/epsilons.py +6 -0
- snappy/drilling/exceptions.py +55 -0
- snappy/drilling/moves.py +620 -0
- snappy/drilling/peripheral_curves.py +210 -0
- snappy/drilling/perturb.py +188 -0
- snappy/drilling/shorten.py +36 -0
- snappy/drilling/subdivide.py +274 -0
- snappy/drilling/test.py +23 -0
- snappy/drilling/test_cases.py +132 -0
- snappy/drilling/tracing.py +351 -0
- snappy/exceptions.py +26 -0
- snappy/export_stl.py +120 -0
- snappy/exterior_to_link/__init__.py +2 -0
- snappy/exterior_to_link/barycentric_geometry.py +463 -0
- snappy/exterior_to_link/exceptions.py +6 -0
- snappy/exterior_to_link/geodesic_map.json +14408 -0
- snappy/exterior_to_link/hyp_utils.py +112 -0
- snappy/exterior_to_link/link_projection.py +323 -0
- snappy/exterior_to_link/main.py +198 -0
- snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
- snappy/exterior_to_link/mcomplex_with_link.py +687 -0
- snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
- snappy/exterior_to_link/pl_utils.py +491 -0
- snappy/exterior_to_link/put_in_S3.py +156 -0
- snappy/exterior_to_link/rational_linear_algebra.py +130 -0
- snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
- snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
- snappy/exterior_to_link/stored_moves.py +475 -0
- snappy/exterior_to_link/test.py +31 -0
- snappy/filedialog.py +28 -0
- snappy/geometric_structure/__init__.py +212 -0
- snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
- snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +691 -0
- snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +480 -0
- snappy/geometric_structure/cusp_neighborhood/exceptions.py +41 -0
- snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +294 -0
- snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +156 -0
- snappy/geometric_structure/cusp_neighborhood/vertices.py +35 -0
- snappy/geometric_structure/geodesic/__init__.py +0 -0
- snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
- snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
- snappy/geometric_structure/geodesic/canonical_representatives.py +52 -0
- snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
- snappy/geometric_structure/geodesic/constants.py +6 -0
- snappy/geometric_structure/geodesic/exceptions.py +22 -0
- snappy/geometric_structure/geodesic/fixed_points.py +106 -0
- snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
- snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
- snappy/geometric_structure/geodesic/line.py +30 -0
- snappy/geometric_structure/geodesic/multiplicity.py +127 -0
- snappy/geometric_structure/geodesic/tiles_for_geodesic.py +128 -0
- snappy/geometric_structure/test.py +22 -0
- snappy/gui.py +121 -0
- snappy/horoviewer.py +443 -0
- snappy/hyperboloid/__init__.py +212 -0
- snappy/hyperboloid/distances.py +259 -0
- snappy/hyperboloid/horoball.py +19 -0
- snappy/hyperboloid/line.py +35 -0
- snappy/hyperboloid/point.py +9 -0
- snappy/hyperboloid/triangle.py +29 -0
- snappy/info_icon.gif +0 -0
- snappy/infowindow.py +65 -0
- snappy/isometry_signature.py +389 -0
- snappy/len_spec/__init__.py +609 -0
- snappy/len_spec/geodesic_info.py +129 -0
- snappy/len_spec/geodesic_key_info_dict.py +116 -0
- snappy/len_spec/geodesic_piece.py +146 -0
- snappy/len_spec/geometric_structure.py +182 -0
- snappy/len_spec/geometry.py +136 -0
- snappy/len_spec/length_spectrum_geodesic_info.py +185 -0
- snappy/len_spec/spine.py +128 -0
- snappy/len_spec/test.py +24 -0
- snappy/len_spec/test_cases.py +69 -0
- snappy/len_spec/tile.py +276 -0
- snappy/len_spec/word.py +86 -0
- snappy/manifolds/HTWKnots/alternating.gz +0 -0
- snappy/manifolds/HTWKnots/nonalternating.gz +0 -0
- snappy/manifolds/__init__.py +3 -0
- snappy/margulis/__init__.py +332 -0
- snappy/margulis/cusp_neighborhood_neighborhood.py +66 -0
- snappy/margulis/geodesic_neighborhood.py +152 -0
- snappy/margulis/margulis_info.py +21 -0
- snappy/margulis/mu_from_neighborhood_pair.py +175 -0
- snappy/margulis/neighborhood.py +29 -0
- snappy/margulis/test.py +22 -0
- snappy/math_basics.py +187 -0
- snappy/matrix.py +525 -0
- snappy/number.py +657 -0
- snappy/numeric_output_checker.py +345 -0
- snappy/pari.py +41 -0
- snappy/phone_home.py +57 -0
- snappy/polyviewer.py +259 -0
- snappy/ptolemy/__init__.py +17 -0
- snappy/ptolemy/component.py +103 -0
- snappy/ptolemy/coordinates.py +2290 -0
- snappy/ptolemy/fieldExtensions.py +153 -0
- snappy/ptolemy/findLoops.py +473 -0
- snappy/ptolemy/geometricRep.py +59 -0
- snappy/ptolemy/homology.py +165 -0
- snappy/ptolemy/magma/default.magma_template +229 -0
- snappy/ptolemy/magma/radicalsOfPrimaryDecomposition.magma_template +79 -0
- snappy/ptolemy/manifoldMethods.py +395 -0
- snappy/ptolemy/matrix.py +350 -0
- snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +113 -0
- snappy/ptolemy/polynomial.py +856 -0
- snappy/ptolemy/processComponents.py +173 -0
- snappy/ptolemy/processFileBase.py +247 -0
- snappy/ptolemy/processFileDispatch.py +46 -0
- snappy/ptolemy/processMagmaFile.py +392 -0
- snappy/ptolemy/processRurFile.py +150 -0
- snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +102 -0
- snappy/ptolemy/ptolemyObstructionClass.py +64 -0
- snappy/ptolemy/ptolemyVariety.py +995 -0
- snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +140 -0
- snappy/ptolemy/reginaWrapper.py +698 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/rur.py +545 -0
- snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +277 -0
- snappy/ptolemy/test.py +1126 -0
- snappy/ptolemy/testing_files/3_1__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/3_1__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl4_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl4_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/5_2__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/5_2__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c0.magma_out +95 -0
- snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c1.magma_out +95 -0
- snappy/ptolemy/testing_files/m015__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c4.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c5.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c6.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c7.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/s000__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/s000__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/t00000__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/t00000__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m004__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m004__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_rur/m052__sl3_c0.rur.bz2 +0 -0
- snappy/ptolemy/utilities.py +236 -0
- snappy/raytracing/__init__.py +64 -0
- snappy/raytracing/additional_horospheres.py +64 -0
- snappy/raytracing/additional_len_spec_choices.py +63 -0
- snappy/raytracing/cohomology_fractal.py +197 -0
- snappy/raytracing/eyeball.py +124 -0
- snappy/raytracing/finite_raytracing_data.py +237 -0
- snappy/raytracing/finite_viewer.py +590 -0
- snappy/raytracing/geodesic_tube_info.py +174 -0
- snappy/raytracing/geodesics.py +246 -0
- snappy/raytracing/geodesics_window.py +258 -0
- snappy/raytracing/gui_utilities.py +293 -0
- snappy/raytracing/hyperboloid_navigation.py +556 -0
- snappy/raytracing/hyperboloid_utilities.py +234 -0
- snappy/raytracing/ideal_raytracing_data.py +592 -0
- snappy/raytracing/inside_viewer.py +974 -0
- snappy/raytracing/pack.py +22 -0
- snappy/raytracing/raytracing_data.py +126 -0
- snappy/raytracing/raytracing_view.py +454 -0
- snappy/raytracing/shaders/Eye.png +0 -0
- snappy/raytracing/shaders/NonGeometric.png +0 -0
- snappy/raytracing/shaders/__init__.py +101 -0
- snappy/raytracing/shaders/fragment.glsl +1744 -0
- snappy/raytracing/test.py +29 -0
- snappy/raytracing/tooltip.py +146 -0
- snappy/raytracing/upper_halfspace_utilities.py +98 -0
- snappy/raytracing/view_scale_controller.py +98 -0
- snappy/raytracing/zoom_slider/__init__.py +263 -0
- snappy/raytracing/zoom_slider/inward.png +0 -0
- snappy/raytracing/zoom_slider/inward18.png +0 -0
- snappy/raytracing/zoom_slider/outward.png +0 -0
- snappy/raytracing/zoom_slider/outward18.png +0 -0
- snappy/raytracing/zoom_slider/test.py +20 -0
- snappy/sage_helper.py +119 -0
- snappy/settings.py +407 -0
- snappy/shell.py +53 -0
- snappy/snap/__init__.py +117 -0
- snappy/snap/character_varieties.py +375 -0
- snappy/snap/find_field.py +372 -0
- snappy/snap/fox_milnor.py +271 -0
- snappy/snap/fundamental_polyhedron.py +569 -0
- snappy/snap/generators.py +39 -0
- snappy/snap/interval_reps.py +81 -0
- snappy/snap/kernel_structures.py +128 -0
- snappy/snap/mcomplex_base.py +18 -0
- snappy/snap/nsagetools.py +716 -0
- snappy/snap/peripheral/__init__.py +1 -0
- snappy/snap/peripheral/dual_cellulation.py +219 -0
- snappy/snap/peripheral/link.py +127 -0
- snappy/snap/peripheral/peripheral.py +159 -0
- snappy/snap/peripheral/surface.py +522 -0
- snappy/snap/peripheral/test.py +35 -0
- snappy/snap/polished_reps.py +335 -0
- snappy/snap/shapes.py +152 -0
- snappy/snap/slice_obs_HKL/__init__.py +194 -0
- snappy/snap/slice_obs_HKL/basics.py +236 -0
- snappy/snap/slice_obs_HKL/direct.py +217 -0
- snappy/snap/slice_obs_HKL/poly_norm.py +212 -0
- snappy/snap/slice_obs_HKL/rep_theory.py +424 -0
- snappy/snap/t3mlite/__init__.py +2 -0
- snappy/snap/t3mlite/arrow.py +243 -0
- snappy/snap/t3mlite/corner.py +22 -0
- snappy/snap/t3mlite/edge.py +172 -0
- snappy/snap/t3mlite/face.py +37 -0
- snappy/snap/t3mlite/files.py +211 -0
- snappy/snap/t3mlite/homology.py +53 -0
- snappy/snap/t3mlite/linalg.py +419 -0
- snappy/snap/t3mlite/mcomplex.py +1499 -0
- snappy/snap/t3mlite/perm4.py +320 -0
- snappy/snap/t3mlite/setup.py +12 -0
- snappy/snap/t3mlite/simplex.py +199 -0
- snappy/snap/t3mlite/spun.py +297 -0
- snappy/snap/t3mlite/surface.py +519 -0
- snappy/snap/t3mlite/test.py +20 -0
- snappy/snap/t3mlite/test_vs_regina.py +86 -0
- snappy/snap/t3mlite/tetrahedron.py +109 -0
- snappy/snap/t3mlite/vertex.py +42 -0
- snappy/snap/test.py +139 -0
- snappy/snap/utilities.py +288 -0
- snappy/test.py +213 -0
- snappy/test_cases.py +263 -0
- snappy/testing.py +131 -0
- snappy/tiling/__init__.py +2 -0
- snappy/tiling/dict_based_set.py +79 -0
- snappy/tiling/floor.py +49 -0
- snappy/tiling/hyperboloid_dict.py +54 -0
- snappy/tiling/iter_utils.py +78 -0
- snappy/tiling/lifted_tetrahedron.py +22 -0
- snappy/tiling/lifted_tetrahedron_set.py +54 -0
- snappy/tiling/quotient_dict.py +70 -0
- snappy/tiling/real_hash_dict.py +164 -0
- snappy/tiling/test.py +23 -0
- snappy/tiling/tile.py +224 -0
- snappy/tiling/triangle.py +33 -0
- snappy/tkterminal.py +920 -0
- snappy/twister/__init__.py +20 -0
- snappy/twister/main.py +646 -0
- snappy/twister/surfaces/S_0_1 +3 -0
- snappy/twister/surfaces/S_0_2 +3 -0
- snappy/twister/surfaces/S_0_4 +7 -0
- snappy/twister/surfaces/S_0_4_Lantern +8 -0
- snappy/twister/surfaces/S_1 +3 -0
- snappy/twister/surfaces/S_1_1 +4 -0
- snappy/twister/surfaces/S_1_2 +5 -0
- snappy/twister/surfaces/S_1_2_5 +6 -0
- snappy/twister/surfaces/S_2 +6 -0
- snappy/twister/surfaces/S_2_1 +8 -0
- snappy/twister/surfaces/S_2_heeg +10 -0
- snappy/twister/surfaces/S_3 +8 -0
- snappy/twister/surfaces/S_3_1 +10 -0
- snappy/twister/surfaces/S_4_1 +12 -0
- snappy/twister/surfaces/S_5_1 +14 -0
- snappy/twister/surfaces/heeg_fig8 +9 -0
- snappy/twister/twister_core.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/upper_halfspace/__init__.py +146 -0
- snappy/upper_halfspace/ideal_point.py +29 -0
- snappy/verify/__init__.py +13 -0
- snappy/verify/canonical.py +542 -0
- snappy/verify/complex_volume/__init__.py +18 -0
- snappy/verify/complex_volume/adjust_torsion.py +86 -0
- snappy/verify/complex_volume/closed.py +168 -0
- snappy/verify/complex_volume/compute_ptolemys.py +90 -0
- snappy/verify/complex_volume/cusped.py +56 -0
- snappy/verify/complex_volume/extended_bloch.py +201 -0
- snappy/verify/cusp_translations.py +85 -0
- snappy/verify/edge_equations.py +80 -0
- snappy/verify/exceptions.py +254 -0
- snappy/verify/hyperbolicity.py +224 -0
- snappy/verify/interval_newton_shapes_engine.py +523 -0
- snappy/verify/interval_tree.py +400 -0
- snappy/verify/krawczyk_shapes_engine.py +518 -0
- snappy/verify/real_algebra.py +286 -0
- snappy/verify/shapes.py +25 -0
- snappy/verify/square_extensions.py +1005 -0
- snappy/verify/test.py +72 -0
- snappy/verify/volume.py +128 -0
- snappy/version.py +2 -0
- snappy-3.3.dist-info/METADATA +58 -0
- snappy-3.3.dist-info/RECORD +541 -0
- snappy-3.3.dist-info/WHEEL +6 -0
- snappy-3.3.dist-info/entry_points.txt +2 -0
- snappy-3.3.dist-info/top_level.txt +28 -0
snappy/cache.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class SnapPyCache(dict):
|
|
2
|
+
"""
|
|
3
|
+
Implementation of a simple cache used by the Manifold and Triangulation
|
|
4
|
+
to save the results of methods which require a significant amount of
|
|
5
|
+
computation.
|
|
6
|
+
|
|
7
|
+
This cache uses the tuple (method.__name, args, kwargs) as its key.
|
|
8
|
+
"""
|
|
9
|
+
debug = False
|
|
10
|
+
_clear = dict.clear
|
|
11
|
+
|
|
12
|
+
def save(self, answer, method_name, *args, **kwargs):
|
|
13
|
+
self[(method_name, args, tuple(kwargs.items()))] = answer
|
|
14
|
+
return answer
|
|
15
|
+
|
|
16
|
+
def lookup(self, method_name, *args, **kwargs):
|
|
17
|
+
return self[(method_name, args, tuple(kwargs.items()))]
|
|
18
|
+
|
|
19
|
+
def clear(self, key=None, message=''):
|
|
20
|
+
if self.debug:
|
|
21
|
+
print('_clear_cache: %s' % message)
|
|
22
|
+
if key is None:
|
|
23
|
+
self._clear()
|
|
24
|
+
else:
|
|
25
|
+
self.pop(key)
|
snappy/canonical.py
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
from . import verify
|
|
2
|
+
from . import Triangulation, TriangulationHP, Manifold, ManifoldHP
|
|
3
|
+
|
|
4
|
+
from typing import Optional, Union, Sequence, Tuple
|
|
5
|
+
|
|
6
|
+
__all__ = ['canonical_retriangulation', 'canonical_retriangulation_hp']
|
|
7
|
+
|
|
8
|
+
def _canonical_retriangulation(
|
|
9
|
+
manifold : Union[Manifold, ManifoldHP],
|
|
10
|
+
verified : bool,
|
|
11
|
+
interval_bits_precs : Sequence[int],
|
|
12
|
+
exact_bits_prec_and_degrees : Sequence[Tuple[int, int]],
|
|
13
|
+
verbose : bool) -> Union[Triangulation, TriangulationHP,
|
|
14
|
+
Manifold, ManifoldHP]:
|
|
15
|
+
"""
|
|
16
|
+
Returns a triangulation canonically associated to the hyperbolic manifold.
|
|
17
|
+
That is, the triangulation is (up to combinatorial isomorphism relabeling
|
|
18
|
+
the tetrahedra and vertices) completely determined by the isometry type of
|
|
19
|
+
the hyperbolic manifold.
|
|
20
|
+
|
|
21
|
+
Manifolds with incomplete cusps are rejected (unlike in the case of
|
|
22
|
+
:meth:`isometry_signature <snappy.Manifold.isometry_signature>`).
|
|
23
|
+
|
|
24
|
+
We now describe the canonical retriangulation. If all cells of
|
|
25
|
+
the canonical cell decomposition (defined by `Epstein and Penner '88
|
|
26
|
+
<https://projecteuclid.org/euclid.jdg/1214441650>`_) are tetrahedral,
|
|
27
|
+
:meth:`canonical_retriangulation <Manifold.canonical_retriangulation>`
|
|
28
|
+
simply returns that ideal triangulation as a
|
|
29
|
+
:class:`Manifold <snappy.Manifold>`. Here is an example::
|
|
30
|
+
|
|
31
|
+
>>> M = Manifold("m015")
|
|
32
|
+
>>> K = M.canonical_retriangulation()
|
|
33
|
+
>>> K.has_finite_vertices()
|
|
34
|
+
False
|
|
35
|
+
>>> K.solution_type()
|
|
36
|
+
'all tetrahedra positively oriented'
|
|
37
|
+
|
|
38
|
+
If there are non-tetrahedral cells,
|
|
39
|
+
:meth:`canonical_retriangulation <Manifold.canonical_retriangulation>`
|
|
40
|
+
subdivides the canonical cell decomposition. It introduces a finite vertex
|
|
41
|
+
for each canonical cell resulting in a
|
|
42
|
+
:class:`Triangulation <snappy.Triangulation>`. Here is an example where the
|
|
43
|
+
canonical cell is a cube::
|
|
44
|
+
|
|
45
|
+
>>> M = Manifold("m412")
|
|
46
|
+
>>> K = M.canonical_retriangulation()
|
|
47
|
+
>>> K.has_finite_vertices()
|
|
48
|
+
True
|
|
49
|
+
|
|
50
|
+
The canonical retriangulation can be used to find the symmetries of a
|
|
51
|
+
single manifold. It also can compute the isometries between two
|
|
52
|
+
manifolds. We do this using
|
|
53
|
+
:meth:`isomorphisms_to <snappy.Triangulation.isomorphisms_to>`::
|
|
54
|
+
|
|
55
|
+
>>> M = Manifold("5_2").canonical_retriangulation()
|
|
56
|
+
>>> N = Manifold("m015").canonical_retriangulation()
|
|
57
|
+
>>> M.isomorphisms_to(M) #doctest: +ELLIPSIS
|
|
58
|
+
[0 -> 0
|
|
59
|
+
[1 0]
|
|
60
|
+
[0 1]
|
|
61
|
+
...
|
|
62
|
+
>>> M.isomorphisms_to(N) #doctest: +ELLIPSIS
|
|
63
|
+
[0 -> 0
|
|
64
|
+
[-1 2]
|
|
65
|
+
[ 0 -1]
|
|
66
|
+
...
|
|
67
|
+
|
|
68
|
+
The canonical retriangulation is also the basis for the
|
|
69
|
+
:meth:`isometry_signature <snappy.Manifold.isometry_signature>`.
|
|
70
|
+
|
|
71
|
+
**Subdivision**
|
|
72
|
+
|
|
73
|
+
If the canonical cell decomposition has a non-tetrahedral cell, the method
|
|
74
|
+
subdivides. You can think of the subdivision in either of the following
|
|
75
|
+
(equivalent) ways:
|
|
76
|
+
|
|
77
|
+
- A coarsening of the barycentric subdivision with only a quarter of the
|
|
78
|
+
number of tetrahedra. That is, take the barycentric subdivision and
|
|
79
|
+
merge the four tetrahedra adjacent to a barycentric edge connecting
|
|
80
|
+
an edge midpoint to a face midpoint.
|
|
81
|
+
- Taking the double suspension of each face (which is an ideal n-gon)
|
|
82
|
+
about the centers of the two neighboring 3-cells. Then split each
|
|
83
|
+
such topological "lens" into n tetrahedra along its central axis.
|
|
84
|
+
|
|
85
|
+
**Verified computations**
|
|
86
|
+
|
|
87
|
+
While the canonical retriangulation is combinatorial, some intermediate
|
|
88
|
+
computations are numerical. Thus, if :attr:`verified = False`,
|
|
89
|
+
floating-point issues can arise.
|
|
90
|
+
(Arguably this gave rise to a mistake in the
|
|
91
|
+
non-orientable census. ``x101`` and ``x103`` were later identified as
|
|
92
|
+
the same by `Burton '14 <http://arxiv.org/abs/1311.7615>`_.)
|
|
93
|
+
|
|
94
|
+
The method can be made :ref:`verified <verify-primer>` by passing
|
|
95
|
+
:attr:`verified = True`::
|
|
96
|
+
|
|
97
|
+
sage: M = Manifold("v2986")
|
|
98
|
+
sage: K = M.canonical_retriangulation(verified = True)
|
|
99
|
+
sage: K.has_finite_vertices() # Cell decomposition verified to be tetrahedral
|
|
100
|
+
False
|
|
101
|
+
sage: K.triangulation_isosig(decorated=False) # Verified isometry signature.
|
|
102
|
+
'jvLALQQdeefgihihiokcmmwwswg'
|
|
103
|
+
sage: len(K.isomorphisms_to(K)) # Verified to have no (non-trivial) symmetries.
|
|
104
|
+
1
|
|
105
|
+
|
|
106
|
+
Interval arithmetic can only be used to verify the canonical cell decomposition
|
|
107
|
+
if all cells are tetrahedral. For non-tetrahedral cells, the method
|
|
108
|
+
automatically switches to
|
|
109
|
+
exact methods to verify the canonical cell decomposition. That is, it uses
|
|
110
|
+
snap-like methods
|
|
111
|
+
(`LLL-algorithm <http://en.wikipedia.org/wiki/Lenstra%E2%80%93Lenstra%E2%80%93Lov%C3%A1sz_lattice_basis_reduction_algorithm>`_)
|
|
112
|
+
to guess a representation of the
|
|
113
|
+
shapes in the shape field. It then uses exact arithmetic to verify the
|
|
114
|
+
shapes form a valid geometric structure and compute the necessary tilts
|
|
115
|
+
to verify the canonical cell decomposition. Note that this can take a
|
|
116
|
+
long time!
|
|
117
|
+
|
|
118
|
+
Here is an example where exact methods are used::
|
|
119
|
+
|
|
120
|
+
sage: M = Manifold("m412")
|
|
121
|
+
sage: K = M.canonical_retriangulation(verified = True)
|
|
122
|
+
sage: K.has_finite_vertices() # Has non-tetrahedral cell
|
|
123
|
+
True
|
|
124
|
+
|
|
125
|
+
If the canonical retriangulation cannot be verified, an exception will be
|
|
126
|
+
raised. (Note that this is new (and safer) in Version 3.2. Prior to that
|
|
127
|
+
version, :meth:`Manifold.canonical_retriangulation` could return ``None``
|
|
128
|
+
instead.)
|
|
129
|
+
|
|
130
|
+
Here is an example where we skip the (potentially lengthy) exact methods
|
|
131
|
+
needed to verify a non-tetrahedral cell. The method fails (early
|
|
132
|
+
and with an exception) since the cells are actually tetrahedral::
|
|
133
|
+
|
|
134
|
+
sage: M = Manifold("m412")
|
|
135
|
+
sage: K = M.canonical_retriangulation(verified = True, exact_bits_prec_and_degrees = []) # doctest: +ELLIPSIS +IGNORE_EXCEPTION_DETAIL
|
|
136
|
+
Traceback (most recent call last):
|
|
137
|
+
...
|
|
138
|
+
snappy.verify.exceptions.TiltInequalityNumericalVerifyError: Numerical verification that tilt is negative has failed: ... < 0
|
|
139
|
+
|
|
140
|
+
:param verified:
|
|
141
|
+
Use :ref:`verified computation <verify-primer>`.
|
|
142
|
+
:param interval_bits_precs:
|
|
143
|
+
Only relevant if :attr:`verified = True`.
|
|
144
|
+
A list of (increasing) precisions used to try to
|
|
145
|
+
certify the canonical cell decomposition using intervals. Each
|
|
146
|
+
precision is tried until we succeed. If none succeeded, we move on
|
|
147
|
+
to exact methods.
|
|
148
|
+
:param exact_bits_prec_and_degrees:
|
|
149
|
+
Only relevant if :attr:`verified = True`.
|
|
150
|
+
A list of pairs (precision, max degree) used when the
|
|
151
|
+
LLL-algorithm is trying to find the defining
|
|
152
|
+
polynomial of the shape field with
|
|
153
|
+
``ListOfApproximateAlgebraicNumbers.find_field``.
|
|
154
|
+
Each pair is tried until we succeed.
|
|
155
|
+
:param verbose:
|
|
156
|
+
Print information about the methods tried to compute and verify the
|
|
157
|
+
canonical retriangulation.
|
|
158
|
+
:return:
|
|
159
|
+
If the canonical cell decomposition exists entirely of
|
|
160
|
+
(hyperbolic ideal) tetrahedra, a :class:`Manifold` with those
|
|
161
|
+
tetrahedra.
|
|
162
|
+
Otherwise, a :class:`Triangulation` that is a subdivision of the
|
|
163
|
+
canonical cell decomposition.
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
# More information on the canonical retriangulation can be found in the
|
|
167
|
+
# SnapPea kernel ``canonize_part_2.c`` and in Section 3.1 of
|
|
168
|
+
# `Fominykh, Garoufalidis, Goerner, Tarkaev, Vesnin <http://arxiv.org/abs/1502.00383>`_.
|
|
169
|
+
|
|
170
|
+
if not all(manifold.cusp_info('complete?')):
|
|
171
|
+
# It is unclear what to do when there are filling coefficients.
|
|
172
|
+
# The SnapPea kernel ignores them and uses the complete structure
|
|
173
|
+
# to compute the canonical retriangulation.
|
|
174
|
+
#
|
|
175
|
+
# That makes sense to, e.g., compute a canonical representation
|
|
176
|
+
# of a surgery diagram.
|
|
177
|
+
#
|
|
178
|
+
# In other situations, it makes perfectly sense to fill the cusps
|
|
179
|
+
# instead. That is, e.g., what the isometry_signature does.
|
|
180
|
+
#
|
|
181
|
+
# Since it is ambiguous, I decided to simply reject it here.
|
|
182
|
+
#
|
|
183
|
+
# It is easy enough for a user to either call fill_triangulation
|
|
184
|
+
# or to save the coefficients and unfill all cusps.
|
|
185
|
+
#
|
|
186
|
+
raise ValueError(
|
|
187
|
+
'Canonical retriangulation needs all cusps to be complete.')
|
|
188
|
+
|
|
189
|
+
if verified:
|
|
190
|
+
# verified_canonical_retriangulation has code to check
|
|
191
|
+
# for incomplete cusps and fill them that never gets
|
|
192
|
+
# executed because of the above "if"
|
|
193
|
+
return verify.verified_canonical_retriangulation(
|
|
194
|
+
manifold,
|
|
195
|
+
interval_bits_precs=interval_bits_precs,
|
|
196
|
+
exact_bits_prec_and_degrees=exact_bits_prec_and_degrees,
|
|
197
|
+
verbose=verbose)
|
|
198
|
+
else:
|
|
199
|
+
# Note that the SnapPea kernel actually ignores Dehn-fillings
|
|
200
|
+
# when computing the canonical retriangulation.
|
|
201
|
+
if not all(manifold.cusp_info('complete?')):
|
|
202
|
+
# Never executed because of above "if".
|
|
203
|
+
manifold = manifold.filled_triangulation()
|
|
204
|
+
if not all(manifold.cusp_info('complete?')):
|
|
205
|
+
raise ValueError(
|
|
206
|
+
'Could not compute filled triangulation. '
|
|
207
|
+
'Are the filling coefficients co-prime integers?')
|
|
208
|
+
|
|
209
|
+
K = manifold._canonical_retriangulation()
|
|
210
|
+
if K.has_finite_vertices():
|
|
211
|
+
return K
|
|
212
|
+
else:
|
|
213
|
+
if isinstance(manifold, ManifoldHP):
|
|
214
|
+
return ManifoldHP(K)
|
|
215
|
+
else:
|
|
216
|
+
return Manifold(K)
|
|
217
|
+
|
|
218
|
+
# Wraps _canonical_retriangulation to have the correct return type
|
|
219
|
+
def canonical_retriangulation(
|
|
220
|
+
manifold : Manifold,
|
|
221
|
+
verified : bool = False,
|
|
222
|
+
interval_bits_precs : Sequence[int] = verify.default_interval_bits_precs,
|
|
223
|
+
exact_bits_prec_and_degrees : Sequence[Tuple[int, int]] = verify.default_exact_bits_prec_and_degrees,
|
|
224
|
+
verbose : bool = False) -> Union[Triangulation, Manifold]:
|
|
225
|
+
return _canonical_retriangulation(
|
|
226
|
+
manifold,
|
|
227
|
+
verified = verified,
|
|
228
|
+
interval_bits_precs = interval_bits_precs,
|
|
229
|
+
exact_bits_prec_and_degrees = exact_bits_prec_and_degrees,
|
|
230
|
+
verbose = verbose)
|
|
231
|
+
canonical_retriangulation.__doc__ = _canonical_retriangulation.__doc__
|
|
232
|
+
|
|
233
|
+
# Wraps _canonical_retriangulation to have the correct return type
|
|
234
|
+
def canonical_retriangulation_hp(
|
|
235
|
+
manifold : ManifoldHP,
|
|
236
|
+
verified : bool = False,
|
|
237
|
+
interval_bits_precs : Sequence[int] = verify.default_interval_bits_precs,
|
|
238
|
+
exact_bits_prec_and_degrees : Sequence[Tuple[int, int]] = verify.default_exact_bits_prec_and_degrees,
|
|
239
|
+
verbose : bool = False) -> Union[TriangulationHP, ManifoldHP]:
|
|
240
|
+
return _canonical_retriangulation(
|
|
241
|
+
manifold,
|
|
242
|
+
verified = verified,
|
|
243
|
+
interval_bits_precs = interval_bits_precs,
|
|
244
|
+
exact_bits_prec_and_degrees = exact_bits_prec_and_degrees,
|
|
245
|
+
verbose = verbose)
|
|
246
|
+
canonical_retriangulation_hp.__doc__ = _canonical_retriangulation.__doc__
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
|
snappy/cusps/__init__.py
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Computing data about cusps such as cusp matrix, shape, translations
|
|
3
|
+
and exceptional slopes.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from ..geometric_structure.cusp_neighborhood.complex_cusp_cross_section import ComplexCuspCrossSection
|
|
7
|
+
from ..geometric_structure.cusp_neighborhood.exceptions import IncompleteCuspError
|
|
8
|
+
from ..verify.shapes import compute_hyperbolic_shapes
|
|
9
|
+
from ..exceptions import NonorientableManifoldError
|
|
10
|
+
from . import short_slopes_for_cusp
|
|
11
|
+
from . import cusp_areas_from_matrix
|
|
12
|
+
|
|
13
|
+
from typing import Optional, List
|
|
14
|
+
|
|
15
|
+
def compute_cusp_shapes(manifold, verified, bits_prec=None):
|
|
16
|
+
"""
|
|
17
|
+
Compute cusp shapes. Following the SnapPea kernel convention,
|
|
18
|
+
it returns the conjugate of the quotient of the translations
|
|
19
|
+
corresponding to the longitude and meridian for each cusp.
|
|
20
|
+
|
|
21
|
+
>>> M = Manifold('s843')
|
|
22
|
+
>>> M.cusp_info('shape', bits_prec = 100) # doctest: +NUMERIC21
|
|
23
|
+
[0.46738227586341496791816972792 + 1.1903600506742881207098973751*I, 0.084187324414612694374797271558 + 1.0506945576790020048456757228*I]
|
|
24
|
+
|
|
25
|
+
sage: M = Manifold('s843')
|
|
26
|
+
sage: M.cusp_info('shape', verified = True) # doctest: +NUMERIC9
|
|
27
|
+
[0.46738227587? + 1.19036005068?*I, 0.0841873244146? + 1.0506945576790?*I]
|
|
28
|
+
|
|
29
|
+
sage: M.cusp_info('shape', verified = True, bits_prec = 100) # doctest: +NUMERIC21
|
|
30
|
+
[0.4673822758634149679181698? + 1.1903600506742881207098974?*I, 0.084187324414612694374797272? + 1.050694557679002004845675723?*I]
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
if not manifold.is_orientable():
|
|
34
|
+
raise NonorientableManifoldError(manifold)
|
|
35
|
+
|
|
36
|
+
for cusp_info in manifold.cusp_info():
|
|
37
|
+
if not cusp_info['complete?']:
|
|
38
|
+
raise IncompleteCuspError(manifold)
|
|
39
|
+
|
|
40
|
+
shapes = compute_hyperbolic_shapes(
|
|
41
|
+
manifold, verified=verified, bits_prec=bits_prec)
|
|
42
|
+
|
|
43
|
+
# Compute cusp cross section
|
|
44
|
+
c = ComplexCuspCrossSection.fromManifoldAndShapes(manifold, shapes)
|
|
45
|
+
|
|
46
|
+
# Compute shape
|
|
47
|
+
return c.cusp_shapes()
|
|
48
|
+
|
|
49
|
+
def cusp_areas(manifold,
|
|
50
|
+
policy : str = 'unbiased',
|
|
51
|
+
method : str = 'maximal',
|
|
52
|
+
verified : bool = False,
|
|
53
|
+
bits_prec : Optional[int] = None,
|
|
54
|
+
first_cusps : List[int] = []):
|
|
55
|
+
"""
|
|
56
|
+
Returns a list of areas, one for each cusp. The cusp neighborhoods
|
|
57
|
+
defined by these areas are embedded and disjoint. Furthermore, these
|
|
58
|
+
neighborhoods are maximal in that they fail to be embedded or
|
|
59
|
+
disjoint if any cusp neighborhood is enlarged (unless :attr:`method`
|
|
60
|
+
is set to a value different from the default).
|
|
61
|
+
|
|
62
|
+
There are different policies how these cusp neighborhoods are found.
|
|
63
|
+
|
|
64
|
+
The default :attr:`policy` is ``unbiased``. This means that the
|
|
65
|
+
cusp neighborhoods are blown up simultaneously and a cusp neighborhood
|
|
66
|
+
stops growing when it touches any cusp neighborhood including itself::
|
|
67
|
+
|
|
68
|
+
>>> M = Manifold("s776")
|
|
69
|
+
>>> M.cusp_areas() # doctest: +NUMERIC9
|
|
70
|
+
[2.64575131106459, 2.64575131106459, 2.64575131106459]
|
|
71
|
+
|
|
72
|
+
Alternatively, :attr:`policy='greedy'` can be specified. This means
|
|
73
|
+
that the first cusp neighborhood is blown up until it touches itself,
|
|
74
|
+
then the second cusp neighborhood is blown up until it touches itself
|
|
75
|
+
or the first cusp neighborhood, and so on::
|
|
76
|
+
|
|
77
|
+
>>> M.cusp_areas(policy='greedy') # doctest: +NUMERIC9
|
|
78
|
+
[5.29150262212918, 1.32287565553230, 1.32287565553229]
|
|
79
|
+
|
|
80
|
+
Use :attr:`first_cusps` to specify the order in which the cusp
|
|
81
|
+
neighborhoods are blown up::
|
|
82
|
+
|
|
83
|
+
>>> M.cusp_areas(policy='greedy', first_cusps=[1,0,2]) # doctest: +NUMERIC9
|
|
84
|
+
[1.32287565553230, 5.29150262212918, 1.32287565553229]
|
|
85
|
+
|
|
86
|
+
An incomplete list can be given to :attr:`first_cusps`. In this case,
|
|
87
|
+
the list is automatically completed by appending the remaining cusps in
|
|
88
|
+
order. Thus, the above call is equivalent to::
|
|
89
|
+
|
|
90
|
+
>>> M.cusp_areas(policy='greedy', first_cusps=[1]) # doctest: +NUMERIC9
|
|
91
|
+
[1.32287565553230, 5.29150262212918, 1.32287565553229]
|
|
92
|
+
|
|
93
|
+
Under the hood, this method is using
|
|
94
|
+
:meth:`~snappy.Manifold.cusp_area_matrix`.
|
|
95
|
+
|
|
96
|
+
**Verified computation**
|
|
97
|
+
|
|
98
|
+
If :attr:`verified = False`, floating-point issues can arise resulting in
|
|
99
|
+
incorrect values. The method can be made
|
|
100
|
+
:ref:`verified <verify-primer>` by passing :attr:`verified = True`::
|
|
101
|
+
|
|
102
|
+
sage: M=Manifold("s776")
|
|
103
|
+
sage: M.cusp_areas(verified=True) # doctest: +NUMERIC9
|
|
104
|
+
[2.64575131107?, 2.64575131107?, 2.64575131107?]
|
|
105
|
+
|
|
106
|
+
:param verified:
|
|
107
|
+
Use :ref:`verified computation <verify-primer>`.
|
|
108
|
+
:param bits_prec:
|
|
109
|
+
Precision used for computation. Increase if computation
|
|
110
|
+
did not succeed or a more precise result is desired.
|
|
111
|
+
:param method:
|
|
112
|
+
Passed to :meth:`~snappy.Manifold.cusp_area_matrix`. If set
|
|
113
|
+
to a value different from the default ``maximal``, the cusp
|
|
114
|
+
neighborhoods stop growing when the corresponding value
|
|
115
|
+
in the computed cusp area matrix is exceeded. At this point,
|
|
116
|
+
the cusp neighborhood might not necessarily touch any other
|
|
117
|
+
cusp neighborhood since we do not use the maximal cusp area
|
|
118
|
+
matrix.
|
|
119
|
+
:param policy:
|
|
120
|
+
Specifies process of choosing cusp neighborhoods.
|
|
121
|
+
Either ``unbiased`` or ``greedy``, see above.
|
|
122
|
+
:param first_cusps:
|
|
123
|
+
Preference order of cusps.
|
|
124
|
+
Only relevant if :attr:`policy='greedy'`, see above.
|
|
125
|
+
:return:
|
|
126
|
+
Areas of maximal embedded and disjoint cusp neighborhoods
|
|
127
|
+
(default). Or areas of some embedded and disjoint cusp
|
|
128
|
+
neighborhoods (if :attr:`method` switches to older algorithm).
|
|
129
|
+
"""
|
|
130
|
+
if policy not in ['unbiased', 'greedy']:
|
|
131
|
+
raise ValueError("policy passed to cusp_areas must be 'unbiased' "
|
|
132
|
+
"or 'greedy'.")
|
|
133
|
+
|
|
134
|
+
m = manifold.cusp_area_matrix(
|
|
135
|
+
method=method, verified=verified, bits_prec=bits_prec)
|
|
136
|
+
|
|
137
|
+
if policy == 'unbiased':
|
|
138
|
+
return cusp_areas_from_matrix.unbiased_cusp_areas_from_cusp_area_matrix(m)
|
|
139
|
+
else:
|
|
140
|
+
return cusp_areas_from_matrix.greedy_cusp_areas_from_cusp_area_matrix(m, first_cusps=first_cusps)
|
|
141
|
+
|
|
142
|
+
def _cusp_shapes_and_areas(
|
|
143
|
+
manifold, *,
|
|
144
|
+
policy : str,
|
|
145
|
+
method : str,
|
|
146
|
+
verified : bool,
|
|
147
|
+
bits_prec : Optional[int],
|
|
148
|
+
first_cusps : List[int]):
|
|
149
|
+
|
|
150
|
+
cusp_shapes = manifold.cusp_info(
|
|
151
|
+
'shape', verified=verified, bits_prec=bits_prec)
|
|
152
|
+
cusp_areas = manifold.cusp_areas(
|
|
153
|
+
policy=policy, method=method,
|
|
154
|
+
verified=verified, bits_prec=bits_prec, first_cusps=first_cusps)
|
|
155
|
+
|
|
156
|
+
return zip(cusp_shapes, cusp_areas)
|
|
157
|
+
|
|
158
|
+
def short_slopes(manifold,
|
|
159
|
+
length=6,
|
|
160
|
+
policy : str = 'unbiased',
|
|
161
|
+
method : str = 'maximal',
|
|
162
|
+
verified : bool = False,
|
|
163
|
+
bits_prec : Optional[int] = None,
|
|
164
|
+
first_cusps : List[int] = []):
|
|
165
|
+
"""
|
|
166
|
+
Returns a list of short slopes (for Dehn-fillings) for each cusp.
|
|
167
|
+
|
|
168
|
+
That is, the method uses :meth:`~snappy.Manifold.cusp_areas` to find
|
|
169
|
+
(maximal) embedded and disjoint cusp neighborhoods. It uses the boundaries
|
|
170
|
+
of these cusp neighborhoods to measure the length of a peripheral curve.
|
|
171
|
+
For each cusp, it determines all simple peripheral curves shorter than
|
|
172
|
+
the given :attr:`length` (which defaults to 6). The result is a list
|
|
173
|
+
of the corresponding slopes for each cusp::
|
|
174
|
+
|
|
175
|
+
>>> M = Manifold("otet20_00022")
|
|
176
|
+
>>> M.short_slopes()
|
|
177
|
+
[[(1, 0), (-1, 1), (0, 1)], [(1, 0)]]
|
|
178
|
+
|
|
179
|
+
It takes the same arguments as :meth:`~snappy.Manifold.cusp_areas`::
|
|
180
|
+
|
|
181
|
+
>>> M.short_slopes(policy = 'greedy')
|
|
182
|
+
[[(1, 0)], [(1, 0)]]
|
|
183
|
+
|
|
184
|
+
The ten exceptional slopes of the figure-eight knot::
|
|
185
|
+
|
|
186
|
+
>>> M = Manifold("4_1")
|
|
187
|
+
>>> M.short_slopes()
|
|
188
|
+
[[(1, 0), (-4, 1), (-3, 1), (-2, 1), (-1, 1), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1)]]
|
|
189
|
+
|
|
190
|
+
Two more slopes appear when increasing length to :math:`2\\pi`::
|
|
191
|
+
|
|
192
|
+
>>> M.short_slopes(length = 6.283185307179586)
|
|
193
|
+
[[(1, 0), (-5, 1), (-4, 1), (-3, 1), (-2, 1), (-1, 1), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1)]]
|
|
194
|
+
|
|
195
|
+
**Verified computation**
|
|
196
|
+
|
|
197
|
+
If :attr:`verified = False`, floating-point issues can arise resulting in
|
|
198
|
+
incorrect values. The method can be made
|
|
199
|
+
:ref:`verified <verify-primer>` by passing :attr:`verified = True`::
|
|
200
|
+
|
|
201
|
+
sage: M = Manifold("4_1")
|
|
202
|
+
sage: M.short_slopes(verified = True)
|
|
203
|
+
[[(1, 0), (-4, 1), (-3, 1), (-2, 1), (-1, 1), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1)]]
|
|
204
|
+
|
|
205
|
+
If :attr:`verified = True`, the result is guaranteed to contain all short
|
|
206
|
+
slopes and might contain additional slopes (with lengths slightly longer
|
|
207
|
+
than the given :attr:`length` but this could not be proven using the
|
|
208
|
+
interval estimates).
|
|
209
|
+
|
|
210
|
+
The given :attr:`length` is cast to a SageMath ``RealIntervalField`` of the
|
|
211
|
+
given precision if :attr:`verified = True`::
|
|
212
|
+
|
|
213
|
+
sage: from sage.all import pi
|
|
214
|
+
sage: M.short_slopes(length = 2 * pi, verified = True, bits_prec = 100)
|
|
215
|
+
[[(1, 0), (-5, 1), (-4, 1), (-3, 1), (-2, 1), (-1, 1), (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1)]]
|
|
216
|
+
|
|
217
|
+
"""
|
|
218
|
+
|
|
219
|
+
return [
|
|
220
|
+
short_slopes_for_cusp.short_slopes_from_cusp_shape_and_area(
|
|
221
|
+
cusp_shape, cusp_area, length=length)
|
|
222
|
+
for cusp_shape, cusp_area
|
|
223
|
+
in _cusp_shapes_and_areas(
|
|
224
|
+
manifold,
|
|
225
|
+
policy = policy,
|
|
226
|
+
method = method,
|
|
227
|
+
verified = verified,
|
|
228
|
+
bits_prec = bits_prec,
|
|
229
|
+
first_cusps = first_cusps) ]
|
|
230
|
+
|
|
231
|
+
def cusp_translations(manifold,
|
|
232
|
+
policy : str = 'unbiased',
|
|
233
|
+
method : str = 'maximal',
|
|
234
|
+
verified : bool = False,
|
|
235
|
+
bits_prec : Optional[int] = None,
|
|
236
|
+
first_cusps : List[int] = []):
|
|
237
|
+
"""
|
|
238
|
+
Returns a list of the (complex) Euclidean translations corresponding to the
|
|
239
|
+
meridian and longitude of each cusp.
|
|
240
|
+
|
|
241
|
+
That is, the method uses :meth:`~snappy.Manifold.cusp_areas` to find
|
|
242
|
+
(maximal) embedded and disjoint cusp neighborhoods. It then uses the
|
|
243
|
+
boundaries of these cusp neighborhoods to measure the meridian and
|
|
244
|
+
longitude of each cusp. The result is a pair for each cusp. The first
|
|
245
|
+
entry of the pair corresponds to the meridian and is complex. The
|
|
246
|
+
second entry corresponds to the longitude and is always real::
|
|
247
|
+
|
|
248
|
+
>>> M = Manifold("s776")
|
|
249
|
+
>>> M.cusp_translations() # doctest: +NUMERIC9
|
|
250
|
+
[(0.500000000000000 + 1.32287565553230*I, 2.00000000000000), (0.500000000000000 + 1.32287565553230*I, 2.00000000000000), (0.499999999999999 + 1.32287565553230*I, 2.00000000000000)]
|
|
251
|
+
|
|
252
|
+
It takes the same arguments as :meth:`~snappy.Manifold.cusp_areas`::
|
|
253
|
+
|
|
254
|
+
>>> M.cusp_translations(policy = 'greedy') # doctest: +NUMERIC9
|
|
255
|
+
[(0.70710678118654752440084436210 + 1.8708286933869706927918743662*I, 2.8284271247461900976033774484), (0.35355339059327376220042218105 + 0.93541434669348534639593718308*I, 1.4142135623730950488016887242), (0.35355339059327376220042218105 + 0.93541434669348534639593718308*I, 1.4142135623730950488016887242)]
|
|
256
|
+
|
|
257
|
+
**Verified computations**
|
|
258
|
+
|
|
259
|
+
If :attr:`verified = False`, floating-point issues can arise resulting in
|
|
260
|
+
incorrect values. The method can be made
|
|
261
|
+
:ref:`verified <verify-primer>` by passing :attr:`verified = True`::
|
|
262
|
+
|
|
263
|
+
sage: M.cusp_translations(verified = True) # doctest: +NUMERIC9
|
|
264
|
+
[(0.50000000000? + 1.32287565553?*I, 2.00000000000?), (0.500000000000? + 1.32287565554?*I, 2.00000000000?), (0.500000000000? + 1.32287565554?*I, 2.00000000000?)]
|
|
265
|
+
|
|
266
|
+
Note that the first element of each pair is a SageMath ``ComplexIntervalField`` and
|
|
267
|
+
the second element a ``RealIntervalField``.
|
|
268
|
+
"""
|
|
269
|
+
|
|
270
|
+
return [
|
|
271
|
+
short_slopes_for_cusp.translations_from_cusp_shape_and_area(
|
|
272
|
+
cusp_shape, cusp_area, kernel_convention=True)
|
|
273
|
+
for cusp_shape, cusp_area
|
|
274
|
+
in _cusp_shapes_and_areas(
|
|
275
|
+
manifold,
|
|
276
|
+
policy = policy,
|
|
277
|
+
method = method,
|
|
278
|
+
verified = verified,
|
|
279
|
+
bits_prec = bits_prec,
|
|
280
|
+
first_cusps = first_cusps) ]
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
from .maximal_cusp_area_matrix import maximal_cusp_area_matrix
|
|
2
|
+
from .trig_cusp_area_matrix import triangulation_dependent_cusp_area_matrix
|
|
3
|
+
from ..geometric_structure.cusp_neighborhood.exceptions import IncompleteCuspError
|
|
4
|
+
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
def cusp_area_matrix(
|
|
8
|
+
manifold,
|
|
9
|
+
method : str = 'maximal',
|
|
10
|
+
verified : bool = False,
|
|
11
|
+
bits_prec : Optional[int] = None):
|
|
12
|
+
"""
|
|
13
|
+
Returns the maximal cusp area matrix :math:`(A_{ij})` where
|
|
14
|
+
:math:`A_{ij}` is defined as follows.
|
|
15
|
+
Let :math:`C_i` and :math:`C_j` be the (open) cusp neighborhoods about cusp
|
|
16
|
+
:math:`i` and :math:`j`. Let :math:`A(C_i)` and :math:`A(C_j)` be the
|
|
17
|
+
areas of :math:`C_i` and :math:`C_j`, respectively. Then, :math:`C_i`
|
|
18
|
+
and :math:`C_j` are embedded (if :math:`i = j`) or disjoint (otherwise)
|
|
19
|
+
if and only if :math:`A(C_i)A(C_j) \\leq A_{ij}`.
|
|
20
|
+
|
|
21
|
+
Here is an example::
|
|
22
|
+
|
|
23
|
+
>>> M = Manifold("L6a5")
|
|
24
|
+
>>> M.cusp_area_matrix() # doctest: +NUMERIC12
|
|
25
|
+
[27.9999999999996 7.00000000000000 7.00000000000000]
|
|
26
|
+
[7.00000000000000 27.9999999999999 7.00000000000000]
|
|
27
|
+
[7.00000000000000 7.00000000000000 28.0000000000001]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
**Faster lower bounds**
|
|
31
|
+
|
|
32
|
+
This section can be skipped by most users!
|
|
33
|
+
|
|
34
|
+
Prior to SnapPy version 3.2, the algorithm to compute the maximal cusp
|
|
35
|
+
area matrix was much slower and required :attr:`verified = True` and
|
|
36
|
+
SageMath. Thus, in prior versions, :attr:`method` defaulted to
|
|
37
|
+
``trigDependentTryCanonize``. This meant, that, by default,
|
|
38
|
+
:meth:`~snappy.Manifold.cusp_area_matrix` only returned
|
|
39
|
+
(some) lower bounds for the maximal cusp area matrix entries.
|
|
40
|
+
|
|
41
|
+
These lower bounds can still be accessed::
|
|
42
|
+
|
|
43
|
+
>>> M.cusp_area_matrix(method = 'trigDependentTryCanonize') # doctest: +NUMERIC12
|
|
44
|
+
[21.4375000000000 7.00000000000000 7.00000000000000]
|
|
45
|
+
[7.00000000000000 28.0000000000000 7.00000000000000]
|
|
46
|
+
[7.00000000000000 7.00000000000000 28.0000000000000]
|
|
47
|
+
|
|
48
|
+
If :attr:`method = 'trigDependent'` or
|
|
49
|
+
:attr:`method = 'trigDependenyTryCanonize'`, the result is triangulation
|
|
50
|
+
dependent or not even deterministic, respectively.
|
|
51
|
+
Furthermore, if :attr:`verified = True` is also set, while the left
|
|
52
|
+
endpoints of the intervals are lower bounds for the maximal cusp area
|
|
53
|
+
matrix entries, the right endpoints are meaningless and could be smaller
|
|
54
|
+
or larger than the maximal cusp area matrix entries.
|
|
55
|
+
|
|
56
|
+
**Verified computation**
|
|
57
|
+
|
|
58
|
+
If :attr:`verified = False`, floating-point issues can arise resulting in
|
|
59
|
+
incorrect values. The method can be made
|
|
60
|
+
:ref:`verified <verify-primer>` by passing :attr:`verified = True`::
|
|
61
|
+
|
|
62
|
+
sage: M.cusp_area_matrix(verified=True) # doctest: +NUMERIC3
|
|
63
|
+
[ 28.0000? 7.000000000000? 7.00000000000?]
|
|
64
|
+
[7.000000000000? 28.000000? 7.00000000000?]
|
|
65
|
+
[ 7.00000000000? 7.00000000000? 28.00000?]
|
|
66
|
+
|
|
67
|
+
:param verified:
|
|
68
|
+
Use :ref:`verified computation <verify-primer>`.
|
|
69
|
+
:param bits_prec:
|
|
70
|
+
Precision used for computation. Increase if computation
|
|
71
|
+
did not succeed or a more precise result is desired.
|
|
72
|
+
:param method:
|
|
73
|
+
Switches to older algorithms giving lower bounds when
|
|
74
|
+
``trigDependentTryCanonize`` and ``trigDependent``.
|
|
75
|
+
:return:
|
|
76
|
+
Maximal cusp area matrix (default) or lower bounds
|
|
77
|
+
(if :attr:`method` switches to older algorithm).
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
for cusp_info in manifold.cusp_info():
|
|
81
|
+
if not cusp_info['complete?']:
|
|
82
|
+
raise IncompleteCuspError(manifold)
|
|
83
|
+
|
|
84
|
+
if method == 'maximal':
|
|
85
|
+
return maximal_cusp_area_matrix(
|
|
86
|
+
manifold, bits_prec=bits_prec, verified=verified)
|
|
87
|
+
if method in ['trigDependent', 'trigDependentTryCanonize']:
|
|
88
|
+
if method == 'trigDependentTryCanonize':
|
|
89
|
+
manifold = manifold.copy()
|
|
90
|
+
manifold.canonize()
|
|
91
|
+
|
|
92
|
+
return triangulation_dependent_cusp_area_matrix(
|
|
93
|
+
manifold, bits_prec=bits_prec, verified=verified)
|
|
94
|
+
|
|
95
|
+
raise ValueError("method passed to cusp_area_matrix must be "
|
|
96
|
+
"'trigDependent', 'trigDependentTryCanonize', "
|
|
97
|
+
"or 'maximal'.")
|
|
98
|
+
|