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,335 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A Sage module for finding the holonomy representation of a hyperbolic
|
|
3
|
+
3-manifold to very high precision.
|
|
4
|
+
"""
|
|
5
|
+
from itertools import product, chain
|
|
6
|
+
from ..sage_helper import _within_sage
|
|
7
|
+
from ..math_basics import prod
|
|
8
|
+
from ..pari import pari
|
|
9
|
+
|
|
10
|
+
from .fundamental_polyhedron import *
|
|
11
|
+
|
|
12
|
+
if _within_sage:
|
|
13
|
+
from ..sage_helper import RealField, ComplexField, gcd, prod, powerset
|
|
14
|
+
from ..sage_helper import MatrixSpace, matrix, vector, ZZ
|
|
15
|
+
from ..sage_helper import SageObject as Object
|
|
16
|
+
|
|
17
|
+
identity = lambda A: MatrixSpace(A.base_ring(), A.nrows())(1)
|
|
18
|
+
abelian_group_elt = lambda v: vector(ZZ, v)
|
|
19
|
+
else:
|
|
20
|
+
Object = object
|
|
21
|
+
from .utilities import Matrix2x2 as matrix, powerset
|
|
22
|
+
from ..number import Number
|
|
23
|
+
|
|
24
|
+
def identity(A):
|
|
25
|
+
return matrix(A.base_ring(), 1.0, 0.0, 0.0, 1.0)
|
|
26
|
+
abelian_group_elt = lambda v: v
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# ----------------------------------------------------------------
|
|
30
|
+
#
|
|
31
|
+
# Abelianization of the fundamental group
|
|
32
|
+
#
|
|
33
|
+
# ----------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
class MapToFreeAbelianization(Object):
|
|
36
|
+
"""
|
|
37
|
+
>>> import snappy
|
|
38
|
+
>>> M = snappy.Manifold('m125')
|
|
39
|
+
>>> G = M.fundamental_group(False, False, False)
|
|
40
|
+
>>> rho = MapToFreeAbelianization(G)
|
|
41
|
+
>>> for g in G.generators(): print( g, rho(g) )
|
|
42
|
+
...
|
|
43
|
+
a (3, -1)
|
|
44
|
+
b (5, -2)
|
|
45
|
+
c (0, 1)
|
|
46
|
+
d (1, 0)
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def __init__(self, fund_group):
|
|
50
|
+
self.generators = gens = fund_group.generators()
|
|
51
|
+
self.relators = rels = fund_group.relators()
|
|
52
|
+
entries = list(chain(*(self.abelianize_word(r) for r in rels)))
|
|
53
|
+
presentation = pari.matrix(len(rels), len(gens), entries).mattranspose()
|
|
54
|
+
U, V, D = presentation.matsnf(flag=1) # D = U*R*V is the smith form
|
|
55
|
+
self.U = U
|
|
56
|
+
elementary_divisors = D.matsnf().list()
|
|
57
|
+
self._rank = elementary_divisors.count(0)
|
|
58
|
+
|
|
59
|
+
def abelianize_word(self, word):
|
|
60
|
+
return [word.count(g) - word.count(g.swapcase()) for g in self.generators]
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def rank(self):
|
|
64
|
+
return self._rank
|
|
65
|
+
|
|
66
|
+
def __call__(self, word):
|
|
67
|
+
v = self.U*pari(self.abelianize_word(word)).mattranspose()
|
|
68
|
+
return abelian_group_elt( tuple(int(x) for x in list(v[0])[:self._rank]) )
|
|
69
|
+
|
|
70
|
+
# General code for storing high-precision representations.
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def clean_RR(r, error):
|
|
74
|
+
return 0 if abs(r) < error else r
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
if _within_sage:
|
|
78
|
+
def clean_CC(z, error, prec):
|
|
79
|
+
CC = ComplexField(prec)
|
|
80
|
+
return CC( clean_RR(z.real(),error), clean_RR(z.imag(), error) )
|
|
81
|
+
else:
|
|
82
|
+
def clean_CC(z, error, prec):
|
|
83
|
+
re, im = z.real(), z.imag()
|
|
84
|
+
prec = re.prec()
|
|
85
|
+
clean_z = pari.complex( clean_RR(re.gen, error), clean_RR(im.gen, error) )
|
|
86
|
+
return Number(clean_z, precision=prec)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def clean_matrix(A, error, prec):
|
|
90
|
+
return matrix([[clean_CC(A[x], error, prec) for x in ((i,0),(i,1))]
|
|
91
|
+
for i in (0,1)])
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def SL2C_inverse(A):
|
|
95
|
+
return matrix([[A[1,1], -A[0, 1]], [-A[1, 0], A[0, 0]]])
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def matrix_norm(A):
|
|
99
|
+
return max( [abs(a) for a in A.list()])
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def matrix_difference_norm(A, B):
|
|
103
|
+
return max([abs(a - b) for a, b in zip(A.list(), B.list())])
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def projective_distance(A, B):
|
|
107
|
+
return min( matrix_norm(A-B), matrix_norm(A+B) )
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def compare_matrices(Mats0, Mats1):
|
|
111
|
+
return max([projective_distance(A, B) for A, B in zip(Mats0, Mats1)])
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def make_epsilon(A):
|
|
115
|
+
prec = A.base_ring().precision()
|
|
116
|
+
RR = RealField(prec)
|
|
117
|
+
return RR(2)**(RR(-0.6)*prec)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def make_trace_2(A):
|
|
121
|
+
P = A if A.trace() > 0 else - A
|
|
122
|
+
if abs(P.trace() - 2) < make_epsilon(A):
|
|
123
|
+
return P
|
|
124
|
+
else:
|
|
125
|
+
raise ValueError("Matrix of peripheral element doesn't seem to be parabolic")
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def parabolic_eigenvector(A):
|
|
129
|
+
P, CC, epsilon = make_trace_2(A), A.base_ring(), make_epsilon(A)
|
|
130
|
+
for v in [vector(CC, (1, 0) ), vector(CC, (0, 1))]:
|
|
131
|
+
if (v - P*v).norm() < epsilon:
|
|
132
|
+
return v
|
|
133
|
+
|
|
134
|
+
v = vector( CC , pari(P - 1).matker()[0])
|
|
135
|
+
assert (v - P*v).norm() < epsilon
|
|
136
|
+
return v
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def extend_to_basis(v):
|
|
140
|
+
u = (1/v.norm())*v
|
|
141
|
+
w = vector(v.base_ring(), (-u[1].conjugate(), u[0].conjugate()))
|
|
142
|
+
return matrix( [u, w] ).transpose()
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def is_essentially_Id2(M, error=10**-3):
|
|
146
|
+
diff = M - identity(M)
|
|
147
|
+
error = diff.base_ring()(error)
|
|
148
|
+
return all(abs(d) < error for d in diff.list())
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class MatrixRepresentation(Object):
|
|
152
|
+
def __init__(self, gens, relators, matrices):
|
|
153
|
+
self._gens, self._relators, self._matrices = gens, relators, matrices
|
|
154
|
+
self._build_hom_dict()
|
|
155
|
+
A = matrices[0]
|
|
156
|
+
self._id = identity(A)
|
|
157
|
+
|
|
158
|
+
def _build_hom_dict(self):
|
|
159
|
+
gens, matrices = self._gens, self._matrices
|
|
160
|
+
inv_gens = [g.upper() for g in gens]
|
|
161
|
+
inv_mat = [SL2C_inverse(m) for m in matrices]
|
|
162
|
+
self._hom_dict = dict(zip(gens + inv_gens, matrices + inv_mat))
|
|
163
|
+
|
|
164
|
+
def generators(self):
|
|
165
|
+
return self._gens
|
|
166
|
+
|
|
167
|
+
def num_generators(self):
|
|
168
|
+
return len(self._gens)
|
|
169
|
+
|
|
170
|
+
def relators(self):
|
|
171
|
+
return self._relators
|
|
172
|
+
|
|
173
|
+
def __call__(self, word):
|
|
174
|
+
return prod([self._hom_dict[g] for g in word], self._id)
|
|
175
|
+
|
|
176
|
+
def is_nonprojective_representation(self):
|
|
177
|
+
"""
|
|
178
|
+
True if this is an SL(2,C)-representation, i.e., if multiplying the generators
|
|
179
|
+
in a word yields the identity matrix.
|
|
180
|
+
"""
|
|
181
|
+
return all(is_essentially_Id2(self(R)) for R in self.relators())
|
|
182
|
+
|
|
183
|
+
def is_projective_representation(self):
|
|
184
|
+
"""
|
|
185
|
+
True if this is an PSL(2,C)-representation, i.e., if multiplying the generators
|
|
186
|
+
in a word yields the identity matrix or its negative.
|
|
187
|
+
"""
|
|
188
|
+
rel_images = (self(R) for R in self.relators())
|
|
189
|
+
return all(is_essentially_Id2(M) or is_essentially_Id2(-M)
|
|
190
|
+
for M in rel_images)
|
|
191
|
+
|
|
192
|
+
def lift_to_SL2C(self):
|
|
193
|
+
assert self.is_projective_representation()
|
|
194
|
+
base_gen_images = [self(g) for g in self.generators()]
|
|
195
|
+
generators, relators = self.generators(), self.relators()
|
|
196
|
+
|
|
197
|
+
# Make into a real rep
|
|
198
|
+
pos_signs = product( *([(1, -1)]*len(base_gen_images)))
|
|
199
|
+
for signs in pos_signs:
|
|
200
|
+
gen_images = [ s*M for s, M in zip(signs, base_gen_images)]
|
|
201
|
+
rho = MatrixRepresentation(generators, relators, gen_images)
|
|
202
|
+
if rho.is_nonprojective_representation():
|
|
203
|
+
self._matrices = gen_images
|
|
204
|
+
self._build_hom_dict()
|
|
205
|
+
break
|
|
206
|
+
|
|
207
|
+
assert self.is_nonprojective_representation()
|
|
208
|
+
|
|
209
|
+
def all_lifts_to_SL2C(self):
|
|
210
|
+
ans = []
|
|
211
|
+
self.lift_to_SL2C()
|
|
212
|
+
base_gen_images = [self(g) for g in self.generators()]
|
|
213
|
+
pos_signs = product( *([(1, -1)]*len(base_gen_images)))
|
|
214
|
+
for signs in pos_signs:
|
|
215
|
+
beta = MatrixRepresentation(self.generators(), self.relators(), [ s*A for s, A in zip(signs, base_gen_images)])
|
|
216
|
+
if beta.is_nonprojective_representation():
|
|
217
|
+
ans.append(beta)
|
|
218
|
+
return ans
|
|
219
|
+
|
|
220
|
+
def trace_field_generators(self):
|
|
221
|
+
gens = self.generators()
|
|
222
|
+
enough_elts = [ ''.join(sorted(s)) for s in powerset(gens) if len(s) > 0]
|
|
223
|
+
return [self(w).trace() for w in enough_elts]
|
|
224
|
+
|
|
225
|
+
def invariant_trace_field_generators(self):
|
|
226
|
+
gens = self.generators()
|
|
227
|
+
if min([abs(self(g).trace()) for g in gens]) < 0.001:
|
|
228
|
+
raise ValueError("Algorithm fails when a generator has trace 0, see page 125 of ML")
|
|
229
|
+
gens = [2*g for g in gens]
|
|
230
|
+
enough_elts = [ ''.join(sorted(s)) for s in powerset(gens) if len(s) > 0]
|
|
231
|
+
return [self(w).trace() for w in enough_elts]
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class ManifoldGroup(MatrixRepresentation):
|
|
235
|
+
def __init__(self, gens, relators, peripheral_curves=None, matrices=None):
|
|
236
|
+
MatrixRepresentation.__init__(self, gens, relators, matrices)
|
|
237
|
+
self._peripheral_curves = peripheral_curves
|
|
238
|
+
|
|
239
|
+
def peripheral_curves(self):
|
|
240
|
+
return self._peripheral_curves
|
|
241
|
+
|
|
242
|
+
def SL2C(self, word):
|
|
243
|
+
return self(word)
|
|
244
|
+
|
|
245
|
+
def check_representation(self):
|
|
246
|
+
relator_matrices = (self.SL2C(R) for R in self.relators())
|
|
247
|
+
return max(projective_distance(A, identity(A)) for A in relator_matrices)
|
|
248
|
+
|
|
249
|
+
def cusp_shape(self, cusp_num=0):
|
|
250
|
+
"""
|
|
251
|
+
Get the polished cusp shape for this representation::
|
|
252
|
+
|
|
253
|
+
sage: M = ManifoldHP('m015')
|
|
254
|
+
sage: rho = M.polished_holonomy(bits_prec=100)
|
|
255
|
+
sage: rho.cusp_shape() # doctest: +NUMERIC24
|
|
256
|
+
-0.49024466750661447990098220731 + 2.9794470664789769463726817144*I
|
|
257
|
+
|
|
258
|
+
"""
|
|
259
|
+
M, L = (self.SL2C(w) for w in self.peripheral_curves()[cusp_num])
|
|
260
|
+
C = extend_to_basis(parabolic_eigenvector(M))
|
|
261
|
+
M, L = ( make_trace_2( C**(-1)*A*C ) for A in [M, L] )
|
|
262
|
+
z = L[0][1]/M[0][1]
|
|
263
|
+
return z.conjugate()
|
|
264
|
+
|
|
265
|
+
def lift_to_SL2C(self):
|
|
266
|
+
MatrixRepresentation.lift_to_SL2C(self)
|
|
267
|
+
# Now make things correspond to our convention that tr(rho(meridian)) = +2, *when possible*.
|
|
268
|
+
phi = MapToFreeAbelianization(self)
|
|
269
|
+
meridian = self.peripheral_curves()[0][0]
|
|
270
|
+
meridian_trace = self(meridian).trace()
|
|
271
|
+
if phi.rank == 1 and phi(meridian) % 2 != 0 and meridian_trace < 0:
|
|
272
|
+
def twist(g, gen_image):
|
|
273
|
+
return gen_image if phi(g)[0] % 2 == 0 else -gen_image
|
|
274
|
+
self._matrices = [ twist(g, M) for g, M in zip(self._gens, self._matrices) ]
|
|
275
|
+
self._build_hom_dict()
|
|
276
|
+
assert self.is_nonprojective_representation()
|
|
277
|
+
assert self(meridian).trace() > 0
|
|
278
|
+
|
|
279
|
+
def all_lifts_to_SL2C(self):
|
|
280
|
+
ans = []
|
|
281
|
+
self.lift_to_SL2C()
|
|
282
|
+
base_gen_images = [self(g) for g in self.generators()]
|
|
283
|
+
pos_signs = product( *([(1, -1)]*len(base_gen_images)))
|
|
284
|
+
for signs in pos_signs:
|
|
285
|
+
beta = ManifoldGroup(self.generators(), self.relators(),
|
|
286
|
+
self.peripheral_curves(),
|
|
287
|
+
[ s*A for s, A in zip(signs, base_gen_images)])
|
|
288
|
+
if beta.is_nonprojective_representation():
|
|
289
|
+
ans.append(beta)
|
|
290
|
+
return ans
|
|
291
|
+
|
|
292
|
+
def __repr__(self):
|
|
293
|
+
return 'Generators:\n %s\nRelators:\n %s' % (
|
|
294
|
+
','.join(self.generators()),
|
|
295
|
+
'\n '.join(self.relators()))
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
def polished_holonomy(manifold,
|
|
299
|
+
bits_prec=100,
|
|
300
|
+
fundamental_group_args=[],
|
|
301
|
+
lift_to_SL2=True,
|
|
302
|
+
ignore_solution_type=False,
|
|
303
|
+
dec_prec=None,
|
|
304
|
+
match_kernel=True):
|
|
305
|
+
"""
|
|
306
|
+
Return the fundamental group of M equipped with a high-precision version of
|
|
307
|
+
the holonomy representation::
|
|
308
|
+
|
|
309
|
+
sage: M = Manifold('m004')
|
|
310
|
+
sage: G = M.polished_holonomy()
|
|
311
|
+
sage: G('a').trace()
|
|
312
|
+
1.5000000000000000000000000000 - 0.86602540378443864676372317075*I
|
|
313
|
+
sage: G = M.polished_holonomy(bits_prec=1000)
|
|
314
|
+
sage: G('a').trace().parent()
|
|
315
|
+
Complex Field with 1000 bits of precision
|
|
316
|
+
"""
|
|
317
|
+
M = manifold
|
|
318
|
+
if dec_prec:
|
|
319
|
+
bits_prec = None
|
|
320
|
+
error = 10**(-dec_prec*0.8)
|
|
321
|
+
else:
|
|
322
|
+
error = 2**(-bits_prec*0.8)
|
|
323
|
+
shapes = M.tetrahedra_shapes('rect', bits_prec=bits_prec, dec_prec=dec_prec)
|
|
324
|
+
G = M.fundamental_group(*fundamental_group_args)
|
|
325
|
+
f = FundamentalPolyhedronEngine.from_manifold_and_shapes(
|
|
326
|
+
M, shapes, normalize_matrices=True, match_kernel=match_kernel)
|
|
327
|
+
mats = f.matrices_for_presentation(G, match_kernel=True)
|
|
328
|
+
clean_mats = [clean_matrix(A, error=error, prec=bits_prec) for A in mats]
|
|
329
|
+
PG = ManifoldGroup(G.generators(), G.relators(), G.peripheral_curves(), clean_mats)
|
|
330
|
+
if lift_to_SL2:
|
|
331
|
+
PG.lift_to_SL2C()
|
|
332
|
+
else:
|
|
333
|
+
assert PG.is_projective_representation()
|
|
334
|
+
|
|
335
|
+
return PG
|
snappy/snap/shapes.py
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
from ..sage_helper import _within_sage
|
|
2
|
+
from ..pari import pari, prec_dec_to_bits, prec_bits_to_dec, Gen
|
|
3
|
+
|
|
4
|
+
if _within_sage:
|
|
5
|
+
from ..sage_helper import ComplexField
|
|
6
|
+
else:
|
|
7
|
+
from snappy.number import Number
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def is_pari(x) -> bool:
|
|
11
|
+
return isinstance(x, Gen)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def pari_matrix(A):
|
|
15
|
+
return pari.matrix(len(A), len(A[0]), [pari(x) for x in sum(A, [])])
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def pari_row_vector(v):
|
|
19
|
+
return pari(v).Vec()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def pari_column_vector(v):
|
|
23
|
+
return pari(v).Col()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def pari_vector_to_list(v):
|
|
27
|
+
return v.Vec().python_list()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def pari_matrix_to_lists(A):
|
|
31
|
+
'Return the entries of A in *column major* order'
|
|
32
|
+
return [pari_vector_to_list(v) for v in A.list()]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def eval_gluing_equation(eqn, shapes):
|
|
36
|
+
if is_pari(eqn):
|
|
37
|
+
shapes = pari_vector_to_list(shapes)
|
|
38
|
+
a, b, c = eqn
|
|
39
|
+
ans = int(c)
|
|
40
|
+
for i, z in enumerate(shapes):
|
|
41
|
+
ans = ans * (z**int(a[i]) * (1 - z)**int(b[i]))
|
|
42
|
+
return ans
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def gluing_equation_errors(eqns, shapes):
|
|
46
|
+
return [eval_gluing_equation(eqn, shapes) - 1 for eqn in eqns]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def infinity_norm(L):
|
|
50
|
+
if is_pari(L):
|
|
51
|
+
L = pari_vector_to_list(L)
|
|
52
|
+
return max([abs(x) for x in L])
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def gluing_equation_error(eqns, shapes):
|
|
56
|
+
return infinity_norm(gluing_equation_errors(eqns, shapes))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def enough_gluing_equations(manifold):
|
|
60
|
+
"""
|
|
61
|
+
Select a full-rank portion of the gluing equations.
|
|
62
|
+
"""
|
|
63
|
+
n_tet = manifold.num_tetrahedra()
|
|
64
|
+
n_cusps = manifold.num_cusps()
|
|
65
|
+
eqns = manifold.gluing_equations("rect")
|
|
66
|
+
edge_eqns = pari_matrix([a + b for a, b, _ in eqns[:n_tet]])
|
|
67
|
+
edge_eqns_with_RHS = pari_matrix([a + b + [(1 - c) // 2]
|
|
68
|
+
for a, b, c in eqns[:n_tet]])
|
|
69
|
+
H, U = edge_eqns.mattranspose().mathnf(flag=1)
|
|
70
|
+
assert H.ncols() == n_tet - n_cusps
|
|
71
|
+
edge_eqns_with_RHS = pari_matrix_to_lists((edge_eqns_with_RHS.mattranspose() * U))[n_cusps:]
|
|
72
|
+
edge_eqns_with_RHS = [(e[:n_tet], e[n_tet: 2 * n_tet], pari(-1)**e[-1])
|
|
73
|
+
for e in edge_eqns_with_RHS]
|
|
74
|
+
|
|
75
|
+
cusp_eqns = []
|
|
76
|
+
j = n_tet
|
|
77
|
+
for i in range(n_cusps):
|
|
78
|
+
cusp_eqns.append(eqns[j])
|
|
79
|
+
j += 2 if manifold.cusp_info(i)['complete?'] else 1
|
|
80
|
+
|
|
81
|
+
ans_eqns = edge_eqns_with_RHS + cusp_eqns
|
|
82
|
+
|
|
83
|
+
ans_matrix = pari_matrix([a + b for a, b, _ in ans_eqns])
|
|
84
|
+
assert len(ans_eqns) == n_tet and len(ans_matrix.mattranspose().matkerint()) == 0
|
|
85
|
+
return [(list(map(int, A)), list(map(int, B)), int(c)) for A, B, c in ans_eqns]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def float_to_pari(x, dec_prec):
|
|
89
|
+
return pari(0) if x == 0 else pari(x).precision(dec_prec)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def complex_to_pari(z, dec_prec):
|
|
93
|
+
return pari.complex(float_to_pari(z.real, dec_prec),
|
|
94
|
+
float_to_pari(z.imag, dec_prec))
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def polished_tetrahedra_shapes(manifold, dec_prec=None, bits_prec=200, ignore_solution_type=False):
|
|
98
|
+
"""
|
|
99
|
+
Refines the current solution to the gluing equations to one with
|
|
100
|
+
the specified accuracy.
|
|
101
|
+
"""
|
|
102
|
+
if dec_prec is None:
|
|
103
|
+
dec_prec = prec_bits_to_dec(bits_prec)
|
|
104
|
+
else:
|
|
105
|
+
bits_prec = prec_dec_to_bits(dec_prec)
|
|
106
|
+
working_prec = dec_prec + 10
|
|
107
|
+
target_espilon = float_to_pari(10.0, working_prec)**-dec_prec
|
|
108
|
+
if _within_sage:
|
|
109
|
+
CC = ComplexField(bits_prec)
|
|
110
|
+
number = CC
|
|
111
|
+
else:
|
|
112
|
+
def number(z):
|
|
113
|
+
return Number(z, precision=bits_prec)
|
|
114
|
+
|
|
115
|
+
# This is a potentially long calculation, so we cache the result
|
|
116
|
+
|
|
117
|
+
if "polished_shapes" in manifold._cache:
|
|
118
|
+
curr_bits_prec, curr_sol = manifold._cache["polished_shapes"]
|
|
119
|
+
if bits_prec <= curr_bits_prec:
|
|
120
|
+
return [number(s) for s in pari_vector_to_list(curr_sol)]
|
|
121
|
+
|
|
122
|
+
# Check and make sure initial solution is reasonable
|
|
123
|
+
|
|
124
|
+
if not ignore_solution_type and manifold.solution_type() not in ['all tetrahedra positively oriented', 'contains negatively oriented tetrahedra']:
|
|
125
|
+
raise ValueError('Initial solution to gluing equations has flat or degenerate tetrahedra')
|
|
126
|
+
|
|
127
|
+
init_shapes = pari_column_vector([complex_to_pari(complex(z), working_prec) for z in manifold.tetrahedra_shapes('rect')])
|
|
128
|
+
init_equations = manifold.gluing_equations('rect')
|
|
129
|
+
if gluing_equation_error(init_equations, init_shapes) > pari(0.000001):
|
|
130
|
+
raise ValueError('Initial solution not very good')
|
|
131
|
+
|
|
132
|
+
# Now begin the actual computation
|
|
133
|
+
eqns = enough_gluing_equations(manifold)
|
|
134
|
+
shapes = init_shapes
|
|
135
|
+
initial_error = infinity_norm(gluing_equation_errors(eqns, shapes))
|
|
136
|
+
for i in range(100):
|
|
137
|
+
errors = gluing_equation_errors(eqns, shapes)
|
|
138
|
+
error = infinity_norm(errors)
|
|
139
|
+
if error < target_espilon or error > 100 * initial_error:
|
|
140
|
+
break
|
|
141
|
+
derivative = pari_matrix([[eqn[0][i] / z - eqn[1][i] / (1 - z)
|
|
142
|
+
for i, z in enumerate(pari_vector_to_list(shapes))] for eqn in eqns])
|
|
143
|
+
gauss = derivative.matsolve(pari_column_vector(errors))
|
|
144
|
+
shapes = shapes - gauss
|
|
145
|
+
|
|
146
|
+
# Check to make sure things worked out ok.
|
|
147
|
+
error = gluing_equation_error(init_equations, shapes)
|
|
148
|
+
total_change = infinity_norm(init_shapes - shapes)
|
|
149
|
+
if error > 1000 * target_espilon or total_change > pari(0.0000001):
|
|
150
|
+
raise ValueError('Did not find a good solution to the gluing equations')
|
|
151
|
+
manifold._cache["polished_shapes"] = (bits_prec, shapes)
|
|
152
|
+
return [number(s) for s in pari_vector_to_list(shapes)]
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Using metabelian representations to obstruct slicing
|
|
3
|
+
====================================================
|
|
4
|
+
|
|
5
|
+
Based on::
|
|
6
|
+
|
|
7
|
+
Herald, Kirk, and Livingston, Math Zeit., 2010
|
|
8
|
+
https://dx.doi.org/10.1007/s00209-009-0548-1
|
|
9
|
+
https://arXiv.org/abs/0804.1355
|
|
10
|
+
|
|
11
|
+
and::
|
|
12
|
+
|
|
13
|
+
Dunfield and Gong, "Ribbon concordances and slice obstructions:
|
|
14
|
+
experiments and examples", https://arXiv.org/abs/2512.21825
|
|
15
|
+
|
|
16
|
+
In in the basic case, the implementation follows the [HKL] paper closely, with a
|
|
17
|
+
few minor changes:
|
|
18
|
+
|
|
19
|
+
1. We use the default simplified presentation for pi_1(knot exterior)
|
|
20
|
+
that SnapPy provides, rather than a Wirtinger presentation, as the
|
|
21
|
+
former has many fewer generators (but of course much longer
|
|
22
|
+
relators).
|
|
23
|
+
|
|
24
|
+
2. The construction of the metabelian representations in Section 7 of
|
|
25
|
+
[HKL] is done the language of twisted cohomology and specifically
|
|
26
|
+
twisted cocycles, whereas this viewpoint is not quite explicit
|
|
27
|
+
(though clearly implied) in [HKL].
|
|
28
|
+
|
|
29
|
+
3. To match the conventions of the other twisted Alexander polynomials
|
|
30
|
+
computed by SnapPy, we insist on all actions are on the left,
|
|
31
|
+
rather than the mix of left and right actions used in [HKL].
|
|
32
|
+
|
|
33
|
+
4. For the final check of whether the twisted polynomial is a norm, we
|
|
34
|
+
simply use that Sage can factor univariate polynomials over
|
|
35
|
+
cyclotomic fields into irreducibles, rather than the various
|
|
36
|
+
generalizations of Gauss's Lemma in [HKL].
|
|
37
|
+
|
|
38
|
+
Additionally, we implement the refinements and generalizations
|
|
39
|
+
introduced in [DG].
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
from ... import SnapPy
|
|
43
|
+
from ...sage_helper import _within_sage, sage_method
|
|
44
|
+
if _within_sage:
|
|
45
|
+
from ...sage_helper import ZZ, prime_range, prime_powers
|
|
46
|
+
from . import basics, rep_theory, direct
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def expand_prime_power_spec(spec):
|
|
50
|
+
if spec in ZZ:
|
|
51
|
+
a, b = 0, spec
|
|
52
|
+
else:
|
|
53
|
+
if len(spec) != 2:
|
|
54
|
+
raise ValueError(f'Spec {spec} does not specify a range')
|
|
55
|
+
a, b = spec
|
|
56
|
+
return prime_powers(a, b + 1)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def expand_prime_spec(spec):
|
|
60
|
+
if spec in ZZ:
|
|
61
|
+
a, b = 0, spec
|
|
62
|
+
else:
|
|
63
|
+
if len(spec) != 2:
|
|
64
|
+
raise ValueError(f'Spec {spec} does not specify a range')
|
|
65
|
+
a, b = spec
|
|
66
|
+
return prime_range(a, b + 1)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@sage_method
|
|
70
|
+
def slice_obstruction_HKL(self,
|
|
71
|
+
primes_spec,
|
|
72
|
+
verbose=0,
|
|
73
|
+
check_in_S3=True,
|
|
74
|
+
method='advanced',
|
|
75
|
+
ribbon_mode=False):
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
For the exterior of a knot in the 3-sphere, search for a
|
|
79
|
+
Herald-Kirk-Livingston (HKL) topological slice obstruction as
|
|
80
|
+
described in Section 3 of Dunfield and Gong's paper
|
|
81
|
+
`[DG] <https://arXiv.org/abs/2512.21825>`_.
|
|
82
|
+
|
|
83
|
+
Specifically, it looks at the cyclic branched covers of the knot
|
|
84
|
+
of prime-power order p and the F_q homology thereof where q is
|
|
85
|
+
prime. The range of such (p, q) pairs searched is given by
|
|
86
|
+
primes_spec as a list of (p_max, [q_min, q_max]). It returns the
|
|
87
|
+
pair (p, q) of the first nonzero obstruction found (in which case
|
|
88
|
+
K is not slice), and otherwise returns ``None``::
|
|
89
|
+
|
|
90
|
+
sage: M = Manifold('K12n813')
|
|
91
|
+
sage: spec = [(10, [0, 20]), (20, [0, 10])]
|
|
92
|
+
sage: M.slice_obstruction_HKL(spec, method='basic', verbose=1)
|
|
93
|
+
Looking at (2, 3) ...
|
|
94
|
+
Looking at (3, 2) ...
|
|
95
|
+
Looking at (3, 7) ...
|
|
96
|
+
(3, 7)
|
|
97
|
+
|
|
98
|
+
You can also specify the p to examine by a range [p_min, p_max] or
|
|
99
|
+
the q by just q_max::
|
|
100
|
+
|
|
101
|
+
sage: spec = [([5, 10], 10)]
|
|
102
|
+
sage: M.slice_obstruction_HKL(spec, method='advanced', verbose=1)
|
|
103
|
+
Looking at (8, 3) ...
|
|
104
|
+
(8, 3)
|
|
105
|
+
|
|
106
|
+
If primes_spec is just a pair (p, q) then only that obstruction is
|
|
107
|
+
checked::
|
|
108
|
+
|
|
109
|
+
sage: M.slice_obstruction_HKL((3, 7))
|
|
110
|
+
(3, 7)
|
|
111
|
+
|
|
112
|
+
The ``method`` argument determines which HKL tests are employed:
|
|
113
|
+
|
|
114
|
+
* ``method='basic'`` employs Lemma 3.5 of [DG] and corresponds
|
|
115
|
+
roughly to the test used in SnapPy 3.1 and 3.2, though these
|
|
116
|
+
earlier versions required p to be prime and forbid q = 2.
|
|
117
|
+
|
|
118
|
+
* ``method='advanced'`` is the default and employs Theorem 3.8
|
|
119
|
+
from [DG]. This subsumes the `basic` method, but can be quite
|
|
120
|
+
slow when the multiplicity of an irreducible V_i is large.
|
|
121
|
+
|
|
122
|
+
An example where this method has more success::
|
|
123
|
+
|
|
124
|
+
sage: M.slice_obstruction_HKL((2, 3), method='basic') # returns None
|
|
125
|
+
sage: M.slice_obstruction_HKL((2, 3), method='advanced')
|
|
126
|
+
(2, 3)
|
|
127
|
+
|
|
128
|
+
* ``method='direct'`` employs the method of Section 3.20 of [DG] to
|
|
129
|
+
consider not just the F_q homology of the cover, but
|
|
130
|
+
epimorphisms of its group to Z/q^e Z for e > 1. This is the
|
|
131
|
+
most computationally expensive method. Example::
|
|
132
|
+
|
|
133
|
+
sage: M = Manifold('K14n16945')
|
|
134
|
+
sage: M.slice_obstruction_HKL((2, 3), method='advanced') # returns None
|
|
135
|
+
sage: M.slice_obstruction_HKL((2, 3), method='direct')
|
|
136
|
+
(2, 3)
|
|
137
|
+
|
|
138
|
+
For any method, q = 2 is handled using Section 3.11 of [DG].
|
|
139
|
+
|
|
140
|
+
If ``verbose`` is ``1`` or ``True``, it prints each pair (p, q) being considered;
|
|
141
|
+
when ``verbose`` is ``2``, information is printed about each step.
|
|
142
|
+
|
|
143
|
+
Finally, if ``ribbon_mode`` is ``True`` then it searches for
|
|
144
|
+
obstructions to being topologically homotopy ribbon. These differ
|
|
145
|
+
from the slice case only when q = 2; see Theorem 3.12 of [DG]::
|
|
146
|
+
|
|
147
|
+
sage: M = Manifold('DT: qaqcJpEHnoDKBMqIgfal') # The knot 17nh_0630889
|
|
148
|
+
sage: M.slice_obstruction_HKL((3, 2)) # returns None
|
|
149
|
+
sage: M.slice_obstruction_HKL((3, 2), ribbon_mode=True)
|
|
150
|
+
(3, 2)
|
|
151
|
+
"""
|
|
152
|
+
if method not in ['basic', 'advanced', 'direct']:
|
|
153
|
+
raise ValueError("Argument method is not 'basic', 'advanced', or 'direct'")
|
|
154
|
+
|
|
155
|
+
M = self
|
|
156
|
+
|
|
157
|
+
if M.cusp_info('is_complete') != [True]:
|
|
158
|
+
raise ValueError('Need exactly one cusp which should be unfilled')
|
|
159
|
+
if M.homology().elementary_divisors() != [0]:
|
|
160
|
+
raise ValueError('Not the exterior of knot in S^3 as H_1 != Z')
|
|
161
|
+
if check_in_S3:
|
|
162
|
+
T = SnapPy.Triangulation(M)
|
|
163
|
+
T.dehn_fill((1, 0))
|
|
164
|
+
if T.fundamental_group().num_generators() != 0:
|
|
165
|
+
raise ValueError('The (1, 0) filling is not obviously S^3')
|
|
166
|
+
|
|
167
|
+
# Special case of only one (p, q) to check
|
|
168
|
+
if len(primes_spec) == 2 and primes_spec[0] in ZZ and primes_spec[1] in ZZ:
|
|
169
|
+
primes_spec = [([primes_spec[0]], [primes_spec[1]])]
|
|
170
|
+
else:
|
|
171
|
+
primes_spec = [(expand_prime_power_spec(a), expand_prime_spec(b))
|
|
172
|
+
for a, b in primes_spec]
|
|
173
|
+
|
|
174
|
+
for ps, qs in primes_spec:
|
|
175
|
+
for p in ps:
|
|
176
|
+
d = basics.nonzero_divisor_product(M, p)
|
|
177
|
+
for q in qs:
|
|
178
|
+
if d % q == 0:
|
|
179
|
+
if verbose:
|
|
180
|
+
print(' Looking at', (p, q), '...')
|
|
181
|
+
if method=='direct':
|
|
182
|
+
success = direct.slicing_obstructed_by_larger_quotient(M, p, q,
|
|
183
|
+
ribbon_mode=ribbon_mode,
|
|
184
|
+
verbose=(verbose > 1))
|
|
185
|
+
else:
|
|
186
|
+
success = rep_theory.slicing_is_obstructed(M, p, q,
|
|
187
|
+
skip_higher_mult=(method=='basic'),
|
|
188
|
+
ribbon_mode=ribbon_mode,
|
|
189
|
+
verbose=(verbose > 1))
|
|
190
|
+
if verbose > 1:
|
|
191
|
+
print()
|
|
192
|
+
|
|
193
|
+
if success:
|
|
194
|
+
return (p, q)
|