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,153 @@
|
|
|
1
|
+
from .polynomial import Polynomial, Monomial
|
|
2
|
+
from . import matrix
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def my_rnfequation(base_poly, extension_poly):
|
|
6
|
+
"""
|
|
7
|
+
This is returning the same as pari's
|
|
8
|
+
rnfequation(base_poly, extension_poly, flag = 3) but
|
|
9
|
+
assumes that base_poly and extension_poly are irreducible
|
|
10
|
+
and thus is much faster.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
# Get the degrees of the polynomial and the variables they are in
|
|
14
|
+
|
|
15
|
+
# Example: base_poly t^2 + 1, extension_poly s^3 + t
|
|
16
|
+
|
|
17
|
+
base_vars = base_poly.variables()
|
|
18
|
+
assert len(base_vars) == 1
|
|
19
|
+
base_var = base_vars[0] # would be y
|
|
20
|
+
base_degree = base_poly.degree() # would be 2
|
|
21
|
+
assert base_degree > 1
|
|
22
|
+
|
|
23
|
+
extension_vars = extension_poly.variables()
|
|
24
|
+
extra_vars = set(extension_vars) - set(base_vars)
|
|
25
|
+
assert len(extra_vars) == 1
|
|
26
|
+
extension_var = list(extra_vars)[0] # would be x
|
|
27
|
+
extension_degree = extension_poly.degree(extension_var) # would be 3
|
|
28
|
+
assert extension_degree > 1
|
|
29
|
+
|
|
30
|
+
# total degree
|
|
31
|
+
total_degree = base_degree * extension_degree
|
|
32
|
+
|
|
33
|
+
# If the extension_poly does not contain base_var, e.g.,
|
|
34
|
+
# s^2 + 1 and t^2 - 2, then we know that neither s nor t will
|
|
35
|
+
# generate the entire field, so skip k = 0
|
|
36
|
+
start_k = 0 if base_var in extension_vars else -1
|
|
37
|
+
|
|
38
|
+
# Try different k to find a generator for the total field
|
|
39
|
+
for k in range(start_k, -100, -1):
|
|
40
|
+
|
|
41
|
+
# Use x = s + k * t as potential generator
|
|
42
|
+
|
|
43
|
+
x = ( Polynomial.from_variable_name(extension_var)
|
|
44
|
+
+ Polynomial.constant_polynomial(k) *
|
|
45
|
+
Polynomial.from_variable_name(base_var))
|
|
46
|
+
|
|
47
|
+
# Holds the i-th power of x in the reduced form
|
|
48
|
+
|
|
49
|
+
power_of_x = Polynomial.constant_polynomial(1)
|
|
50
|
+
|
|
51
|
+
# The i-th row holds the coefficient of the polynomial
|
|
52
|
+
# obtained by reducing the i-th power with respect to the
|
|
53
|
+
# Groebner basis
|
|
54
|
+
|
|
55
|
+
mat = [ ]
|
|
56
|
+
|
|
57
|
+
for i in range(total_degree):
|
|
58
|
+
|
|
59
|
+
# Add to matrix
|
|
60
|
+
|
|
61
|
+
mat.append(
|
|
62
|
+
_poly_to_row(power_of_x,
|
|
63
|
+
base_var, base_degree,
|
|
64
|
+
extension_var, extension_degree))
|
|
65
|
+
|
|
66
|
+
# Compute next power
|
|
67
|
+
|
|
68
|
+
power_of_x = (
|
|
69
|
+
_reduced_polynomial(
|
|
70
|
+
_reduced_polynomial(power_of_x * x,
|
|
71
|
+
extension_poly,
|
|
72
|
+
extension_var,
|
|
73
|
+
extension_degree),
|
|
74
|
+
base_poly,
|
|
75
|
+
base_var,
|
|
76
|
+
base_degree))
|
|
77
|
+
|
|
78
|
+
row_largest_power = _poly_to_row(
|
|
79
|
+
power_of_x,
|
|
80
|
+
base_var, base_degree, extension_var, extension_degree)
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
mat_inv = matrix.matrix_inverse(mat)
|
|
84
|
+
except Exception as e:
|
|
85
|
+
if not matrix.matrix_determinant(mat) == 0:
|
|
86
|
+
raise e
|
|
87
|
+
else:
|
|
88
|
+
mat_inv_t = matrix.matrix_transpose(mat_inv)
|
|
89
|
+
|
|
90
|
+
new_poly_1 = _row_to_poly(
|
|
91
|
+
matrix.matrix_mult_vector(
|
|
92
|
+
mat_inv_t,
|
|
93
|
+
row_largest_power))
|
|
94
|
+
new_poly_2 = Polynomial.from_variable_name('x') ** total_degree
|
|
95
|
+
new_poly = new_poly_2 - new_poly_1
|
|
96
|
+
|
|
97
|
+
old_var_in_new_var = _row_to_poly(
|
|
98
|
+
matrix.matrix_mult_vector(
|
|
99
|
+
mat_inv_t,
|
|
100
|
+
[0, 1] + (total_degree - 2) * [0]))
|
|
101
|
+
|
|
102
|
+
return new_poly, old_var_in_new_var, k
|
|
103
|
+
|
|
104
|
+
raise Exception("Should not get here")
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _row_to_poly(row):
|
|
108
|
+
zero = Polynomial.constant_polynomial(0)
|
|
109
|
+
x = Polynomial.from_variable_name('x')
|
|
110
|
+
return sum([ Polynomial.constant_polynomial(c) * x ** i
|
|
111
|
+
for i, c in enumerate(row)],
|
|
112
|
+
zero)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _poly_to_row(poly, base_var, base_degree, extension_var, extension_degree):
|
|
116
|
+
row = base_degree * extension_degree * [ 0 ]
|
|
117
|
+
for m in poly.get_monomials():
|
|
118
|
+
degrees = dict(m.get_vars())
|
|
119
|
+
degree1 = degrees.get(base_var, 0)
|
|
120
|
+
degree2 = degrees.get(extension_var, 0)
|
|
121
|
+
index = degree2 * base_degree + degree1
|
|
122
|
+
row[index] = m.get_coefficient()
|
|
123
|
+
return row
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _reduced_polynomial(poly, mod_pol, mod_var, mod_degree):
|
|
127
|
+
|
|
128
|
+
def degree_of_monomial(m):
|
|
129
|
+
vars = dict(m.get_vars())
|
|
130
|
+
return vars.get(mod_var, 0)
|
|
131
|
+
|
|
132
|
+
def reducing_polynomial(m):
|
|
133
|
+
def new_degree(var, expo):
|
|
134
|
+
if var == mod_var:
|
|
135
|
+
return (var, expo - mod_degree)
|
|
136
|
+
else:
|
|
137
|
+
return (var, expo)
|
|
138
|
+
new_degrees = [ new_degree(var, expo)
|
|
139
|
+
for var, expo in m.get_vars() ]
|
|
140
|
+
new_degrees_filtered = tuple([ (var, expo)
|
|
141
|
+
for var, expo in new_degrees
|
|
142
|
+
if expo > 0 ])
|
|
143
|
+
monomial = Monomial(m.get_coefficient(), new_degrees_filtered)
|
|
144
|
+
return Polynomial((monomial,))
|
|
145
|
+
|
|
146
|
+
while True:
|
|
147
|
+
degree = poly.degree(mod_var)
|
|
148
|
+
if degree < mod_degree:
|
|
149
|
+
return poly
|
|
150
|
+
|
|
151
|
+
for m in poly.get_monomials():
|
|
152
|
+
if degree_of_monomial(m) == degree:
|
|
153
|
+
poly = poly - reducing_polynomial(m) * mod_pol
|
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
from . import matrix
|
|
2
|
+
|
|
3
|
+
# Given a SnapPy Manifold, find loops of short, middle, and long edges of the
|
|
4
|
+
# doubly truncated simplices that represent the generators of the fundamental
|
|
5
|
+
# group in the unsimplified presentation.
|
|
6
|
+
|
|
7
|
+
# We construct a fundamental domain of the Manifold from doubly truncated
|
|
8
|
+
# simplices. See Figure 18 for simplices.
|
|
9
|
+
# Garoufalidis, Goerner, Zickert:
|
|
10
|
+
# Gluing Equations for PGL(n,C)-Representations of 3-Manifolds
|
|
11
|
+
# https://arxiv.org/abs/1207.6711
|
|
12
|
+
|
|
13
|
+
# We use SnapPy's _choose_generators_info to construct the same fundamental
|
|
14
|
+
# domain and side pairing that SnapPy uses for the unsimplified fundamental
|
|
15
|
+
# group presentation.
|
|
16
|
+
|
|
17
|
+
# We then pick a vertex of one doubly truncated simplex as origin and compute
|
|
18
|
+
# for each vertex a shortest path from the origin to that vertex.
|
|
19
|
+
|
|
20
|
+
# For each face marked as outbound_generator, pick a vertex on the face and
|
|
21
|
+
# a path from the origin to that vertex. Then, the side pairing gives a
|
|
22
|
+
# corresponding face on an inbound_generator, pick a path to the corresponding
|
|
23
|
+
# vertex. Compute the first path with the inverse of the second.
|
|
24
|
+
# There are six such choices for each outbound_generator face. Pick the one
|
|
25
|
+
# yielding the shortest loop (in terms of number of short and long edges).
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Vertex(tuple):
|
|
29
|
+
"""
|
|
30
|
+
A triple (tet, v0, v1, v2) representing a vertex of a doubly truncated
|
|
31
|
+
simplex.
|
|
32
|
+
v0, v1, and v2 are distinct integers between 0 and 3 (inclusively).
|
|
33
|
+
As in the paper, it denotes the vertex that is closest to vertex v0 of
|
|
34
|
+
the simplex, closest to the edge v0 v1 of the simplex and on the face
|
|
35
|
+
v0 v1 v2 of the simplex.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __new__(cls, tet, v0, v1, v2):
|
|
39
|
+
return super().__new__(cls, (tet, v0, v1, v2))
|
|
40
|
+
|
|
41
|
+
def edges_starting_at_vertex(self):
|
|
42
|
+
"""
|
|
43
|
+
Return the three edges of the simplex starting at this point.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
return [ ShortEdge(self), MiddleEdge(self), LongEdge(self) ]
|
|
47
|
+
|
|
48
|
+
def __repr__(self):
|
|
49
|
+
return "Vertex(%d,%d,%d,%d)" % self
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class Edge():
|
|
53
|
+
"""
|
|
54
|
+
Base class representing a directed edge of the doubly truncated
|
|
55
|
+
simplex.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
def __init__(self, start_point):
|
|
59
|
+
"""
|
|
60
|
+
Constructs an edge starting at the given start_point which is
|
|
61
|
+
of type Vertex.
|
|
62
|
+
"""
|
|
63
|
+
self._start_point = start_point
|
|
64
|
+
|
|
65
|
+
def start_point(self):
|
|
66
|
+
"""
|
|
67
|
+
The Vertex object that is the start point of edge.
|
|
68
|
+
"""
|
|
69
|
+
return self._start_point
|
|
70
|
+
|
|
71
|
+
def __pow__(self, other):
|
|
72
|
+
"""
|
|
73
|
+
Invert an edge with ** -1
|
|
74
|
+
"""
|
|
75
|
+
assert other == -1
|
|
76
|
+
return type(self)(self.end_point())
|
|
77
|
+
|
|
78
|
+
def __repr__(self):
|
|
79
|
+
return type(self).__name__ + "(%r)" % (self._start_point,)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class ShortEdge(Edge):
|
|
83
|
+
"""
|
|
84
|
+
A short edge of a doubly truncated simplex.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
def end_point(self):
|
|
88
|
+
"""
|
|
89
|
+
The vertex at the end of the edge.
|
|
90
|
+
"""
|
|
91
|
+
tet, v0, v1, v2 = self._start_point
|
|
92
|
+
return Vertex(tet, v0, v1, 6 - v0 - v1 - v2)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class MiddleEdge(Edge):
|
|
96
|
+
"""
|
|
97
|
+
A middle edge of a doubly truncated simplex.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
def end_point(self):
|
|
101
|
+
"""
|
|
102
|
+
The vertex at the end of the edge.
|
|
103
|
+
"""
|
|
104
|
+
tet, v0, v1, v2 = self._start_point
|
|
105
|
+
|
|
106
|
+
return Vertex(tet, v0, v2, v1)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class LongEdge(Edge):
|
|
110
|
+
"""
|
|
111
|
+
A log edge of a doubly truncated simplex.
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
def end_point(self):
|
|
115
|
+
"""
|
|
116
|
+
The vertex at the end of the edge.
|
|
117
|
+
"""
|
|
118
|
+
tet, v0, v1, v2 = self._start_point
|
|
119
|
+
return Vertex(tet, v1, v0, v2)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class Path(tuple):
|
|
123
|
+
"""
|
|
124
|
+
A tuple of edges that form a path.
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
def __pow__(self, other):
|
|
128
|
+
"""
|
|
129
|
+
The inverse path can be computes as edge ** -1
|
|
130
|
+
"""
|
|
131
|
+
assert other == -1
|
|
132
|
+
return Path([edge ** -1 for edge in self][::-1])
|
|
133
|
+
|
|
134
|
+
def __mul__(self, other):
|
|
135
|
+
"""
|
|
136
|
+
Two paths a, b can be composed as a * b.
|
|
137
|
+
An edge e can be appended with a * e.
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
if isinstance(other, Path):
|
|
141
|
+
return Path(self + other)
|
|
142
|
+
return Path(self + (other,))
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _penalty_of_path(path, penalties):
|
|
146
|
+
|
|
147
|
+
def penalty(edge):
|
|
148
|
+
if isinstance(edge, ShortEdge):
|
|
149
|
+
return penalties[0]
|
|
150
|
+
if isinstance(edge, MiddleEdge):
|
|
151
|
+
return penalties[1]
|
|
152
|
+
return penalties[2]
|
|
153
|
+
|
|
154
|
+
return sum([penalty(edge) for edge in path])
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _perm4_iterator():
|
|
158
|
+
for v0 in range(4):
|
|
159
|
+
for v1 in range(4):
|
|
160
|
+
if v1 != v0:
|
|
161
|
+
for v2 in range(4):
|
|
162
|
+
if v2 != v0 and v2 != v1:
|
|
163
|
+
yield v0, v1, v2, 6 - v0 - v1 - v2
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _compute_origin(choose_generators_info):
|
|
167
|
+
"""
|
|
168
|
+
Using the info from SnapPy's choose_generators_info, return the vertex
|
|
169
|
+
(0, 1, 2) of the simplex that SnapPy used to compute a spanning tree of
|
|
170
|
+
the dual 1-skeleton.
|
|
171
|
+
"""
|
|
172
|
+
# Picks the one tetrahedron with generator_path = -1.
|
|
173
|
+
# If choose_generators_info comes from a regina triangulation, then
|
|
174
|
+
# generator_path is missing and we pick the first tetrahedron.
|
|
175
|
+
|
|
176
|
+
tet = [info['index'] for info in choose_generators_info
|
|
177
|
+
if info.get('generator_path', -1) == -1][0]
|
|
178
|
+
return Vertex(tet, 0, 1, 2)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def _compute_point_identification_dict(choose_generators_info):
|
|
182
|
+
"""
|
|
183
|
+
A vertex in the fundamental domain is an equivalence class of
|
|
184
|
+
vertices (tet, v0, v1, v2) of doubly truncated simplicies under face
|
|
185
|
+
gluings not corresponding to generators.
|
|
186
|
+
|
|
187
|
+
This method computes the equivalence classes and returns them
|
|
188
|
+
as dictionary mapping a vertex quadruple (tet, v0, v1, v2) to
|
|
189
|
+
the set of equivalent triples.
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
# Initialize: each vertex is mapped to set of only itself
|
|
193
|
+
d = {Vertex(tet, v0, v1, v2): {Vertex(tet, v0, v1, v2)}
|
|
194
|
+
for tet in range(len(choose_generators_info))
|
|
195
|
+
for v0, v1, v2, v3 in _perm4_iterator()}
|
|
196
|
+
|
|
197
|
+
# Go through all points on faces not corresponding to
|
|
198
|
+
# generators
|
|
199
|
+
for this_tet, info in enumerate(choose_generators_info):
|
|
200
|
+
for this_v0, this_v1, this_v2, this_v3 in _perm4_iterator():
|
|
201
|
+
if info['generators'][this_v0] == 0:
|
|
202
|
+
|
|
203
|
+
# Determine the point
|
|
204
|
+
this_pt = Vertex(this_tet, this_v1, this_v2, this_v3)
|
|
205
|
+
|
|
206
|
+
# And the point identified by the face gluing
|
|
207
|
+
other_tet = info['neighbors'][this_v0]
|
|
208
|
+
gluing = info['gluings'][this_v0]
|
|
209
|
+
other_pt = Vertex(
|
|
210
|
+
other_tet,
|
|
211
|
+
gluing[this_v1], gluing[this_v2], gluing[this_v3])
|
|
212
|
+
|
|
213
|
+
# These two points are in the same equivalence class,
|
|
214
|
+
# thus merge the two sets corresponding to these points
|
|
215
|
+
identified_pts = d[this_pt] | d[other_pt]
|
|
216
|
+
|
|
217
|
+
# And set that set as new value for each of these points
|
|
218
|
+
for pt in identified_pts:
|
|
219
|
+
d[pt] = identified_pts
|
|
220
|
+
|
|
221
|
+
return d
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def _compute_point_to_shortest_path(point_identification_dict, origin,
|
|
225
|
+
penalties):
|
|
226
|
+
"""
|
|
227
|
+
Given the equivalence classes of quadruples (tet, v0, v1, v2) representing
|
|
228
|
+
the same vertex in the fundamental domain and an origin,
|
|
229
|
+
compute a shortest path from the origin to each vertex.
|
|
230
|
+
|
|
231
|
+
This is returned as a dictionary mapping each triple to a shortest path.
|
|
232
|
+
Triples corresponding to the same identified vertex all have the same
|
|
233
|
+
path.
|
|
234
|
+
"""
|
|
235
|
+
|
|
236
|
+
# Record the paths in d
|
|
237
|
+
d = {}
|
|
238
|
+
|
|
239
|
+
# As said above, equivalent triples map to the same path.
|
|
240
|
+
# To maintain this, here is a helper that produces a dictionary with
|
|
241
|
+
# this property. It maps all triples equivalent to pt to path.
|
|
242
|
+
|
|
243
|
+
def identified_points_to_path(pt, path):
|
|
244
|
+
return {
|
|
245
|
+
identified_pt: path
|
|
246
|
+
for identified_pt in point_identification_dict[pt] }
|
|
247
|
+
|
|
248
|
+
# Trivial paths for points identified with origin
|
|
249
|
+
previously_added = identified_points_to_path(origin, Path())
|
|
250
|
+
|
|
251
|
+
# Iterate to compute longer and longer paths until an iteration
|
|
252
|
+
# yielded no more paths.
|
|
253
|
+
while previously_added:
|
|
254
|
+
|
|
255
|
+
# First, insert all paths into the dictionary that we computed
|
|
256
|
+
# in the previous iteration
|
|
257
|
+
d.update(previously_added)
|
|
258
|
+
|
|
259
|
+
# Compute new paths by starting from the paths computed in the
|
|
260
|
+
# previous iteration
|
|
261
|
+
new_paths = {}
|
|
262
|
+
|
|
263
|
+
# Iterate through the previously added paths
|
|
264
|
+
# We want the algorithm to be deterministic, thus sort items.
|
|
265
|
+
for pt, path in sorted(previously_added.items()):
|
|
266
|
+
# Look at all edges starting where the previous path ended
|
|
267
|
+
for edge in pt.edges_starting_at_vertex():
|
|
268
|
+
# Construct a new path by appending the edge and
|
|
269
|
+
# add that path
|
|
270
|
+
new_path = path * edge
|
|
271
|
+
new_end_point = edge.end_point()
|
|
272
|
+
|
|
273
|
+
# If the end point of this edge does not have a path
|
|
274
|
+
# yet or the new path is shorter.
|
|
275
|
+
if (new_end_point not in d
|
|
276
|
+
or _penalty_of_path(new_path, penalties) <
|
|
277
|
+
_penalty_of_path(d[new_end_point], penalties)):
|
|
278
|
+
new_paths.update(
|
|
279
|
+
identified_points_to_path(new_end_point, new_path))
|
|
280
|
+
|
|
281
|
+
# We are at the end of the iteration, remember the paths
|
|
282
|
+
# constructed now for the next iteration.
|
|
283
|
+
previously_added = new_paths
|
|
284
|
+
|
|
285
|
+
return d
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def _compute_num_generators(choose_generators_info):
|
|
289
|
+
"""
|
|
290
|
+
Compute the number of generators.
|
|
291
|
+
"""
|
|
292
|
+
|
|
293
|
+
return max([ max(info['generators']) for info in choose_generators_info ])
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def _compute_loops_for_generators_from_info(choose_generators_info,
|
|
297
|
+
point_to_shortest_path,
|
|
298
|
+
penalties):
|
|
299
|
+
"""
|
|
300
|
+
Using the result of SnapPy's _choose_generators_info() that
|
|
301
|
+
indicates which face pairings correspond to which generators and
|
|
302
|
+
the shortest path dictionary computed previously,
|
|
303
|
+
compute a loop in the short and long edges for each generator.
|
|
304
|
+
"""
|
|
305
|
+
|
|
306
|
+
# Allocate an array to hold all the loops
|
|
307
|
+
num_generators = _compute_num_generators(choose_generators_info)
|
|
308
|
+
loops_for_generators = num_generators * [ None ]
|
|
309
|
+
|
|
310
|
+
# Go through all tets
|
|
311
|
+
for this_tet, info in enumerate(choose_generators_info):
|
|
312
|
+
# Go through all faces and vertices on that face
|
|
313
|
+
for this_v0, this_v1, this_v2, this_v3 in _perm4_iterator():
|
|
314
|
+
# Consider the face opposite of vertex v0
|
|
315
|
+
generator_index = info['generators'][this_v0]
|
|
316
|
+
# If this face corresponds to an outbound_generator
|
|
317
|
+
if generator_index > 0:
|
|
318
|
+
# Take the vertex
|
|
319
|
+
this_pt = Vertex(this_tet, this_v1, this_v2, this_v3)
|
|
320
|
+
|
|
321
|
+
# Take the vertex glued to it through face pairing
|
|
322
|
+
other_tet = info['neighbors'][this_v0]
|
|
323
|
+
gluing = info['gluings'][this_v0]
|
|
324
|
+
other_pt = Vertex(
|
|
325
|
+
other_tet,
|
|
326
|
+
gluing[this_v1], gluing[this_v2], gluing[this_v3])
|
|
327
|
+
|
|
328
|
+
# Compute a loop by composing the shortest path to
|
|
329
|
+
# the vertex with the inverse shortest path to the
|
|
330
|
+
# glued vertex
|
|
331
|
+
new_loop = (
|
|
332
|
+
point_to_shortest_path[this_pt] *
|
|
333
|
+
point_to_shortest_path[other_pt] ** -1 )
|
|
334
|
+
|
|
335
|
+
# Save the resulting loop in the array if the array
|
|
336
|
+
# did not contain a result already or the loop is better
|
|
337
|
+
# (i.e., has less edges)
|
|
338
|
+
loop = loops_for_generators[generator_index - 1]
|
|
339
|
+
if (loop is None
|
|
340
|
+
or _penalty_of_path(new_loop, penalties) <
|
|
341
|
+
_penalty_of_path(loop, penalties)):
|
|
342
|
+
loops_for_generators[generator_index - 1] = new_loop
|
|
343
|
+
|
|
344
|
+
return loops_for_generators
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def compute_loops_for_generators(M, penalties):
|
|
348
|
+
"""
|
|
349
|
+
Given a SnapPy Manifold M, return a loop of short, middle, and long edges
|
|
350
|
+
representing a generator of the fundamental group in the
|
|
351
|
+
unsimplified presentation for each generator.
|
|
352
|
+
|
|
353
|
+
Each short, middle, respectively, long edge has an associate penalty
|
|
354
|
+
(encoded the triple penalties). For each generator, the method returns
|
|
355
|
+
a loop with the smallest total penalty.
|
|
356
|
+
"""
|
|
357
|
+
|
|
358
|
+
# Get the necessary information from SnapPea kernel
|
|
359
|
+
M._choose_generators(False, False)
|
|
360
|
+
choose_generators_info = M._choose_generators_info()
|
|
361
|
+
|
|
362
|
+
# Compute which vertices of doubly truncated simplices are identified
|
|
363
|
+
# to form the fundamental domain
|
|
364
|
+
point_identification_dict = _compute_point_identification_dict(
|
|
365
|
+
choose_generators_info)
|
|
366
|
+
|
|
367
|
+
# Pick an origin
|
|
368
|
+
origin = _compute_origin(choose_generators_info)
|
|
369
|
+
|
|
370
|
+
# Compute shortest paths form the origin to every vertex
|
|
371
|
+
point_to_shortest_path = _compute_point_to_shortest_path(
|
|
372
|
+
point_identification_dict, origin, penalties)
|
|
373
|
+
|
|
374
|
+
# Compute the loops
|
|
375
|
+
return _compute_loops_for_generators_from_info(
|
|
376
|
+
choose_generators_info, point_to_shortest_path, penalties)
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
def _evaluate_path(coordinate_object, path):
|
|
380
|
+
"""
|
|
381
|
+
Given PtolemyCoordinates or CrossRatios (or more generally, any object that
|
|
382
|
+
supports _get_identity_matrix, short_edge, middle_edge, and long_edge) and
|
|
383
|
+
a path, return the product of the matrices returned by the respective
|
|
384
|
+
calls to short_edge, middle_edge, and long_edge.
|
|
385
|
+
"""
|
|
386
|
+
|
|
387
|
+
# Start with identity
|
|
388
|
+
m = coordinate_object._get_identity_matrix()
|
|
389
|
+
|
|
390
|
+
# Multiply the matrices
|
|
391
|
+
for edge in path:
|
|
392
|
+
|
|
393
|
+
if isinstance(edge, ShortEdge):
|
|
394
|
+
matrix_method = coordinate_object.short_edge
|
|
395
|
+
elif isinstance(edge, MiddleEdge):
|
|
396
|
+
matrix_method = coordinate_object.middle_edge
|
|
397
|
+
elif isinstance(edge, LongEdge):
|
|
398
|
+
matrix_method = coordinate_object.long_edge
|
|
399
|
+
else:
|
|
400
|
+
raise Exception("Edge of unknown type in path")
|
|
401
|
+
|
|
402
|
+
m = matrix.matrix_mult(m, matrix_method(*edge.start_point()))
|
|
403
|
+
|
|
404
|
+
return m
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
def images_of_original_generators(coordinate_object, penalties):
|
|
408
|
+
"""
|
|
409
|
+
Given Ptolemy coordinates or cross ratio (or anything which supports
|
|
410
|
+
get_manifold and methods to return matrices for short, middle, and long
|
|
411
|
+
edges) and penalties (triple giving preferences to avoid short, middle,
|
|
412
|
+
and long edges), give two lists of matrices that are the images and inverse
|
|
413
|
+
images of the fundamental group generators of the unsimplified presentation.
|
|
414
|
+
"""
|
|
415
|
+
# Get the manifold
|
|
416
|
+
M = coordinate_object.get_manifold()
|
|
417
|
+
|
|
418
|
+
if M is None:
|
|
419
|
+
raise Exception("Need to have a manifold")
|
|
420
|
+
|
|
421
|
+
loops = compute_loops_for_generators(M, penalties=penalties)
|
|
422
|
+
|
|
423
|
+
return (
|
|
424
|
+
[ _evaluate_path(coordinate_object, loop ) for loop in loops ],
|
|
425
|
+
[ _evaluate_path(coordinate_object, loop ** -1) for loop in loops ])
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
def _apply_hom_to_word(word, G):
|
|
429
|
+
# No G given means nothing is done to the word
|
|
430
|
+
if G is None:
|
|
431
|
+
return word
|
|
432
|
+
|
|
433
|
+
# G is a SnapPy Fundamental group
|
|
434
|
+
if hasattr(G, 'generators_in_originals'):
|
|
435
|
+
|
|
436
|
+
result = ""
|
|
437
|
+
|
|
438
|
+
# Get how each letter translates into the original generators
|
|
439
|
+
imgs = G.generators_in_originals()
|
|
440
|
+
for letter in word:
|
|
441
|
+
|
|
442
|
+
if letter.isupper():
|
|
443
|
+
# Upper case letter correspond to inverses
|
|
444
|
+
# Inverse is formed by swapping case, then reversing string
|
|
445
|
+
result += imgs[ord(letter) - ord('A')].swapcase()[::-1]
|
|
446
|
+
else:
|
|
447
|
+
result += imgs[ord(letter) - ord('a')]
|
|
448
|
+
return result
|
|
449
|
+
|
|
450
|
+
raise Exception("Given argument is not a SnapPy fundamental group")
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
def evaluate_word(identity_matrix, generator_matrices, inverse_matrices,
|
|
454
|
+
word, G):
|
|
455
|
+
|
|
456
|
+
# Start with the identity matrix
|
|
457
|
+
m = identity_matrix
|
|
458
|
+
|
|
459
|
+
image_of_word = _apply_hom_to_word(word, G)
|
|
460
|
+
|
|
461
|
+
# Iterate through word
|
|
462
|
+
for letter in image_of_word:
|
|
463
|
+
|
|
464
|
+
if letter.isupper():
|
|
465
|
+
# Upper case letters correspond to inverse generators
|
|
466
|
+
g = inverse_matrices[ord(letter) - ord('A')]
|
|
467
|
+
else:
|
|
468
|
+
g = generator_matrices[ord(letter) - ord('a')]
|
|
469
|
+
|
|
470
|
+
# Multiply
|
|
471
|
+
m = matrix.matrix_mult(m, g)
|
|
472
|
+
|
|
473
|
+
return m
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
def compute_geometric_solution(M, N=2, numerical=False,
|
|
2
|
+
engine=None,
|
|
3
|
+
memory_limit=750000000, directory=None,
|
|
4
|
+
prefer_rur=False, data_url=False,
|
|
5
|
+
verbose=None):
|
|
6
|
+
"""
|
|
7
|
+
Given a manifold M, compute the exact or numerical solutions to the
|
|
8
|
+
Ptolemy variety (pass numerical = True for numerical solutions). The additional
|
|
9
|
+
options are the same as the ones passed to compute_solutions of a PtolemyVariety.
|
|
10
|
+
|
|
11
|
+
>>> from snappy.ptolemy.geometricRep import compute_geometric_solutions
|
|
12
|
+
>>> compute_geometric_solutions(Manifold("m004")) #doctest: +SKIP
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
if verbose is None:
|
|
17
|
+
verbose = (engine == 'retrieve')
|
|
18
|
+
|
|
19
|
+
obstruction_class = 'all' if N % 2 == 0 else None
|
|
20
|
+
varieties = M.ptolemy_variety(N, obstruction_class=obstruction_class)
|
|
21
|
+
|
|
22
|
+
if engine == 'retrieve':
|
|
23
|
+
sols = varieties.retrieve_solutions(numerical=numerical,
|
|
24
|
+
prefer_rur=prefer_rur,
|
|
25
|
+
data_url=data_url,
|
|
26
|
+
verbose=verbose)
|
|
27
|
+
else:
|
|
28
|
+
sols = varieties.compute_solutions(engine=engine,
|
|
29
|
+
numerical=numerical,
|
|
30
|
+
memory_limit=memory_limit,
|
|
31
|
+
directory=directory,
|
|
32
|
+
verbose=verbose)
|
|
33
|
+
|
|
34
|
+
for sol in sols.flatten(3):
|
|
35
|
+
if sol.is_geometric():
|
|
36
|
+
return sol
|
|
37
|
+
|
|
38
|
+
return None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def retrieve_geometric_solution(M, N=2,
|
|
42
|
+
numerical=False,
|
|
43
|
+
prefer_rur=False,
|
|
44
|
+
data_url=None,
|
|
45
|
+
verbose=True):
|
|
46
|
+
"""
|
|
47
|
+
Given a manifold M, retrieve the exact or numerical solutions to the
|
|
48
|
+
Ptolemy variety (pass numerical = True for numerical solutions). The additional
|
|
49
|
+
options are the same as the ones passed to retrieve_solutions of a PtolemyVariety.
|
|
50
|
+
|
|
51
|
+
>>> from snappy.ptolemy.geometricRep import retrieve_geometric_solutions
|
|
52
|
+
>>> retrieve_geometric_solutions(Manifold("m004")) #doctest: +SKIP
|
|
53
|
+
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
return compute_geometric_solution(M, N, numerical=numerical,
|
|
57
|
+
engine='retrieve',
|
|
58
|
+
prefer_rur=prefer_rur,
|
|
59
|
+
data_url=data_url, verbose=verbose)
|