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
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
from .geometric_structure import mcomplex_for_len_spec
|
|
2
|
+
from .tile import compute_length_spectrum_tiles, LengthSpectrumTile
|
|
3
|
+
from .geodesic_info import (
|
|
4
|
+
GeodesicStreamInfoBase, GeodesicIntermediateInfo, GeodesicInfoBase,
|
|
5
|
+
GeodesicKeyInfo, CoreCurveGeodesicInfo)
|
|
6
|
+
from .geodesic_key_info_dict import get_geodesic_key_info_set
|
|
7
|
+
from .word import simplify_geodesic_word
|
|
8
|
+
from .length_spectrum_geodesic_info import LengthSpectrumGeodesicInfo
|
|
9
|
+
|
|
10
|
+
from ..snap.t3mlite import Mcomplex
|
|
11
|
+
from ..geometric_structure import word_list_to_psl2c_matrix
|
|
12
|
+
from ..upper_halfspace import psl2c_to_o13
|
|
13
|
+
from ..hyperboloid.distances import distance_r13_point_line
|
|
14
|
+
from ..hyperboloid.line import R13Line
|
|
15
|
+
from ..SnapPy import list_as_word, inverse_list_word
|
|
16
|
+
from ..math_basics import lower, correct_max, correct_min # type: ignore
|
|
17
|
+
from ..exceptions import InsufficientPrecisionError, NonorientableManifoldError
|
|
18
|
+
from ..sage_helper import _within_sage, SageNotAvailable
|
|
19
|
+
|
|
20
|
+
if _within_sage:
|
|
21
|
+
from sage.rings.real_mpfi import RealIntervalField
|
|
22
|
+
|
|
23
|
+
import heapq
|
|
24
|
+
|
|
25
|
+
from typing import Any, Optional, List, Sequence
|
|
26
|
+
|
|
27
|
+
_len_fudge_factor = 1.0000152
|
|
28
|
+
|
|
29
|
+
_optimization : bool = False
|
|
30
|
+
|
|
31
|
+
def length_spectrum_alt_gen(manifold,
|
|
32
|
+
bits_prec : Optional[int] = None,
|
|
33
|
+
verified : bool = False,
|
|
34
|
+
include_intermediates : bool = False
|
|
35
|
+
) -> Sequence[LengthSpectrumGeodesicInfo]:
|
|
36
|
+
"""
|
|
37
|
+
Returns a generator for the geodesics sorted by real length. The method
|
|
38
|
+
only supports orientable manifolds.
|
|
39
|
+
|
|
40
|
+
Here is an example::
|
|
41
|
+
|
|
42
|
+
>>> M = Manifold("m202(3,4)(0,0)")
|
|
43
|
+
>>> spec = M.length_spectrum_alt_gen()
|
|
44
|
+
>>> next(spec) # doctest: +NUMERIC9
|
|
45
|
+
Length Core curve Word
|
|
46
|
+
0.14742465268512 - 1.78287093565202*I Cusp 0 aabcDabcB
|
|
47
|
+
>>> next(spec) # doctest: +NUMERIC9
|
|
48
|
+
0.81161414965958 + 2.72911699294426*I - b
|
|
49
|
+
>>> next(spec) # doctest: +NUMERIC9
|
|
50
|
+
0.84163270359334 + 2.61245944742151*I - aB
|
|
51
|
+
|
|
52
|
+
Note that the shortest geodesic in the above example happens to be the
|
|
53
|
+
core curve of the filled cusp (Cusp 0).
|
|
54
|
+
|
|
55
|
+
Access just the length or word::
|
|
56
|
+
|
|
57
|
+
>>> g = next(spec)
|
|
58
|
+
>>> g.length # doctest: +NUMERIC9
|
|
59
|
+
0.93461379591349 + 2.70060614107722*I
|
|
60
|
+
>>> g.word
|
|
61
|
+
'a'
|
|
62
|
+
|
|
63
|
+
The word is given with respect to the unsimplified fundamental group::
|
|
64
|
+
|
|
65
|
+
>>> G = M.fundamental_group(simplify_presentation=False)
|
|
66
|
+
>>> G.complex_length('a') # doctest: +NUMERIC9
|
|
67
|
+
0.93461379591349 + 2.70060614107722*I
|
|
68
|
+
|
|
69
|
+
The method also supports higher precision::
|
|
70
|
+
|
|
71
|
+
>>> M = Manifold("m003(-3,1)")
|
|
72
|
+
>>> spec = M.length_spectrum_alt_gen(bits_prec=100)
|
|
73
|
+
>>> next(spec).length # doctest: +NUMERIC24
|
|
74
|
+
0.58460368501798696932015666264 + 2.4953704555604684110903962008*I
|
|
75
|
+
|
|
76
|
+
**Performance**
|
|
77
|
+
|
|
78
|
+
This method uses a different algorithm than
|
|
79
|
+
:meth:`length_spectrum <Manifold.length_spectrum>`. In particular,
|
|
80
|
+
it does not compute the Dirichlet domain. It also allows for
|
|
81
|
+
:ref:`verified computations <verify-primer>`.
|
|
82
|
+
It is implemented in python and thus
|
|
83
|
+
typically slower than :meth:`length_spectrum <Manifold.length_spectrum>`.
|
|
84
|
+
But there are also some cases where it is significantly faster. In
|
|
85
|
+
particular, this applies to spun triangulations such as ``m004(21,10)``.
|
|
86
|
+
|
|
87
|
+
Here is example where we can help the algorithm by guessing and drilling
|
|
88
|
+
and filling a short geodesic::
|
|
89
|
+
|
|
90
|
+
>>> M = Manifold("o9_00639")
|
|
91
|
+
|
|
92
|
+
Over an hour to compute::
|
|
93
|
+
|
|
94
|
+
>>> M.high_precision().length_spectrum(0.1) # doctest: +SKIP
|
|
95
|
+
mult length topology parity
|
|
96
|
+
1 0.00150226276052 - 2.39996262244127*I circle +
|
|
97
|
+
|
|
98
|
+
A couple of minutes to compute::
|
|
99
|
+
|
|
100
|
+
>>> spec = M.length_spectrum_alt_gen(bits_prec = 150)
|
|
101
|
+
>>> next(spec) # doctest: +SKIP
|
|
102
|
+
Length Word Core curve
|
|
103
|
+
0.00150226276052 - 2.39996262244127*I a -
|
|
104
|
+
|
|
105
|
+
After drilling and filling, less than a second to compute::
|
|
106
|
+
|
|
107
|
+
>>> N = M.drill_word('a')
|
|
108
|
+
>>> N.dehn_fill((1,0),-1) # N is now isometric to o9_00639 but as a surgery m125(0,0)(34,55)
|
|
109
|
+
>>> spec = N.length_spectrum_alt_gen()
|
|
110
|
+
>>> next(spec) # doctest: +NUMERIC9
|
|
111
|
+
Length Core curve Word
|
|
112
|
+
0.00150226276073 - 2.39996262244128*I Cusp 1 cDcDDcDcDDcDDcDcDDcDcDDcDDcDcDDcDD
|
|
113
|
+
>>> next(spec).length.real() # doctest: +NUMERIC9
|
|
114
|
+
0.96218768626877
|
|
115
|
+
|
|
116
|
+
**Verified computations**
|
|
117
|
+
|
|
118
|
+
The method also supports :ref:`verified computations <verify-primer>`::
|
|
119
|
+
|
|
120
|
+
sage: M = Manifold("m019")
|
|
121
|
+
sage: spec = M.length_spectrum_alt_gen(verified=True, bits_prec=100)
|
|
122
|
+
sage: next(spec)
|
|
123
|
+
Length Core curve Word
|
|
124
|
+
0.43153441294719... + 2.35105908147863...*I - a
|
|
125
|
+
sage: next(spec)
|
|
126
|
+
0.88944299721255... - 2.94185904702273...*I - bD
|
|
127
|
+
|
|
128
|
+
If :attr:`verified = True` is passed, the algorithm guarantees that the lower
|
|
129
|
+
bound of the real length is (non-strictly) increasing. In particular, we know
|
|
130
|
+
that we have found all geodesics less than the following length::
|
|
131
|
+
|
|
132
|
+
sage: next(spec).length.real().lower() # doctest: +NUMERIC12
|
|
133
|
+
0.94135129037387168886341739832
|
|
134
|
+
|
|
135
|
+
To illustrate some pitfalls, here is an example of a potential a result
|
|
136
|
+
of the method:
|
|
137
|
+
|
|
138
|
+
+----------------------+-------+
|
|
139
|
+
| Real length interval | Word |
|
|
140
|
+
+======================+=======+
|
|
141
|
+
| ``[1.0, 2.0]`` | ``a`` |
|
|
142
|
+
+----------------------+-------+
|
|
143
|
+
| ``[1.2, 1.3]`` | ``b`` |
|
|
144
|
+
+----------------------+-------+
|
|
145
|
+
| ``[1.7, 1.8]`` | ``c`` |
|
|
146
|
+
+----------------------+-------+
|
|
147
|
+
| ``[3.0, 4.0]`` | ``d`` |
|
|
148
|
+
+----------------------+-------+
|
|
149
|
+
|
|
150
|
+
Note that we cannot say whether geodesic ``a`` is actually the first,
|
|
151
|
+
second or third shortest geodesic or tied with ``b`` or ``c``. Increasing
|
|
152
|
+
precision can change (representative words and) the order in which the
|
|
153
|
+
geodesics are emitted.
|
|
154
|
+
|
|
155
|
+
We can say that together ``a``, ``b`` and ``c`` are the three shortest
|
|
156
|
+
geodesics. Furthermore, we can also say that the systole
|
|
157
|
+
of the manifold is in ``[1.0, 2.0]`` even though ``a`` itself might not be
|
|
158
|
+
the shortest geodesic. The latter is true in general:
|
|
159
|
+
|
|
160
|
+
**Verified systole**
|
|
161
|
+
|
|
162
|
+
It is not necessarily true that the first geodesic returned
|
|
163
|
+
by the method is the shortest geodesic. Despite this, the interval for
|
|
164
|
+
the real length of the first geodesic always contains the systole of
|
|
165
|
+
the manifold::
|
|
166
|
+
|
|
167
|
+
sage: M = Manifold("m004")
|
|
168
|
+
sage: spec = M.length_spectrum_alt_gen(verified=True)
|
|
169
|
+
sage: g = next(spec) # g might or might not be shortest geodesic
|
|
170
|
+
sage: systole = g.length.real() # But interval is large enough to contain systole
|
|
171
|
+
sage: systole # doctest: +NUMERIC6
|
|
172
|
+
1.08707015?
|
|
173
|
+
|
|
174
|
+
:param bits_prec:
|
|
175
|
+
Precision used for the computation. Increase if computation did
|
|
176
|
+
not succeed.
|
|
177
|
+
:param verified:
|
|
178
|
+
Use :ref:`verified computation <verify-primer>`.
|
|
179
|
+
:param include_intermediates:
|
|
180
|
+
For advanced users, add intermediate lower bounds to the stream.
|
|
181
|
+
These lower bounds do not correspond to ageodesic but indicate that
|
|
182
|
+
all geodesics up to the indicated (real) length have already
|
|
183
|
+
occurred in the stream. When ``verified=True``, the size of the
|
|
184
|
+
intervals might fluctate and the left endpoint is not guaranteed
|
|
185
|
+
to be non-decreasing.
|
|
186
|
+
:return:
|
|
187
|
+
A generator to enumerate the geodesics such that the (lower bound
|
|
188
|
+
of the) real length is non-decreasing.
|
|
189
|
+
"""
|
|
190
|
+
|
|
191
|
+
if not manifold.is_orientable():
|
|
192
|
+
raise NonorientableManifoldError(
|
|
193
|
+
"Manifold.length_spectrum_alt_gen", manifold)
|
|
194
|
+
|
|
195
|
+
# Triangulation with necessary geometric structures
|
|
196
|
+
mcomplex : Mcomplex = mcomplex_for_len_spec(
|
|
197
|
+
manifold,
|
|
198
|
+
bits_prec=bits_prec, verified=verified)
|
|
199
|
+
# Needed to know whether we convert a word such as [ 1 ] to
|
|
200
|
+
# a or to x1.
|
|
201
|
+
num_generators = len([g for g in mcomplex.GeneratorMatrices.keys()
|
|
202
|
+
if g > 0])
|
|
203
|
+
is_first = True
|
|
204
|
+
|
|
205
|
+
geodesic : GeodesicStreamInfoBase
|
|
206
|
+
for geodesic in _length_spectrum_from_mcomplex(
|
|
207
|
+
mcomplex, manifold, include_intermediates):
|
|
208
|
+
# Convert information to user-friendly form
|
|
209
|
+
if isinstance(geodesic, GeodesicIntermediateInfo):
|
|
210
|
+
yield LengthSpectrumGeodesicInfo(
|
|
211
|
+
_is_first = False,
|
|
212
|
+
length = geodesic.length,
|
|
213
|
+
_is_intermediate = True)
|
|
214
|
+
else:
|
|
215
|
+
if isinstance(geodesic, CoreCurveGeodesicInfo):
|
|
216
|
+
core_curve = geodesic.core_curve
|
|
217
|
+
else:
|
|
218
|
+
core_curve = None
|
|
219
|
+
yield LengthSpectrumGeodesicInfo(
|
|
220
|
+
# _is_first indicates whether to print the header
|
|
221
|
+
_is_first = is_first,
|
|
222
|
+
length = geodesic.length,
|
|
223
|
+
# Convert word to a or x1
|
|
224
|
+
word = list_as_word(
|
|
225
|
+
simplify_geodesic_word(geodesic.word),
|
|
226
|
+
num_generators,
|
|
227
|
+
verbose_form=False),
|
|
228
|
+
core_curve = core_curve,
|
|
229
|
+
parity = 'orientation-preserving',
|
|
230
|
+
topology = 'circle',
|
|
231
|
+
multiplicity = 1,
|
|
232
|
+
_is_intermediate = False)
|
|
233
|
+
is_first = False
|
|
234
|
+
|
|
235
|
+
def length_spectrum_alt(manifold,
|
|
236
|
+
count : Optional[int] = None,
|
|
237
|
+
max_len : Optional[Any] = None,
|
|
238
|
+
bits_prec : Optional[int] = None,
|
|
239
|
+
verified : bool = False
|
|
240
|
+
) -> List[LengthSpectrumGeodesicInfo]:
|
|
241
|
+
"""
|
|
242
|
+
Returns a list of geodesics. How far this list goes can be specified
|
|
243
|
+
by a cut-off length or a count. The method only supports
|
|
244
|
+
orientable manifolds. It is a convenience method for
|
|
245
|
+
:meth:`~snappy.Manifold.length_spectrum_alt_gen`.
|
|
246
|
+
We refer the reader to
|
|
247
|
+
:meth:`~snappy.Manifold.length_spectrum_alt_gen`
|
|
248
|
+
for further details not covered here.
|
|
249
|
+
|
|
250
|
+
**Cut-off length**
|
|
251
|
+
|
|
252
|
+
Here is an example where a cut-off length for the geodesics is specified::
|
|
253
|
+
|
|
254
|
+
>>> M = Manifold("m202(3,4)(3,4)")
|
|
255
|
+
>>> M.length_spectrum_alt(max_len = 0.5) # doctest: +SKIP
|
|
256
|
+
[Length Core curve Word
|
|
257
|
+
0.14820741547094 - 1.76955170166922*I Cusp 1 bcDc,
|
|
258
|
+
0.14820741547097 - 1.76955170166923*I Cusp 0 aabcDabcB]
|
|
259
|
+
|
|
260
|
+
It also supports :ref:`verified <verify-primer>` computations::
|
|
261
|
+
|
|
262
|
+
sage: M.length_spectrum_alt(max_len = 0.5, verified = True, bits_prec = 100) # doctest: +SKIP
|
|
263
|
+
[Length Core curve Word
|
|
264
|
+
0.148207415470948? - 1.76955170166924? *I Cusp 0 aabcDabcB,
|
|
265
|
+
0.14820741547094... - 1.76955170166923...*I Cusp 1 bcDc]
|
|
266
|
+
|
|
267
|
+
If :attr:`verified=True`, the returned list is guaranteed to include all
|
|
268
|
+
geodesics up to the given cut-off length and might include additional
|
|
269
|
+
geodesics.
|
|
270
|
+
|
|
271
|
+
**Count**
|
|
272
|
+
|
|
273
|
+
Here is an example where a count is specified::
|
|
274
|
+
|
|
275
|
+
>>> M = Manifold("m202(3,4)(3,4)")
|
|
276
|
+
>>> M.length_spectrum_alt(count = 3) # doctest: +SKIP
|
|
277
|
+
[Length Core curve Word
|
|
278
|
+
0.14820741547094 - 1.76955170166922*I Cusp 1 bcDc,
|
|
279
|
+
0.14820741547097 - 1.76955170166923*I Cusp 0 aabcDabcB,
|
|
280
|
+
0.79356651781096 + 2.65902431489655*I - aB,
|
|
281
|
+
0.79356651781096 + 2.65902431489655*I - b]
|
|
282
|
+
|
|
283
|
+
Note that the number of geodesics listed might be larger than the given
|
|
284
|
+
count. In particular, this happens when the same (real) length appears
|
|
285
|
+
multiple times. If :attr:`verified=True`, the returned list is guaranteed
|
|
286
|
+
to include the :attr:`count` shortest geodesics and might include additional
|
|
287
|
+
geodesics.
|
|
288
|
+
|
|
289
|
+
**Verified systole**
|
|
290
|
+
|
|
291
|
+
Even though, the first reported geodesic might not be the shortest, we
|
|
292
|
+
obtain an interval containing the systole as follows, also see
|
|
293
|
+
:meth:`~snappy.Manifold.length_spectrum_alt_gen`::
|
|
294
|
+
|
|
295
|
+
sage: M = Manifold("m004")
|
|
296
|
+
sage: M.length_spectrum_alt(count=1, verified=True, bits_prec=100)[0].length.real() # doctest: +NUMERIC21
|
|
297
|
+
1.0870701449957390997853?
|
|
298
|
+
|
|
299
|
+
:param count:
|
|
300
|
+
Number of shortest geodesics to list. The actual result might
|
|
301
|
+
contain additional geodesics. For advanced users: if
|
|
302
|
+
:attr:`max_len` is also given, the result contains either the
|
|
303
|
+
:attr:`count` shortest geodesics or all geodesics shorter than
|
|
304
|
+
:attr:`max_len` (and maybe additional geodesics).
|
|
305
|
+
:param max_len:
|
|
306
|
+
Cut-off length for geodesics. The actual result includes all
|
|
307
|
+
geodesics up to the given length and might include additional
|
|
308
|
+
geodesics. See :attr:`count` when used with :attr:`count`.
|
|
309
|
+
:param bits_prec:
|
|
310
|
+
Precision used for the computation. Increase if computation did
|
|
311
|
+
not succeed.
|
|
312
|
+
:param verified:
|
|
313
|
+
Use :ref:`verified computation <verify-primer>`.
|
|
314
|
+
:return:
|
|
315
|
+
A list of geodesics such that the (lower bound of) the real
|
|
316
|
+
length is non-decreasing.
|
|
317
|
+
"""
|
|
318
|
+
|
|
319
|
+
if count is None and max_len is None:
|
|
320
|
+
raise ValueError(
|
|
321
|
+
"Must specify at least one of count or max_len.")
|
|
322
|
+
|
|
323
|
+
if not count is None:
|
|
324
|
+
if not hasattr(count, '__index__'):
|
|
325
|
+
raise ValueError(
|
|
326
|
+
"count must be an integer.")
|
|
327
|
+
|
|
328
|
+
if max_len is None:
|
|
329
|
+
resolved_max_len = None
|
|
330
|
+
else:
|
|
331
|
+
if verified:
|
|
332
|
+
if not _within_sage:
|
|
333
|
+
raise SageNotAvailable('Sorry, this feature requires using SnapPy inside Sage.')
|
|
334
|
+
if bits_prec is None:
|
|
335
|
+
resolved_bits_prec = manifold._precision()
|
|
336
|
+
else:
|
|
337
|
+
resolved_bits_prec = bits_prec
|
|
338
|
+
RIF = RealIntervalField(resolved_bits_prec)
|
|
339
|
+
resolved_max_len = RIF(max_len)
|
|
340
|
+
else:
|
|
341
|
+
# A bit of fudge
|
|
342
|
+
resolved_max_len = _len_fudge_factor * max_len
|
|
343
|
+
|
|
344
|
+
return list(
|
|
345
|
+
_length_spectrum_alt_impl(
|
|
346
|
+
manifold, count, resolved_max_len, bits_prec, verified))
|
|
347
|
+
|
|
348
|
+
def _length_spectrum_alt_impl(manifold,
|
|
349
|
+
count : Optional[int],
|
|
350
|
+
max_len : Optional[Any],
|
|
351
|
+
bits_prec : Optional[int],
|
|
352
|
+
verified : bool
|
|
353
|
+
) -> Sequence[LengthSpectrumGeodesicInfo]:
|
|
354
|
+
|
|
355
|
+
# Number of geodesics encountered so far.
|
|
356
|
+
num_geodesics = 0
|
|
357
|
+
# Maximum length of any geodesic encountered so far (plus a little extra
|
|
358
|
+
# if not verified).
|
|
359
|
+
max_len_geodesics = None
|
|
360
|
+
|
|
361
|
+
info : LengthSpectrumGeodesicInfo
|
|
362
|
+
for info in length_spectrum_alt_gen(manifold = manifold,
|
|
363
|
+
bits_prec = bits_prec,
|
|
364
|
+
verified = verified,
|
|
365
|
+
include_intermediates = True):
|
|
366
|
+
# By guarantees from length_spectrum_alt_gen guarantees, all geodesics
|
|
367
|
+
# with real length less than (the left end point) of this_len have
|
|
368
|
+
# occurred in the length spectrum stream.
|
|
369
|
+
this_len = info.length.real()
|
|
370
|
+
|
|
371
|
+
if max_len_geodesics is None or this_len > max_len_geodesics:
|
|
372
|
+
# We have a clean break.
|
|
373
|
+
# That is all subsequent geodesics have length strictly larger than
|
|
374
|
+
# any geodesics encountered so far.
|
|
375
|
+
|
|
376
|
+
# Check whether any of the conditions to stop is fulfilled.
|
|
377
|
+
if count is not None:
|
|
378
|
+
if num_geodesics >= count:
|
|
379
|
+
break
|
|
380
|
+
|
|
381
|
+
if max_len is not None:
|
|
382
|
+
if this_len > max_len:
|
|
383
|
+
break
|
|
384
|
+
|
|
385
|
+
if info._is_intermediate:
|
|
386
|
+
# Skip intermediates
|
|
387
|
+
continue
|
|
388
|
+
|
|
389
|
+
# Update max_len_geodesics
|
|
390
|
+
if verified:
|
|
391
|
+
this_len_fudge = this_len
|
|
392
|
+
else:
|
|
393
|
+
# Fudge factor when not verified
|
|
394
|
+
this_len_fudge = _len_fudge_factor * this_len
|
|
395
|
+
|
|
396
|
+
if max_len_geodesics is None:
|
|
397
|
+
max_len_geodesics = this_len_fudge
|
|
398
|
+
else:
|
|
399
|
+
max_len_geodesics = correct_max(
|
|
400
|
+
[max_len_geodesics, this_len_fudge])
|
|
401
|
+
|
|
402
|
+
num_geodesics += 1
|
|
403
|
+
|
|
404
|
+
yield info
|
|
405
|
+
|
|
406
|
+
def _length_spectrum_from_mcomplex(
|
|
407
|
+
mcomplex : Mcomplex,
|
|
408
|
+
manifold,
|
|
409
|
+
include_intermediates : bool = False
|
|
410
|
+
) -> Sequence[GeodesicStreamInfoBase]:
|
|
411
|
+
"""
|
|
412
|
+
Implements length_spectrum given an Mcomplex constructed with
|
|
413
|
+
mcomplex_for_len_spec and the SnapPy Manifold.
|
|
414
|
+
"""
|
|
415
|
+
|
|
416
|
+
if mcomplex.verified:
|
|
417
|
+
epsilon = 0
|
|
418
|
+
else:
|
|
419
|
+
# A bit of extra tiling before outputting a geodesic.
|
|
420
|
+
epsilon = mcomplex.RF(0.0001)
|
|
421
|
+
|
|
422
|
+
# A set-like structure holding GeodesicKeyInfo's to record
|
|
423
|
+
# which geodesics were already emitted.
|
|
424
|
+
# Two geodesics are regarded as equal if one is a
|
|
425
|
+
# multiple of another (including inverse) and if they are
|
|
426
|
+
# conjugates.
|
|
427
|
+
#
|
|
428
|
+
# Note that the structure does not work correctly if we add
|
|
429
|
+
# a multiple of a geodesic to it first. If we add a geodesic
|
|
430
|
+
# that is not a multiple first though, trying to add a multiple of
|
|
431
|
+
# that geodesic will be detected and add will return False.
|
|
432
|
+
#
|
|
433
|
+
# The structure does not hold geodesics corresponding to
|
|
434
|
+
# core curves.
|
|
435
|
+
#
|
|
436
|
+
visited_geodesics = get_geodesic_key_info_set(mcomplex)
|
|
437
|
+
|
|
438
|
+
# A priority queue of geodesics (including those corresponding
|
|
439
|
+
# to core curves.). The key is the lower bound of the geodesic
|
|
440
|
+
# length.
|
|
441
|
+
#
|
|
442
|
+
# The reason for the queue is this:
|
|
443
|
+
# When tiling to find geodesics, the geodesics are not emitted in order.
|
|
444
|
+
# The tiling algorithm does tell us though that we have seen all geodesics
|
|
445
|
+
# up to a certain length.
|
|
446
|
+
#
|
|
447
|
+
# We will add geodesics to the priority queue as we tile.
|
|
448
|
+
# And we pick off a geodesic g from the top of the priority queue
|
|
449
|
+
# when we know that we have tiled far enough to see all geodesics that
|
|
450
|
+
# could be shorter than g.
|
|
451
|
+
pending_geodesics : Sequence[GeodesicInfoBase] = []
|
|
452
|
+
|
|
453
|
+
# Core curves are treated differently. We add them here to the priority
|
|
454
|
+
# queue explicitly and filter them out when tiling later.
|
|
455
|
+
for geodesic in _geodesic_key_infos_for_core_curves(
|
|
456
|
+
mcomplex, manifold):
|
|
457
|
+
heapq.heappush(pending_geodesics, geodesic)
|
|
458
|
+
|
|
459
|
+
# The real length of the last geodesic that we emitted.
|
|
460
|
+
last_real_length : Optional[Any] = None
|
|
461
|
+
|
|
462
|
+
for tile in compute_length_spectrum_tiles(mcomplex):
|
|
463
|
+
|
|
464
|
+
# We have tiled far enough to have seen all geodesics up to
|
|
465
|
+
# this length.
|
|
466
|
+
#
|
|
467
|
+
# Note that this comment about tiling only applies to the non-core
|
|
468
|
+
# curve geodesics. However, we have already added all core curves
|
|
469
|
+
# explicitly earlier, so we are fine.
|
|
470
|
+
#
|
|
471
|
+
r = tile.lower_bound_geodesic_length
|
|
472
|
+
while (pending_geodesics and
|
|
473
|
+
pending_geodesics[0].length.real() < r - epsilon):
|
|
474
|
+
# We can emit the geodesic g from the top of the priority queue
|
|
475
|
+
# - if we haven't emitted it already earlier.
|
|
476
|
+
# That is because all geodesics that we have not seen when
|
|
477
|
+
# tiling this far have length larger than g - or at least its
|
|
478
|
+
# lower bound is larger than than the lengths of those unseen
|
|
479
|
+
# geodesics.
|
|
480
|
+
geodesic : GeodesicInfoBase = heapq.heappop(pending_geodesics)
|
|
481
|
+
real_length = geodesic.length.real()
|
|
482
|
+
|
|
483
|
+
if _optimization:
|
|
484
|
+
# An optimization. If the geodesic has length less than
|
|
485
|
+
# what the last one, we know it is a duplicate.
|
|
486
|
+
if last_real_length is not None:
|
|
487
|
+
if last_real_length > real_length:
|
|
488
|
+
continue
|
|
489
|
+
|
|
490
|
+
if isinstance(geodesic, GeodesicKeyInfo):
|
|
491
|
+
# Handle the non-core curve case.
|
|
492
|
+
line : R13Line = geodesic.r13_line()
|
|
493
|
+
|
|
494
|
+
# If this geodesic does not intersect the spine, it is conjugate
|
|
495
|
+
# to a geodesic that we have already seen earlier, so we can
|
|
496
|
+
# skip it.
|
|
497
|
+
#
|
|
498
|
+
# Note that this also filters out parabolics. For them, the
|
|
499
|
+
# fixed points coincide and we get a degenerate line. We can
|
|
500
|
+
# still compute the distance to the spine center and it will
|
|
501
|
+
# be a very large number or interval with a large number as
|
|
502
|
+
# lower bound and infinity as upper bound.
|
|
503
|
+
|
|
504
|
+
# We first do a quick global check to see whether the spine
|
|
505
|
+
# intersects a ball containing the spine.
|
|
506
|
+
if distance_r13_point_line(
|
|
507
|
+
mcomplex.spine_center, line) > mcomplex.spine_radius:
|
|
508
|
+
continue
|
|
509
|
+
|
|
510
|
+
# And then a similar check per tetrahedron.
|
|
511
|
+
if all(distance_r13_point_line(
|
|
512
|
+
tet.spine_center, line) > tet.spine_radius
|
|
513
|
+
for tet in mcomplex.Tetrahedra):
|
|
514
|
+
continue
|
|
515
|
+
|
|
516
|
+
if mcomplex.verified:
|
|
517
|
+
# We need to make sure that the intervals are tight enough
|
|
518
|
+
# that we do not accidentally add a multiple before adding
|
|
519
|
+
# a primitive.
|
|
520
|
+
if not real_length.relative_diameter() < 0.125:
|
|
521
|
+
raise InsufficientPrecisionError(
|
|
522
|
+
"Interval of real length of geodesic too large. "
|
|
523
|
+
"Increase precision to fix it.")
|
|
524
|
+
|
|
525
|
+
# We also ignore core curves here since they have been
|
|
526
|
+
# explicitly added earlier.
|
|
527
|
+
#
|
|
528
|
+
# Note that this requires computing the start point info
|
|
529
|
+
# which can be expensive so we do the other checks first.
|
|
530
|
+
#
|
|
531
|
+
if geodesic.geodesic_start_point_info().core_curve_cusp:
|
|
532
|
+
continue
|
|
533
|
+
|
|
534
|
+
# Check that we have not visited this geodesic already
|
|
535
|
+
if not visited_geodesics.add(geodesic):
|
|
536
|
+
continue
|
|
537
|
+
# else:
|
|
538
|
+
# This is a core curve. We already know that they are
|
|
539
|
+
# de-duplicated (and cannot be parabolics), so no checks
|
|
540
|
+
# to perform.
|
|
541
|
+
|
|
542
|
+
if not real_length > 0:
|
|
543
|
+
raise InsufficientPrecisionError(
|
|
544
|
+
"Could not verify that a geodesic is not a parabolic. "
|
|
545
|
+
"This is most likely due to insufficient precision.")
|
|
546
|
+
|
|
547
|
+
if last_real_length is not None:
|
|
548
|
+
if not lower(last_real_length) <= lower(real_length):
|
|
549
|
+
raise InsufficientPrecisionError(
|
|
550
|
+
"Lower bound of new geodesics is less than that of "
|
|
551
|
+
"already seen geodesics. Re-start length spectrum "
|
|
552
|
+
"computation with higher precision to see more "
|
|
553
|
+
"geodesics.")
|
|
554
|
+
|
|
555
|
+
last_real_length = real_length
|
|
556
|
+
|
|
557
|
+
yield geodesic
|
|
558
|
+
|
|
559
|
+
if include_intermediates:
|
|
560
|
+
# Minimum of length from pre-length spectrum and geodesics
|
|
561
|
+
# that are still in the priority queue and have not been
|
|
562
|
+
# emitted yet.
|
|
563
|
+
if pending_geodesics:
|
|
564
|
+
lower_bound_geodesic_length = correct_min(
|
|
565
|
+
[ r - epsilon,
|
|
566
|
+
pending_geodesics[0].length.real() ])
|
|
567
|
+
else:
|
|
568
|
+
lower_bound_geodesic_length = (
|
|
569
|
+
r - epsilon)
|
|
570
|
+
yield GeodesicIntermediateInfo(
|
|
571
|
+
length = lower_bound_geodesic_length)
|
|
572
|
+
|
|
573
|
+
heapq.heappush(
|
|
574
|
+
pending_geodesics,
|
|
575
|
+
GeodesicKeyInfo(mcomplex, tile.word, tile.o13_matrix))
|
|
576
|
+
|
|
577
|
+
def _geodesic_key_infos_for_core_curves(
|
|
578
|
+
mcomplex, manifold) -> Sequence[CoreCurveGeodesicInfo]:
|
|
579
|
+
"""
|
|
580
|
+
Computes geodesic info for all core curves given Mcomplex constructed
|
|
581
|
+
with mcomplex_for_len_spec and the SnapPy Manifold.
|
|
582
|
+
"""
|
|
583
|
+
|
|
584
|
+
G = manifold.fundamental_group(False)
|
|
585
|
+
all_peripheral_words = G.peripheral_curves(as_int_list = True)
|
|
586
|
+
|
|
587
|
+
for cusp, peripheral_words in zip(mcomplex.Vertices, all_peripheral_words):
|
|
588
|
+
if cusp.is_complete:
|
|
589
|
+
continue
|
|
590
|
+
|
|
591
|
+
word = []
|
|
592
|
+
|
|
593
|
+
# Add suitable multiples of word corresponding to meridian and longitude
|
|
594
|
+
for peripheral_word, f in zip(peripheral_words, cusp.filling_matrix[1]):
|
|
595
|
+
if f == 0:
|
|
596
|
+
continue
|
|
597
|
+
if f < 0:
|
|
598
|
+
peripheral_word = inverse_list_word(peripheral_word)
|
|
599
|
+
f = -f
|
|
600
|
+
word += f * peripheral_word
|
|
601
|
+
|
|
602
|
+
psl2c_matrix = word_list_to_psl2c_matrix(mcomplex, word)
|
|
603
|
+
|
|
604
|
+
o13_matrix = psl2c_to_o13(psl2c_matrix)
|
|
605
|
+
|
|
606
|
+
yield CoreCurveGeodesicInfo(
|
|
607
|
+
word,
|
|
608
|
+
o13_matrix,
|
|
609
|
+
core_curve = cusp.Index)
|