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/number.py
ADDED
|
@@ -0,0 +1,657 @@
|
|
|
1
|
+
# SnapPy Numbers are designed to interoperate with elements of a Sage
|
|
2
|
+
# RealField or ComplexField, with Sage Integers or Rationals, and with
|
|
3
|
+
# other SnapPyNumbers.
|
|
4
|
+
|
|
5
|
+
from .sage_helper import _within_sage
|
|
6
|
+
from .pari import *
|
|
7
|
+
import re
|
|
8
|
+
|
|
9
|
+
strip_zeros = re.compile(r'(-?\d+\.\d*?\d)0*((\s?[eE]-?\d+)?)$')
|
|
10
|
+
left_zeros = re.compile(r'0\.0*')
|
|
11
|
+
precision_of_exact_GEN = pari(0).precision()
|
|
12
|
+
|
|
13
|
+
if _within_sage:
|
|
14
|
+
from .sage_helper import RealField, Integer, Rational, ZZ, QQ, RR, CC
|
|
15
|
+
from sage.structure.parent import Parent
|
|
16
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
17
|
+
from sage.categories.homset import Hom
|
|
18
|
+
from sage.categories.sets_cat import Sets
|
|
19
|
+
from sage.categories.morphism import Morphism
|
|
20
|
+
from sage.categories.rings import Rings
|
|
21
|
+
from sage.categories.fields import Fields
|
|
22
|
+
from sage.structure.element import FieldElement
|
|
23
|
+
from sage.rings.real_mpfr import RealField_class
|
|
24
|
+
from sage.misc.classcall_metaclass import ClasscallMetaclass
|
|
25
|
+
from .sage_helper import ComplexField, ComplexField_class
|
|
26
|
+
|
|
27
|
+
class SnappyNumbersMetaclass(ClasscallMetaclass):
|
|
28
|
+
"""
|
|
29
|
+
Metaclass for Sage parents of SnapPy Number objects.
|
|
30
|
+
"""
|
|
31
|
+
def __new__(mcs, name, bases, dict):
|
|
32
|
+
dict['category'] = lambda self: Fields()
|
|
33
|
+
return ClasscallMetaclass.__new__(
|
|
34
|
+
mcs, name, bases, dict)
|
|
35
|
+
|
|
36
|
+
class MorphismToSPN(Morphism):
|
|
37
|
+
def __init__(self, source, target, precision):
|
|
38
|
+
Morphism.__init__(self, Hom(source, target, Rings()))
|
|
39
|
+
self.SPN = target
|
|
40
|
+
self.target_precision = precision
|
|
41
|
+
|
|
42
|
+
def _call_(self, x):
|
|
43
|
+
result = Number(x, precision=self.SPN.precision())
|
|
44
|
+
# The next line is a hack to trick sage into creating a
|
|
45
|
+
# number with the correct precision when performing binary
|
|
46
|
+
# operations involving SnapPy Numbers and Sage Numbers.
|
|
47
|
+
# The image of a number x under this morphism will have
|
|
48
|
+
# the same parent as x, but its actual precision may be
|
|
49
|
+
# different from the precision of x. These bastard
|
|
50
|
+
# numbers will only be created in the course of evaluating
|
|
51
|
+
# the binary operation, and the bastards will disappear as
|
|
52
|
+
# soon as the result of the operation is returned. The
|
|
53
|
+
# precision of the result will be the minimum of the two
|
|
54
|
+
# precisions.
|
|
55
|
+
result._precision = self.target_precision
|
|
56
|
+
return result
|
|
57
|
+
|
|
58
|
+
class SnapPyNumbers(UniqueRepresentation, Parent,
|
|
59
|
+
metaclass=SnappyNumbersMetaclass):
|
|
60
|
+
"""
|
|
61
|
+
Sage parents of SnapPy Number objects.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def __init__(self, precision):
|
|
65
|
+
Parent.__init__(self)
|
|
66
|
+
self._precision = precision
|
|
67
|
+
self.register_coercion(MorphismToSPN(ZZ, self, self._precision))
|
|
68
|
+
self.register_coercion(MorphismToSPN(QQ, self, self._precision))
|
|
69
|
+
try:
|
|
70
|
+
from sage.symbolic.ring import SR
|
|
71
|
+
except ImportError:
|
|
72
|
+
pass
|
|
73
|
+
else:
|
|
74
|
+
to_SR = Hom(self, SR, Sets())(lambda x: SR(x.sage()))
|
|
75
|
+
SR.register_coercion(to_SR)
|
|
76
|
+
|
|
77
|
+
def _repr_(self):
|
|
78
|
+
return "SnapPy Numbers with %s bits precision" % self._precision
|
|
79
|
+
|
|
80
|
+
def __call__(self, x):
|
|
81
|
+
try:
|
|
82
|
+
return Number(RealField(self._precision)(x))
|
|
83
|
+
except Exception:
|
|
84
|
+
return Number(ComplexField(self._precision)(x))
|
|
85
|
+
|
|
86
|
+
def _an_element_(self):
|
|
87
|
+
return Number(RealField(self._precision)(1.0))
|
|
88
|
+
|
|
89
|
+
def _element_constructor_(self, x):
|
|
90
|
+
return Number(RealField(self._precision)(x))
|
|
91
|
+
|
|
92
|
+
def _coerce_map_from_(self, S):
|
|
93
|
+
if (isinstance(S, RealField_class) or
|
|
94
|
+
isinstance(S, ComplexField_class)):
|
|
95
|
+
prec = min(S.prec(), self._precision)
|
|
96
|
+
return MorphismToSPN(S, self, prec)
|
|
97
|
+
|
|
98
|
+
def precision(self):
|
|
99
|
+
return self._precision
|
|
100
|
+
|
|
101
|
+
prec = precision
|
|
102
|
+
|
|
103
|
+
def is_field(self, *args, **kwargs):
|
|
104
|
+
return True
|
|
105
|
+
|
|
106
|
+
def is_commutative(self):
|
|
107
|
+
return True
|
|
108
|
+
|
|
109
|
+
def pi(self):
|
|
110
|
+
return Number(RealField(self._precision).pi())
|
|
111
|
+
|
|
112
|
+
def I(self):
|
|
113
|
+
return Number(ComplexField(self._precision).gen())
|
|
114
|
+
|
|
115
|
+
def random_element(self, min=-1, max=1):
|
|
116
|
+
return Number(RealField(self._precision).random_element(min, max))
|
|
117
|
+
|
|
118
|
+
def zero(self):
|
|
119
|
+
return Number(RealField(self._precision).zero())
|
|
120
|
+
|
|
121
|
+
Number_baseclass = FieldElement
|
|
122
|
+
|
|
123
|
+
def is_exact(x):
|
|
124
|
+
if isinstance(x, int) or isinstance(x, Integer) or isinstance(x, Rational):
|
|
125
|
+
return True
|
|
126
|
+
if isinstance(x, Gen):
|
|
127
|
+
return x.precision() == precision_of_exact_GEN
|
|
128
|
+
if isinstance(x, Number):
|
|
129
|
+
return x.gen.precision() == precision_of_exact_GEN
|
|
130
|
+
return False
|
|
131
|
+
|
|
132
|
+
def float_to_gen(x, precision):
|
|
133
|
+
return pari(x)
|
|
134
|
+
|
|
135
|
+
def complex_to_gen(x, precision):
|
|
136
|
+
return pari(x)
|
|
137
|
+
|
|
138
|
+
else: # We are not in Sage
|
|
139
|
+
Number_baseclass = object
|
|
140
|
+
|
|
141
|
+
def is_exact(x):
|
|
142
|
+
if isinstance(x, int):
|
|
143
|
+
return True
|
|
144
|
+
if isinstance(x, Gen):
|
|
145
|
+
return x.precision() == precision_of_exact_GEN
|
|
146
|
+
if isinstance(x, Number):
|
|
147
|
+
return x.gen.precision() == precision_of_exact_GEN
|
|
148
|
+
return False
|
|
149
|
+
|
|
150
|
+
def float_to_gen(x, precision):
|
|
151
|
+
return pari._real_coerced_to_bits_prec(x, precision)
|
|
152
|
+
|
|
153
|
+
def complex_to_gen(x, precision):
|
|
154
|
+
return pari.complex(
|
|
155
|
+
pari._real_coerced_to_bits_prec(x.real, precision),
|
|
156
|
+
pari._real_coerced_to_bits_prec(x.imag, precision))
|
|
157
|
+
|
|
158
|
+
class SnapPyNumbers():
|
|
159
|
+
"""
|
|
160
|
+
Surrogate parent for a SnapPy Number, to make calls to Number.parent() work
|
|
161
|
+
in or out of Sage. This allows the following paradigm to work:
|
|
162
|
+
|
|
163
|
+
>>> from snappy.number import Number
|
|
164
|
+
>>> x = Number(1.5, precision=200)
|
|
165
|
+
>>> x
|
|
166
|
+
1.500000000000000000000000000000000000000000000000000000000000
|
|
167
|
+
>>> y = x.parent()(2.5)
|
|
168
|
+
>>> y
|
|
169
|
+
2.500000000000000000000000000000000000000000000000000000000000
|
|
170
|
+
|
|
171
|
+
>>> Number("1.0e20", precision = 53)
|
|
172
|
+
1.000000000000000 E20
|
|
173
|
+
>>> Number("1.0e20", precision = 53, accuracy = 0)
|
|
174
|
+
1.0 E20
|
|
175
|
+
>>> Number("1.0e20", precision = 53, accuracy = 3)
|
|
176
|
+
1.000 E20
|
|
177
|
+
>>> Number("1.23456", precision = 53)
|
|
178
|
+
1.234560000000000
|
|
179
|
+
>>> Number("1.23456", precision = 53, accuracy = 0)
|
|
180
|
+
1.23456
|
|
181
|
+
>>> Number("1.23456", precision = 53, accuracy = 4)
|
|
182
|
+
1.2346
|
|
183
|
+
>>> Number("0.01", precision = 53)
|
|
184
|
+
0.010000000000000
|
|
185
|
+
>>> Number("0.01", precision = 53, accuracy = 0)
|
|
186
|
+
0.01
|
|
187
|
+
>>> Number("0.01", precision = 53, accuracy = 3)
|
|
188
|
+
0.010
|
|
189
|
+
>>> Number("3.0123e-20", precision = 53)
|
|
190
|
+
3.01230000000000 E-20
|
|
191
|
+
>>> Number("3.0123e-20", precision = 53, accuracy = 0)
|
|
192
|
+
3.0123 E-20
|
|
193
|
+
>>> Number("3.0123e-20", precision = 53, accuracy = 3)
|
|
194
|
+
3.01 E-20
|
|
195
|
+
|
|
196
|
+
"""
|
|
197
|
+
_cache = {}
|
|
198
|
+
|
|
199
|
+
def __new__(cls, precision=53):
|
|
200
|
+
if precision not in SnapPyNumbers._cache:
|
|
201
|
+
obj = super().__new__(cls)
|
|
202
|
+
obj._precision = precision
|
|
203
|
+
SnapPyNumbers._cache[precision] = obj
|
|
204
|
+
return obj
|
|
205
|
+
else:
|
|
206
|
+
return SnapPyNumbers._cache[precision]
|
|
207
|
+
|
|
208
|
+
def __repr__(self):
|
|
209
|
+
return "SnapPy Numbers with %s bits precision" % self._precision
|
|
210
|
+
|
|
211
|
+
def __call__(self, x):
|
|
212
|
+
return Number(x, precision=self._precision)
|
|
213
|
+
|
|
214
|
+
def precision(self):
|
|
215
|
+
return self._precision
|
|
216
|
+
|
|
217
|
+
prec = precision
|
|
218
|
+
|
|
219
|
+
def pi(self):
|
|
220
|
+
return self(pari.pi(precision=self._precision))
|
|
221
|
+
|
|
222
|
+
def I(self):
|
|
223
|
+
return self(pari('I'))
|
|
224
|
+
|
|
225
|
+
def random_element(self, min=-1, max=1):
|
|
226
|
+
min = self(min)
|
|
227
|
+
max = self(max)
|
|
228
|
+
limit = (max - min) * (self(2)**self._precision)
|
|
229
|
+
normalizer = self(2.0)**-self._precision
|
|
230
|
+
return min + normalizer * gen.random(limit.gen)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
class SupportsMultiplicationByNumber():
|
|
234
|
+
pass
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
class Number(Number_baseclass):
|
|
238
|
+
"""
|
|
239
|
+
Python class which wraps PARI GENs of type t_INT, t_FRAC, t_REAL
|
|
240
|
+
or t_COMPLEX.
|
|
241
|
+
|
|
242
|
+
A Number has both a precision and an optional attribute accuracy.
|
|
243
|
+
The precision represents the number of bits in the mantissa of the
|
|
244
|
+
floating point representation of the number. It determines the
|
|
245
|
+
number of words in the pari gen.
|
|
246
|
+
|
|
247
|
+
THE ACCURACY DOES NOT ACCOUNT FOR ROUNDOFF ERROR. By default, the
|
|
248
|
+
accuracy of a Number is None. The accuracy attribute is set only
|
|
249
|
+
for Numbers that are computed from tetrahedron shapes. It
|
|
250
|
+
represents the number of digits to the right of the decimal point
|
|
251
|
+
that can be expected to be correct. The accuracy of a shape is
|
|
252
|
+
computed by the SnapPea kernel while performing Newton iterations
|
|
253
|
+
to compute the shape. The value is the number of digits to the
|
|
254
|
+
right of the decimal point for which the last two values computed
|
|
255
|
+
by Newton's method agree.
|
|
256
|
+
|
|
257
|
+
When doing arithmetic with SnapPy Numbers, the accuracy of a
|
|
258
|
+
result is set to the smaller of the accuracies of the operands,
|
|
259
|
+
or None. The precision of the result is the minimum of the
|
|
260
|
+
precisions.
|
|
261
|
+
|
|
262
|
+
When a number with accuracy is converted to a string, the value is
|
|
263
|
+
rounded to a decimal number for which all digits to the right of
|
|
264
|
+
the decimal point (including trailing zeros) have place value
|
|
265
|
+
that exceeds the accuracy. If the accuracy is None, all digits are
|
|
266
|
+
included, except that trailing zeros are removed.
|
|
267
|
+
"""
|
|
268
|
+
|
|
269
|
+
# When doctesting, we want our numerical results to print
|
|
270
|
+
# with fixed (somewhat low) accuracy. In all normal
|
|
271
|
+
# circumstances this flag is set to None and then ignored
|
|
272
|
+
_accuracy_for_testing = None
|
|
273
|
+
|
|
274
|
+
_default_precision = 53
|
|
275
|
+
|
|
276
|
+
def __init__(self, data, accuracy=None, precision=None):
|
|
277
|
+
if precision is None:
|
|
278
|
+
if hasattr(data, 'prec'):
|
|
279
|
+
self._precision = data.prec()
|
|
280
|
+
else:
|
|
281
|
+
self._precision = self._default_precision
|
|
282
|
+
else:
|
|
283
|
+
self._precision = precision
|
|
284
|
+
self.decimal_precision = prec_bits_to_dec(self._precision)
|
|
285
|
+
if isinstance(data, Gen):
|
|
286
|
+
self.gen = data
|
|
287
|
+
elif isinstance(data, float):
|
|
288
|
+
self.gen = float_to_gen(data, self._precision)
|
|
289
|
+
elif isinstance(data, complex):
|
|
290
|
+
self.gen = complex_to_gen(data, self._precision)
|
|
291
|
+
else:
|
|
292
|
+
self.gen = pari(data)
|
|
293
|
+
type = self.gen.type()
|
|
294
|
+
if type not in ('t_INT', 't_FRAC', 't_REAL', 't_COMPLEX'):
|
|
295
|
+
raise ValueError(
|
|
296
|
+
'Invalid initialization for a Number: %s has type %s!' % (self.gen, type))
|
|
297
|
+
if type == 't_REAL' or type == 't_COMPLEX':
|
|
298
|
+
self.gen = self.gen.bitprecision(self._precision)
|
|
299
|
+
if type == 't_INT' or type == 't_FRAC' or self.gen.precision() == 0:
|
|
300
|
+
self.accuracy = self.decimal_precision
|
|
301
|
+
else:
|
|
302
|
+
if accuracy is None:
|
|
303
|
+
accuracy = prec_bits_to_dec(64 * (self.gen.sizeword() - 2))
|
|
304
|
+
|
|
305
|
+
self.accuracy = min(accuracy, self.decimal_precision)
|
|
306
|
+
self._parent = SnapPyNumbers(self._precision)
|
|
307
|
+
if _within_sage:
|
|
308
|
+
Number_baseclass.__init__(self, self._parent)
|
|
309
|
+
|
|
310
|
+
def __hash__(self):
|
|
311
|
+
return hash(self.gen)
|
|
312
|
+
|
|
313
|
+
# How to convert a Number to a Pari gen.
|
|
314
|
+
def _pari_(self):
|
|
315
|
+
return self.gen
|
|
316
|
+
|
|
317
|
+
# Variant for Sage 8.0 and on.
|
|
318
|
+
def __pari__(self):
|
|
319
|
+
return self.gen
|
|
320
|
+
|
|
321
|
+
def _get_acc_prec(self, other):
|
|
322
|
+
if is_exact(other):
|
|
323
|
+
return (self.accuracy, self._precision)
|
|
324
|
+
other_accuracy = getattr(other, 'accuracy', None)
|
|
325
|
+
try:
|
|
326
|
+
other_precision = other.prec()
|
|
327
|
+
except AttributeError:
|
|
328
|
+
if isinstance(other, Gen):
|
|
329
|
+
other_precision = prec_words_to_bits(other.sizeword())
|
|
330
|
+
else:
|
|
331
|
+
other_precision = self._default_precision
|
|
332
|
+
if is_exact(self):
|
|
333
|
+
return (other_accuracy, other_precision)
|
|
334
|
+
else:
|
|
335
|
+
if self.accuracy is None or other_accuracy is None:
|
|
336
|
+
accuracy = None
|
|
337
|
+
else:
|
|
338
|
+
accuracy = min(self.accuracy, other_accuracy)
|
|
339
|
+
return accuracy, min(self._precision, other_precision)
|
|
340
|
+
|
|
341
|
+
# This makes Number-valued properties, e.g real and imag, also work as methods
|
|
342
|
+
def __call__(self):
|
|
343
|
+
return self
|
|
344
|
+
|
|
345
|
+
def _real_string(self, gen, accuracy, full_precision=False):
|
|
346
|
+
if gen == 0:
|
|
347
|
+
return '0'
|
|
348
|
+
if full_precision:
|
|
349
|
+
accuracy = self._precision
|
|
350
|
+
elif self._accuracy_for_testing:
|
|
351
|
+
accuracy = self._accuracy_for_testing
|
|
352
|
+
if accuracy:
|
|
353
|
+
# Trick PARI into rounding to the correct number of digits.
|
|
354
|
+
# Simulates the printf %.Nf format, where N is the accuracy.
|
|
355
|
+
try:
|
|
356
|
+
int_part = gen.truncate().abs()
|
|
357
|
+
except PariError:
|
|
358
|
+
# Happens if gen holds large number.
|
|
359
|
+
# Setting to 1 so that we display something.
|
|
360
|
+
int_part = 1
|
|
361
|
+
if int_part == 0:
|
|
362
|
+
# Deal with zeros to the right of the decimal point.
|
|
363
|
+
try:
|
|
364
|
+
left_side = 2 - len(left_zeros.findall(str(gen))[0])
|
|
365
|
+
except IndexError: # no zeros
|
|
366
|
+
left_side = 0
|
|
367
|
+
else:
|
|
368
|
+
left_side = len(str(int_part))
|
|
369
|
+
if left_side + accuracy > 0:
|
|
370
|
+
old_precision = pari.set_real_precision(left_side + accuracy)
|
|
371
|
+
result = str(gen)
|
|
372
|
+
pari.set_real_precision(old_precision)
|
|
373
|
+
else:
|
|
374
|
+
# The number of zeros to the right of the decimal point
|
|
375
|
+
# exceeds the accuracy.
|
|
376
|
+
result = '0.0'
|
|
377
|
+
else:
|
|
378
|
+
old_precision = pari.set_real_precision(self.decimal_precision)
|
|
379
|
+
result = str(gen)
|
|
380
|
+
m = strip_zeros.match(result)
|
|
381
|
+
if m:
|
|
382
|
+
result = m.group(1) + m.group(2)
|
|
383
|
+
pari.set_real_precision(old_precision)
|
|
384
|
+
return result
|
|
385
|
+
|
|
386
|
+
def as_string(self, full_precision=True):
|
|
387
|
+
"""
|
|
388
|
+
Return a string representation of this number. If full_precision
|
|
389
|
+
is True, use the full precision of the gen. Otherwise use the
|
|
390
|
+
accuracy attribute.
|
|
391
|
+
"""
|
|
392
|
+
gen = self.gen
|
|
393
|
+
if gen.imag() == 0:
|
|
394
|
+
return self._real_string(
|
|
395
|
+
gen.real(), self.accuracy, full_precision)
|
|
396
|
+
else:
|
|
397
|
+
real_part = self._real_string(
|
|
398
|
+
gen.real(), self.accuracy, full_precision)
|
|
399
|
+
imag_part = self._real_string(
|
|
400
|
+
gen.imag(), self.accuracy, full_precision)
|
|
401
|
+
return ('%s + %s*I' % (real_part, imag_part)).replace('+ -', '- ')
|
|
402
|
+
|
|
403
|
+
def _binop(self, operator, other):
|
|
404
|
+
try:
|
|
405
|
+
shut_up()
|
|
406
|
+
operand = pari(other)
|
|
407
|
+
except PariError:
|
|
408
|
+
speak_up()
|
|
409
|
+
return NotImplemented
|
|
410
|
+
speak_up()
|
|
411
|
+
return Number(operator(operand), *self._get_acc_prec(other))
|
|
412
|
+
|
|
413
|
+
def __repr__(self):
|
|
414
|
+
return self.as_string(full_precision=False)
|
|
415
|
+
|
|
416
|
+
def __reduce__(self):
|
|
417
|
+
return Number, (self.as_string(), self.accuracy, self._precision)
|
|
418
|
+
|
|
419
|
+
def __float__(self):
|
|
420
|
+
return float(self.gen)
|
|
421
|
+
|
|
422
|
+
def __complex__(self):
|
|
423
|
+
return complex(self.gen)
|
|
424
|
+
|
|
425
|
+
def __int__(self):
|
|
426
|
+
return int(float(self.gen))
|
|
427
|
+
|
|
428
|
+
def __add__(self, other):
|
|
429
|
+
return self._binop(self.gen.__add__, other)
|
|
430
|
+
__iadd__ = __add__
|
|
431
|
+
|
|
432
|
+
def __sub__(self, other):
|
|
433
|
+
return self._binop(self.gen.__sub__, other)
|
|
434
|
+
__isub__ = __sub__
|
|
435
|
+
|
|
436
|
+
def __mul__(self, other):
|
|
437
|
+
if isinstance(other, SupportsMultiplicationByNumber):
|
|
438
|
+
return other._multiply_by_scalar(self)
|
|
439
|
+
return self._binop(self.gen.__mul__, other)
|
|
440
|
+
__imul__ = __mul__
|
|
441
|
+
|
|
442
|
+
def __div__(self, other):
|
|
443
|
+
return self._binop(self.gen.__div__, other)
|
|
444
|
+
__idiv__ = __div__
|
|
445
|
+
|
|
446
|
+
def __truediv__(self, other):
|
|
447
|
+
return self._binop(self.gen.__truediv__, other)
|
|
448
|
+
|
|
449
|
+
def __floordiv__(self, other):
|
|
450
|
+
result = self._binop(self.gen.__truediv__, other)
|
|
451
|
+
if result != NotImplemented:
|
|
452
|
+
result = result.floor()
|
|
453
|
+
return result
|
|
454
|
+
|
|
455
|
+
def __radd__(self, other):
|
|
456
|
+
return self._binop(self.gen.__radd__, other)
|
|
457
|
+
|
|
458
|
+
def __rsub__(self, other):
|
|
459
|
+
return self._binop(self.gen.__rsub__, other)
|
|
460
|
+
|
|
461
|
+
def __rmul__(self, other):
|
|
462
|
+
return self._binop(self.gen.__rmul__, other)
|
|
463
|
+
|
|
464
|
+
def __rdiv__(self, other):
|
|
465
|
+
return self._binop(self.gen.__rdiv__, other)
|
|
466
|
+
|
|
467
|
+
def __rtruediv__(self, other):
|
|
468
|
+
return self._binop(self.gen.__rtruediv__, other)
|
|
469
|
+
|
|
470
|
+
def __rfloordiv__(self, other):
|
|
471
|
+
result = self._binop(self.gen.__rtruediv__, other)
|
|
472
|
+
if result != NotImplemented:
|
|
473
|
+
result = result.floor()
|
|
474
|
+
return result
|
|
475
|
+
|
|
476
|
+
def __mod__(self, other):
|
|
477
|
+
return self._binop(self.gen.__mod__, other)
|
|
478
|
+
|
|
479
|
+
def __eq__(self, other):
|
|
480
|
+
return self.gen.__eq__(pari(other))
|
|
481
|
+
|
|
482
|
+
def __ne__(self, other):
|
|
483
|
+
return self.gen.__ne__(pari(other))
|
|
484
|
+
|
|
485
|
+
def __lt__(self, other):
|
|
486
|
+
return self.gen.__lt__(pari(other))
|
|
487
|
+
|
|
488
|
+
def __gt__(self, other):
|
|
489
|
+
return self.gen.__gt__(pari(other))
|
|
490
|
+
|
|
491
|
+
def __le__(self, other):
|
|
492
|
+
return self.gen.__le__(pari(other))
|
|
493
|
+
|
|
494
|
+
def __ge__(self, other):
|
|
495
|
+
return self.gen.__ge__(pari(other))
|
|
496
|
+
|
|
497
|
+
def __neg__(self):
|
|
498
|
+
return Number(-self.gen, self.accuracy, self._precision)
|
|
499
|
+
|
|
500
|
+
def __abs__(self):
|
|
501
|
+
return Number(self.gen.abs(), self.accuracy, self._precision)
|
|
502
|
+
|
|
503
|
+
def __inv__(self):
|
|
504
|
+
return 1/self
|
|
505
|
+
|
|
506
|
+
def __pow__(self, *args):
|
|
507
|
+
return Number(self.gen.__pow__(*args), self.accuracy, self._precision)
|
|
508
|
+
|
|
509
|
+
def __round__(self, ndigits):
|
|
510
|
+
return round(float(self), ndigits)
|
|
511
|
+
|
|
512
|
+
def abs(self):
|
|
513
|
+
return abs(self)
|
|
514
|
+
|
|
515
|
+
def conjugate(self):
|
|
516
|
+
return Number(self.gen.conj(), self.accuracy, self._precision)
|
|
517
|
+
|
|
518
|
+
def precision(self):
|
|
519
|
+
"""Return the *binary* precision of the Number. Note that the value
|
|
520
|
+
of a Number may be exact, even though it has a specified
|
|
521
|
+
precision.
|
|
522
|
+
|
|
523
|
+
"""
|
|
524
|
+
return self._precision
|
|
525
|
+
|
|
526
|
+
# Emulate the behavior of Sage RealField or ComplexField elements.
|
|
527
|
+
# This is needed for some Sage interoperation to work.
|
|
528
|
+
prec = precision
|
|
529
|
+
|
|
530
|
+
@property
|
|
531
|
+
def real(self):
|
|
532
|
+
return Number(self.gen.real(), self.accuracy, self._precision)
|
|
533
|
+
|
|
534
|
+
@property
|
|
535
|
+
def imag(self):
|
|
536
|
+
return Number(self.gen.imag(), self.accuracy, self._precision)
|
|
537
|
+
|
|
538
|
+
def pari_type(self):
|
|
539
|
+
return self.gen.type()
|
|
540
|
+
|
|
541
|
+
def volume(self):
|
|
542
|
+
"""
|
|
543
|
+
Return the volume of a tetrahedron with this shape
|
|
544
|
+
"""
|
|
545
|
+
z = self.gen
|
|
546
|
+
if z == 0 or z == 1:
|
|
547
|
+
volume = 0
|
|
548
|
+
else:
|
|
549
|
+
zz = 1/(1-z)
|
|
550
|
+
zzz = 1 - 1/z
|
|
551
|
+
A = z/z.abs()
|
|
552
|
+
B = zz/zz.abs()
|
|
553
|
+
C = zzz/zzz.abs()
|
|
554
|
+
bits = self._precision
|
|
555
|
+
volume = ((A * A).dilog(precision=bits).imag()
|
|
556
|
+
+ (B * B).dilog(precision=bits).imag()
|
|
557
|
+
+ (C * C).dilog(precision=bits).imag()
|
|
558
|
+
) / 2
|
|
559
|
+
return Number(volume, self.accuracy, self._precision)
|
|
560
|
+
|
|
561
|
+
def sage(self):
|
|
562
|
+
"""
|
|
563
|
+
Return as an element of the appropriate RealField or
|
|
564
|
+
ComplexField
|
|
565
|
+
"""
|
|
566
|
+
if not _within_sage:
|
|
567
|
+
raise ImportError("Not within SAGE.")
|
|
568
|
+
if self.gen.type() == 't_REAL':
|
|
569
|
+
return RealField(self._precision)(self.gen)
|
|
570
|
+
elif self.gen.type() == 't_COMPLEX':
|
|
571
|
+
return ComplexField(self._precision)(self.gen)
|
|
572
|
+
else:
|
|
573
|
+
return self.gen.sage()
|
|
574
|
+
|
|
575
|
+
def parent(self):
|
|
576
|
+
return self._parent
|
|
577
|
+
|
|
578
|
+
def hex(self):
|
|
579
|
+
return float(self).hex()
|
|
580
|
+
|
|
581
|
+
def sqrtn(self, n):
|
|
582
|
+
"""
|
|
583
|
+
>>> r = Number(2.0, precision=100)
|
|
584
|
+
>>> r.sqrtn(10) # doctest: +NUMERIC27
|
|
585
|
+
(1.071773462536293164213006325023, 0.809016994374947424102293417183 + 0.587785252292473129168705954639*I)
|
|
586
|
+
"""
|
|
587
|
+
a, b = self.gen.sqrtn(n, precision=self._precision)
|
|
588
|
+
return self._parent(a), self._parent(b)
|
|
589
|
+
|
|
590
|
+
def _complex_mpfi_(self, CIF):
|
|
591
|
+
return CIF(self.sage())
|
|
592
|
+
|
|
593
|
+
# add a bunch of analytical methods to the Number class
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
def add_number_method(name, include_precision=True):
|
|
597
|
+
method = getattr(Gen, name)
|
|
598
|
+
if include_precision:
|
|
599
|
+
setattr(Number, name, lambda self: self.parent()(
|
|
600
|
+
method(self.gen, precision=self._precision)))
|
|
601
|
+
else:
|
|
602
|
+
setattr(Number, name, lambda self: self.parent()(method(self.gen)))
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
for method in ['acos', 'acosh', 'arg', 'asin', 'asinh', 'atan', 'atanh',
|
|
606
|
+
'cos', 'cosh', 'cotan', 'dilog', 'exp', 'log', 'sin',
|
|
607
|
+
'sinh', 'tan', 'tanh', 'sqrt']:
|
|
608
|
+
add_number_method(method)
|
|
609
|
+
|
|
610
|
+
for method in ['ceil', 'floor', 'round']:
|
|
611
|
+
add_number_method(method, include_precision=False)
|
|
612
|
+
|
|
613
|
+
for trig in ['cos', 'cosh', 'sin', 'sinh', 'tan', 'tanh']:
|
|
614
|
+
setattr(Number, 'arc' + trig, getattr(Number, 'a' + trig))
|
|
615
|
+
|
|
616
|
+
Number.argument = Number.arg
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
def use_field_conversion(func):
|
|
620
|
+
global number_to_native_number
|
|
621
|
+
|
|
622
|
+
if func == 'sage':
|
|
623
|
+
def number_to_native_number(n):
|
|
624
|
+
"""
|
|
625
|
+
Converts a SnapPy number to the corresponding SageMath type.
|
|
626
|
+
|
|
627
|
+
In general snappy.number.number_to_native_number converts a SnapPy number to
|
|
628
|
+
the corresponding SageMath type (when in SageMath) or just returns
|
|
629
|
+
the SnapPy number itself (when SageMath is not available).
|
|
630
|
+
|
|
631
|
+
However, this behavior can be overridden by
|
|
632
|
+
snappy.number.use_field_conversion which replaces
|
|
633
|
+
number_to_native_number.
|
|
634
|
+
"""
|
|
635
|
+
return n.sage()
|
|
636
|
+
elif func == 'snappy':
|
|
637
|
+
def number_to_native_number(n):
|
|
638
|
+
"""
|
|
639
|
+
Simply returns the given SnapPy number.
|
|
640
|
+
|
|
641
|
+
In general snappy.number.number_to_native_number converts a SnapPy number to
|
|
642
|
+
the corresponding SageMath type (when in SageMath) or just returns
|
|
643
|
+
the SnapPy number itself (when SageMath is not available).
|
|
644
|
+
|
|
645
|
+
However, this behavior can be overridden by
|
|
646
|
+
snappy.number.use_field_conversion which replaces
|
|
647
|
+
number_to_native_number.
|
|
648
|
+
"""
|
|
649
|
+
return n
|
|
650
|
+
else:
|
|
651
|
+
number_to_native_number = func
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
if _within_sage:
|
|
655
|
+
use_field_conversion('sage')
|
|
656
|
+
else:
|
|
657
|
+
use_field_conversion('snappy')
|