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,456 @@
|
|
|
1
|
+
from . import exceptions
|
|
2
|
+
from . import epsilons
|
|
3
|
+
from . import debug
|
|
4
|
+
from .tracing import trace_geodesic
|
|
5
|
+
from .perturb import perturb_geodesics
|
|
6
|
+
from .subdivide import traverse_geodesics_to_subdivide
|
|
7
|
+
from .barycentric import mark_subtetrahedra_about_geodesic_pieces
|
|
8
|
+
from .shorten import shorten_in_barycentric_subdivision
|
|
9
|
+
from .crush import crush_geodesic_pieces
|
|
10
|
+
from .cusps import (
|
|
11
|
+
CuspPostDrillInfo,
|
|
12
|
+
index_geodesics_and_add_post_drill_infos,
|
|
13
|
+
reorder_vertices_and_get_post_drill_infos,
|
|
14
|
+
refill_and_adjust_peripheral_curves)
|
|
15
|
+
|
|
16
|
+
from .. import Manifold, ManifoldHP
|
|
17
|
+
|
|
18
|
+
from ..geometric_structure.geodesic.geodesic_start_point_info import GeodesicStartPointInfo, compute_geodesic_start_point_info
|
|
19
|
+
from ..geometric_structure import (add_r13_geometry,
|
|
20
|
+
add_filling_information)
|
|
21
|
+
from ..geometric_structure.geodesic.add_core_curves import add_r13_core_curves
|
|
22
|
+
from ..geometric_structure.geodesic.line import R13LineWithMatrix
|
|
23
|
+
from ..snap.t3mlite import Mcomplex
|
|
24
|
+
from ..exceptions import InsufficientPrecisionError
|
|
25
|
+
|
|
26
|
+
from typing import Optional, Sequence
|
|
27
|
+
|
|
28
|
+
def drill_word(manifold,
|
|
29
|
+
word : str,
|
|
30
|
+
verified : bool = False,
|
|
31
|
+
bits_prec : Optional[int] = None,
|
|
32
|
+
verbose : bool = False) -> Manifold:
|
|
33
|
+
"""
|
|
34
|
+
Drills the geodesic corresponding to the given word in the unsimplified
|
|
35
|
+
fundamental group. Here is an example::
|
|
36
|
+
|
|
37
|
+
>>> M = Manifold("m004")
|
|
38
|
+
>>> M.length_spectrum_alt(max_len=1.2) # doctest: +NUMERIC9
|
|
39
|
+
[Length Core curve Word
|
|
40
|
+
1.08707014499574 + 1.72276844987009*I - bC,
|
|
41
|
+
1.08707014499574 - 1.72276844987009*I - a]
|
|
42
|
+
>>> N = M.drill_word('a')
|
|
43
|
+
>>> N.identify()
|
|
44
|
+
[m129(0,0)(0,0), 5^2_1(0,0)(0,0), L5a1(0,0)(0,0), ooct01_00001(0,0)(0,0)]
|
|
45
|
+
|
|
46
|
+
The last cusp of the resulting manifold corresponds to the drilled
|
|
47
|
+
geodesic. The longitude and meridian for that cusp are chosen such that
|
|
48
|
+
``(1,0)``-filling the last cusp results in the given (undrilled) manifold::
|
|
49
|
+
|
|
50
|
+
>>> N.dehn_fill((1,0),-1)
|
|
51
|
+
>>> M.is_isometric_to(N)
|
|
52
|
+
True
|
|
53
|
+
>>> N.cusp_info(1)['core_length'] # doctest: +NUMERIC9
|
|
54
|
+
1.08707014499574 - 1.72276844987009*I
|
|
55
|
+
|
|
56
|
+
The orientation of the new longitude is chosen so that it is parallel to
|
|
57
|
+
the closed geodesic. That is, the new longitude is homotopic to the closed
|
|
58
|
+
geodesic when embedding the drilled manifold into the given manifold.
|
|
59
|
+
|
|
60
|
+
If the given geodesic coincides with a core curve of a filled cusp, the
|
|
61
|
+
cusp is unfilled instead::
|
|
62
|
+
|
|
63
|
+
>>> M = Manifold("m004(2,3)")
|
|
64
|
+
>>> M.volume() # doctest: +NUMERIC9
|
|
65
|
+
1.73712388065
|
|
66
|
+
>>> M.cusp_info(0)['core_length'] # doctest: +NUMERIC9
|
|
67
|
+
0.178792491242577 - 2.11983007979743*I
|
|
68
|
+
>>> M.fundamental_group(simplify_presentation = False).complex_length('aBAbbABab') # doctest: +NUMERIC9
|
|
69
|
+
0.178792491242577 - 2.11983007979743*I
|
|
70
|
+
>>> N = M.drill_word('aBAbbABab')
|
|
71
|
+
>>> N
|
|
72
|
+
m004_drilled(0,0)
|
|
73
|
+
>>> N.num_cusps()
|
|
74
|
+
1
|
|
75
|
+
|
|
76
|
+
In this case, the peripheral information is also
|
|
77
|
+
updated such that the above remark about ``(1,0)``-filling applies again::
|
|
78
|
+
|
|
79
|
+
>>> N.dehn_fill((1,0), -1)
|
|
80
|
+
>>> N.volume() # doctest: +NUMERIC9
|
|
81
|
+
1.73712388065
|
|
82
|
+
|
|
83
|
+
That is, the longitude and meridian of the unfilled cusps are reinstalled
|
|
84
|
+
and the cusps reindexed so that the unfilled cusp becomes the last cusp.
|
|
85
|
+
|
|
86
|
+
Here is another example where we drill the core geodesic::
|
|
87
|
+
|
|
88
|
+
>>> M = Manifold("v2986(3,4)")
|
|
89
|
+
>>> N = M.drill_word('EdFgabcGEdFgaDcc')
|
|
90
|
+
>>> N.is_isometric_to(Manifold("v2986"), return_isometries = True) # doctest: +NORMALIZE_WHITESPACE
|
|
91
|
+
[0 -> 0
|
|
92
|
+
[3 -1]
|
|
93
|
+
[4 -1]
|
|
94
|
+
Does not extend to link]
|
|
95
|
+
|
|
96
|
+
While the result of drilling a geodesic is a triangulation and thus
|
|
97
|
+
combinatorial in nature, some intermediate computations (for example,
|
|
98
|
+
to compute the intersections of the geodesic with the faces of the
|
|
99
|
+
tetrahedra) are numerical. Sometimes, it is necessary to increase the
|
|
100
|
+
precision with :attr:`bits_prec` to make the method succeed and produce
|
|
101
|
+
the correct result.
|
|
102
|
+
|
|
103
|
+
**Verified computation**
|
|
104
|
+
|
|
105
|
+
If :attr:`verified = False`, floating-point issues can arise resulting
|
|
106
|
+
in drilling the wrong loop. The method can be made
|
|
107
|
+
:ref:`verified <verify-primer>` by passing :attr:`verified = True`::
|
|
108
|
+
|
|
109
|
+
sage: M = Manifold("m004(2,3)")
|
|
110
|
+
sage: M.drill_word('caa', verified = True, bits_prec = 100)
|
|
111
|
+
m004_drilled(2,3)(0,0)
|
|
112
|
+
|
|
113
|
+
That is, if the precision is insufficient to prove the result is correct,
|
|
114
|
+
the algorithm fails with an exception (most likely
|
|
115
|
+
``InsufficientPrecisionError``).
|
|
116
|
+
|
|
117
|
+
:param word:
|
|
118
|
+
The word in the unsimplified fundamental group specifying the
|
|
119
|
+
geodesic to be drilled.
|
|
120
|
+
:param bits_prec:
|
|
121
|
+
The precision used in the intermediate computation. Increase
|
|
122
|
+
if the computation failed.
|
|
123
|
+
:param verified:
|
|
124
|
+
Use :ref:`verified computation <verify-primer>`.
|
|
125
|
+
:param verbose:
|
|
126
|
+
Print intermediate results and statistics.
|
|
127
|
+
|
|
128
|
+
:return:
|
|
129
|
+
Manifold obtained by drilling geodesic. ``(1,0)``-filling the
|
|
130
|
+
last cusp gives the given (undrilled) manifold.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
return drill_words(manifold,
|
|
134
|
+
[word],
|
|
135
|
+
verified=verified,
|
|
136
|
+
bits_prec=bits_prec,
|
|
137
|
+
verbose=verbose)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def drill_words(manifold,
|
|
141
|
+
words : Sequence[str],
|
|
142
|
+
verified : bool = False,
|
|
143
|
+
bits_prec : Optional[int] = None,
|
|
144
|
+
verbose : bool = False) -> Manifold:
|
|
145
|
+
"""
|
|
146
|
+
A generalization of :meth:`drill_word <Manifold.drill_word>` to drill
|
|
147
|
+
several geodesics simultaneously. It takes a list of words in the
|
|
148
|
+
unsimplified fundamental group.
|
|
149
|
+
|
|
150
|
+
Here is an example where we drill two geodesics. One of the geodesics is
|
|
151
|
+
the core curve corresponding to the third cusp. The other geodesic is not
|
|
152
|
+
a core curve::
|
|
153
|
+
|
|
154
|
+
>>> M=Manifold("t12047(0,0)(1,3)(1,4)(1,5)")
|
|
155
|
+
>>> [ info.get('core_length') for info in M.cusp_info() ] # doctest: +NUMERIC9
|
|
156
|
+
[None,
|
|
157
|
+
0.510804267610103 + 1.92397456664239*I,
|
|
158
|
+
0.317363079597924 + 1.48157893409218*I,
|
|
159
|
+
0.223574975263386 + 1.26933288854145*I]
|
|
160
|
+
>>> G = M.fundamental_group(simplify_presentation = False)
|
|
161
|
+
>>> G.complex_length('c') # doctest: +NUMERIC9
|
|
162
|
+
0.317363079597924 + 1.48157893409218*I
|
|
163
|
+
>>> G.complex_length('fA') # doctest: +NUMERIC9
|
|
164
|
+
1.43914411734250 + 2.66246879992795*I
|
|
165
|
+
>>> N = M.drill_words(['c','fA'])
|
|
166
|
+
>>> N
|
|
167
|
+
t12047_drilled(0,0)(1,3)(1,5)(0,0)(0,0)
|
|
168
|
+
|
|
169
|
+
Let n be the number of geodesics that were drilled. Then the last n
|
|
170
|
+
cusps correspond to the drilled geodesics and appear in the same order than
|
|
171
|
+
the geodesics were given as words. Note that in the above example, we expect
|
|
172
|
+
six cusps since we started with four cusps and drilled two geodesics. However,
|
|
173
|
+
we only obtain five cusps because one geodesic was a core curve. The
|
|
174
|
+
corresponding cusp was unfilled (from ``(1,4)``) and grouped with the other
|
|
175
|
+
cusps coming from drilling.
|
|
176
|
+
|
|
177
|
+
We obtain the given (undrilled) manifold by ``(1,0)``-filling the last n
|
|
178
|
+
cusps.
|
|
179
|
+
|
|
180
|
+
>>> N.dehn_fill((1,0), -2)
|
|
181
|
+
>>> N.dehn_fill((1,0), -1)
|
|
182
|
+
>>> M.is_isometric_to(N)
|
|
183
|
+
True
|
|
184
|
+
>>> [ info.get('core_length') for info in N.cusp_info() ] # doctest: +NUMERIC9
|
|
185
|
+
[None,
|
|
186
|
+
0.510804267610103 + 1.92397456664239*I,
|
|
187
|
+
0.223574975263386 + 1.26933288854145*I,
|
|
188
|
+
0.317363079597924 + 1.48157893409218*I,
|
|
189
|
+
1.43914411734251 + 2.66246879992796*I]
|
|
190
|
+
|
|
191
|
+
:param word:
|
|
192
|
+
The words in the unsimplified fundamental group specifying the
|
|
193
|
+
geodesics to be drilled.
|
|
194
|
+
:param bits_prec:
|
|
195
|
+
The precision used in the intermediate computation. Increase
|
|
196
|
+
if the computation failed.
|
|
197
|
+
:param verified:
|
|
198
|
+
Use :ref:`verified computation <verify-primer>`.
|
|
199
|
+
:param verbose:
|
|
200
|
+
Print intermediate results and statistics.
|
|
201
|
+
|
|
202
|
+
:return:
|
|
203
|
+
Manifold obtained by drilling geodesics. ``(1,0)``-filling the
|
|
204
|
+
last n cusps gives the given (undrilled) manifold where n is the
|
|
205
|
+
number of given words.
|
|
206
|
+
"""
|
|
207
|
+
|
|
208
|
+
if isinstance(words, str):
|
|
209
|
+
raise ValueError("words has to be a list of strings, not a single string.")
|
|
210
|
+
|
|
211
|
+
if len(words) == 0:
|
|
212
|
+
# Just return copy of manifold if nothing is drilled.
|
|
213
|
+
return manifold.copy()
|
|
214
|
+
|
|
215
|
+
if not manifold.is_orientable():
|
|
216
|
+
raise ValueError("Drilling only supported for orientable manifolds.")
|
|
217
|
+
|
|
218
|
+
try:
|
|
219
|
+
# First try to drill the geodesics without perturbing them.
|
|
220
|
+
return drill_words_implementation(
|
|
221
|
+
manifold,
|
|
222
|
+
words=words,
|
|
223
|
+
verified=verified,
|
|
224
|
+
bits_prec=bits_prec,
|
|
225
|
+
verbose=verbose)
|
|
226
|
+
except exceptions.GeodesicHittingOneSkeletonError:
|
|
227
|
+
# Exceptions raised when geodesic is intersecting the 1-skeleton
|
|
228
|
+
# (including that a positive length piece of the geodesic lying
|
|
229
|
+
# in a face).
|
|
230
|
+
# An interesting example is the shortest geodesic ("a" in
|
|
231
|
+
# unsimplified fundamental group) of m125: the entire geodesic
|
|
232
|
+
# lies in the faces of the triangulation.
|
|
233
|
+
pass
|
|
234
|
+
|
|
235
|
+
# If geodesic is intersecting 1-skeleton, try again, this time
|
|
236
|
+
# perturbing the geodesic before drilling it.
|
|
237
|
+
try:
|
|
238
|
+
return drill_words_implementation(
|
|
239
|
+
manifold,
|
|
240
|
+
words=words,
|
|
241
|
+
verified=verified,
|
|
242
|
+
bits_prec=bits_prec,
|
|
243
|
+
perturb=True,
|
|
244
|
+
verbose=verbose)
|
|
245
|
+
except exceptions.RayHittingOneSkeletonError as e:
|
|
246
|
+
# Sometimes, the code runs into numerical issues and cannot
|
|
247
|
+
# determine whether the perturbed geodesic is passing an edge
|
|
248
|
+
# on one side or the other. This can usually be fixed by
|
|
249
|
+
# increasing precision - change the exception type to tell the
|
|
250
|
+
# user.
|
|
251
|
+
raise InsufficientPrecisionError(
|
|
252
|
+
"The geodesic is so closer to an edge of the "
|
|
253
|
+
"triangulation that it cannot be unambiguously traced "
|
|
254
|
+
"with the current precision. "
|
|
255
|
+
"Increasing the precision should solve this problem.") from e
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def drill_words_implementation(
|
|
259
|
+
manifold,
|
|
260
|
+
words,
|
|
261
|
+
verified,
|
|
262
|
+
bits_prec,
|
|
263
|
+
perturb=False,
|
|
264
|
+
verbose : bool = False):
|
|
265
|
+
|
|
266
|
+
# Convert SnapPea kernel triangulation to python triangulation
|
|
267
|
+
# snappy.snap.t3mlite.Mcomplex
|
|
268
|
+
mcomplex = Mcomplex(manifold)
|
|
269
|
+
|
|
270
|
+
# Add vertices in hyperboloid model and other geometric information
|
|
271
|
+
add_r13_geometry(mcomplex,
|
|
272
|
+
manifold,
|
|
273
|
+
verified=verified, bits_prec=bits_prec)
|
|
274
|
+
add_filling_information(mcomplex, manifold)
|
|
275
|
+
add_r13_core_curves(mcomplex, manifold)
|
|
276
|
+
|
|
277
|
+
# For the words compute basic information such as the corresponding
|
|
278
|
+
# matrix and the end points and a sample point on the fixed line.
|
|
279
|
+
# Try to conjugate/translate matrix and end points such that the
|
|
280
|
+
# line intersects the fundamental domain.
|
|
281
|
+
geodesics : Sequence[GeodesicStartPointInfo] = [
|
|
282
|
+
compute_geodesic_start_point_info(mcomplex, word)
|
|
283
|
+
for word in words ]
|
|
284
|
+
|
|
285
|
+
# Record information in the geodesics and triangulation needed
|
|
286
|
+
# to index the cusps after drilling and transform the peripheral
|
|
287
|
+
# curves and unfill the cusps if drilling a core curve.
|
|
288
|
+
index_geodesics_and_add_post_drill_infos(geodesics, mcomplex)
|
|
289
|
+
|
|
290
|
+
# Only drill the geodesics that are not core curves of filled
|
|
291
|
+
# cusps. For the other geodesics, we simply unfill the cusp instead.
|
|
292
|
+
geodesics_to_drill = [ g for g in geodesics
|
|
293
|
+
if not g.core_curve_cusp ]
|
|
294
|
+
|
|
295
|
+
if verbose:
|
|
296
|
+
for g in geodesics:
|
|
297
|
+
if g.core_curve_cusp:
|
|
298
|
+
print("%s is core curve" % g.word)
|
|
299
|
+
|
|
300
|
+
if perturb:
|
|
301
|
+
# Move the sample point for each geodesic a bit and use it
|
|
302
|
+
# as start point. Much of perturb_geodesics is about computing
|
|
303
|
+
# the maximal amount we can move all the start points without
|
|
304
|
+
# changing the isotopy class of the system of resulting closed
|
|
305
|
+
# curves.
|
|
306
|
+
perturb_geodesics(mcomplex,
|
|
307
|
+
geodesics_to_drill,
|
|
308
|
+
verbose=verbose)
|
|
309
|
+
|
|
310
|
+
# At this point, the information in each entry of geodesics_to_drill
|
|
311
|
+
# "should" (*) contain a start point in the interior of a tetrahedron
|
|
312
|
+
# of the fundamental domain and an end point that is the image under
|
|
313
|
+
# the stored matrix corresponding to the geodesic.
|
|
314
|
+
# Depending on perturb, the start point is either on or close
|
|
315
|
+
# the line fixed by the matrix.
|
|
316
|
+
# The image of the line segment from start point to end point
|
|
317
|
+
# in the manifold is a closed curve that is equal or isotopic to the
|
|
318
|
+
# geodesic. If multiple words are given, the system of closed curve
|
|
319
|
+
# is isotopic to the system of geodesics.
|
|
320
|
+
|
|
321
|
+
# (*) This is not true if perturb is false and the geodesic intersects
|
|
322
|
+
# the 1-skeleton. In this case, drill_geodesics raises a
|
|
323
|
+
# GeodesicHittingOneSkeletonError which is caught by the callee so that
|
|
324
|
+
# the callee can call this function again with perturb = True.
|
|
325
|
+
|
|
326
|
+
# For each geodesic to drill, trace the line segment from start to end
|
|
327
|
+
# point through the triangulation, and then drill the closed curve.
|
|
328
|
+
drilled_mcomplex : Mcomplex = drill_geodesics(mcomplex,
|
|
329
|
+
geodesics_to_drill,
|
|
330
|
+
verbose=verbose)
|
|
331
|
+
|
|
332
|
+
# Index the cusps of the new triangulation and extract information
|
|
333
|
+
# needed later
|
|
334
|
+
post_drill_infos : Sequence[CuspPostDrillInfo] = (
|
|
335
|
+
reorder_vertices_and_get_post_drill_infos(drilled_mcomplex))
|
|
336
|
+
|
|
337
|
+
# Convert python triangulation to SnapPea kernel triangulation.
|
|
338
|
+
# Note that this will remove the finite vertices created by
|
|
339
|
+
# drill_geodesics.
|
|
340
|
+
drilled_manifold = drilled_mcomplex.snappy_manifold()
|
|
341
|
+
|
|
342
|
+
# If there was a filled cusp whose core curve was not drilled, we need
|
|
343
|
+
# to refill it. If there was a filled cusp whose core curve was drilled,
|
|
344
|
+
# we need to change the peripheral curves such that the longitude
|
|
345
|
+
# corresponds to the core curve so that (1,0)-filling results in the
|
|
346
|
+
# original manifold.
|
|
347
|
+
refill_and_adjust_peripheral_curves(drilled_manifold, post_drill_infos)
|
|
348
|
+
|
|
349
|
+
# Set name
|
|
350
|
+
drilled_manifold.set_name(manifold.name() + "_drilled")
|
|
351
|
+
|
|
352
|
+
return drilled_manifold
|
|
353
|
+
|
|
354
|
+
def drill_geodesics(mcomplex : Mcomplex,
|
|
355
|
+
geodesics : Sequence[GeodesicStartPointInfo],
|
|
356
|
+
verbose : bool = False) -> Mcomplex:
|
|
357
|
+
"""
|
|
358
|
+
Given a triangulation with geometric structure attached with
|
|
359
|
+
add_r13_geometry and basic information about geodesics, computes
|
|
360
|
+
the triangulation (with finite vertices) obtained by drilling
|
|
361
|
+
the geodesics.
|
|
362
|
+
|
|
363
|
+
Each provided GeodesicStartPointInfo is supposed to have a start point and
|
|
364
|
+
a tetrahedron in the fundamental domain that contains the start point
|
|
365
|
+
in its interior and an end point such that the line segment from the
|
|
366
|
+
start to the endpoint forms a closed curve in the manifold.
|
|
367
|
+
"""
|
|
368
|
+
|
|
369
|
+
if len(geodesics) == 0:
|
|
370
|
+
# Nothing to do if there is nothing to drill
|
|
371
|
+
return mcomplex
|
|
372
|
+
|
|
373
|
+
for g in geodesics:
|
|
374
|
+
# We need a tetrahedron guaranteed to contain the start point
|
|
375
|
+
# to start tracing.
|
|
376
|
+
if not g.tet:
|
|
377
|
+
raise exceptions.GeodesicStartPointOnTwoSkeletonError()
|
|
378
|
+
|
|
379
|
+
# For each line segment described above, trace it through the
|
|
380
|
+
# triangulation.
|
|
381
|
+
all_pieces : Sequence[Sequence[GeodesicPiece]] = [
|
|
382
|
+
trace_geodesic(g, verified=mcomplex.verified)
|
|
383
|
+
for g in geodesics ]
|
|
384
|
+
|
|
385
|
+
if verbose:
|
|
386
|
+
print("Number of geodesic pieces:",
|
|
387
|
+
[len(pieces) for pieces in all_pieces])
|
|
388
|
+
|
|
389
|
+
# Perform 1-4 and 2-3 moves such that the closed curves embed
|
|
390
|
+
# into the 1-skeleton of the resulting triangulation.
|
|
391
|
+
#
|
|
392
|
+
# Rather than creating a triangulation object (and thus
|
|
393
|
+
# computing the Vertex, Edge, ... objects), we just compute
|
|
394
|
+
# the tetrahedra forming the triangulation.
|
|
395
|
+
tetrahedra : Sequence[Tetrahedron] = traverse_geodesics_to_subdivide(
|
|
396
|
+
mcomplex, all_pieces)
|
|
397
|
+
|
|
398
|
+
if verbose:
|
|
399
|
+
print("Number of tets after subdividing: %d" % (
|
|
400
|
+
len(tetrahedra)))
|
|
401
|
+
|
|
402
|
+
# Mark which subtetrahedra in the barycentric subdivision
|
|
403
|
+
# are adjacent to the closed curve we traced.
|
|
404
|
+
mark_subtetrahedra_about_geodesic_pieces(tetrahedra)
|
|
405
|
+
|
|
406
|
+
# If the simple closed curve is having two consecutive pieces
|
|
407
|
+
# adjacent to the same face, making it shorter by replacing
|
|
408
|
+
# the two pieces by just one corresponding to the third edge
|
|
409
|
+
# of the triangle.
|
|
410
|
+
shorten_in_barycentric_subdivision(tetrahedra, verbose)
|
|
411
|
+
|
|
412
|
+
# Perform a barycentric subdivision. Then crush all tetrahedra
|
|
413
|
+
# touching the closed curve we traced. Note that
|
|
414
|
+
# crush_geodesic_pieces is actually doing the subdivision and
|
|
415
|
+
# crushing of the subsimplices marked above in just one step.
|
|
416
|
+
result : Mcomplex = crush_geodesic_pieces(tetrahedra)
|
|
417
|
+
|
|
418
|
+
# Sanity checks while we are still testing the new features.
|
|
419
|
+
debug.check_vertex_indices(result.Tetrahedra)
|
|
420
|
+
debug.check_peripheral_curves(result.Tetrahedra)
|
|
421
|
+
|
|
422
|
+
return result
|
|
423
|
+
|
|
424
|
+
def drill_word_hp(manifold,
|
|
425
|
+
word : str,
|
|
426
|
+
verified : bool = False,
|
|
427
|
+
bits_prec : Optional[int] = None,
|
|
428
|
+
verbose : bool = False) -> ManifoldHP:
|
|
429
|
+
return drill_word(
|
|
430
|
+
manifold,
|
|
431
|
+
word = word,
|
|
432
|
+
verified = verified,
|
|
433
|
+
bits_prec = bits_prec,
|
|
434
|
+
verbose = verbose).high_precision()
|
|
435
|
+
drill_word_hp.__doc__ = drill_word.__doc__
|
|
436
|
+
|
|
437
|
+
def drill_words_hp(manifold,
|
|
438
|
+
words : Sequence[str],
|
|
439
|
+
verified : bool = False,
|
|
440
|
+
bits_prec : Optional[int] = None,
|
|
441
|
+
verbose : bool = False) -> ManifoldHP:
|
|
442
|
+
return drill_words(
|
|
443
|
+
manifold,
|
|
444
|
+
words = words,
|
|
445
|
+
verified = verified,
|
|
446
|
+
bits_prec = bits_prec,
|
|
447
|
+
verbose = verbose).high_precision()
|
|
448
|
+
drill_words_hp.__doc__ = drill_words.__doc__
|
|
449
|
+
|
|
450
|
+
def _add_methods(mfld_class, high_precision=False):
|
|
451
|
+
if high_precision:
|
|
452
|
+
mfld_class.drill_word = drill_word_hp
|
|
453
|
+
mfld_class.drill_words = drill_words_hp
|
|
454
|
+
else:
|
|
455
|
+
mfld_class.drill_word = drill_word
|
|
456
|
+
mfld_class.drill_words = drill_words
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from .tracing import GeodesicPiece
|
|
2
|
+
|
|
3
|
+
from ..snap.t3mlite import Tetrahedron, Perm4, simplex
|
|
4
|
+
|
|
5
|
+
from typing import Dict, List, Sequence, Tuple
|
|
6
|
+
|
|
7
|
+
def mark_subtetrahedra_about_geodesic_pieces(
|
|
8
|
+
tetrahedra : Sequence[Tetrahedron]) -> None:
|
|
9
|
+
"""
|
|
10
|
+
Record which subtetrahedra of the barycentric subdivision
|
|
11
|
+
are adjacent to a piece of the geodesic.
|
|
12
|
+
|
|
13
|
+
This is recorded in the array Tetrahedron.marked_subtetrahedra.
|
|
14
|
+
|
|
15
|
+
Recall that the subtetrahedra of the barycentric subdivision
|
|
16
|
+
are indexed by S4 permutations. The index within
|
|
17
|
+
Tetrahedron.marked_subtetrahedra is given by perm_to_index(p).
|
|
18
|
+
|
|
19
|
+
The value of Tetrahedron.marked_subtetrahedra[j] is 0 if
|
|
20
|
+
the subtetrahedron is not adjacent to any piece of the geodesic.
|
|
21
|
+
Otherwise, it is +/-1 depending on whether the 0-1 edge
|
|
22
|
+
of the subtetrahedron is parallel or anti-parallel to the
|
|
23
|
+
geodesic piece. This is recorded to orient the meridian
|
|
24
|
+
and longitude.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
for tet in tetrahedra:
|
|
28
|
+
tet.marked_subtetrahedra = 24 * [ 0 ]
|
|
29
|
+
|
|
30
|
+
for tet in tetrahedra:
|
|
31
|
+
for piece in tet.geodesic_pieces:
|
|
32
|
+
mark_subtetrahedra_about_edge(tet, _perm_for_piece(piece))
|
|
33
|
+
|
|
34
|
+
transpositions : List[Perm4] = [ Perm4((1,0,2,3)),
|
|
35
|
+
Perm4((0,2,1,3)),
|
|
36
|
+
Perm4((0,1,3,2)) ]
|
|
37
|
+
|
|
38
|
+
def perm_to_index(perm : Perm4) -> int:
|
|
39
|
+
"""
|
|
40
|
+
list(Perm4.S4())[perm_to_index(p)] returns the same Perm4 p.
|
|
41
|
+
"""
|
|
42
|
+
return _perm_tuple_to_index[perm.tuple()]
|
|
43
|
+
|
|
44
|
+
_perm_tuple_to_index : Dict[Tuple[int, int, int, int], int] = {
|
|
45
|
+
perm.tuple() : i for i, perm in enumerate(Perm4.S4()) }
|
|
46
|
+
|
|
47
|
+
def _perm_for_piece(piece : GeodesicPiece):
|
|
48
|
+
"""
|
|
49
|
+
Given a GeodesicPiece with endpoints being on the vertices
|
|
50
|
+
of the tetrahedron and spanning an oriented edge of the tetrahedron,
|
|
51
|
+
find an "edge embedding permutation" (similar to regina's
|
|
52
|
+
edge embedding) that maps the 0-1 edge to the given edge.
|
|
53
|
+
|
|
54
|
+
The subtetrahedron corresponding to this permutation is
|
|
55
|
+
adjacent to half of this edge.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
s0 = piece.endpoints[0].subsimplex
|
|
59
|
+
s1 = piece.endpoints[1].subsimplex
|
|
60
|
+
|
|
61
|
+
# Important to consistently always pick a permutation of the
|
|
62
|
+
# same parity and respect the ordering of the vertices V0 and V1
|
|
63
|
+
# since this affects which subtetrahedron will be chosen as peripheral
|
|
64
|
+
# base subtetrahedron - and thus ultimately affects the orientation
|
|
65
|
+
# of the meridian and longitude computed by install_peripheral_curves.
|
|
66
|
+
for perm in Perm4.A4():
|
|
67
|
+
if perm.image(simplex.V0) == s0 and perm.image(simplex.V1) == s1:
|
|
68
|
+
return perm
|
|
69
|
+
|
|
70
|
+
def mark_subtetrahedra_about_edge(tet0 : Tetrahedron, perm0 : Perm4, orientation : int = 1):
|
|
71
|
+
"""
|
|
72
|
+
Given a subtetrahedron in the barycentric subdivision parametrized
|
|
73
|
+
by a tetrahedron and permutation, find all subtetrahedra adjacent to the
|
|
74
|
+
same edge in the original triangulation and mark them in
|
|
75
|
+
Tetrahedron.marked_subtetrahedra.
|
|
76
|
+
|
|
77
|
+
By default (orientation = 1), the subtetrahedra are marked by +/-1 according
|
|
78
|
+
to whether each is parallel or anti-parallel to the given edge.
|
|
79
|
+
Subtetrahedra can be unmarked by forcing orientation = 0.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
tet = tet0
|
|
83
|
+
perm = perm0
|
|
84
|
+
|
|
85
|
+
while True:
|
|
86
|
+
# All subtetrahedra touching the same edge in the current
|
|
87
|
+
# tetrahedron.
|
|
88
|
+
for edge_perm in [ perm,
|
|
89
|
+
perm * transpositions[2] ]:
|
|
90
|
+
for marked_subtet, subtet_perm in [
|
|
91
|
+
(+orientation, edge_perm),
|
|
92
|
+
(-orientation, edge_perm * transpositions[0]) ]:
|
|
93
|
+
j = perm_to_index(subtet_perm)
|
|
94
|
+
tet.marked_subtetrahedra[j] = marked_subtet
|
|
95
|
+
|
|
96
|
+
# Find the next "edge embedding"
|
|
97
|
+
face = perm.image(simplex.F3)
|
|
98
|
+
tet, perm = (
|
|
99
|
+
tet.Neighbor[face],
|
|
100
|
+
tet.Gluing[face] * perm * transpositions[2])
|
|
101
|
+
# Stop if back at the first "edge embedding"
|
|
102
|
+
if tet is tet0 and perm.tuple() == perm0.tuple():
|
|
103
|
+
return
|