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,523 @@
|
|
|
1
|
+
from ..matrix import make_matrix, make_vector, mat_solve
|
|
2
|
+
from .. import snap
|
|
3
|
+
from ..sage_helper import _within_sage, sage_method
|
|
4
|
+
|
|
5
|
+
if _within_sage:
|
|
6
|
+
from sage.rings.complex_interval_field import ComplexIntervalField
|
|
7
|
+
from sage.rings.real_mpfi import RealIntervalField
|
|
8
|
+
from ..pari import prec_dec_to_bits
|
|
9
|
+
|
|
10
|
+
__all__ = ['IntervalNewtonShapesEngine']
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class IntervalNewtonShapesEngine:
|
|
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
|
|
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 the Newton interval method instead of the Krawczyk
|
|
36
|
+
test (we implement Gaussian elimination in interval arithmetic to
|
|
37
|
+
compute the inverse of an interval matrix having interval arithmetic
|
|
38
|
+
semantics, see mat_solve).
|
|
39
|
+
|
|
40
|
+
2. It uses complex numbers in it's Newton interval method.
|
|
41
|
+
We simply use Sage's complex interval type avoiding the need of
|
|
42
|
+
converting n x n complex matrices into 2n x 2n real matrices as
|
|
43
|
+
described Section 3.4 of the HIKMOT paper.
|
|
44
|
+
|
|
45
|
+
3. We avoid automatic differentiation. We pick an independent set of
|
|
46
|
+
equations of the following form and try to solve them:
|
|
47
|
+
|
|
48
|
+
log(LHS) = 0
|
|
49
|
+
|
|
50
|
+
where
|
|
51
|
+
|
|
52
|
+
LHS = c * z0^a0 * (1-z0)^b0 * z1^a1 * (1-z1)^b1 * ...
|
|
53
|
+
|
|
54
|
+
with a, b and c's as returned by Manifold.gluing_equations('rect').
|
|
55
|
+
|
|
56
|
+
The derivative of log (LHS) with respect to zj is simply given by
|
|
57
|
+
|
|
58
|
+
aj/zj - bj/(1-zj)
|
|
59
|
+
|
|
60
|
+
and thus no need for automatic differentiation.
|
|
61
|
+
|
|
62
|
+
In contrast to HIKMOT, we use and return Sage's native implementation of
|
|
63
|
+
(complex) interval arithmetic here, which allows for increased interoperability.
|
|
64
|
+
Another advantage is that Sage supports arbitrary precision. Unfortunately,
|
|
65
|
+
performance suffers and this implementation is 5-10 times slower than HIKMOT.
|
|
66
|
+
|
|
67
|
+
Here is an example how to explicitly invoke the IntervalNewtonShapesEngine::
|
|
68
|
+
|
|
69
|
+
sage: shapes = M.tetrahedra_shapes('rect', bits_prec = 80)
|
|
70
|
+
sage: C = IntervalNewtonShapesEngine(M, shapes, bits_prec = 80)
|
|
71
|
+
sage: C.expand_until_certified()
|
|
72
|
+
True
|
|
73
|
+
sage: C.certified_shapes # doctest: +ELLIPSIS
|
|
74
|
+
(0.662358978622373012981? + 0.562279512062301243...?*I, 0.66235897862237301298...? + 0.562279512062301243...?*I, 0.66235897862237301298...? + 0.562279512062301243...?*I)
|
|
75
|
+
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
@staticmethod
|
|
79
|
+
def log_gluing_LHSs(equations, shapes):
|
|
80
|
+
"""
|
|
81
|
+
Given the result of M.gluing_equations('rect') or a
|
|
82
|
+
subset of rows of it and shapes, return a vector of
|
|
83
|
+
log(LHS) where
|
|
84
|
+
|
|
85
|
+
LHS = c * z0 ** a0 * (1-z0) ** b0 * z1 ** a1 * ...
|
|
86
|
+
|
|
87
|
+
Let f: C^n -> C^n denote the function which takes
|
|
88
|
+
shapes and returns the vector of log(LHS).
|
|
89
|
+
|
|
90
|
+
The reason we take the logarithm of the rectangular
|
|
91
|
+
gluing equations is because the logarithmic derivative
|
|
92
|
+
is of a particular nice form::
|
|
93
|
+
|
|
94
|
+
sage: from snappy import Manifold
|
|
95
|
+
sage: M = Manifold("m019")
|
|
96
|
+
sage: equations = M.gluing_equations('rect')
|
|
97
|
+
sage: RIF = RealIntervalField(80)
|
|
98
|
+
sage: CIF = ComplexIntervalField(80)
|
|
99
|
+
sage: zero = CIF(0).center()
|
|
100
|
+
sage: shape1 = CIF(RIF(0.78055,0.78056), RIF(0.9144, 0.9145))
|
|
101
|
+
sage: shape2 = CIF(RIF(0.46002,0.46003), RIF(0.6326, 0.6327))
|
|
102
|
+
|
|
103
|
+
An interval solution containing the true solution. The log of each
|
|
104
|
+
rectangular equation should be 0 for the true solution, hence the interval
|
|
105
|
+
should contain zero::
|
|
106
|
+
|
|
107
|
+
sage: shapes = [shape1, shape1, shape2]
|
|
108
|
+
sage: LHSs = IntervalNewtonShapesEngine.log_gluing_LHSs(equations, shapes)
|
|
109
|
+
sage: LHSs # doctest: +ELLIPSIS
|
|
110
|
+
(0.000? + 0.000?*I, 0.000? + 0.000?*I, 0.000? + 0.000?*I, 0.000...? + 0.000...?*I, 0.000? + 0.000?*I)
|
|
111
|
+
sage: zero in LHSs[0]
|
|
112
|
+
True
|
|
113
|
+
|
|
114
|
+
An interval not containing the true solution::
|
|
115
|
+
|
|
116
|
+
sage: shapes = [shape1, shape1, shape1]
|
|
117
|
+
sage: LHSs = IntervalNewtonShapesEngine.log_gluing_LHSs(equations, shapes)
|
|
118
|
+
sage: LHSs # doctest: +ELLIPSIS
|
|
119
|
+
(0.430? - 0.078?*I, -0.2...? + 0.942?*I, -0.1...? - 0.8...?*I, 0.000...? + 0.000...?*I, 0.430? - 0.078?*I)
|
|
120
|
+
sage: zero in LHSs[0]
|
|
121
|
+
False
|
|
122
|
+
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
# Determine the field (should be ComplexField
|
|
126
|
+
# or ComplexIntervalField with some precision)
|
|
127
|
+
# of the shapes
|
|
128
|
+
BaseField = shapes[0].parent()
|
|
129
|
+
|
|
130
|
+
one = BaseField(1)
|
|
131
|
+
# The resulting vector as python list
|
|
132
|
+
gluing_LHSs = []
|
|
133
|
+
# Iterate through the rows of the result similar to
|
|
134
|
+
# M.gluing_equations('rect')
|
|
135
|
+
for A, B, c in equations:
|
|
136
|
+
# A and B are rows, c is an entry
|
|
137
|
+
# prod keeps the above product
|
|
138
|
+
prod = BaseField(c)
|
|
139
|
+
for a, b, shape in zip(A, B, shapes):
|
|
140
|
+
prod *= (shape ** a) * (one - shape) ** b
|
|
141
|
+
|
|
142
|
+
# Take log of the entire product
|
|
143
|
+
gluing_LHSs.append(prod.log())
|
|
144
|
+
|
|
145
|
+
return make_vector(gluing_LHSs, ring=BaseField)
|
|
146
|
+
|
|
147
|
+
@staticmethod
|
|
148
|
+
def log_gluing_LHS_derivatives(equations, shapes):
|
|
149
|
+
"""
|
|
150
|
+
Compute the Jacobian of the vector-valued function f
|
|
151
|
+
described in the above log_gluing_LHSs::
|
|
152
|
+
|
|
153
|
+
sage: from snappy import Manifold
|
|
154
|
+
sage: M = Manifold("m019")
|
|
155
|
+
sage: equations = M.gluing_equations('rect')
|
|
156
|
+
sage: RIF = RealIntervalField(80)
|
|
157
|
+
sage: CIF = ComplexIntervalField(80)
|
|
158
|
+
sage: shape1 = CIF(RIF(0.78055,0.78056), RIF(0.9144, 0.9145))
|
|
159
|
+
sage: shape2 = CIF(RIF(0.46002,0.46003), RIF(0.6326, 0.6327))
|
|
160
|
+
sage: shapes = [shape1, shape1, shape2]
|
|
161
|
+
sage: IntervalNewtonShapesEngine.log_gluing_LHS_derivatives(equations, shapes) # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
|
|
162
|
+
[ 0.292? - 1.66...?*I 0.292? - 1.66...?*I 0.752? - 1.034...?*I]
|
|
163
|
+
[-0.5400? + 0.63...?*I -0.5400? + 0.63...?*I 1.561? + 1.829...?*I]
|
|
164
|
+
[ 0.2482? + 1.034...?*I 0.2482? + 1.034...?*I -2.313? - 0.795...?*I]
|
|
165
|
+
[ 0.5400? - 0.63...?*I -0.5400? + 0.63...?*I 0]
|
|
166
|
+
[...-0.4963? - 2.068?*I 1.0800? - 1.26...?*I 0.752? - 1.034...?*I]
|
|
167
|
+
|
|
168
|
+
"""
|
|
169
|
+
|
|
170
|
+
# Similar to log_gluing_LHS
|
|
171
|
+
BaseField = shapes[0].parent()
|
|
172
|
+
zero = BaseField(0)
|
|
173
|
+
one = BaseField(1)
|
|
174
|
+
|
|
175
|
+
# 1 / z for each shape z
|
|
176
|
+
shape_inverses = [ one / shape for shape in shapes ]
|
|
177
|
+
|
|
178
|
+
# 1 / (1-z) for each shape z
|
|
179
|
+
one_minus_shape_inverses = [ one / (one - shape) for shape in shapes ]
|
|
180
|
+
|
|
181
|
+
gluing_LHS_derivatives = []
|
|
182
|
+
for A, B, c in equations:
|
|
183
|
+
row = []
|
|
184
|
+
for a, b, shape_inverse, one_minus_shape_inverse in zip(
|
|
185
|
+
A, B, shape_inverses, one_minus_shape_inverses):
|
|
186
|
+
# Equation for the derivative
|
|
187
|
+
# derivative = ( a / z - b / (1-z) )
|
|
188
|
+
derivative = zero
|
|
189
|
+
if not a == 0:
|
|
190
|
+
derivative = BaseField(int(a)) * shape_inverse
|
|
191
|
+
if not b == 0:
|
|
192
|
+
derivative -= BaseField(int(b)) * one_minus_shape_inverse
|
|
193
|
+
|
|
194
|
+
row.append( derivative )
|
|
195
|
+
|
|
196
|
+
gluing_LHS_derivatives.append(row)
|
|
197
|
+
|
|
198
|
+
return make_matrix(gluing_LHS_derivatives, ring=BaseField)
|
|
199
|
+
|
|
200
|
+
@staticmethod
|
|
201
|
+
def interval_vector_mid_points(vec):
|
|
202
|
+
"""
|
|
203
|
+
Given a vector of complex intervals, return the midpoints (as 0-length
|
|
204
|
+
complex intervals) of them.
|
|
205
|
+
"""
|
|
206
|
+
# Should be ComplexIntervalField with the desired precision
|
|
207
|
+
BaseField = vec[0].parent()
|
|
208
|
+
|
|
209
|
+
return vec.apply_map(lambda shape: BaseField(shape.center()))
|
|
210
|
+
|
|
211
|
+
@staticmethod
|
|
212
|
+
def newton_iteration(equations, shape_intervals,
|
|
213
|
+
point_in_intervals=None,
|
|
214
|
+
interval_value_at_point=None):
|
|
215
|
+
"""
|
|
216
|
+
Perform a Newton interval method of iteration for
|
|
217
|
+
the function f described in log_gluing_LHSs.
|
|
218
|
+
|
|
219
|
+
Let z denote the shape intervals.
|
|
220
|
+
Let z_center be a point close to the center point of the shape
|
|
221
|
+
intervals (in the implementation, z_center is an interval of
|
|
222
|
+
again, of length zero).
|
|
223
|
+
|
|
224
|
+
The result returned will be
|
|
225
|
+
|
|
226
|
+
N(z) = z_center - ((Df)(z))^-1 f(z_center)
|
|
227
|
+
|
|
228
|
+
The user can overwrite the z_center to be used by providing
|
|
229
|
+
point_in_intervals (which have to be 0-length complex intervals).
|
|
230
|
+
The user can also give the interval value of f(z_center) by providing
|
|
231
|
+
interval_value_at_point to avoid re-evaluation of f(z_center).
|
|
232
|
+
|
|
233
|
+
A very approximate solution::
|
|
234
|
+
|
|
235
|
+
sage: from snappy import Manifold
|
|
236
|
+
sage: M = Manifold("m019")
|
|
237
|
+
sage: shapes = [ 0.7+1j, 0.7+1j, 0.5+0.5j ]
|
|
238
|
+
|
|
239
|
+
Get the equations and initialize zero-length intervals from it::
|
|
240
|
+
|
|
241
|
+
sage: C = IntervalNewtonShapesEngine(M, shapes, bits_prec = 80)
|
|
242
|
+
sage: C.initial_shapes
|
|
243
|
+
(0.69999999999999995559107902? + 1*I, 0.69999999999999995559107902? + 1*I, 0.50000000000000000000000000? + 0.50000000000000000000000000?*I)
|
|
244
|
+
|
|
245
|
+
Do several Newton interval operations to get a better solution::
|
|
246
|
+
|
|
247
|
+
sage: shape_intervals = C.initial_shapes
|
|
248
|
+
sage: for i in range(4): # doctest: +ELLIPSIS
|
|
249
|
+
... shape_intervals = IntervalNewtonShapesEngine.newton_iteration(C.equations, shape_intervals)
|
|
250
|
+
... print(shape_intervals)
|
|
251
|
+
(0.78674683118381457770...? + 0.9208680745160821379529?*I, 0.786746831183814577703...? + 0.9208680745160821379529?*I, 0.459868058287098030934...? + 0.61940871855835167317...?*I)
|
|
252
|
+
(0.78056102517632648594...? + 0.9144962118446750482...?*I, 0.78056102517632648594...? + 0.9144962118446750482...?*I, 0.4599773577869384936554? + 0.63251940718694538695...?*I)
|
|
253
|
+
(0.78055253104531610049...? + 0.9144736621585220345231?*I, 0.780552531045316100497...? + 0.9144736621585220345231?*I, 0.460021167103732494700...? + 0.6326241909236695020810...?*I)
|
|
254
|
+
(0.78055252785072483256...? + 0.91447366296772644033...?*I, 0.7805525278507248325678? + 0.914473662967726440333...?*I, 0.4600211755737178641204...? + 0.6326241936052562241142...?*I)
|
|
255
|
+
|
|
256
|
+
For comparison::
|
|
257
|
+
|
|
258
|
+
sage: M.tetrahedra_shapes('rect')
|
|
259
|
+
[0.780552527850725 + 0.914473662967726*I, 0.780552527850725 + 0.914473662967726*I, 0.460021175573718 + 0.632624193605256*I]
|
|
260
|
+
|
|
261
|
+
Start with a rather big interval, note that the Newton interval method is
|
|
262
|
+
stable in the sense that the interval size decreases::
|
|
263
|
+
|
|
264
|
+
sage: box = C.CIF(C.RIF(-0.0001,0.0001),C.RIF(-0.0001,0.0001))
|
|
265
|
+
sage: shape_intervals = C.initial_shapes.apply_map(lambda shape: shape + box)
|
|
266
|
+
sage: shape_intervals
|
|
267
|
+
(0.700? + 1.000?*I, 0.700? + 1.000?*I, 0.500? + 0.500?*I)
|
|
268
|
+
sage: for i in range(7):
|
|
269
|
+
... shape_intervals = IntervalNewtonShapesEngine.newton_iteration(C.equations, shape_intervals)
|
|
270
|
+
sage: print(shape_intervals) # doctest: +ELLIPSIS
|
|
271
|
+
(0.78055252785072483798...? + 0.91447366296772645593...?*I, 0.7805525278507248379869? + 0.914473662967726455938...?*I, 0.460021175573717872891...? + 0.632624193605256171637...?*I)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
"""
|
|
275
|
+
|
|
276
|
+
if point_in_intervals is None:
|
|
277
|
+
point_in_intervals = (
|
|
278
|
+
IntervalNewtonShapesEngine.interval_vector_mid_points(
|
|
279
|
+
shape_intervals))
|
|
280
|
+
if interval_value_at_point is None:
|
|
281
|
+
interval_value_at_point = IntervalNewtonShapesEngine.log_gluing_LHSs(
|
|
282
|
+
equations, point_in_intervals)
|
|
283
|
+
|
|
284
|
+
# Compute (DF)(z)
|
|
285
|
+
derivatives = IntervalNewtonShapesEngine.log_gluing_LHS_derivatives(
|
|
286
|
+
equations, shape_intervals)
|
|
287
|
+
|
|
288
|
+
return ( point_in_intervals
|
|
289
|
+
- mat_solve(derivatives, interval_value_at_point))
|
|
290
|
+
|
|
291
|
+
@staticmethod
|
|
292
|
+
def interval_vector_is_contained_in(vecA, vecB):
|
|
293
|
+
"""
|
|
294
|
+
Given two vectors of intervals, return whether the first one
|
|
295
|
+
is contained in the second one. Examples::
|
|
296
|
+
|
|
297
|
+
sage: RIF = RealIntervalField(80)
|
|
298
|
+
sage: CIF = ComplexIntervalField(80)
|
|
299
|
+
sage: box = CIF(RIF(-1,1),RIF(-1,1))
|
|
300
|
+
sage: a = [ CIF(0.1), CIF(1) + box ]
|
|
301
|
+
sage: b = [ CIF(0) + box, CIF(1) + 2 * box ]
|
|
302
|
+
sage: c = [ CIF(0), CIF(1) + 3 * box ]
|
|
303
|
+
|
|
304
|
+
sage: IntervalNewtonShapesEngine.interval_vector_is_contained_in(a, b)
|
|
305
|
+
True
|
|
306
|
+
sage: IntervalNewtonShapesEngine.interval_vector_is_contained_in(a, c)
|
|
307
|
+
False
|
|
308
|
+
sage: IntervalNewtonShapesEngine.interval_vector_is_contained_in(b, a)
|
|
309
|
+
False
|
|
310
|
+
sage: IntervalNewtonShapesEngine.interval_vector_is_contained_in(b, c)
|
|
311
|
+
False
|
|
312
|
+
sage: IntervalNewtonShapesEngine.interval_vector_is_contained_in(c, a)
|
|
313
|
+
False
|
|
314
|
+
sage: IntervalNewtonShapesEngine.interval_vector_is_contained_in(c, b)
|
|
315
|
+
False
|
|
316
|
+
"""
|
|
317
|
+
return all((a in b) for a, b in zip(vecA, vecB))
|
|
318
|
+
|
|
319
|
+
@staticmethod
|
|
320
|
+
def interval_vector_union(vecA, vecB):
|
|
321
|
+
"""
|
|
322
|
+
Given two vectors of intervals, return the vector of their unions,
|
|
323
|
+
i.e., the smallest interval containing both intervals.
|
|
324
|
+
"""
|
|
325
|
+
return make_vector([a.union(b) for a, b in zip(vecA, vecB)])
|
|
326
|
+
|
|
327
|
+
@staticmethod
|
|
328
|
+
def certified_newton_iteration(equations, shape_intervals,
|
|
329
|
+
point_in_intervals=None,
|
|
330
|
+
interval_value_at_point=None):
|
|
331
|
+
"""
|
|
332
|
+
Given shape intervals z, performs a Newton interval iteration N(z)
|
|
333
|
+
as described in newton_iteration. Returns a pair (boolean, N(z)) where
|
|
334
|
+
the boolean is True if N(z) is contained in z.
|
|
335
|
+
|
|
336
|
+
If the boolean is True, it is certified that N(z) contains a true
|
|
337
|
+
solution, e.g., a point for which f is truly zero.
|
|
338
|
+
|
|
339
|
+
See newton_iteration for the other parameters.
|
|
340
|
+
|
|
341
|
+
This follows from Theorem 1 of `Zgliczynski's notes
|
|
342
|
+
<http://ww2.ii.uj.edu.pl/~zgliczyn/cap07/krawczyk.pdf>`_.
|
|
343
|
+
|
|
344
|
+
Some examples::
|
|
345
|
+
|
|
346
|
+
sage: from snappy import Manifold
|
|
347
|
+
sage: M = Manifold("m019")
|
|
348
|
+
sage: C = IntervalNewtonShapesEngine(M, M.tetrahedra_shapes('rect'),
|
|
349
|
+
... bits_prec = 80)
|
|
350
|
+
|
|
351
|
+
Intervals containing the true solution::
|
|
352
|
+
|
|
353
|
+
sage: from sage.all import vector
|
|
354
|
+
sage: good_shapes = vector([
|
|
355
|
+
... C.CIF(C.RIF(0.78055, 0.78056), C.RIF(0.91447, 0.91448)),
|
|
356
|
+
... C.CIF(C.RIF(0.78055, 0.78056), C.RIF(0.91447, 0.91448)),
|
|
357
|
+
... C.CIF(C.RIF(0.46002, 0.46003), C.RIF(0.63262, 0.63263))])
|
|
358
|
+
sage: is_certified, shapes = IntervalNewtonShapesEngine.certified_newton_iteration(C.equations, good_shapes)
|
|
359
|
+
|
|
360
|
+
sage: is_certified
|
|
361
|
+
True
|
|
362
|
+
sage: shapes # doctest: +ELLIPSIS
|
|
363
|
+
(0.78055253? + 0.91447366...?*I, 0.7805525...? + 0.9144736...?*I, 0.4600211...? + 0.632624...?*I)
|
|
364
|
+
|
|
365
|
+
This means that a true solution to the rectangular gluing equations is
|
|
366
|
+
contained in both the given intervals (good_shapes) and the returned
|
|
367
|
+
intervals (shapes) which are a refinement of the given intervals.
|
|
368
|
+
|
|
369
|
+
Intervals not containing a true solution::
|
|
370
|
+
|
|
371
|
+
sage: from sage.all import vector
|
|
372
|
+
sage: bad_shapes = vector([
|
|
373
|
+
... C.CIF(C.RIF(0.78054, 0.78055), C.RIF(0.91447, 0.91448)),
|
|
374
|
+
... C.CIF(C.RIF(0.78055, 0.78056), C.RIF(0.91447, 0.91448)),
|
|
375
|
+
... C.CIF(C.RIF(0.46002, 0.46003), C.RIF(0.63262, 0.63263))])
|
|
376
|
+
sage: is_certified, shapes = IntervalNewtonShapesEngine.certified_newton_iteration(C.equations, bad_shapes)
|
|
377
|
+
sage: is_certified
|
|
378
|
+
False
|
|
379
|
+
|
|
380
|
+
"""
|
|
381
|
+
|
|
382
|
+
new_shapes = IntervalNewtonShapesEngine.newton_iteration(
|
|
383
|
+
equations, shape_intervals,
|
|
384
|
+
point_in_intervals=point_in_intervals,
|
|
385
|
+
interval_value_at_point=interval_value_at_point)
|
|
386
|
+
return (
|
|
387
|
+
IntervalNewtonShapesEngine.interval_vector_is_contained_in(
|
|
388
|
+
new_shapes, shape_intervals),
|
|
389
|
+
new_shapes)
|
|
390
|
+
|
|
391
|
+
@sage_method
|
|
392
|
+
def __init__(self, M, initial_shapes, bits_prec=None, dec_prec=None):
|
|
393
|
+
"""
|
|
394
|
+
Initializes the IntervalNewtonShapesEngine given an orientable SnapPy
|
|
395
|
+
Manifold M, approximated solutions initial_shapes to the
|
|
396
|
+
gluing equations (e.g., as returned by M.tetrahedra_shapes('rect'))
|
|
397
|
+
and the precision to be used for the desired computations in either
|
|
398
|
+
bits bits_prec or decimal digits dec_prec.
|
|
399
|
+
|
|
400
|
+
This requires Sage since it uses Sage's ComplexIntervalField for its
|
|
401
|
+
computations.
|
|
402
|
+
|
|
403
|
+
Note that this will choose an independent set of edge equations and
|
|
404
|
+
one equation per cusp. It is known that a solution to such a subset of
|
|
405
|
+
rectangular gluing equations is also a solution to the full set of
|
|
406
|
+
rectangular gluing equations::
|
|
407
|
+
|
|
408
|
+
sage: from snappy import Manifold
|
|
409
|
+
sage: M = Manifold("m019")
|
|
410
|
+
|
|
411
|
+
sage: C = IntervalNewtonShapesEngine(M, M.tetrahedra_shapes('rect'), bits_prec = 53)
|
|
412
|
+
sage: C.expand_until_certified()
|
|
413
|
+
True
|
|
414
|
+
sage: C.certified_shapes # doctest: +ELLIPSIS
|
|
415
|
+
(0.780552527850...? + 0.914473662967...?*I, 0.780552527850...? + 0.91447366296773?*I, 0.4600211755737...? + 0.6326241936052...?*I)
|
|
416
|
+
|
|
417
|
+
Does not work with non-orientable manifolds::
|
|
418
|
+
|
|
419
|
+
sage: M = Manifold("m000")
|
|
420
|
+
sage: IntervalNewtonShapesEngine(M, M.tetrahedra_shapes('rect'), bits_prec = 53)
|
|
421
|
+
Traceback (most recent call last):
|
|
422
|
+
...
|
|
423
|
+
ValueError: Manifold needs to be orientable
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
Or some non-hyperbolic manifolds::
|
|
427
|
+
|
|
428
|
+
sage: Manifold("t02333(1,0)").tetrahedra_shapes(intervals = True)
|
|
429
|
+
Traceback (most recent call last):
|
|
430
|
+
...
|
|
431
|
+
RuntimeError: Could not certify shape intervals, either there are degenerate shapes or the precision must be increased.
|
|
432
|
+
|
|
433
|
+
"""
|
|
434
|
+
|
|
435
|
+
# Convert to precision in bits if necessary
|
|
436
|
+
if dec_prec:
|
|
437
|
+
self.prec = prec_dec_to_bits(dec_prec)
|
|
438
|
+
elif bits_prec:
|
|
439
|
+
self.prec = bits_prec
|
|
440
|
+
else:
|
|
441
|
+
raise ValueError("Need dec_prec or bits_prec")
|
|
442
|
+
|
|
443
|
+
# Setup interval types of desired precision
|
|
444
|
+
self.CIF = ComplexIntervalField(self.prec)
|
|
445
|
+
self.RIF = RealIntervalField(self.prec)
|
|
446
|
+
|
|
447
|
+
# Verify that manifold is orientable
|
|
448
|
+
if not M.is_orientable():
|
|
449
|
+
raise ValueError("Manifold needs to be orientable")
|
|
450
|
+
|
|
451
|
+
# Initialize the shape intervals, they have zero length
|
|
452
|
+
self.initial_shapes = make_vector(
|
|
453
|
+
[self.CIF(shape) for shape in initial_shapes])
|
|
454
|
+
|
|
455
|
+
# Get an independent set of gluing equations from snap
|
|
456
|
+
self.equations = snap.shapes.enough_gluing_equations(M)
|
|
457
|
+
|
|
458
|
+
# Shapes have not been certified yet
|
|
459
|
+
self.certified_shapes = None
|
|
460
|
+
|
|
461
|
+
def expand_until_certified(self, verbose=False):
|
|
462
|
+
"""
|
|
463
|
+
Try Newton interval iterations, expanding the shape intervals
|
|
464
|
+
until we can certify they contain a true solution.
|
|
465
|
+
If succeeded, return True and write certified shapes to
|
|
466
|
+
certified_shapes.
|
|
467
|
+
Set verbose = True for printing additional information.
|
|
468
|
+
"""
|
|
469
|
+
|
|
470
|
+
# In the equation for the Newton interval iteration
|
|
471
|
+
# N(z) = z_center - ((Df)(z))^-1 f(z_center)
|
|
472
|
+
#
|
|
473
|
+
# We always let z_center be the initial_shapes (which is a 0-length
|
|
474
|
+
# interval) and expand the interval for z.
|
|
475
|
+
# We evaluate the interval value of f(z_center) only once, here:
|
|
476
|
+
interval_value_at_initial_shapes = (
|
|
477
|
+
IntervalNewtonShapesEngine.log_gluing_LHSs(
|
|
478
|
+
self.equations, self.initial_shapes))
|
|
479
|
+
|
|
480
|
+
# Initialize the interval shapes to be the initial shapes
|
|
481
|
+
shapes = self.initial_shapes
|
|
482
|
+
|
|
483
|
+
# Number of iterations we do before giving up.
|
|
484
|
+
# For double precision, give up quickly because failure to
|
|
485
|
+
# converge here most likely indicates we need to use higher
|
|
486
|
+
# precision.
|
|
487
|
+
num_iterations = (25 if self.prec > 53 else 11)
|
|
488
|
+
|
|
489
|
+
# Do several Newton interval iteration
|
|
490
|
+
for i in range(num_iterations + 1):
|
|
491
|
+
# Remember the old shapes
|
|
492
|
+
old_shapes = shapes
|
|
493
|
+
|
|
494
|
+
# Do the Newton step
|
|
495
|
+
try:
|
|
496
|
+
is_certified, shapes = (
|
|
497
|
+
IntervalNewtonShapesEngine.certified_newton_iteration(
|
|
498
|
+
self.equations, shapes,
|
|
499
|
+
point_in_intervals=self.initial_shapes,
|
|
500
|
+
interval_value_at_point=interval_value_at_initial_shapes))
|
|
501
|
+
except ZeroDivisionError:
|
|
502
|
+
if verbose:
|
|
503
|
+
print("Division by zero in interval Gaussian elimination")
|
|
504
|
+
return False
|
|
505
|
+
|
|
506
|
+
# If the shapes are certified, set them, we are done
|
|
507
|
+
if is_certified:
|
|
508
|
+
if verbose:
|
|
509
|
+
print("Certified shapes after %d iterations" % (i + 1))
|
|
510
|
+
|
|
511
|
+
self.certified_shapes = shapes
|
|
512
|
+
return True
|
|
513
|
+
|
|
514
|
+
# Expand the shape intervals by taking the union of the
|
|
515
|
+
# old and new shapes
|
|
516
|
+
shapes = IntervalNewtonShapesEngine.interval_vector_union(
|
|
517
|
+
shapes, old_shapes)
|
|
518
|
+
|
|
519
|
+
# After several iterations, still no certified shapes, give up.
|
|
520
|
+
if verbose:
|
|
521
|
+
print("Could not certify shapes")
|
|
522
|
+
|
|
523
|
+
return False
|