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,518 @@
|
|
|
1
|
+
from .. import snap
|
|
2
|
+
from ..matrix import make_identity_matrix, make_matrix, make_vector
|
|
3
|
+
|
|
4
|
+
from ..sage_helper import _within_sage, sage_method
|
|
5
|
+
|
|
6
|
+
if _within_sage:
|
|
7
|
+
from ..sage_helper import ComplexDoubleField, ComplexIntervalField, RealIntervalField
|
|
8
|
+
from snappy.pari import prec_dec_to_bits
|
|
9
|
+
|
|
10
|
+
__all__ = ['KrawczykShapesEngine']
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class KrawczykShapesEngine:
|
|
14
|
+
|
|
15
|
+
"""
|
|
16
|
+
An engine that is initialized with an approximated candidate solution to
|
|
17
|
+
the rectangular gluing equations and produces intervals certified to
|
|
18
|
+
contain a true solution. After the engine is successfully run, the
|
|
19
|
+
resulting intervals are stored in certified_shapes which is a vector of
|
|
20
|
+
elements in a Sage's ComplexIntervalField.
|
|
21
|
+
|
|
22
|
+
A simple example to obtain certified shape intervals that uses the
|
|
23
|
+
KrawczykShapesEngine or IntervalNewtonShapesEngine under the hood::
|
|
24
|
+
|
|
25
|
+
sage: from snappy import Manifold
|
|
26
|
+
sage: M = Manifold("m015")
|
|
27
|
+
sage: M.tetrahedra_shapes('rect', bits_prec = 80, intervals = True) # doctest: +NUMERIC15 +NORMALIZE_WHITESPACE
|
|
28
|
+
[0.6623589786223730129805? + 0.5622795120623012438992?*I,
|
|
29
|
+
0.6623589786223730129805? + 0.5622795120623012438992?*I,
|
|
30
|
+
0.6623589786223730129805? + 0.5622795120623012438992?*I]
|
|
31
|
+
|
|
32
|
+
Its objective is thus the same as HIKMOT and it is certainly HIKMOT
|
|
33
|
+
inspired. However, it conceptually differs in that:
|
|
34
|
+
|
|
35
|
+
1. It uses complex numbers in it's computations.
|
|
36
|
+
We simply use Sage's complex interval type avoiding the need of
|
|
37
|
+
converting n x n complex matrices into 2n x 2n real matrices as
|
|
38
|
+
described Section 3.4 of the HIKMOT paper.
|
|
39
|
+
|
|
40
|
+
2. We avoid automatic differentiation. We pick an independent set of
|
|
41
|
+
equations of the following form and try to solve them:
|
|
42
|
+
|
|
43
|
+
log(LHS) = 0
|
|
44
|
+
|
|
45
|
+
where
|
|
46
|
+
|
|
47
|
+
LHS = c * z0^a0 * (1-z0)^b0 * z1^a1 * (1-z1)^b1 * ...
|
|
48
|
+
|
|
49
|
+
with a, b and c's as returned by Manifold.gluing_equations('rect').
|
|
50
|
+
|
|
51
|
+
The derivative of log (LHS) with respect to zj is simply given by
|
|
52
|
+
|
|
53
|
+
aj/zj - bj/(1-zj)
|
|
54
|
+
|
|
55
|
+
and thus no need for automatic differentiation.
|
|
56
|
+
|
|
57
|
+
3. For speed-up, the approximate inverse is always computed with
|
|
58
|
+
double's. Some intermediate matrix computations are performed sparsely.
|
|
59
|
+
|
|
60
|
+
In contrast to HIKMOT, we use and return Sage's native implementation of
|
|
61
|
+
(complex) interval arithmetic here, which allows for increased interoperability.
|
|
62
|
+
Another advantage is that Sage supports arbitrary precision.
|
|
63
|
+
|
|
64
|
+
Here is an example how to explicitly invoke the KrawczykShapesEngine::
|
|
65
|
+
|
|
66
|
+
sage: shapes = M.tetrahedra_shapes('rect', bits_prec = 80)
|
|
67
|
+
sage: C = KrawczykShapesEngine(M, shapes, bits_prec = 80)
|
|
68
|
+
sage: C.expand_until_certified()
|
|
69
|
+
True
|
|
70
|
+
sage: C.certified_shapes # doctest: +NUMERIC12
|
|
71
|
+
(0.6623589786223730129805? + 0.5622795120623012438992?*I, 0.6623589786223730129805? + 0.5622795120623012438992?*I, 0.6623589786223730129805? + 0.5622795120623012438992?*I)
|
|
72
|
+
|
|
73
|
+
And here an example where the initial solution is somewhat off::
|
|
74
|
+
|
|
75
|
+
sage: M = Manifold("m019")
|
|
76
|
+
sage: shapes = [0.780559+0.91449j, 0.780559+0.9144j, 0.46009+0.639j]
|
|
77
|
+
sage: C = KrawczykShapesEngine(M, shapes, bits_prec = 100)
|
|
78
|
+
sage: C.expand_until_certified()
|
|
79
|
+
True
|
|
80
|
+
sage: C.certified_shapes # doctest: +ELLIPSIS
|
|
81
|
+
(0.7806? + 0.9145?*I, 0.7806? + 0.9145?*I, 0.460...? + 0.6326?*I)
|
|
82
|
+
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
def log_gluing_LHSs(self, shapes):
|
|
86
|
+
"""
|
|
87
|
+
Given the result of M.gluing_equations('rect') or a
|
|
88
|
+
subset of rows of it and shapes, return a vector of
|
|
89
|
+
log(LHS) where
|
|
90
|
+
|
|
91
|
+
LHS = c * z0 ** a0 * (1-z0) ** b0 * z1 ** a1 * ...
|
|
92
|
+
|
|
93
|
+
Let f: C^n -> C^n denote the function which takes
|
|
94
|
+
shapes and returns the vector of log(LHS).
|
|
95
|
+
|
|
96
|
+
The reason we take the logarithm of the rectangular
|
|
97
|
+
gluing equations is because the logarithmic derivative
|
|
98
|
+
is of a particular nice form::
|
|
99
|
+
|
|
100
|
+
sage: from snappy import Manifold
|
|
101
|
+
sage: M = Manifold("m019")
|
|
102
|
+
sage: equations = M.gluing_equations('rect')
|
|
103
|
+
sage: RIF = RealIntervalField(80)
|
|
104
|
+
sage: CIF = ComplexIntervalField(80)
|
|
105
|
+
sage: zero = CIF(0).center()
|
|
106
|
+
sage: shape1 = CIF(RIF(0.78055,0.78056), RIF(0.9144, 0.9145))
|
|
107
|
+
sage: shape2 = CIF(RIF(0.46002,0.46003), RIF(0.6326, 0.6327))
|
|
108
|
+
|
|
109
|
+
An interval solution containing the true solution. The log of each
|
|
110
|
+
rectangular equation should be 0 for the true solution, hence the interval
|
|
111
|
+
should contain zero::
|
|
112
|
+
|
|
113
|
+
sage: shapes = [shape1, shape1, shape2]
|
|
114
|
+
sage: C = KrawczykShapesEngine(M, [shape.center() for shape in shapes], bits_prec = 53)
|
|
115
|
+
sage: LHSs = C.log_gluing_LHSs(shapes)
|
|
116
|
+
sage: LHSs # doctest: +NUMERIC6
|
|
117
|
+
(0.000? + 0.000?*I, 0.000? + 0.000?*I, 0.0000? + 0.0000?*I)
|
|
118
|
+
sage: zero in LHSs[0]
|
|
119
|
+
True
|
|
120
|
+
|
|
121
|
+
An interval not containing the true solution::
|
|
122
|
+
|
|
123
|
+
sage: shapes = [shape1, shape1, shape1]
|
|
124
|
+
sage: LHSs = C.log_gluing_LHSs(shapes)
|
|
125
|
+
sage: LHSs # doctest: +NUMERIC3
|
|
126
|
+
(0.430? - 0.078?*I, 0.246? - 0.942?*I, 0.0000? + 0.0000?*I)
|
|
127
|
+
sage: zero in LHSs[0]
|
|
128
|
+
False
|
|
129
|
+
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
# Determine the field (should be ComplexField
|
|
133
|
+
# or ComplexIntervalField with some precision)
|
|
134
|
+
# of the shapes
|
|
135
|
+
BaseField = shapes[0].parent()
|
|
136
|
+
|
|
137
|
+
one = BaseField(1)
|
|
138
|
+
# The resulting vector as python list
|
|
139
|
+
gluing_LHSs = []
|
|
140
|
+
# Iterate through the rows of the result similar to
|
|
141
|
+
# M.gluing_equations('rect')
|
|
142
|
+
for A, B, c in self.equations:
|
|
143
|
+
# A and B are rows, c is an entry
|
|
144
|
+
# prod keeps the above product
|
|
145
|
+
prod = BaseField(c)
|
|
146
|
+
for a, b, shape in zip(A, B, shapes):
|
|
147
|
+
prod *= (shape ** a) * (one - shape) ** b
|
|
148
|
+
|
|
149
|
+
# Take log of the entire product
|
|
150
|
+
gluing_LHSs.append(prod.log())
|
|
151
|
+
|
|
152
|
+
return make_vector(gluing_LHSs, ring=BaseField)
|
|
153
|
+
|
|
154
|
+
def log_gluing_LHS_derivatives(self, shapes):
|
|
155
|
+
"""
|
|
156
|
+
Compute the Jacobian of the vector-valued function f
|
|
157
|
+
described in the above log_gluing_LHSs::
|
|
158
|
+
|
|
159
|
+
sage: from snappy import Manifold
|
|
160
|
+
sage: M = Manifold("m019")
|
|
161
|
+
sage: shapes = M.tetrahedra_shapes('rect', bits_prec = 80)
|
|
162
|
+
sage: C = KrawczykShapesEngine(M, shapes, bits_prec = 80)
|
|
163
|
+
sage: RIF = RealIntervalField(80)
|
|
164
|
+
sage: CIF = ComplexIntervalField(80)
|
|
165
|
+
sage: shape1 = CIF(RIF(0.78055,0.78056), RIF(0.9144, 0.9145))
|
|
166
|
+
sage: shape2 = CIF(RIF(0.46002,0.46003), RIF(0.6326, 0.6327))
|
|
167
|
+
sage: shapes = [shape1, shape1, shape2]
|
|
168
|
+
sage: C.log_gluing_LHS_derivatives(shapes) # doctest: +NUMERIC3
|
|
169
|
+
[ 0.292? - 1.6666?*I 0.292? - 1.6666?*I 0.752? - 1.0340?*I]
|
|
170
|
+
[ 0.5400? - 0.6327?*I 0.5400? - 0.6327?*I -1.561? - 1.8290?*I]
|
|
171
|
+
[ 0.5400? - 0.6327?*I -0.5400? + 0.6327?*I 0]
|
|
172
|
+
|
|
173
|
+
"""
|
|
174
|
+
|
|
175
|
+
# Similar to log_gluing_LHS
|
|
176
|
+
BaseField = shapes[0].parent()
|
|
177
|
+
zero = BaseField(0)
|
|
178
|
+
one = BaseField(1)
|
|
179
|
+
|
|
180
|
+
# 1 / z for each shape z
|
|
181
|
+
shape_inverses = [ one / shape for shape in shapes ]
|
|
182
|
+
|
|
183
|
+
# 1 / (1-z) for each shape z
|
|
184
|
+
one_minus_shape_inverses = [ one / (one - shape) for shape in shapes ]
|
|
185
|
+
|
|
186
|
+
gluing_LHS_derivatives = []
|
|
187
|
+
for A, B, c in self.equations:
|
|
188
|
+
row = []
|
|
189
|
+
for a, b, shape_inverse, one_minus_shape_inverse in zip(
|
|
190
|
+
A, B, shape_inverses, one_minus_shape_inverses):
|
|
191
|
+
# Equation for the derivative
|
|
192
|
+
# derivative = ( a / z - b / (1-z) )
|
|
193
|
+
derivative = zero
|
|
194
|
+
if not a == 0:
|
|
195
|
+
derivative = BaseField(int(a)) * shape_inverse
|
|
196
|
+
if not b == 0:
|
|
197
|
+
derivative -= BaseField(int(b)) * one_minus_shape_inverse
|
|
198
|
+
|
|
199
|
+
row.append( derivative )
|
|
200
|
+
|
|
201
|
+
gluing_LHS_derivatives.append(row)
|
|
202
|
+
|
|
203
|
+
return make_matrix(gluing_LHS_derivatives, ring=BaseField)
|
|
204
|
+
|
|
205
|
+
def log_gluing_LHS_derivatives_sparse(self, shapes):
|
|
206
|
+
"""
|
|
207
|
+
A column-sparse matrix version of log_gluing_LHS_derivatives_sparse.
|
|
208
|
+
The result is a list of list of pairs. Each list of pairs corresponds
|
|
209
|
+
to a column, a pair being (index of row, value) where the index is
|
|
210
|
+
increasing.
|
|
211
|
+
"""
|
|
212
|
+
|
|
213
|
+
# Similar to log_gluing_LHS
|
|
214
|
+
BaseField = shapes[0].parent()
|
|
215
|
+
zero = BaseField(0)
|
|
216
|
+
one = BaseField(1)
|
|
217
|
+
|
|
218
|
+
gluing_LHS_derivatives = []
|
|
219
|
+
|
|
220
|
+
# For each shape z
|
|
221
|
+
for eqns_column, shape in zip(self.sparse_equations, shapes):
|
|
222
|
+
shape_inverse = one / shape
|
|
223
|
+
one_minus_shape_inverse = one / (one - shape)
|
|
224
|
+
|
|
225
|
+
# Compute the respective column
|
|
226
|
+
column = []
|
|
227
|
+
for r, (a, b) in eqns_column:
|
|
228
|
+
derivative = zero
|
|
229
|
+
if not a == 0:
|
|
230
|
+
derivative = BaseField(int(a)) * shape_inverse
|
|
231
|
+
if not b == 0:
|
|
232
|
+
derivative -= BaseField(int(b)) * one_minus_shape_inverse
|
|
233
|
+
column.append((r, derivative))
|
|
234
|
+
gluing_LHS_derivatives.append(column)
|
|
235
|
+
return gluing_LHS_derivatives
|
|
236
|
+
|
|
237
|
+
@staticmethod
|
|
238
|
+
def matrix_times_sparse(m, sparse_m):
|
|
239
|
+
"""
|
|
240
|
+
Multiply a (dense) Sage matrix with a column-sparse matrix
|
|
241
|
+
(in the format described in log_gluing_LHS_derivatives_sparse).
|
|
242
|
+
"""
|
|
243
|
+
|
|
244
|
+
CIF = m.base_ring()
|
|
245
|
+
zero = CIF(0)
|
|
246
|
+
rows = []
|
|
247
|
+
for row in m.rows():
|
|
248
|
+
result_row = []
|
|
249
|
+
for col in sparse_m:
|
|
250
|
+
v = zero
|
|
251
|
+
for r, d in col:
|
|
252
|
+
v += d * row[r]
|
|
253
|
+
result_row.append(v)
|
|
254
|
+
rows.append(result_row)
|
|
255
|
+
return make_matrix(rows, ring=CIF)
|
|
256
|
+
|
|
257
|
+
@staticmethod
|
|
258
|
+
def interval_vector_mid_points(vec):
|
|
259
|
+
"""
|
|
260
|
+
Given a vector of complex intervals, return the midpoints (as 0-length
|
|
261
|
+
complex intervals) of them.
|
|
262
|
+
"""
|
|
263
|
+
# Should be ComplexIntervalField with the desired precision
|
|
264
|
+
BaseField = vec[0].parent()
|
|
265
|
+
|
|
266
|
+
return vec.apply_map(lambda shape: BaseField(shape.center()))
|
|
267
|
+
|
|
268
|
+
def krawczyk_interval(self, shape_intervals):
|
|
269
|
+
"""
|
|
270
|
+
Compute the interval in the Krawczyk test.
|
|
271
|
+
|
|
272
|
+
It is given as
|
|
273
|
+
|
|
274
|
+
K(z0, [z], f) := z0 - c * f(z0) + (Id - c * df([z])) * ([z] - z0)
|
|
275
|
+
|
|
276
|
+
where
|
|
277
|
+
- z0 is the approximate candidate solution,
|
|
278
|
+
- [z] are the shape_intervals we try to verify,
|
|
279
|
+
- f is the function taking the shapes to the errors of the logarithmic gluing equations
|
|
280
|
+
- c is an approximate inverse of df
|
|
281
|
+
- df([z]) is the derivative of f (interval-)evaluated for [z]
|
|
282
|
+
|
|
283
|
+
Note that z0 in self.initial_shapes which are complex intervals
|
|
284
|
+
containing only one value (the candidate solution given initially).
|
|
285
|
+
|
|
286
|
+
If K is contained in [z], then we have proven that [z] contains a solution
|
|
287
|
+
to the gluing equations.
|
|
288
|
+
|
|
289
|
+
Do several Krawczyk operations to get a better solution::
|
|
290
|
+
|
|
291
|
+
sage: from sage.all import vector
|
|
292
|
+
sage: M = Manifold("m019")
|
|
293
|
+
sage: shapes = vector(ComplexIntervalField(53), [ 0.5+0.8j, 0.5+0.8j, 0.5+0.8j])
|
|
294
|
+
sage: for i in range(15):
|
|
295
|
+
... penultimateShapes = shapes
|
|
296
|
+
... centers = [ shape.center() for shape in shapes ]
|
|
297
|
+
... C = KrawczykShapesEngine(M, centers, bits_prec = 53)
|
|
298
|
+
... shapes = C.krawczyk_interval(shapes)
|
|
299
|
+
sage: shapes # doctest: +NUMERIC12
|
|
300
|
+
(0.78055252785073? + 0.91447366296773?*I, 0.780552527850725? + 0.91447366296773?*I, 0.460021175573718? + 0.632624193605256?*I)
|
|
301
|
+
|
|
302
|
+
"""
|
|
303
|
+
|
|
304
|
+
# Compute df([z])
|
|
305
|
+
derivative = self.log_gluing_LHS_derivatives_sparse(shape_intervals)
|
|
306
|
+
|
|
307
|
+
# Compute c * df([z])
|
|
308
|
+
p = KrawczykShapesEngine.matrix_times_sparse(
|
|
309
|
+
self.approx_inverse, derivative)
|
|
310
|
+
|
|
311
|
+
# Compute Id - c * df([z])
|
|
312
|
+
diff = self.identity - p
|
|
313
|
+
|
|
314
|
+
# self.first_term is z0 - c * f(z0)
|
|
315
|
+
|
|
316
|
+
return (self.first_term
|
|
317
|
+
+ diff * (shape_intervals - self.initial_shapes))
|
|
318
|
+
|
|
319
|
+
@staticmethod
|
|
320
|
+
def interval_vector_is_contained_in(vecA, vecB):
|
|
321
|
+
"""
|
|
322
|
+
Given two vectors of intervals, return whether the first one
|
|
323
|
+
is contained in the second one. Examples::
|
|
324
|
+
|
|
325
|
+
sage: RIF = RealIntervalField(80)
|
|
326
|
+
sage: CIF = ComplexIntervalField(80)
|
|
327
|
+
sage: box = CIF(RIF(-1,1),RIF(-1,1))
|
|
328
|
+
sage: a = [ CIF(0.1), CIF(1) + box ]
|
|
329
|
+
sage: b = [ CIF(0) + box, CIF(1) + 2 * box ]
|
|
330
|
+
sage: c = [ CIF(0), CIF(1) + 3 * box ]
|
|
331
|
+
|
|
332
|
+
sage: KrawczykShapesEngine.interval_vector_is_contained_in(a, b)
|
|
333
|
+
True
|
|
334
|
+
sage: KrawczykShapesEngine.interval_vector_is_contained_in(a, c)
|
|
335
|
+
False
|
|
336
|
+
sage: KrawczykShapesEngine.interval_vector_is_contained_in(b, a)
|
|
337
|
+
False
|
|
338
|
+
sage: KrawczykShapesEngine.interval_vector_is_contained_in(b, c)
|
|
339
|
+
False
|
|
340
|
+
sage: KrawczykShapesEngine.interval_vector_is_contained_in(c, a)
|
|
341
|
+
False
|
|
342
|
+
sage: KrawczykShapesEngine.interval_vector_is_contained_in(c, b)
|
|
343
|
+
False
|
|
344
|
+
"""
|
|
345
|
+
return all((a in b) for a, b in zip(vecA, vecB))
|
|
346
|
+
|
|
347
|
+
@staticmethod
|
|
348
|
+
def interval_vector_union(vecA, vecB):
|
|
349
|
+
"""
|
|
350
|
+
Given two vectors of intervals, return the vector of their unions,
|
|
351
|
+
i.e., the smallest interval containing both intervals.
|
|
352
|
+
"""
|
|
353
|
+
|
|
354
|
+
return make_vector([a.union(b) for a, b in zip(vecA, vecB)])
|
|
355
|
+
|
|
356
|
+
@sage_method
|
|
357
|
+
def __init__(self, M, initial_shapes, bits_prec=None, dec_prec=None):
|
|
358
|
+
"""
|
|
359
|
+
Initializes the KrawczykShapesEngine given an orientable SnapPy
|
|
360
|
+
Manifold M, approximated solutions initial_shapes to the
|
|
361
|
+
gluing equations (e.g., as returned by M.tetrahedra_shapes('rect'))
|
|
362
|
+
and the precision to be used for the desired computations in either
|
|
363
|
+
bits bits_prec or decimal digits dec_prec.
|
|
364
|
+
|
|
365
|
+
This requires Sage since it uses Sage's ComplexIntervalField for its
|
|
366
|
+
computations.
|
|
367
|
+
|
|
368
|
+
Note that this will choose an independent set of edge equations and
|
|
369
|
+
one equation per cusp. It is known that a solution to such a subset of
|
|
370
|
+
rectangular gluing equations is also a solution to the full set of
|
|
371
|
+
rectangular gluing equations::
|
|
372
|
+
|
|
373
|
+
sage: from snappy import Manifold
|
|
374
|
+
sage: M = Manifold("m019")
|
|
375
|
+
|
|
376
|
+
sage: C = KrawczykShapesEngine(M, M.tetrahedra_shapes('rect'), bits_prec = 53)
|
|
377
|
+
sage: C.expand_until_certified()
|
|
378
|
+
True
|
|
379
|
+
sage: C.certified_shapes # doctest: +ELLIPSIS
|
|
380
|
+
(0.780552527850...? + 0.914473662967...?*I, 0.780552527850...? + 0.91447366296773?*I, 0.4600211755737...? + 0.6326241936052...?*I)
|
|
381
|
+
|
|
382
|
+
Does not work with non-orientable manifolds::
|
|
383
|
+
|
|
384
|
+
sage: M = Manifold("m000")
|
|
385
|
+
sage: KrawczykShapesEngine(M, M.tetrahedra_shapes('rect'), bits_prec = 53)
|
|
386
|
+
Traceback (most recent call last):
|
|
387
|
+
...
|
|
388
|
+
Exception: Manifold needs to be orientable
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
Or some non-hyperbolic manifolds::
|
|
392
|
+
|
|
393
|
+
sage: Manifold("t02333(1,0)").tetrahedra_shapes(intervals = True) # doctest: +SKIP
|
|
394
|
+
Traceback (most recent call last):
|
|
395
|
+
...
|
|
396
|
+
RuntimeError: Could not certify shape intervals, either there are degenerate shapes or the precision must be increased.
|
|
397
|
+
|
|
398
|
+
"""
|
|
399
|
+
|
|
400
|
+
# Convert to precision in bits if necessary
|
|
401
|
+
if dec_prec:
|
|
402
|
+
self.prec = prec_dec_to_bits(dec_prec)
|
|
403
|
+
elif bits_prec:
|
|
404
|
+
self.prec = bits_prec
|
|
405
|
+
else:
|
|
406
|
+
raise Exception("Need dec_prec or bits_prec")
|
|
407
|
+
|
|
408
|
+
# Setup interval types of desired precision
|
|
409
|
+
self.CIF = ComplexIntervalField(self.prec)
|
|
410
|
+
self.RIF = RealIntervalField(self.prec)
|
|
411
|
+
|
|
412
|
+
# Verify that manifold is orientable
|
|
413
|
+
if not M.is_orientable():
|
|
414
|
+
raise Exception("Manifold needs to be orientable")
|
|
415
|
+
|
|
416
|
+
# Initialize the shape intervals, they have zero length
|
|
417
|
+
self.initial_shapes = make_vector(
|
|
418
|
+
[self.CIF(shape) for shape in initial_shapes])
|
|
419
|
+
|
|
420
|
+
# Get an independent set of gluing equations from snap
|
|
421
|
+
self.equations = snap.shapes.enough_gluing_equations(M)
|
|
422
|
+
self._make_sparse_equations()
|
|
423
|
+
|
|
424
|
+
self.identity = make_identity_matrix(ring=self.CIF, n=len(self.initial_shapes))
|
|
425
|
+
|
|
426
|
+
CDF = ComplexDoubleField()
|
|
427
|
+
|
|
428
|
+
# Could be sparse
|
|
429
|
+
approx_deriv = self.log_gluing_LHS_derivatives(
|
|
430
|
+
[ CDF(shape) for shape in initial_shapes] )
|
|
431
|
+
approx_inverse_double = approx_deriv.inverse()
|
|
432
|
+
self.approx_inverse = approx_inverse_double.change_ring(self.CIF)
|
|
433
|
+
|
|
434
|
+
# Compute the term z0 - c * f(z0) in the formula for
|
|
435
|
+
# the Krawczyk interval K(z0, [z], f)
|
|
436
|
+
|
|
437
|
+
value_at_initial_shapes = self.log_gluing_LHSs(self.initial_shapes)
|
|
438
|
+
|
|
439
|
+
self.first_term = (self.initial_shapes
|
|
440
|
+
- self.approx_inverse * value_at_initial_shapes)
|
|
441
|
+
|
|
442
|
+
# Shapes have not been certified yet
|
|
443
|
+
self.certified_shapes = None
|
|
444
|
+
|
|
445
|
+
def _make_sparse_equations(self):
|
|
446
|
+
num_eqns = len(self.equations)
|
|
447
|
+
self.sparse_equations = [ ]
|
|
448
|
+
for c in range(num_eqns):
|
|
449
|
+
column = []
|
|
450
|
+
for r in range(num_eqns):
|
|
451
|
+
A, B, dummy = self.equations[r]
|
|
452
|
+
a = A[c]
|
|
453
|
+
b = B[c]
|
|
454
|
+
if a != 0 or b != 0:
|
|
455
|
+
column.append((r, (a,b)))
|
|
456
|
+
self.sparse_equations.append(column)
|
|
457
|
+
|
|
458
|
+
@staticmethod
|
|
459
|
+
def _expand_intervals_a_little(shapes):
|
|
460
|
+
"""
|
|
461
|
+
Make the intervals a tiny bit larger.
|
|
462
|
+
"""
|
|
463
|
+
return shapes.apply_map(lambda z: z + (z - z) / 64)
|
|
464
|
+
|
|
465
|
+
def expand_until_certified(self, verbose=False):
|
|
466
|
+
"""
|
|
467
|
+
Try Krawczyk iterations (i.e., expanding the shape intervals [z]
|
|
468
|
+
by the Krawczyk interval K(z0, [z], f)) until we can certify they
|
|
469
|
+
contain a true solution.
|
|
470
|
+
|
|
471
|
+
If succeeded, return True and write certified shapes to
|
|
472
|
+
certified_shapes.
|
|
473
|
+
Set verbose = True for printing additional information.
|
|
474
|
+
"""
|
|
475
|
+
|
|
476
|
+
# Initialize the interval shapes to be the initial shapes
|
|
477
|
+
shapes = self.initial_shapes
|
|
478
|
+
|
|
479
|
+
# Number of iterations we do before giving up.
|
|
480
|
+
# For double precision, give up quickly because failure to
|
|
481
|
+
# converge here most likely indicates we need to use higher
|
|
482
|
+
# precision.
|
|
483
|
+
num_iterations = (25 if self.prec > 53 else 11)
|
|
484
|
+
|
|
485
|
+
# Do several "Krawczyk" iterations
|
|
486
|
+
# I.e. compute the union of the current interval with the
|
|
487
|
+
# interval computed in the Krawczyk test
|
|
488
|
+
for i in range(num_iterations + 1):
|
|
489
|
+
# Remember the old shapes
|
|
490
|
+
old_shapes = shapes
|
|
491
|
+
|
|
492
|
+
# Do the Krawczyk test
|
|
493
|
+
shapes = self.krawczyk_interval(shapes)
|
|
494
|
+
|
|
495
|
+
# If the shapes are certified, set them, we are done
|
|
496
|
+
if KrawczykShapesEngine.interval_vector_is_contained_in(
|
|
497
|
+
shapes, old_shapes):
|
|
498
|
+
if verbose:
|
|
499
|
+
print("Certified shapes after %d iterations" % (i + 1))
|
|
500
|
+
|
|
501
|
+
self.certified_shapes = shapes
|
|
502
|
+
return True
|
|
503
|
+
|
|
504
|
+
# Expand the shape intervals by taking the union of the
|
|
505
|
+
# old and new shapes
|
|
506
|
+
shapes = KrawczykShapesEngine.interval_vector_union(
|
|
507
|
+
shapes, old_shapes)
|
|
508
|
+
|
|
509
|
+
# Make it much faster
|
|
510
|
+
if i == 0:
|
|
511
|
+
shapes = KrawczykShapesEngine._expand_intervals_a_little(
|
|
512
|
+
shapes)
|
|
513
|
+
|
|
514
|
+
# After several iterations, still no certified shapes, give up.
|
|
515
|
+
if verbose:
|
|
516
|
+
print("Could not certify shapes")
|
|
517
|
+
|
|
518
|
+
return False
|