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
snappy/database.py
ADDED
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module uses the Manifold class from the SnapPy extension
|
|
3
|
+
module. After the Manifold class has been defined, the "__init__.py"
|
|
4
|
+
module for "snappy" itself sets::
|
|
5
|
+
|
|
6
|
+
database.Manifold = Manifold
|
|
7
|
+
|
|
8
|
+
This file simply defines the ManifoldTable class. The ManifoldTables
|
|
9
|
+
that come with actual data are defined in external packages, such as
|
|
10
|
+
the required "snappy_manifolds". Such a package must provide a
|
|
11
|
+
"get_tables" function that accepts the below "ManifoldTable" as input
|
|
12
|
+
and returns a list of subclasses of "ManifoldTable".
|
|
13
|
+
"""
|
|
14
|
+
from .db_utilities import decode_torsion, decode_matrices, db_hash
|
|
15
|
+
from .sage_helper import _within_sage
|
|
16
|
+
from spherogram.codecs import DTcodec
|
|
17
|
+
import sys
|
|
18
|
+
import sqlite3
|
|
19
|
+
import re
|
|
20
|
+
import random
|
|
21
|
+
import importlib
|
|
22
|
+
import collections
|
|
23
|
+
|
|
24
|
+
if _within_sage:
|
|
25
|
+
from .sage_helper import Integer, RealDoubleElement, RealNumber
|
|
26
|
+
|
|
27
|
+
def is_int(slice):
|
|
28
|
+
return isinstance(slice, (Integer, int))
|
|
29
|
+
|
|
30
|
+
def is_int_or_none(slice):
|
|
31
|
+
return isinstance(slice, (Integer, int, type(None)))
|
|
32
|
+
|
|
33
|
+
def is_float_or_none(slice):
|
|
34
|
+
return isinstance(slice, (float, RealDoubleElement,
|
|
35
|
+
RealNumber, type(None)))
|
|
36
|
+
else:
|
|
37
|
+
def is_int(slice):
|
|
38
|
+
return isinstance(slice, int)
|
|
39
|
+
|
|
40
|
+
def is_int_or_none(slice):
|
|
41
|
+
return isinstance(slice, (int, type(None)))
|
|
42
|
+
|
|
43
|
+
def is_float_or_none(slice):
|
|
44
|
+
return isinstance(slice, (float, type(None)))
|
|
45
|
+
|
|
46
|
+
split_filling_info = re.compile(r'(.*?)((?:\([0-9 .+-]+,[0-9 .+-]+\))*$)')
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def connect_to_db(db_path):
|
|
50
|
+
"""
|
|
51
|
+
Open the given sqlite database, ideally in read-only mode.
|
|
52
|
+
"""
|
|
53
|
+
if sys.version_info >= (3,4):
|
|
54
|
+
uri = 'file:' + db_path + '?mode=ro'
|
|
55
|
+
return sqlite3.connect(uri, uri=True)
|
|
56
|
+
elif sys.platform.startswith('win'):
|
|
57
|
+
try:
|
|
58
|
+
import apsw
|
|
59
|
+
return apsw.Connection(db_path, flags=apsw.SQLITE_OPEN_READONLY)
|
|
60
|
+
except ImportError:
|
|
61
|
+
return sqlite3.connect(db_path)
|
|
62
|
+
else:
|
|
63
|
+
return sqlite3.connect(db_path)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def mfld_hash(manifold):
|
|
67
|
+
"""
|
|
68
|
+
We cache the hash to speed up searching for one manifold in
|
|
69
|
+
multiple tables.
|
|
70
|
+
"""
|
|
71
|
+
if 'db_hash' not in manifold._cache:
|
|
72
|
+
manifold._cache['db_hash'] = db_hash(manifold)
|
|
73
|
+
return manifold._cache['db_hash']
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class ManifoldTable():
|
|
77
|
+
"""
|
|
78
|
+
Iterator for cusped manifolds in an sqlite3 table of manifolds.
|
|
79
|
+
|
|
80
|
+
Initialize with the table name. The table schema is required to
|
|
81
|
+
include a text field called 'name' and a text field called
|
|
82
|
+
'triangulation'. The text holds the result of
|
|
83
|
+
M.triangulation_isosig(), M.triangulation_isosig(decorated = True), or
|
|
84
|
+
M._to_string().
|
|
85
|
+
|
|
86
|
+
Both mapping from the manifold name, and lookup by index are
|
|
87
|
+
supported. Slicing can be done either by numerical index or by
|
|
88
|
+
volume.
|
|
89
|
+
|
|
90
|
+
The __contains__ method is supported, so M in T returns True if M
|
|
91
|
+
is isometric to a manifold in the table T. The method
|
|
92
|
+
T.identify(M) will return the matching manifold from the table.
|
|
93
|
+
"""
|
|
94
|
+
# basic select clause. Can be overridden, e.g. to add additional columns
|
|
95
|
+
_select = 'select name, triangulation from %s '
|
|
96
|
+
|
|
97
|
+
def __init__(self, table='', db_path=None,
|
|
98
|
+
mfld_hash=mfld_hash, **filter_args):
|
|
99
|
+
self._table = table
|
|
100
|
+
self.mfld_hash = mfld_hash
|
|
101
|
+
self._db_path = db_path
|
|
102
|
+
self._connection = connect_to_db(db_path)
|
|
103
|
+
self._cursor = self._connection.cursor()
|
|
104
|
+
self._set_schema()
|
|
105
|
+
self._check_schema()
|
|
106
|
+
self._configure(**filter_args)
|
|
107
|
+
self._get_length()
|
|
108
|
+
self._get_max_volume()
|
|
109
|
+
self._select = self._select % table
|
|
110
|
+
|
|
111
|
+
def _set_schema(self):
|
|
112
|
+
cursor, table = self._cursor, self._table
|
|
113
|
+
rows = cursor.execute("pragma table_info('%s')" % table).fetchall()
|
|
114
|
+
self.schema = {row[1]: row[2].lower() for row in rows}
|
|
115
|
+
|
|
116
|
+
def _check_schema(self):
|
|
117
|
+
assert (self.schema['name'] == 'text' and
|
|
118
|
+
self.schema['triangulation'] == 'text'
|
|
119
|
+
), 'Not a valid Manifold table.'
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def filter(self):
|
|
123
|
+
return self._filter
|
|
124
|
+
|
|
125
|
+
def _get_length(self):
|
|
126
|
+
where_clause = 'where ' + self._filter if self._filter else ''
|
|
127
|
+
length_query = 'select count(*) from %s %s' % (self._table,
|
|
128
|
+
where_clause)
|
|
129
|
+
cursor = self._cursor.execute(length_query)
|
|
130
|
+
self._length = cursor.fetchone()[0]
|
|
131
|
+
|
|
132
|
+
min_id_query = 'select min(id) from %s %s' % (self._table, where_clause)
|
|
133
|
+
cursor = self._cursor.execute(min_id_query)
|
|
134
|
+
self._min_id = cursor.fetchone()[0]
|
|
135
|
+
|
|
136
|
+
max_id_query = 'select max(id) from %s %s' % (self._table, where_clause)
|
|
137
|
+
cursor = self._cursor.execute(max_id_query)
|
|
138
|
+
self._max_id = cursor.fetchone()[0]
|
|
139
|
+
|
|
140
|
+
if self._length > 0:
|
|
141
|
+
self._ids_contiguous = self._length == (self._max_id - self._min_id + 1)
|
|
142
|
+
|
|
143
|
+
def _get_max_volume(self):
|
|
144
|
+
where_clause = 'where ' + self._filter if self._filter else ''
|
|
145
|
+
vol_query = 'select max(volume) from %s %s' % (self._table,
|
|
146
|
+
where_clause)
|
|
147
|
+
cursor = self._cursor.execute(vol_query)
|
|
148
|
+
self._max_volume = cursor.fetchone()[0]
|
|
149
|
+
|
|
150
|
+
def _configure(self, **kwargs):
|
|
151
|
+
"""
|
|
152
|
+
Set up the filter.
|
|
153
|
+
"""
|
|
154
|
+
conditions = []
|
|
155
|
+
|
|
156
|
+
if 'filter' in kwargs:
|
|
157
|
+
conditions.append(kwargs['filter'])
|
|
158
|
+
if 'betti' in kwargs:
|
|
159
|
+
conditions.append('betti=%d ' % kwargs['betti'])
|
|
160
|
+
if 'num_cusps' in kwargs:
|
|
161
|
+
conditions.append('cusps=%d ' % kwargs['num_cusps'])
|
|
162
|
+
if 'cusps' in kwargs:
|
|
163
|
+
conditions.append('cusps=%d ' % kwargs['cusps'])
|
|
164
|
+
if 'num_tets' in kwargs:
|
|
165
|
+
conditions.append('tets=%d ' % kwargs['num_tets'])
|
|
166
|
+
if 'tets' in kwargs:
|
|
167
|
+
conditions.append('tets=%d ' % kwargs['tets'])
|
|
168
|
+
self._filter = ' and '.join(conditions)
|
|
169
|
+
|
|
170
|
+
def __repr__(self):
|
|
171
|
+
class_name = self.__class__.__name__
|
|
172
|
+
if self._filter == '':
|
|
173
|
+
return '%s without filters' % class_name
|
|
174
|
+
else:
|
|
175
|
+
return '%s with filter: %s' % (class_name, self._filter)
|
|
176
|
+
|
|
177
|
+
def __call__(self, **kwargs):
|
|
178
|
+
return self.__class__(**kwargs)
|
|
179
|
+
|
|
180
|
+
def __len__(self):
|
|
181
|
+
return self._length
|
|
182
|
+
|
|
183
|
+
def __iter__(self):
|
|
184
|
+
query = self._select
|
|
185
|
+
if self._filter:
|
|
186
|
+
query += ' where %s order by id' % self._filter
|
|
187
|
+
cursor = self._connection.cursor()
|
|
188
|
+
for row in cursor.execute(query):
|
|
189
|
+
yield self._manifold_factory(row)
|
|
190
|
+
|
|
191
|
+
def __contains__(self, mfld):
|
|
192
|
+
try:
|
|
193
|
+
M = self.identify(mfld)
|
|
194
|
+
# duck test
|
|
195
|
+
return M.num_tetrahedra() > 0
|
|
196
|
+
except:
|
|
197
|
+
return False
|
|
198
|
+
|
|
199
|
+
def __getitem__(self, index):
|
|
200
|
+
if isinstance(index, slice):
|
|
201
|
+
if index.step:
|
|
202
|
+
raise IndexError('Slices with steps are not supported.')
|
|
203
|
+
start, stop = index.start, index.stop
|
|
204
|
+
if is_float_or_none(start) and is_float_or_none(stop):
|
|
205
|
+
# Slice by volume.
|
|
206
|
+
conditions = []
|
|
207
|
+
if self._filter:
|
|
208
|
+
conditions.append(self._filter)
|
|
209
|
+
if start:
|
|
210
|
+
conditions.append('volume >= %f' % start)
|
|
211
|
+
if stop:
|
|
212
|
+
conditions.append('volume < %f' % stop)
|
|
213
|
+
filter = ' and '.join(conditions)
|
|
214
|
+
return self.__class__(filter=filter)
|
|
215
|
+
elif (is_int_or_none(start) and is_int_or_none(stop)):
|
|
216
|
+
if start is None:
|
|
217
|
+
start = 0
|
|
218
|
+
elif start < 0:
|
|
219
|
+
start = int(self._length + start)
|
|
220
|
+
if stop is None:
|
|
221
|
+
stop = self._length
|
|
222
|
+
elif stop < 0:
|
|
223
|
+
stop = int(self._length + stop)
|
|
224
|
+
conditions = []
|
|
225
|
+
base_query = 'select id from %s ' % self._table
|
|
226
|
+
if self._filter:
|
|
227
|
+
base_query += 'where %s ' % self._filter
|
|
228
|
+
query = base_query + 'order by id limit 1 offset %d' % start
|
|
229
|
+
start_id = self._cursor.execute(query).fetchone()
|
|
230
|
+
if start_id is not None:
|
|
231
|
+
conditions.append('id >= %d' % start_id[0])
|
|
232
|
+
query = base_query + 'order by id limit 1 offset %d' % stop
|
|
233
|
+
stop_id = self._cursor.execute(query).fetchone()
|
|
234
|
+
if stop_id is not None:
|
|
235
|
+
conditions.append('id < %d' % stop_id[0])
|
|
236
|
+
if self._filter:
|
|
237
|
+
conditions.append(self._filter)
|
|
238
|
+
return self.__class__(filter=' and '.join(conditions))
|
|
239
|
+
else:
|
|
240
|
+
raise IndexError(
|
|
241
|
+
'Use two ints or two floats for start and stop.')
|
|
242
|
+
elif is_int(index):
|
|
243
|
+
if index < 0:
|
|
244
|
+
index = self._length + index
|
|
245
|
+
matches = self.find(limit=1, offset=index)
|
|
246
|
+
if len(matches) != 1:
|
|
247
|
+
raise IndexError('Manifold index is out of bounds')
|
|
248
|
+
elif isinstance(index, str):
|
|
249
|
+
matches = self.find("name='%s'" % index)
|
|
250
|
+
if len(matches) != 1:
|
|
251
|
+
raise KeyError('The manifold %s was not found.' % index)
|
|
252
|
+
else:
|
|
253
|
+
raise IndexError('%s is not a valid index type for manifolds.' %
|
|
254
|
+
type(index))
|
|
255
|
+
return matches[0]
|
|
256
|
+
|
|
257
|
+
def _manifold_factory(self, row, M=None):
|
|
258
|
+
"""
|
|
259
|
+
Factory for "select name, triangulation" queries.
|
|
260
|
+
Returns a Manifold.
|
|
261
|
+
"""
|
|
262
|
+
|
|
263
|
+
if M is None:
|
|
264
|
+
M = Manifold('empty')
|
|
265
|
+
|
|
266
|
+
# Get fillings, if any
|
|
267
|
+
m = split_filling_info.match(row[1])
|
|
268
|
+
isosig = m.group(1)
|
|
269
|
+
M._from_isosig(isosig)
|
|
270
|
+
|
|
271
|
+
fillings = eval( '[' + m.group(2).replace(')(', '),(') + ']', {})
|
|
272
|
+
|
|
273
|
+
if fillings:
|
|
274
|
+
M.dehn_fill(fillings)
|
|
275
|
+
|
|
276
|
+
self._finalize(M, row)
|
|
277
|
+
return M
|
|
278
|
+
|
|
279
|
+
def _finalize(self, M, row):
|
|
280
|
+
"""
|
|
281
|
+
Give the manifold a name. Override this method for custom
|
|
282
|
+
manifold production.
|
|
283
|
+
"""
|
|
284
|
+
M.set_name(row[0])
|
|
285
|
+
|
|
286
|
+
def _one_manifold(self, name, M):
|
|
287
|
+
"""
|
|
288
|
+
Inflates the given empty Manifold with the table manifold
|
|
289
|
+
with the specified name.
|
|
290
|
+
"""
|
|
291
|
+
if hasattr(self, '_regex'):
|
|
292
|
+
if self._regex.match(name) is None:
|
|
293
|
+
raise KeyError('The manifold %s was not found.' % name)
|
|
294
|
+
cursor = self._cursor.execute(self._select + "where name='" + name + "'")
|
|
295
|
+
rows = cursor.fetchall()
|
|
296
|
+
if len(rows) != 1:
|
|
297
|
+
raise KeyError('The manifold %s was not found.' % name)
|
|
298
|
+
return self._manifold_factory(rows[0], M)
|
|
299
|
+
|
|
300
|
+
def keys(self):
|
|
301
|
+
"""
|
|
302
|
+
Return the list of column names for this manifold table.
|
|
303
|
+
"""
|
|
304
|
+
return self.schema.keys()
|
|
305
|
+
|
|
306
|
+
def find(self, where=None, order_by='id', limit=None, offset=None):
|
|
307
|
+
"""
|
|
308
|
+
Return a list of up to limit manifolds stored in this table,
|
|
309
|
+
satisfying the where clause, and ordered by the order_by
|
|
310
|
+
clause. If limit is None, all matching manifolds are
|
|
311
|
+
returned. If the offset parameter is set, the first offset
|
|
312
|
+
matches are skipped.
|
|
313
|
+
"""
|
|
314
|
+
conditions = [cond for cond in [self._filter, where] if cond]
|
|
315
|
+
suffix = ' where ' if conditions else ' '
|
|
316
|
+
suffix += ' and '.join(conditions)
|
|
317
|
+
suffix += ' order by %s' % order_by
|
|
318
|
+
if limit is not None:
|
|
319
|
+
suffix += ' limit %d' % limit
|
|
320
|
+
if offset is not None:
|
|
321
|
+
suffix += ' offset %d' % offset
|
|
322
|
+
cursor = self._cursor.execute(self._select + suffix)
|
|
323
|
+
return [self._manifold_factory(row) for row in cursor.fetchall()]
|
|
324
|
+
|
|
325
|
+
def siblings(self, mfld):
|
|
326
|
+
"""
|
|
327
|
+
Return all manifolds in the census which have the same hash value.
|
|
328
|
+
"""
|
|
329
|
+
vol = mfld.volume()
|
|
330
|
+
epsilon = vol / 1e5
|
|
331
|
+
v_lower, v_upper = vol - epsilon, vol + epsilon
|
|
332
|
+
cusps = mfld.cusp_info('is_complete').count(True)
|
|
333
|
+
H = mfld.homology()
|
|
334
|
+
betti = H.betti_number()
|
|
335
|
+
torsion = [c for c in H.elementary_divisors() if c != 0]
|
|
336
|
+
txt = "volume between %f and %f and cusps=%d and betti=%d and torsion='%s'"
|
|
337
|
+
initial_candidates = self.find(txt % (v_lower, v_upper, cusps,
|
|
338
|
+
betti, torsion))
|
|
339
|
+
if not initial_candidates:
|
|
340
|
+
return []
|
|
341
|
+
return self.find("hash = '%s'" % self.mfld_hash(mfld))
|
|
342
|
+
|
|
343
|
+
def identify(self, mfld, extends_to_link=False):
|
|
344
|
+
"""
|
|
345
|
+
Look for a manifold in this table which is isometric to the
|
|
346
|
+
argument.
|
|
347
|
+
|
|
348
|
+
Return the matching manifold, if there is one which SnapPea
|
|
349
|
+
declares to be isometric.
|
|
350
|
+
|
|
351
|
+
Return False if no manifold in the table has the same hash.
|
|
352
|
+
|
|
353
|
+
Return None in all other cases (for now).
|
|
354
|
+
|
|
355
|
+
If the flag "extends_to_link" is True, requires that the isometry
|
|
356
|
+
sends meridians to meridians. If the input manifold is closed
|
|
357
|
+
this will result in no matches being returned.
|
|
358
|
+
"""
|
|
359
|
+
if hasattr(mfld, 'volume'):
|
|
360
|
+
bad_types = ['no solution found', 'not attempted']
|
|
361
|
+
if mfld.solution_type() in bad_types:
|
|
362
|
+
return False
|
|
363
|
+
if mfld.volume() > self._max_volume + 0.1:
|
|
364
|
+
return False
|
|
365
|
+
|
|
366
|
+
if extends_to_link and not (True in mfld.cusp_info('complete?')):
|
|
367
|
+
return False
|
|
368
|
+
|
|
369
|
+
sibs = self.siblings(mfld)
|
|
370
|
+
if len(sibs) == 0:
|
|
371
|
+
return False # No hash values match
|
|
372
|
+
|
|
373
|
+
mfld = mfld.copy()
|
|
374
|
+
mflds = [mfld]
|
|
375
|
+
for i in range(4):
|
|
376
|
+
mfld = mfld.copy()
|
|
377
|
+
mfld.randomize()
|
|
378
|
+
mflds.append(mfld)
|
|
379
|
+
|
|
380
|
+
# Check for isometry
|
|
381
|
+
for mfld in mflds:
|
|
382
|
+
for N in sibs:
|
|
383
|
+
try:
|
|
384
|
+
if not extends_to_link:
|
|
385
|
+
if mfld.is_isometric_to(N):
|
|
386
|
+
return N
|
|
387
|
+
else:
|
|
388
|
+
isoms = mfld.is_isometric_to(N, True)
|
|
389
|
+
if True in [i.extends_to_link() for i in isoms]:
|
|
390
|
+
return N
|
|
391
|
+
except RuntimeError:
|
|
392
|
+
pass
|
|
393
|
+
|
|
394
|
+
mfld = Triangulation(mflds[0]) # Drop the hyperbolic structure
|
|
395
|
+
# Check for identical triangulations.
|
|
396
|
+
if (False not in mfld.cusp_info('is_complete')) and not extends_to_link:
|
|
397
|
+
for n in range(100):
|
|
398
|
+
for N in sibs:
|
|
399
|
+
if mfld == N:
|
|
400
|
+
return N
|
|
401
|
+
mfld.randomize()
|
|
402
|
+
|
|
403
|
+
return None
|
|
404
|
+
|
|
405
|
+
def random(self):
|
|
406
|
+
if self._length == 0:
|
|
407
|
+
raise ValueError('ManifoldTable is empty')
|
|
408
|
+
if self._ids_contiguous:
|
|
409
|
+
rand_id = random.randrange(self._min_id, self._max_id + 1)
|
|
410
|
+
query = self._select + ' where id = %d limit 1' % rand_id
|
|
411
|
+
cursor = self._cursor.execute(query)
|
|
412
|
+
return self._manifold_factory(cursor.fetchone())
|
|
413
|
+
return self[random.randrange(len(self))]
|
|
414
|
+
|
|
415
|
+
# The below function is used to add ManifoldTables defined in external
|
|
416
|
+
# packages.
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
this_module = sys.modules[__name__]
|
|
420
|
+
__all_tables__ = collections.OrderedDict()
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
def add_tables_from_package(package_name, must_succeed=True):
|
|
424
|
+
"""
|
|
425
|
+
Given a string with the name of an importable Python package that
|
|
426
|
+
implements a "get_tables" function, load all the tables provided
|
|
427
|
+
and put the results where the rest of SnapPy can find them.
|
|
428
|
+
Returns an ordered dictionary of pairs (table_name, table).
|
|
429
|
+
"""
|
|
430
|
+
|
|
431
|
+
try:
|
|
432
|
+
package = importlib.import_module(package_name)
|
|
433
|
+
except ImportError:
|
|
434
|
+
if not must_succeed:
|
|
435
|
+
return {}
|
|
436
|
+
else:
|
|
437
|
+
raise ImportError('ManifoldTable package %s not found'
|
|
438
|
+
% package_name)
|
|
439
|
+
|
|
440
|
+
new_tables = collections.OrderedDict()
|
|
441
|
+
for table in package.get_tables(ManifoldTable):
|
|
442
|
+
name = table.__class__.__name__
|
|
443
|
+
new_tables[name] = table
|
|
444
|
+
__all_tables__[name] = table
|
|
445
|
+
setattr(this_module, name, table)
|
|
446
|
+
|
|
447
|
+
# We also store the tables here so that their doctests can be
|
|
448
|
+
# checked.
|
|
449
|
+
if not hasattr(this_module, '__test__'):
|
|
450
|
+
this_module.__test__ = {}
|
|
451
|
+
for name, table in new_tables.items():
|
|
452
|
+
this_module.__test__[name] = table.__class__
|
|
453
|
+
|
|
454
|
+
return new_tables
|
snappy/db_utilities.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from hashlib import md5
|
|
2
|
+
import array
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# Codecs we use.
|
|
7
|
+
def encode_torsion(divisors):
|
|
8
|
+
return ''.join(chr(x) for x in divisors).encode('utf8')
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def decode_torsion(utf8):
|
|
12
|
+
return [ord(x) for x in utf8.decode('utf8')]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def encode_matrices(matrices):
|
|
16
|
+
"""
|
|
17
|
+
Convert a list of 2x2 integer matrices into a sequence of bytes.
|
|
18
|
+
"""
|
|
19
|
+
# The tricky thing here is converting signed integers to bytes.
|
|
20
|
+
return bytes(array.array('b', sum(sum(matrices, []), [])).tostring())
|
|
21
|
+
# NOTE: tostring is deprecated in python3, but for now
|
|
22
|
+
# it does the same thing as tobytes.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def decode_matrices(byteseq):
|
|
26
|
+
"""
|
|
27
|
+
Convert a sequence of 4n bytes into a list of n 2x2 integer matrices.
|
|
28
|
+
"""
|
|
29
|
+
m = array.array('b')
|
|
30
|
+
m.fromstring(byteseq)
|
|
31
|
+
return [ [ list(m[n:n+2]), list(m[n+2:n+4]) ]
|
|
32
|
+
for n in range(0, len(m), 4) ]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# Some hash functions for manifolds:
|
|
36
|
+
|
|
37
|
+
def old_basic_hash(mfld, digits=6):
|
|
38
|
+
return '%%%df' % digits % mfld.volume() + " " + repr(mfld.homology())
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def basic_hash(mfld, digits=6):
|
|
42
|
+
if mfld.solution_type() != 'contains degenerate tetrahedra':
|
|
43
|
+
volume = '%%%df' % digits % mfld.volume()
|
|
44
|
+
else:
|
|
45
|
+
volume = 'degenerate'
|
|
46
|
+
return volume + " " + repr(mfld.homology())
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def cover_type(mfld):
|
|
50
|
+
return re.findall("~reg~|~irr~|~cyc~", mfld.name())[-1][1:-1]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def cover_hash(mfld, degrees):
|
|
54
|
+
return [ repr(sorted(
|
|
55
|
+
[(cover_type(C), C.homology())
|
|
56
|
+
for C in mfld.covers(degree, method='snappea')]
|
|
57
|
+
)) for degree in degrees ]
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def old_combined_hash(mfld):
|
|
61
|
+
hash = str(" &and& ".join([old_basic_hash(mfld)] +
|
|
62
|
+
cover_hash(mfld, (2, 3))))
|
|
63
|
+
return hash.encode('utf8')
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def combined_hash(mfld):
|
|
67
|
+
hash = str(" &and& ".join([basic_hash(mfld)] +
|
|
68
|
+
cover_hash(mfld, (2, 3))))
|
|
69
|
+
return hash.encode('utf8')
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# This one is the hash used in the first version of the database.
|
|
73
|
+
def old_db_hash(mfld):
|
|
74
|
+
return md5(old_combined_hash(mfld)).hexdigest()
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# This one is used now.
|
|
78
|
+
def db_hash(mfld):
|
|
79
|
+
return md5(combined_hash(mfld)).hexdigest()
|