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/matrix.py
ADDED
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
from .sage_helper import _within_sage
|
|
2
|
+
|
|
3
|
+
from . import number
|
|
4
|
+
from .math_basics import is_Interval
|
|
5
|
+
|
|
6
|
+
def snappy_make_vector(entries, *, ring=None):
|
|
7
|
+
return SimpleVector(entries, ring)
|
|
8
|
+
|
|
9
|
+
def snappy_make_matrix(entries, *, ring=None):
|
|
10
|
+
return SimpleMatrix(entries, ring)
|
|
11
|
+
|
|
12
|
+
def snappy_make_identity_matrix(*, n, ring):
|
|
13
|
+
return SimpleMatrix.identity(ring, n)
|
|
14
|
+
|
|
15
|
+
if _within_sage:
|
|
16
|
+
from sage.modules.free_module_element import vector as _sage_vector
|
|
17
|
+
from sage.matrix.constructor import matrix as _sage_matrix
|
|
18
|
+
|
|
19
|
+
def sage_make_vector(entries, *, ring=None):
|
|
20
|
+
if ring is None:
|
|
21
|
+
return _sage_vector(entries)
|
|
22
|
+
else:
|
|
23
|
+
return _sage_vector(ring, entries)
|
|
24
|
+
|
|
25
|
+
def sage_make_matrix(entries, *, ring=None):
|
|
26
|
+
if ring is None:
|
|
27
|
+
return _sage_matrix(entries)
|
|
28
|
+
else:
|
|
29
|
+
return _sage_matrix(ring, entries)
|
|
30
|
+
|
|
31
|
+
def sage_make_identity_matrix(*, n, ring):
|
|
32
|
+
return _sage_matrix.identity(ring, n)
|
|
33
|
+
|
|
34
|
+
make_vector = sage_make_vector
|
|
35
|
+
make_matrix = sage_make_matrix
|
|
36
|
+
make_identity_matrix = sage_make_identity_matrix
|
|
37
|
+
else:
|
|
38
|
+
make_vector = snappy_make_vector
|
|
39
|
+
make_matrix = snappy_make_matrix
|
|
40
|
+
make_identity_matrix = snappy_make_identity_matrix
|
|
41
|
+
|
|
42
|
+
class SimpleVector(number.SupportsMultiplicationByNumber):
|
|
43
|
+
def __init__(self, entries, ring=None):
|
|
44
|
+
if ring is None:
|
|
45
|
+
self.data = entries
|
|
46
|
+
else:
|
|
47
|
+
self.data = [ ring(e) for e in entries ]
|
|
48
|
+
try:
|
|
49
|
+
self.type = type(self.data[0])
|
|
50
|
+
self.shape = (len(entries),)
|
|
51
|
+
except IndexError:
|
|
52
|
+
self.type = type(0)
|
|
53
|
+
self.shape = (0,)
|
|
54
|
+
|
|
55
|
+
def __len__(self):
|
|
56
|
+
return len(self.data)
|
|
57
|
+
|
|
58
|
+
def __iter__(self):
|
|
59
|
+
return self.data.__iter__()
|
|
60
|
+
|
|
61
|
+
def __repr__(self):
|
|
62
|
+
str_vector = [str(x) for x in self.data]
|
|
63
|
+
size = max(len(x) for x in str_vector)
|
|
64
|
+
return '(%s)' % ', '.join('% *s' % (size, x) for x in str_vector)
|
|
65
|
+
|
|
66
|
+
def __getitem__(self, key):
|
|
67
|
+
if key < 0:
|
|
68
|
+
raise TypeError("Simple vectors don't have negative indices.")
|
|
69
|
+
return self.data[key]
|
|
70
|
+
|
|
71
|
+
def __setitem__(self, key, value):
|
|
72
|
+
if key < 0:
|
|
73
|
+
raise TypeError("Simple vectors don't have negative indices.")
|
|
74
|
+
self.data[key] = value
|
|
75
|
+
|
|
76
|
+
def entries(self):
|
|
77
|
+
return list(self.data)
|
|
78
|
+
|
|
79
|
+
def list(self):
|
|
80
|
+
return self.entries()
|
|
81
|
+
|
|
82
|
+
def normalized(self):
|
|
83
|
+
l = sum([ abs(x) ** 2 for x in self.data]).sqrt()
|
|
84
|
+
return SimpleVector([x / l for x in self.data])
|
|
85
|
+
|
|
86
|
+
def __add__(self, other):
|
|
87
|
+
if isinstance(other, SimpleVector):
|
|
88
|
+
if self.shape[0] != other.shape[0]:
|
|
89
|
+
raise ValueError(
|
|
90
|
+
'Cannot add vector of length %d and vector of '
|
|
91
|
+
'length %d.' % (self.shape[0], other.shape[0]))
|
|
92
|
+
return SimpleVector(
|
|
93
|
+
[a + b for a, b in zip(self.data, other.data)])
|
|
94
|
+
|
|
95
|
+
return ValueError(
|
|
96
|
+
'SimpleVector only supports addition for another '
|
|
97
|
+
'SimpleVector. Given type was %r.' % type(other))
|
|
98
|
+
|
|
99
|
+
def __sub__(self, other):
|
|
100
|
+
if isinstance(other, SimpleVector):
|
|
101
|
+
if self.shape[0] != other.shape[0]:
|
|
102
|
+
raise ValueError(
|
|
103
|
+
'Cannot add vector of length %d and vector of '
|
|
104
|
+
'length %d.' % (self.shape[0], other.shape[0]))
|
|
105
|
+
return SimpleVector(
|
|
106
|
+
[a - b for a, b in zip(self.data, other.data)])
|
|
107
|
+
|
|
108
|
+
return ValueError(
|
|
109
|
+
'SimpleVector only supports addition for another '
|
|
110
|
+
'SimpleVector. Given type was %r.' % type(other))
|
|
111
|
+
|
|
112
|
+
# Implements SupportsMultiplicationByNumber
|
|
113
|
+
def _multiply_by_scalar(self, other):
|
|
114
|
+
return SimpleVector(
|
|
115
|
+
[ other * e for e in self.data])
|
|
116
|
+
|
|
117
|
+
def __truediv__(self, other):
|
|
118
|
+
return SimpleVector([ x / other for x in self.data])
|
|
119
|
+
|
|
120
|
+
def __neg__(self):
|
|
121
|
+
return SimpleVector([ -e for e in self.data ])
|
|
122
|
+
|
|
123
|
+
def base_ring(self):
|
|
124
|
+
try:
|
|
125
|
+
return self.data[0].parent()
|
|
126
|
+
except IndexError:
|
|
127
|
+
return self.type
|
|
128
|
+
|
|
129
|
+
# A very basic matrix class
|
|
130
|
+
class SimpleMatrix(number.SupportsMultiplicationByNumber):
|
|
131
|
+
"""
|
|
132
|
+
A simple matrix class that wraps a list of lists.
|
|
133
|
+
"""
|
|
134
|
+
def __init__(self, list_of_lists, base_ring=None, ring=None):
|
|
135
|
+
|
|
136
|
+
if isinstance(list_of_lists, SimpleMatrix):
|
|
137
|
+
list_of_lists = list_of_lists.data
|
|
138
|
+
if base_ring is None:
|
|
139
|
+
base_ring = ring # Sage has deprecated "ring"
|
|
140
|
+
if base_ring is not None:
|
|
141
|
+
self.data = [ [ base_ring(e) for e in row ]
|
|
142
|
+
for row in list_of_lists ]
|
|
143
|
+
else:
|
|
144
|
+
# XXX
|
|
145
|
+
# We should really copy the data here since otherwise we might
|
|
146
|
+
# get really weird aliasing effects, i.e.,
|
|
147
|
+
# >>> m = SimpleMatrix([[1]])
|
|
148
|
+
# >>> m2 = SimpleMatrix(m)
|
|
149
|
+
# >>> m[0,0] = 2
|
|
150
|
+
# >>> m2[0,0]
|
|
151
|
+
# 2
|
|
152
|
+
self.data = list_of_lists
|
|
153
|
+
try:
|
|
154
|
+
self.type = type(self.data[0][0])
|
|
155
|
+
self.shape = (len(list_of_lists), len(list_of_lists[0]))
|
|
156
|
+
except IndexError:
|
|
157
|
+
# Shouldn't we just plainly fail if we are given garbage?
|
|
158
|
+
self.type = type(0)
|
|
159
|
+
self.shape = (0,0)
|
|
160
|
+
|
|
161
|
+
def base_ring(self):
|
|
162
|
+
try:
|
|
163
|
+
return self.data[0][0].parent()
|
|
164
|
+
except IndexError:
|
|
165
|
+
return self.type
|
|
166
|
+
|
|
167
|
+
@staticmethod
|
|
168
|
+
def identity(ring, n=0):
|
|
169
|
+
return SimpleMatrix(
|
|
170
|
+
[[ 1 if i == j else 0
|
|
171
|
+
for i in range(n) ]
|
|
172
|
+
for j in range(n) ], ring)
|
|
173
|
+
|
|
174
|
+
def __iter__(self):
|
|
175
|
+
return self.data.__iter__()
|
|
176
|
+
|
|
177
|
+
def __repr__(self):
|
|
178
|
+
str_matrix = [[str(x) for x in row] for row in self.data]
|
|
179
|
+
size = max([max([len(x) for x in row]) for row in str_matrix])
|
|
180
|
+
str_rows = []
|
|
181
|
+
for row in str_matrix:
|
|
182
|
+
str_row = ['% *s' % (size, x) for x in row]
|
|
183
|
+
str_rows.append('[' + ' '.join(str_row) + ']')
|
|
184
|
+
result = '\n'.join(str_rows)
|
|
185
|
+
return result
|
|
186
|
+
|
|
187
|
+
def __str__(self):
|
|
188
|
+
str_matrix = [[str(x) for x in row] for row in self.data]
|
|
189
|
+
size = max([max([len(x) for x in row]) for row in str_matrix])
|
|
190
|
+
str_rows = []
|
|
191
|
+
for row in str_matrix:
|
|
192
|
+
str_row = ['% *s' % (size, x) for x in row]
|
|
193
|
+
str_rows.append(' [' + ' '.join(str_row) + ']')
|
|
194
|
+
result = '\n'.join(str_rows)
|
|
195
|
+
result = '[' + ('\n'.join(str_rows))[1:] + ']'
|
|
196
|
+
return result
|
|
197
|
+
|
|
198
|
+
def __getitem__(self, key):
|
|
199
|
+
if type(key) == tuple:
|
|
200
|
+
i, j = key
|
|
201
|
+
if type(i) == slice or type(j) == slice:
|
|
202
|
+
return SimpleMatrix(
|
|
203
|
+
[ (row[j] if type(j) == slice else [row[j]])
|
|
204
|
+
for row
|
|
205
|
+
in (self.data[i] if type(i) == slice else [ self.data[i] ]) ])
|
|
206
|
+
if i < 0 or j < 0:
|
|
207
|
+
raise TypeError("Simple matrices don't have negative indices.")
|
|
208
|
+
return self.data[i][j]
|
|
209
|
+
|
|
210
|
+
if type(key) == slice:
|
|
211
|
+
return SimpleMatrix(self.data[key])
|
|
212
|
+
|
|
213
|
+
if key < 0:
|
|
214
|
+
raise TypeError("Simple matrices don't have negative indices.")
|
|
215
|
+
|
|
216
|
+
return self.data[key]
|
|
217
|
+
|
|
218
|
+
def _check_indices(self, key):
|
|
219
|
+
if type(key) != tuple:
|
|
220
|
+
raise TypeError("Can only set an entry, not a row of a simple matrix.")
|
|
221
|
+
|
|
222
|
+
i, j = key
|
|
223
|
+
if i < 0 or j < 0:
|
|
224
|
+
raise TypeError("Simple matrices don't have negative indices.")
|
|
225
|
+
|
|
226
|
+
return key
|
|
227
|
+
|
|
228
|
+
def __setitem__(self, key, value):
|
|
229
|
+
i, j = self._check_indices(key)
|
|
230
|
+
self.data[i][j] = value
|
|
231
|
+
|
|
232
|
+
def _noalgebra(self, other):
|
|
233
|
+
raise TypeError('To do matrix algebra, please install numpy '
|
|
234
|
+
'or run SnapPy in Sage.')
|
|
235
|
+
|
|
236
|
+
def entries(self):
|
|
237
|
+
return [x for row in self.data for x in row]
|
|
238
|
+
|
|
239
|
+
def list(self):
|
|
240
|
+
return self.entries()
|
|
241
|
+
|
|
242
|
+
def dimensions(self):
|
|
243
|
+
return self.shape
|
|
244
|
+
|
|
245
|
+
def __neg__(self):
|
|
246
|
+
return SimpleMatrix(
|
|
247
|
+
[ [ -x for x in row ]
|
|
248
|
+
for row in self.data ])
|
|
249
|
+
|
|
250
|
+
# Implements SupportsMultiplicationByNumber
|
|
251
|
+
def _multiply_by_scalar(self, other):
|
|
252
|
+
return SimpleMatrix(
|
|
253
|
+
[[ other * e for e in row ]
|
|
254
|
+
for row in self.data ])
|
|
255
|
+
|
|
256
|
+
def __mul__(self, other):
|
|
257
|
+
if isinstance(other, SimpleMatrix):
|
|
258
|
+
if self.shape[1] != other.shape[0]:
|
|
259
|
+
raise ValueError(
|
|
260
|
+
'Cannot multiply matrices with %d columns by matrix '
|
|
261
|
+
'with %d rows.' % (self.shape[1], other.shape[0]))
|
|
262
|
+
return SimpleMatrix(
|
|
263
|
+
[[ sum(self.data[i][j] * other.data[j][k]
|
|
264
|
+
for j in range(self.shape[1]))
|
|
265
|
+
for k in range(other.shape[1]) ]
|
|
266
|
+
for i in range(self.shape[0])])
|
|
267
|
+
|
|
268
|
+
if isinstance(other, SimpleVector):
|
|
269
|
+
if self.shape[1] != other.shape[0]:
|
|
270
|
+
raise ValueError(
|
|
271
|
+
'Cannot multiply matrix with %d columns by vector of '
|
|
272
|
+
'length %d.' % (self.shape[1], other.shape[0]))
|
|
273
|
+
return SimpleVector(
|
|
274
|
+
[ sum(self.data[i][j] * other.data[j]
|
|
275
|
+
for j in range(self.shape[1]))
|
|
276
|
+
for i in range(self.shape[0])])
|
|
277
|
+
raise TypeError(
|
|
278
|
+
'SimpleMatrix only supports multiplication by another '
|
|
279
|
+
'SimpleMatrix or SimpleVector. Given type was %r.' % type(other))
|
|
280
|
+
|
|
281
|
+
def transpose(self):
|
|
282
|
+
return SimpleMatrix([[ self.data[i][j] for i in range(self.shape[0]) ]
|
|
283
|
+
for j in range(self.shape[1])])
|
|
284
|
+
|
|
285
|
+
def __truediv__(self, other):
|
|
286
|
+
if isinstance(other, number.Number):
|
|
287
|
+
return SimpleMatrix(
|
|
288
|
+
[[ d / other for d in row ]
|
|
289
|
+
for row in self.data])
|
|
290
|
+
raise TypeError("SimpleMatrix / SimpleMatrix not supported")
|
|
291
|
+
|
|
292
|
+
# For python 2.x backwards compatibility.
|
|
293
|
+
__div__ = __truediv__
|
|
294
|
+
|
|
295
|
+
def det(self):
|
|
296
|
+
if self.shape == (2, 2):
|
|
297
|
+
return (
|
|
298
|
+
self.data[0][0] * self.data[1][1]
|
|
299
|
+
- self.data[0][1] * self.data[1][0])
|
|
300
|
+
raise TypeError("SimpleMatrix determinant supported only for 2x2")
|
|
301
|
+
|
|
302
|
+
def trace(self):
|
|
303
|
+
num_rows, num_cols = self.shape
|
|
304
|
+
if num_rows != num_cols:
|
|
305
|
+
raise ValueError("Trace of non-square %dx%d matrix" % self.shape)
|
|
306
|
+
return sum(self.data[i][i]
|
|
307
|
+
for i in range(num_rows))
|
|
308
|
+
|
|
309
|
+
def __eq__(self, other):
|
|
310
|
+
return self.data == other.data
|
|
311
|
+
|
|
312
|
+
def __add__(self, other):
|
|
313
|
+
if not isinstance(other, SimpleMatrix):
|
|
314
|
+
raise TypeError("SimpleMatrix can only be added to SimpleMatrix.")
|
|
315
|
+
if not self.shape == other.shape:
|
|
316
|
+
raise ValueError(
|
|
317
|
+
"Trying to add a %dx%d matrix to a %dx%d matrix" % (
|
|
318
|
+
other.shape[0], other.shape[1],
|
|
319
|
+
self.shape[0], self.shape[1]))
|
|
320
|
+
return SimpleMatrix([[ e0 + e1
|
|
321
|
+
for e0, e1 in zip(row0, row1) ]
|
|
322
|
+
for row0, row1 in zip(self.data, other.data)])
|
|
323
|
+
|
|
324
|
+
def __sub__(self, other):
|
|
325
|
+
if not isinstance(other, SimpleMatrix):
|
|
326
|
+
raise TypeError(
|
|
327
|
+
"SimpleMatrix can only be subtracted from SimpleMatrix.")
|
|
328
|
+
if not self.shape == other.shape:
|
|
329
|
+
raise ValueError(
|
|
330
|
+
"Trying to subtract a %dx%d matrix from a %dx%d matrix" % (
|
|
331
|
+
other.shape[0], other.shape[1],
|
|
332
|
+
self.shape[0], self.shape[1]))
|
|
333
|
+
return SimpleMatrix([[ e0 - e1
|
|
334
|
+
for e0, e1 in zip(row0, row1) ]
|
|
335
|
+
for row0, row1 in zip(self.data, other.data)])
|
|
336
|
+
|
|
337
|
+
__inv__ = _noalgebra
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
if _within_sage:
|
|
341
|
+
from sage.matrix.constructor import matrix
|
|
342
|
+
from sage.modules.free_module_element import vector
|
|
343
|
+
else:
|
|
344
|
+
matrix = SimpleMatrix
|
|
345
|
+
vector = SimpleVector
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
def mat_solve(m, v, epsilon=0):
|
|
349
|
+
"""
|
|
350
|
+
Given a matrix m and a vector v, return the vector a such that
|
|
351
|
+
v = m * a - computed using Gaussian elimination.
|
|
352
|
+
|
|
353
|
+
Note that the matrix and vector can contain real or complex numbers
|
|
354
|
+
or intervals (SageMath's RealIntervalField, ComplexIntervalField).
|
|
355
|
+
|
|
356
|
+
When not given intervals, an epsilon can be specified. If a pivot
|
|
357
|
+
has absolute value less than the given epsilon, a ZeroDivisionError
|
|
358
|
+
will be raised indicating that the matrix is degenerate.
|
|
359
|
+
|
|
360
|
+
We provide mat_solve for two reasons:
|
|
361
|
+
1. To have this functionality outside of SageMath.
|
|
362
|
+
2. To avoid bad numerical results even though the matrix is far
|
|
363
|
+
from degenerate, it is necessary to swap rows during elimination
|
|
364
|
+
when the pivot is really small. However, SageMath instead checks
|
|
365
|
+
whether the pivot is exactly zero rather than close to zero for
|
|
366
|
+
some numerical types. In particular, this applies to interval
|
|
367
|
+
types and SageMath often returns matrices with entries (-inf, inf)
|
|
368
|
+
even though the matrix is far from degenerate.
|
|
369
|
+
|
|
370
|
+
Our implementation improves on this by swapping rows so that the
|
|
371
|
+
element with the largest (lower bound of the) absolute value is
|
|
372
|
+
used as pivot.
|
|
373
|
+
|
|
374
|
+
Setup a complex interval for example::
|
|
375
|
+
|
|
376
|
+
sage: from sage.all import RealIntervalField, ComplexIntervalField
|
|
377
|
+
sage: RIF = RealIntervalField(80)
|
|
378
|
+
sage: CIF = ComplexIntervalField(80)
|
|
379
|
+
sage: fuzzy_four = CIF(RIF(3.9999,4.0001),RIF(-0.0001,0.0001))
|
|
380
|
+
|
|
381
|
+
Construct a matrix/vector with complex interval coefficients. One entry
|
|
382
|
+
is a complex interval with non-zero diameter::
|
|
383
|
+
|
|
384
|
+
sage: m = matrix(CIF,
|
|
385
|
+
... [ [ fuzzy_four, 3, 2, 3],
|
|
386
|
+
... [ 2, 3, 6, 2],
|
|
387
|
+
... [ 2, 4, 1, 6],
|
|
388
|
+
... [ 3, 2,-5, 2]])
|
|
389
|
+
sage: v = vector(CIF, [fuzzy_four, 2, 0 ,1])
|
|
390
|
+
|
|
391
|
+
Now compute the solutions a to v = m * a::
|
|
392
|
+
|
|
393
|
+
sage: a = mat_solve(m, v)
|
|
394
|
+
sage: a # doctest: +ELLIPSIS
|
|
395
|
+
(1.5...? + 0.000?*I, -1.2...? + 0.000?*I, 0.34...? + 0.0000?*I, 0.24...? + 0.000?*I)
|
|
396
|
+
sage: m * a # doctest: +ELLIPSIS
|
|
397
|
+
(4.0...? + 0.00?*I, 2.0...? + 0.00?*I, 0.0...? + 0.00?*I, 1.00? + 0.00?*I)
|
|
398
|
+
|
|
399
|
+
The product actually contains the vector v, we check entry wise::
|
|
400
|
+
|
|
401
|
+
sage: [s in t for s, t in zip(v, m * a)]
|
|
402
|
+
[True, True, True, True]
|
|
403
|
+
"""
|
|
404
|
+
|
|
405
|
+
dim0, dim1 = m.dimensions()
|
|
406
|
+
|
|
407
|
+
if dim0 != len(v) or dim1 != len(v):
|
|
408
|
+
raise ValueError(
|
|
409
|
+
("mat_solve was given a vector with length %d not matching "
|
|
410
|
+
"the size %dx%d of the matrix.") % (len(v), dim0, dim1))
|
|
411
|
+
|
|
412
|
+
is_interval = is_Interval(m[0,0])
|
|
413
|
+
if is_interval and not epsilon == 0:
|
|
414
|
+
raise ValueError(
|
|
415
|
+
"mat_solve's epsilon has to be exactly 0 for verified computations "
|
|
416
|
+
"with intervals.")
|
|
417
|
+
|
|
418
|
+
# m = matrix(QQ,[[4,3,2,3],[2,3,6,2],[2,4,1,6],[3,2,-5,2]])
|
|
419
|
+
# v = vector(QQ,[4,2,0,1])
|
|
420
|
+
|
|
421
|
+
# For illustration, we use the following example of a matrix and
|
|
422
|
+
# vector (which for simplicity are not intervals here):
|
|
423
|
+
#
|
|
424
|
+
# [ 4 3 2 3]
|
|
425
|
+
# m = [ 2 3 6 2] v = (4, 2, 0, 1)
|
|
426
|
+
# [ 2 4 1 6]
|
|
427
|
+
# [ 3 2 -5 2]
|
|
428
|
+
#
|
|
429
|
+
|
|
430
|
+
# Create a block matrix of the form
|
|
431
|
+
# [ 4 3 2 3| 4]
|
|
432
|
+
# [ 2 3 6 2| 2]
|
|
433
|
+
# [ 2 4 1 6| 0]
|
|
434
|
+
# [ 3 2 -5 2| 1]
|
|
435
|
+
|
|
436
|
+
m1 = [ [ m[i][j] for j in range(dim0) ] + [ v[i] ]
|
|
437
|
+
for i in range(dim0) ]
|
|
438
|
+
|
|
439
|
+
# Iterate through the rows to apply row operations resulting
|
|
440
|
+
# in the left part being the identity matrix.
|
|
441
|
+
# After the i-th iteration the first i column will
|
|
442
|
+
|
|
443
|
+
# For example, after the first iteration (i = 0), we get
|
|
444
|
+
# [ 1 3/4 1/2 3/4| 1]
|
|
445
|
+
# [ 0 3/2 5 1/2| 0]
|
|
446
|
+
# [ 0 5/2 0 9/2| -2]
|
|
447
|
+
# [ 0 -1/4 -13/2 -1/4| -2]
|
|
448
|
+
|
|
449
|
+
# For example, after the second iteration (i = 1), we get
|
|
450
|
+
# [ 1 0 1/2 -3/5| 8/5]
|
|
451
|
+
# [ 0 1 0 9/5| -4/5]
|
|
452
|
+
# [ 0 0 5 -11/5| 6/5]
|
|
453
|
+
# [ 0 0 -13/2 1/5|-11/5]
|
|
454
|
+
|
|
455
|
+
for i in range(dim0):
|
|
456
|
+
|
|
457
|
+
# Assume i = 2, then we have the above matrix at the start
|
|
458
|
+
# of the iteration.
|
|
459
|
+
|
|
460
|
+
# We look for the largest absolute value in the i-th column on or
|
|
461
|
+
# below the diagonal and its index. In our example, the value
|
|
462
|
+
# occurs in the last row, so max_index = 1 because -11/2 is
|
|
463
|
+
# occurring at the spot one under the diagonal.
|
|
464
|
+
#
|
|
465
|
+
# Because we have intervals as input, we look for the interval
|
|
466
|
+
# with the largest infimum of the absolute value.
|
|
467
|
+
|
|
468
|
+
if is_interval:
|
|
469
|
+
pivots = [ (j, m1[j][i].abs().lower())
|
|
470
|
+
for j in range(i, dim0)]
|
|
471
|
+
else:
|
|
472
|
+
pivots = [ (j, m1[j][i].abs())
|
|
473
|
+
for j in range(i, dim0)]
|
|
474
|
+
|
|
475
|
+
max_index, max_val = max(pivots, key=lambda x:x[1])
|
|
476
|
+
|
|
477
|
+
if not max_val > epsilon:
|
|
478
|
+
raise ZeroDivisionError
|
|
479
|
+
|
|
480
|
+
# For numerical stability, swap rows to avoid diagonal entries
|
|
481
|
+
# that are close to zero. The results are still correct without
|
|
482
|
+
# this swapping of rows but the intervals would be less narrow.
|
|
483
|
+
|
|
484
|
+
# In the above example, we swap the last two rows:
|
|
485
|
+
# [ 1 0 1/2 -3/5| 8/5]
|
|
486
|
+
# [ 0 1 0 9/5| -4/5]
|
|
487
|
+
# [ 0 0 -13/2 1/5|-11/5]
|
|
488
|
+
# [ 0 0 5 -11/5| 6/5]
|
|
489
|
+
|
|
490
|
+
if max_index != i:
|
|
491
|
+
for j in range(i, dim0 + 1):
|
|
492
|
+
m1[max_index][j], m1[i][j] = m1[i][j], m1[max_index][j]
|
|
493
|
+
|
|
494
|
+
# Divide the i-th row so that its i-th coefficient becomes 1
|
|
495
|
+
# [ 1 0 1/2 -3/5| 8/5]
|
|
496
|
+
# [ 0 1 0 9/5| -4/5]
|
|
497
|
+
# [ 0 0 1 -2/65|22/65]
|
|
498
|
+
# [ 0 0 5 -11/5| 6/5]
|
|
499
|
+
|
|
500
|
+
for j in range(i + 1, dim0 + 1):
|
|
501
|
+
m1[i][j] /= m1[i][i]
|
|
502
|
+
|
|
503
|
+
# Subtract multiples of the current row to make the i-th
|
|
504
|
+
# entries of all other rows zero.
|
|
505
|
+
|
|
506
|
+
# [ 1 0 0 -38/65| 93/65]
|
|
507
|
+
# [ 0 1 0 9/5| -4/5]
|
|
508
|
+
# [ 0 0 1 -2/65| 22/65]
|
|
509
|
+
# [ 0 0 0 -133/65| -32/65]
|
|
510
|
+
|
|
511
|
+
for j in range(dim0):
|
|
512
|
+
if i != j:
|
|
513
|
+
for k in range(i + 1, dim0 + 1):
|
|
514
|
+
m1[j][k] -= m1[j][i] * m1[i][k]
|
|
515
|
+
|
|
516
|
+
# After iterations, we have
|
|
517
|
+
# [ 1 0 0 0| 11/7]
|
|
518
|
+
# [ 0 1 0 0|-164/133]
|
|
519
|
+
# [ 0 0 1 0| 46/133]
|
|
520
|
+
# [ 0 0 0 1| 32/133]
|
|
521
|
+
|
|
522
|
+
# Return the last column
|
|
523
|
+
# (11/7, -164/133, 46/133, 32/133)
|
|
524
|
+
|
|
525
|
+
return make_vector([ row[-1] for row in m1])
|