snappy 3.2__cp310-cp310-macosx_10_12_x86_64.whl
Sign up to get free protection for your applications and to get access to all the features.
- snappy/CyOpenGL.cpython-310-darwin.so +0 -0
- snappy/SnapPy.cpython-310-darwin.so +0 -0
- snappy/SnapPy.ico +0 -0
- snappy/SnapPy.png +0 -0
- snappy/SnapPyHP.cpython-310-darwin.so +0 -0
- snappy/__init__.py +760 -0
- snappy/app.py +605 -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 +38 -0
- snappy/cusps/cusp_area_matrix.py +101 -0
- snappy/cusps/cusp_areas_from_matrix.py +173 -0
- snappy/cusps/maximal_cusp_area_matrix.py +136 -0
- snappy/cusps/test.py +21 -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 +710 -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/geodesics.jpg +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 +51 -0
- snappy/doc/_sources/credits.rst.txt +75 -0
- snappy/doc/_sources/development.rst.txt +259 -0
- snappy/doc/_sources/index.rst.txt +182 -0
- snappy/doc/_sources/installing.rst.txt +247 -0
- snappy/doc/_sources/manifold.rst.txt +6 -0
- snappy/doc/_sources/manifoldhp.rst.txt +46 -0
- snappy/doc/_sources/news.rst.txt +355 -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 +925 -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 +156 -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 +199 -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 +620 -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 +427 -0
- snappy/doc/credits.html +181 -0
- snappy/doc/development.html +384 -0
- snappy/doc/genindex.html +1331 -0
- snappy/doc/index.html +262 -0
- snappy/doc/installing.html +346 -0
- snappy/doc/manifold.html +3452 -0
- snappy/doc/manifoldhp.html +180 -0
- snappy/doc/news.html +388 -0
- snappy/doc/objects.inv +0 -0
- snappy/doc/other.html +161 -0
- snappy/doc/platonic_census.html +375 -0
- snappy/doc/plink.html +210 -0
- snappy/doc/ptolemy.html +254 -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 +1211 -0
- snappy/doc/todo.html +166 -0
- snappy/doc/triangulation.html +1584 -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 +126 -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 +197 -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 +123 -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 +697 -0
- snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +484 -0
- snappy/geometric_structure/cusp_neighborhood/exceptions.py +42 -0
- snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +298 -0
- snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +159 -0
- snappy/geometric_structure/cusp_neighborhood/vertices.py +32 -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_keys.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 +93 -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 +101 -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 +245 -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 +382 -0
- snappy/len_spec/__init__.py +596 -0
- snappy/len_spec/geodesic_info.py +110 -0
- snappy/len_spec/geodesic_key_info_dict.py +117 -0
- snappy/len_spec/geodesic_piece.py +143 -0
- snappy/len_spec/geometric_structure.py +182 -0
- snappy/len_spec/geometry.py +80 -0
- snappy/len_spec/length_spectrum_geodesic_info.py +170 -0
- snappy/len_spec/spine.py +206 -0
- snappy/len_spec/test.py +24 -0
- snappy/len_spec/test_cases.py +69 -0
- snappy/len_spec/tile.py +275 -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/math_basics.py +176 -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 +857 -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 +1029 -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 +123 -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 +117 -0
- snappy/settings.py +409 -0
- snappy/shell.py +53 -0
- snappy/snap/__init__.py +114 -0
- snappy/snap/character_varieties.py +375 -0
- snappy/snap/find_field.py +372 -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 +702 -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.py +668 -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 +134 -0
- snappy/snap/utilities.py +288 -0
- snappy/test.py +209 -0
- snappy/test_cases.py +263 -0
- snappy/testing.py +131 -0
- snappy/tiling/__init__.py +2 -0
- snappy/tiling/canonical_key_dict.py +59 -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/real_hash_dict.py +164 -0
- snappy/tiling/test.py +23 -0
- snappy/tiling/tile.py +215 -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-darwin.so +0 -0
- snappy/upper_halfspace/__init__.py +146 -0
- snappy/upper_halfspace/ideal_point.py +26 -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/maximal_cusp_area_matrix/__init__.py +46 -0
- snappy/verify/maximal_cusp_area_matrix/cusp_tiling_engine.py +419 -0
- snappy/verify/maximal_cusp_area_matrix/cusp_translate_engine.py +153 -0
- snappy/verify/real_algebra.py +286 -0
- snappy/verify/shapes.py +25 -0
- snappy/verify/short_slopes.py +200 -0
- snappy/verify/square_extensions.py +1005 -0
- snappy/verify/test.py +78 -0
- snappy/verify/upper_halfspace/__init__.py +9 -0
- snappy/verify/upper_halfspace/extended_matrix.py +100 -0
- snappy/verify/upper_halfspace/finite_point.py +283 -0
- snappy/verify/upper_halfspace/ideal_point.py +426 -0
- snappy/verify/volume.py +128 -0
- snappy/version.py +2 -0
- snappy-3.2.dist-info/METADATA +58 -0
- snappy-3.2.dist-info/RECORD +503 -0
- snappy-3.2.dist-info/WHEEL +5 -0
- snappy-3.2.dist-info/entry_points.txt +2 -0
- snappy-3.2.dist-info/top_level.txt +28 -0
snappy/ptolemy/test.py
ADDED
@@ -0,0 +1,1126 @@
|
|
1
|
+
# Tests the ptolemy module
|
2
|
+
###
|
3
|
+
# Test in sage with precomputed results in testing_files_directory:
|
4
|
+
# sage -python test.py
|
5
|
+
###
|
6
|
+
# Test in python with precomputed results:
|
7
|
+
# python test.py
|
8
|
+
###
|
9
|
+
# Test in sage computing the results:
|
10
|
+
# sage -python test.py --compute
|
11
|
+
###
|
12
|
+
# Test in python computing the results using magma:
|
13
|
+
# python test.py --compute
|
14
|
+
|
15
|
+
from snappy import Manifold, pari, ptolemy
|
16
|
+
from snappy import ptolemy
|
17
|
+
from snappy.ptolemy import solutions_from_magma, Flattenings, parse_solutions
|
18
|
+
from snappy.ptolemy.processFileBase import get_manifold
|
19
|
+
from snappy.ptolemy import __path__ as ptolemy_paths
|
20
|
+
from snappy.ptolemy.coordinates import PtolemyCannotBeCheckedError
|
21
|
+
from snappy.sage_helper import _within_sage
|
22
|
+
from snappy.testing import doctest_modules
|
23
|
+
from snappy.pari import pari
|
24
|
+
import bz2
|
25
|
+
import os
|
26
|
+
import sys
|
27
|
+
import doctest
|
28
|
+
import traceback
|
29
|
+
|
30
|
+
if _within_sage:
|
31
|
+
from sage.misc.sage_eval import sage_eval
|
32
|
+
|
33
|
+
test_regina = '--regina' in sys.argv
|
34
|
+
compute_solutions = '--compute' in sys.argv
|
35
|
+
|
36
|
+
base_path = ptolemy_paths[0]
|
37
|
+
if test_regina:
|
38
|
+
base_path = os.path.join(base_path, 'regina_')
|
39
|
+
|
40
|
+
testing_files_directory = os.path.join(base_path,'testing_files')
|
41
|
+
testing_files_generalized_directory = os.path.join(base_path,
|
42
|
+
'testing_files_generalized')
|
43
|
+
testing_files_rur_directory = os.path.join(base_path, 'testing_files_rur')
|
44
|
+
|
45
|
+
if test_regina:
|
46
|
+
from regina import NTriangulation
|
47
|
+
from snappy.ptolemy.reginaWrapper import *
|
48
|
+
|
49
|
+
def ManifoldGetter(name):
|
50
|
+
return NTriangulationForPtolemy(
|
51
|
+
NTriangulation(Manifold(name)._to_string()))
|
52
|
+
else:
|
53
|
+
def ManifoldGetter(name):
|
54
|
+
return Manifold(name)
|
55
|
+
|
56
|
+
vol_tet = pari('1.014941606409653625021202554274520285941689307530299792017489106776597476258244022136470354228256695')
|
57
|
+
|
58
|
+
|
59
|
+
def check_volumes(complex_volumes, baseline_complex_volumes,
|
60
|
+
check_real_part_only=False,
|
61
|
+
torsion_imaginary_part=6, epsilon=1e-80):
|
62
|
+
|
63
|
+
# add complex volumes from complex conjugation to baseline
|
64
|
+
|
65
|
+
conjugates = [ -cvol.conj() for cvol in baseline_complex_volumes ]
|
66
|
+
|
67
|
+
baseline_complex_volumes = baseline_complex_volumes + conjugates
|
68
|
+
|
69
|
+
# real parts need to be equal
|
70
|
+
# imaginary parts need to be equal up to pi^2/torstion
|
71
|
+
p = pari('Pi * Pi') / torsion_imaginary_part
|
72
|
+
|
73
|
+
def is_close(cvol1, cvol2):
|
74
|
+
diff = cvol1 - cvol2
|
75
|
+
|
76
|
+
if diff.real().abs() > epsilon:
|
77
|
+
return False
|
78
|
+
|
79
|
+
if check_real_part_only:
|
80
|
+
return True
|
81
|
+
|
82
|
+
return ((( diff.imag()) % p) < epsilon or
|
83
|
+
((-diff.imag()) % p) < epsilon)
|
84
|
+
|
85
|
+
# check that every base line volume appears in computed volumes
|
86
|
+
for cvol1 in baseline_complex_volumes:
|
87
|
+
|
88
|
+
if not any(is_close(cvol1, cvol2) for cvol2 in complex_volumes):
|
89
|
+
print("Missing base line volume:", cvol1)
|
90
|
+
|
91
|
+
print("Volumes:")
|
92
|
+
for i in complex_volumes:
|
93
|
+
print(" ", i)
|
94
|
+
|
95
|
+
raise Exception
|
96
|
+
|
97
|
+
# check that every computed volume is a base line volume
|
98
|
+
for cvol2 in complex_volumes:
|
99
|
+
if not any(is_close(cvol1, cvol2)
|
100
|
+
for cvol1 in baseline_complex_volumes):
|
101
|
+
print("Extra volume:", cvol2)
|
102
|
+
|
103
|
+
print("Volumes:")
|
104
|
+
for i in complex_volumes:
|
105
|
+
print(" ", i)
|
106
|
+
|
107
|
+
raise Exception
|
108
|
+
|
109
|
+
|
110
|
+
def testSolutionsForManifold(M, N, solutions, baseline_cvolumes=None,
|
111
|
+
expect_non_zero_dimensional=None,
|
112
|
+
against_geometric=True):
|
113
|
+
|
114
|
+
old_precision = pari.set_real_precision(100)
|
115
|
+
|
116
|
+
# check solutions exactly
|
117
|
+
|
118
|
+
found_non_zero_dimensional = False
|
119
|
+
|
120
|
+
numerical_solutions = [ ]
|
121
|
+
numerical_cross_ratios = [ ]
|
122
|
+
|
123
|
+
numerical_cross_ratios_alt = [ ]
|
124
|
+
|
125
|
+
for solution in solutions:
|
126
|
+
|
127
|
+
if isinstance(solution,
|
128
|
+
ptolemy.component.NonZeroDimensionalComponent):
|
129
|
+
# encountered non-zero dimensional component
|
130
|
+
|
131
|
+
found_non_zero_dimensional = True
|
132
|
+
else:
|
133
|
+
|
134
|
+
assert solution.N() == N
|
135
|
+
assert solution.num_tetrahedra() == M.num_tetrahedra()
|
136
|
+
|
137
|
+
# check exact solutions
|
138
|
+
solution.check_against_manifold(M)
|
139
|
+
|
140
|
+
# compute numerical solutions and cross ratios
|
141
|
+
for numerical_solution in solution.numerical():
|
142
|
+
numerical_solutions.append(numerical_solution)
|
143
|
+
numerical_cross_ratios.append(numerical_solution.cross_ratios())
|
144
|
+
|
145
|
+
# check exact cross ratios
|
146
|
+
cross_ratios = solution.cross_ratios()
|
147
|
+
if not test_regina:
|
148
|
+
cross_ratios.check_against_manifold(M)
|
149
|
+
|
150
|
+
assert cross_ratios.N() == N
|
151
|
+
|
152
|
+
# compute numerical cross ratios alternatively
|
153
|
+
# (above we converted exact Ptolemy's to numerical and then
|
154
|
+
# converted to cross ratio, here we first compute cross ratios
|
155
|
+
# exactly and then convert to numerical)
|
156
|
+
numerical_cross_ratios_alt += cross_ratios.numerical()
|
157
|
+
|
158
|
+
# check we encountered non-zero dimensional component if that's
|
159
|
+
# expected
|
160
|
+
if expect_non_zero_dimensional is not None:
|
161
|
+
assert expect_non_zero_dimensional == found_non_zero_dimensional
|
162
|
+
|
163
|
+
# check the numerical solutions against the manifold
|
164
|
+
for s in numerical_solutions:
|
165
|
+
s.check_against_manifold(M, epsilon=1e-80)
|
166
|
+
|
167
|
+
# check that they make a flattening
|
168
|
+
if not test_regina:
|
169
|
+
s.flattenings_numerical().check_against_manifold(M, epsilon=1e-80)
|
170
|
+
|
171
|
+
if not test_regina:
|
172
|
+
for s in numerical_cross_ratios:
|
173
|
+
s.check_against_manifold(M, epsilon=1e-80)
|
174
|
+
|
175
|
+
for s in numerical_cross_ratios_alt:
|
176
|
+
s.check_against_manifold(M, epsilon=1e-80)
|
177
|
+
|
178
|
+
# compute complex volumes and volumes
|
179
|
+
complex_volumes = [s.complex_volume_numerical() for s in numerical_solutions]
|
180
|
+
volumes = [s.volume_numerical() for s in numerical_cross_ratios]
|
181
|
+
|
182
|
+
# there should be equally many
|
183
|
+
assert len(complex_volumes) == len(volumes)
|
184
|
+
|
185
|
+
# and real part of cvol should be equal to vol
|
186
|
+
for vol, cvol in zip(volumes, complex_volumes):
|
187
|
+
diff = vol - cvol.real()
|
188
|
+
assert diff.abs() < 1e-80
|
189
|
+
|
190
|
+
# volumes from cross ratios computed the different way
|
191
|
+
volumes_alt = [s.volume_numerical() for s in numerical_cross_ratios_alt]
|
192
|
+
|
193
|
+
# volumes should be equal
|
194
|
+
assert len(volumes) == len(volumes_alt)
|
195
|
+
volumes.sort(key=float)
|
196
|
+
volumes_alt.sort(key=float)
|
197
|
+
for vol1, vol2 in zip(volumes, volumes_alt):
|
198
|
+
assert (vol1 - vol2).abs() < 1e-80
|
199
|
+
|
200
|
+
if against_geometric and not test_regina:
|
201
|
+
if M.solution_type() == 'all tetrahedra positively oriented':
|
202
|
+
geom_vol = M.volume() * (N-1) * N * (N+1) / 6
|
203
|
+
assert True in [
|
204
|
+
abs(geom_vol - vol) < 1e-11 for vol in volumes]
|
205
|
+
|
206
|
+
# check that complex volumes match baseline volumes
|
207
|
+
if baseline_cvolumes is not None:
|
208
|
+
check_volumes(complex_volumes, baseline_cvolumes)
|
209
|
+
|
210
|
+
pari.set_real_precision(old_precision)
|
211
|
+
|
212
|
+
|
213
|
+
def testComputeSolutionsForManifold(manifold, N,
|
214
|
+
compute_solutions=False,
|
215
|
+
baseline_cvolumes=None,
|
216
|
+
expect_non_zero_dimensional=None,
|
217
|
+
print_info=True):
|
218
|
+
|
219
|
+
varieties = manifold.ptolemy_variety(N, obstruction_class="all_original")
|
220
|
+
|
221
|
+
if compute_solutions:
|
222
|
+
def compute(variety):
|
223
|
+
return variety.compute_solutions()
|
224
|
+
|
225
|
+
else:
|
226
|
+
def compute(variety):
|
227
|
+
return compute_using_precomputed_magma(variety)
|
228
|
+
|
229
|
+
solutions = sum([compute(variety) for variety in varieties], [])
|
230
|
+
|
231
|
+
testSolutionsForManifold(manifold, N, solutions,
|
232
|
+
baseline_cvolumes, expect_non_zero_dimensional)
|
233
|
+
|
234
|
+
if manifold.name() == 't00000':
|
235
|
+
testMatrixMethods(manifold, solutions, print_info=print_info)
|
236
|
+
|
237
|
+
|
238
|
+
def testMatrixMethods(manifold, solutions, print_info=True):
|
239
|
+
|
240
|
+
def matrix_is_diagonal(m):
|
241
|
+
return (
|
242
|
+
m[0][0] - m[1][1] == 0 and
|
243
|
+
m[0][1] == 0 and
|
244
|
+
m[1][0] == 0)
|
245
|
+
|
246
|
+
def matrix_is_pm_identity(m):
|
247
|
+
return matrix_is_diagonal(m) and (
|
248
|
+
m[0][0] + 1 == 0 or m[0][0] - 1 == 0)
|
249
|
+
|
250
|
+
if print_info:
|
251
|
+
print("Testing matrix methods...")
|
252
|
+
|
253
|
+
G = manifold.fundamental_group(simplify_presentation=True)
|
254
|
+
Graw = manifold.fundamental_group(simplify_presentation=False)
|
255
|
+
|
256
|
+
for solution in solutions:
|
257
|
+
if solution.dimension == 0:
|
258
|
+
|
259
|
+
solution._testing_check_cocycles()
|
260
|
+
|
261
|
+
cross_ratios = solution.cross_ratios()
|
262
|
+
|
263
|
+
for gen in G.generators():
|
264
|
+
assert not matrix_is_diagonal(
|
265
|
+
solution.evaluate_word(gen, G))
|
266
|
+
assert not matrix_is_diagonal(
|
267
|
+
cross_ratios.evaluate_word(gen, G))
|
268
|
+
|
269
|
+
for gen in Graw.generators():
|
270
|
+
assert not matrix_is_diagonal(
|
271
|
+
solution.evaluate_word(gen, Graw))
|
272
|
+
assert not matrix_is_diagonal(
|
273
|
+
cross_ratios.evaluate_word(gen, Graw))
|
274
|
+
assert not matrix_is_diagonal(
|
275
|
+
solution.evaluate_word(gen))
|
276
|
+
assert not matrix_is_diagonal(
|
277
|
+
cross_ratios.evaluate_word(gen))
|
278
|
+
|
279
|
+
for rel in G.relators():
|
280
|
+
assert matrix_is_pm_identity(
|
281
|
+
solution.evaluate_word(rel, G))
|
282
|
+
assert matrix_is_diagonal(
|
283
|
+
solution.evaluate_word(rel, G))
|
284
|
+
|
285
|
+
for rel in Graw.relators():
|
286
|
+
assert matrix_is_pm_identity(
|
287
|
+
solution.evaluate_word(rel, Graw))
|
288
|
+
assert matrix_is_diagonal(
|
289
|
+
solution.evaluate_word(rel, Graw))
|
290
|
+
assert matrix_is_pm_identity(
|
291
|
+
solution.evaluate_word(rel))
|
292
|
+
assert matrix_is_diagonal(
|
293
|
+
solution.evaluate_word(rel))
|
294
|
+
|
295
|
+
|
296
|
+
def test_flattenings_from_tetrahedra_shapes_of_manifold():
|
297
|
+
|
298
|
+
old_precision = pari.set_real_precision(100)
|
299
|
+
|
300
|
+
# real parts need to be equal
|
301
|
+
# imaginary parts need to be equal up to pi^2/6
|
302
|
+
p = pari('Pi * Pi / 6')
|
303
|
+
|
304
|
+
def is_close(cvol1, cvol2, epsilon):
|
305
|
+
diff = cvol1 - cvol2
|
306
|
+
return diff.real().abs() < epsilon and (
|
307
|
+
( diff.imag() % p) < epsilon or
|
308
|
+
(-diff.imag() % p) < epsilon)
|
309
|
+
|
310
|
+
from snappy import OrientableCuspedCensus
|
311
|
+
|
312
|
+
for M_database in (list(OrientableCuspedCensus()[0:10]) +
|
313
|
+
list(OrientableCuspedCensus()[10000:10010])):
|
314
|
+
|
315
|
+
# The manifold returned by OrientableCuspedCensus is
|
316
|
+
# a SnapPy.Manifold, not a snappy.Manifold (as is overridden
|
317
|
+
# in python/test.py).
|
318
|
+
M = Manifold(M_database)
|
319
|
+
|
320
|
+
flattening = Flattenings.from_tetrahedra_shapes_of_manifold(M)
|
321
|
+
flattening.check_against_manifold(M, epsilon=1e-80)
|
322
|
+
|
323
|
+
if not is_close(flattening.complex_volume(),
|
324
|
+
M.complex_volume(), # returns only double precision
|
325
|
+
epsilon=1e-13):
|
326
|
+
raise Exception("Wrong volume")
|
327
|
+
|
328
|
+
# test high precision
|
329
|
+
|
330
|
+
M = ManifoldGetter("5_2")
|
331
|
+
flattening = Flattenings.from_tetrahedra_shapes_of_manifold(M)
|
332
|
+
flattening.check_against_manifold(M, epsilon=1e-80)
|
333
|
+
|
334
|
+
if not is_close(flattening.complex_volume(),
|
335
|
+
pari('2.828122088330783162763898809276634942770981317300649477043520327258802548322471630936947017929999108 - 3.024128376509301659719951221694600993984450242270735312503300643508917708286193746506469158300472966*I'),
|
336
|
+
epsilon=1e-80):
|
337
|
+
raise Exception("Wrong volume")
|
338
|
+
|
339
|
+
pari.set_real_precision(old_precision)
|
340
|
+
|
341
|
+
|
342
|
+
def checkSolutionsForManifoldGeneralizedObstructionClass(
|
343
|
+
solutions_trivial, solutions_non_trivial,
|
344
|
+
manifold, N, baseline_volumes, baseline_dimensions):
|
345
|
+
|
346
|
+
torsionTrivial = pari('Pi^2/6 * I')
|
347
|
+
torsionNonTrivial = pari('Pi^2/18 * I')
|
348
|
+
|
349
|
+
solutions = (
|
350
|
+
[ (s, False) for s in solutions_trivial ] +
|
351
|
+
[ (s, True) for s in solutions_non_trivial ])
|
352
|
+
|
353
|
+
# Dimensions and volumes encountered
|
354
|
+
dimensions = set()
|
355
|
+
volumes = []
|
356
|
+
volumes_2 = []
|
357
|
+
|
358
|
+
for solution, sol_is_non_trivial in solutions:
|
359
|
+
# Add the dimension
|
360
|
+
dimensions.add(solution.dimension)
|
361
|
+
if solution.dimension == 0:
|
362
|
+
|
363
|
+
if sol_is_non_trivial:
|
364
|
+
got_exception = False
|
365
|
+
try:
|
366
|
+
solution.check_against_manifold(manifold)
|
367
|
+
except PtolemyCannotBeCheckedError:
|
368
|
+
got_exception = True
|
369
|
+
|
370
|
+
assert got_exception, (
|
371
|
+
"check_against_manifold should not have passed")
|
372
|
+
else:
|
373
|
+
solution.check_against_manifold(manifold)
|
374
|
+
|
375
|
+
fl = solution.flattenings_numerical()
|
376
|
+
for f in fl:
|
377
|
+
if not test_regina:
|
378
|
+
# Not supported yet in regina
|
379
|
+
f.check_against_manifold(epsilon=1e-80)
|
380
|
+
|
381
|
+
cvol, modulo = f.complex_volume(with_modulo=True)
|
382
|
+
|
383
|
+
if sol_is_non_trivial and N == 3:
|
384
|
+
assert (modulo - torsionNonTrivial).abs() < 1e-80, (
|
385
|
+
"Wrong modulo returned non-trivial case")
|
386
|
+
else:
|
387
|
+
assert (modulo - torsionTrivial).abs() < 1e-80, (
|
388
|
+
"Wrong modulo returned trivial case")
|
389
|
+
|
390
|
+
volumes_2.append(cvol.real())
|
391
|
+
|
392
|
+
# Add the volumes
|
393
|
+
volumes += solution.volume_numerical()
|
394
|
+
|
395
|
+
# Check that the resulting cross ratios full fill
|
396
|
+
# the gluing equations
|
397
|
+
cross_ratios = solution.cross_ratios()
|
398
|
+
if not test_regina:
|
399
|
+
cross_ratios.check_against_manifold(manifold)
|
400
|
+
|
401
|
+
def is_close(a, b):
|
402
|
+
return (a - b).abs() < 1e-80
|
403
|
+
|
404
|
+
def make_unique(L):
|
405
|
+
L.sort()
|
406
|
+
result = L[:1]
|
407
|
+
|
408
|
+
for i in L:
|
409
|
+
if not is_close(result[-1], i):
|
410
|
+
result.append(i)
|
411
|
+
return result
|
412
|
+
|
413
|
+
volumes = make_unique(volumes)
|
414
|
+
volumes_2 = make_unique(volumes_2)
|
415
|
+
all_expected_volumes = make_unique(baseline_volumes +
|
416
|
+
[-vol for vol in baseline_volumes])
|
417
|
+
|
418
|
+
assert len(all_expected_volumes) >= 2 * len(baseline_volumes) - 1
|
419
|
+
|
420
|
+
for volume, expected_volume in zip(volumes, all_expected_volumes):
|
421
|
+
assert is_close(volume, expected_volume)
|
422
|
+
|
423
|
+
for volume, expected_volume in zip(volumes_2,all_expected_volumes):
|
424
|
+
assert is_close(volume, expected_volume)
|
425
|
+
|
426
|
+
assert dimensions == set(baseline_dimensions)
|
427
|
+
|
428
|
+
|
429
|
+
def testComputeSolutionsForManifoldGeneralizedObstructionClass(
|
430
|
+
manifold, N, compute_solutions, baseline_volumes, baseline_dimensions):
|
431
|
+
|
432
|
+
varieties = manifold.ptolemy_variety(N,
|
433
|
+
obstruction_class="all_generalized"
|
434
|
+
# , simplify = False
|
435
|
+
# , eliminate_fixed_ptolemys = True
|
436
|
+
)
|
437
|
+
|
438
|
+
assert len(varieties) == 2
|
439
|
+
|
440
|
+
if compute_solutions:
|
441
|
+
def compute(variety):
|
442
|
+
return variety.compute_solutions()
|
443
|
+
|
444
|
+
else:
|
445
|
+
def compute(variety):
|
446
|
+
return compute_using_precomputed_magma(
|
447
|
+
variety, dir=testing_files_generalized_directory)
|
448
|
+
|
449
|
+
# Solutions for the trivial obstruction class
|
450
|
+
solutions_trivial = compute(varieties[0])
|
451
|
+
|
452
|
+
# Solutions for the non-trivial obstruction class
|
453
|
+
solutions_non_trivial = sum([compute(variety)
|
454
|
+
for variety in varieties[1:]],
|
455
|
+
[])
|
456
|
+
|
457
|
+
checkSolutionsForManifoldGeneralizedObstructionClass(
|
458
|
+
solutions_trivial, solutions_non_trivial,
|
459
|
+
manifold, N, baseline_volumes, baseline_dimensions)
|
460
|
+
|
461
|
+
|
462
|
+
def testGeneralizedObstructionClass(compute_solutions, print_info = True):
|
463
|
+
|
464
|
+
vols = [
|
465
|
+
pari('0'),
|
466
|
+
2 * vol_tet
|
467
|
+
]
|
468
|
+
test__m003__2 = (ManifoldGetter("m003"), # Manifold
|
469
|
+
2, # N = 2
|
470
|
+
vols, # expected volumes
|
471
|
+
[0]) # expected dimensions
|
472
|
+
|
473
|
+
vols = [
|
474
|
+
2 * vol_tet
|
475
|
+
]
|
476
|
+
test__m004__2 = (ManifoldGetter("m004"), # Manifold
|
477
|
+
2, # N = 2
|
478
|
+
vols, # expected volumes
|
479
|
+
[0]) # expected dimensions
|
480
|
+
|
481
|
+
vols = [
|
482
|
+
pari('0'),
|
483
|
+
pari('2.595387593686742138301993834077989475956329764530314161212797242812715071384508096863829303251915501'),
|
484
|
+
2 * 4 * vol_tet,
|
485
|
+
]
|
486
|
+
test__m003__3 = (ManifoldGetter("m003"), # Manifold
|
487
|
+
3, # N = 3
|
488
|
+
vols, # expected volumes
|
489
|
+
[0,1]) # expected dimensions
|
490
|
+
|
491
|
+
test_cases = [ test__m003__2,
|
492
|
+
test__m004__2]
|
493
|
+
|
494
|
+
if (not _within_sage) or (not compute_solutions):
|
495
|
+
test_cases += [test__m003__3]
|
496
|
+
|
497
|
+
for manifold, N, vols, dims in test_cases:
|
498
|
+
|
499
|
+
if print_info:
|
500
|
+
print("Checking for", manifold.name(), "N = %d" % N)
|
501
|
+
|
502
|
+
testComputeSolutionsForManifoldGeneralizedObstructionClass(
|
503
|
+
manifold, N, compute_solutions, vols, dims)
|
504
|
+
|
505
|
+
|
506
|
+
def testMapleLikeRur():
|
507
|
+
|
508
|
+
M = ManifoldGetter("m052")
|
509
|
+
p = M.ptolemy_variety(3, 0)
|
510
|
+
|
511
|
+
sols = parse_solutions(
|
512
|
+
bz2.BZ2File(os.path.join(testing_files_rur_directory,
|
513
|
+
p.filename_base() + '.rur.bz2'),
|
514
|
+
'r').read().decode('ascii'))
|
515
|
+
assert len(sols) == 4
|
516
|
+
assert [sol.dimension for sol in sols] == [0, 0, 0, 1]
|
517
|
+
|
518
|
+
sols.check_against_manifold()
|
519
|
+
cross_ratios = sols.cross_ratios()
|
520
|
+
cross_ratios.check_against_manifold()
|
521
|
+
|
522
|
+
assert sols.number_field()[0:3] == [
|
523
|
+
pari('3*x^5 - 3*x^4 + 7*x^3 - 11*x^2 + 6*x - 1'),
|
524
|
+
pari('x^5 - 3*x^4 + x^3 + x^2 + 2*x - 1'),
|
525
|
+
pari('29987478321*x^50 + 79088110854*x^49 + 146016538609*x^48 + 168029123283*x^47 + 195292402206*x^46 + 249251168329*x^45 + 342446347782*x^44 + 342999865332*x^43 + 169423424001*x^42 - 273623428749*x^41 - 913797131672*x^40 - 1673817412888*x^39 - 2346916788229*x^38 - 2864053668977*x^37 - 3089416575581*x^36 - 3067233025932*x^35 - 2754270808082*x^34 - 2290714735763*x^33 - 1691408820544*x^32 - 1128722560267*x^31 - 616892765351*x^30 - 264545491200*x^29 - 28918206196*x^28 + 65364520067*x^27 + 95427288700*x^26 + 68490651548*x^25 + 40427041992*x^24 + 8765319150*x^23 - 5368633716*x^22 - 14060382008*x^21 - 12638294169*x^20 - 10728252922*x^19 - 6615567685*x^18 - 4275928015*x^17 - 2168416333*x^16 - 1279131210*x^15 - 627103252*x^14 - 403508975*x^13 - 222568645*x^12 - 147840406*x^11 - 81185759*x^10 - 46353128*x^9 - 21481295*x^8 - 9738710*x^7 - 3418080*x^6 - 1145883*x^5 - 254870*x^4 - 44273*x^3 - 565*x^2 + 2925*x + 487')]
|
526
|
+
|
527
|
+
sols[0].multiply_terms_in_RUR().check_against_manifold()
|
528
|
+
sols[0].multiply_and_simplify_terms_in_RUR().check_against_manifold()
|
529
|
+
sol_pur = sols[0].to_PUR()
|
530
|
+
sol_pur.check_against_manifold()
|
531
|
+
|
532
|
+
cross_ratios[0].multiply_terms_in_RUR().check_against_manifold()
|
533
|
+
cross_ratios[0].multiply_and_simplify_terms_in_RUR().check_against_manifold()
|
534
|
+
cross_ratio_pur = cross_ratios[0].to_PUR()
|
535
|
+
|
536
|
+
old_precision = pari.set_real_precision(60)
|
537
|
+
|
538
|
+
sols.numerical().check_against_manifold(epsilon=1e-50)
|
539
|
+
sols.numerical().cross_ratios().check_against_manifold(epsilon=1e-50)
|
540
|
+
cross_ratios.numerical().check_against_manifold(epsilon=1e-50)
|
541
|
+
sol_pur.numerical().check_against_manifold(epsilon=1e-50)
|
542
|
+
cross_ratio_pur.numerical().check_against_manifold(epsilon=1e-50)
|
543
|
+
|
544
|
+
expected_cvols = [
|
545
|
+
pari('-0.78247122081308825152609555186377860994691907952043*I'),
|
546
|
+
pari('-0.72702516069067618470921136741414357709195254197557*I'),
|
547
|
+
pari('-0.68391161907531103571619313072177855528960855942240*I'),
|
548
|
+
pari('-0.56931748709124386099667356226108260894423337722116*I'),
|
549
|
+
pari('-0.51896820855866930434990357344936169357239176536016*I'),
|
550
|
+
pari('-0.51572066892431201326839038002795162651553325964817*I'),
|
551
|
+
pari('-0.43203716183360487568405407399314603426109522825732*I'),
|
552
|
+
pari('-0.36010613661069069469455670342059458401551240819467*I'),
|
553
|
+
pari('-0.30859303742385031407330927444373574273739067157054*I'),
|
554
|
+
pari('-0.026277944917886842767978680898127354858352285383691*I'),
|
555
|
+
pari('0.0248303748672046904847696634069363554930433748091423*I'),
|
556
|
+
pari('0.099321499468818761939078653627745421972173499236569*I'),
|
557
|
+
pari('0.10014328074298669302370298811922885078531513167037*I'),
|
558
|
+
pari('0.26650486587884614841887735378855648561147071193673*I'),
|
559
|
+
pari('0.28149146457238928303062789829916587391163953396165*I'),
|
560
|
+
pari('0.31647148942727816629296211895022802382665885673450*I'),
|
561
|
+
pari('0.43039483620012844786769013182478937263427654168349*I'),
|
562
|
+
pari('0.69353686619303521491910998831602468798059163569136*I'),
|
563
|
+
pari('0.54467996179900207437301145027949601489757288486931 - 0.63094967104322016076042058145264363658770535751782*I'),
|
564
|
+
pari('2.01433658377684250427882647709079550884158567943161 - 0.49992935281631459421725377501106345869263727223108*I'),
|
565
|
+
pari('2.5032821968844998826603550693091792509880846739036 - 0.26075155111137757913541371074811175755130345738250*I'),
|
566
|
+
pari('2.9278315480495821855974883510454022661942898386197 + 0.19505171376983273645226251276721729342140990274561*I'),
|
567
|
+
pari('3.3588310807753976907039310005151876035685073404636 - 0.59541514146929793136574297969820009572263815053647*I'),
|
568
|
+
pari('3.5588560966663108341691237279801529977950803397723 - 0.65837426652607617086885854703688633418948363301344*I'),
|
569
|
+
pari('4.3805052030906555151826572095707468309691641904106 - 0.53144574794454652850763996164828079301339638663719*I'),
|
570
|
+
pari('5.2749826604398957699736902920967737019972675833349 + 0.72096167973012423863761073630614422902154219296456*I'),
|
571
|
+
pari('5.5615522795375430947143486065492921841179004148132 - 0.28072986489486989042244876551205538542949560983728*I'),
|
572
|
+
pari('8.0573463351073700171153059083631820353663427177264 - 0.35478334441703194039659993339822864555159918771765*I'),
|
573
|
+
pari('13.232966218921677854715244009824382732164844146922 + 0.13989736389653471530824083989755826875684215156147*I')
|
574
|
+
]
|
575
|
+
|
576
|
+
expected_cvols = expected_cvols + [ -a.conj() for a in expected_cvols ]
|
577
|
+
|
578
|
+
cvols = sols.complex_volume_numerical().flatten(2) # Include witnesses
|
579
|
+
|
580
|
+
check_volumes(cvols, expected_cvols, epsilon=1e-40)
|
581
|
+
|
582
|
+
vols = sols.volume_numerical().flatten(2) # Include witnesses
|
583
|
+
|
584
|
+
check_volumes(vols, expected_cvols, check_real_part_only=True, epsilon=1e-40)
|
585
|
+
|
586
|
+
pari.set_real_precision(old_precision)
|
587
|
+
|
588
|
+
|
589
|
+
def testNumericalSolutions():
|
590
|
+
|
591
|
+
M = ManifoldGetter("m003")
|
592
|
+
N = 3
|
593
|
+
|
594
|
+
varieties = M.ptolemy_variety(N, obstruction_class='all')
|
595
|
+
|
596
|
+
solutions = [
|
597
|
+
solutions_from_magma(
|
598
|
+
get_precomputed_magma(variety,
|
599
|
+
dir=testing_files_generalized_directory),
|
600
|
+
numerical=True)
|
601
|
+
for variety in varieties ]
|
602
|
+
|
603
|
+
for obstruction_index, obstruction in enumerate(solutions):
|
604
|
+
for component in obstruction:
|
605
|
+
for solution in component:
|
606
|
+
flattenings = solution.flattenings_numerical()
|
607
|
+
if not test_regina:
|
608
|
+
flattenings.check_against_manifold(epsilon=1e-80)
|
609
|
+
order = flattenings.get_order()
|
610
|
+
|
611
|
+
if obstruction_index:
|
612
|
+
assert order == 6
|
613
|
+
else:
|
614
|
+
assert order == 2
|
615
|
+
|
616
|
+
cross_ratios = solution.cross_ratios()
|
617
|
+
is_cr = cross_ratios.is_pu_2_1_representation(epsilon=1e-80,
|
618
|
+
epsilon2=1e-10)
|
619
|
+
|
620
|
+
if cross_ratios.volume_numerical().abs() < 1e-10:
|
621
|
+
# Every volume 0 representation of m003 happens to be
|
622
|
+
# cr
|
623
|
+
assert is_cr
|
624
|
+
else:
|
625
|
+
assert not is_cr
|
626
|
+
|
627
|
+
number_one_dimensional = 0
|
628
|
+
|
629
|
+
allComponents = sum(solutions, [])
|
630
|
+
|
631
|
+
dimension_dict = {}
|
632
|
+
degree_dict = {}
|
633
|
+
|
634
|
+
for component in allComponents:
|
635
|
+
|
636
|
+
dim = component.dimension
|
637
|
+
deg = len(component)
|
638
|
+
|
639
|
+
dimension_dict[dim] = 1 + dimension_dict.get(dim, 0)
|
640
|
+
degree_dict[deg] = 1 + degree_dict.get(deg, 0)
|
641
|
+
|
642
|
+
assert (dim == 0) ^ (deg == 0)
|
643
|
+
|
644
|
+
assert dimension_dict == {0: 4, 1: 2}
|
645
|
+
assert degree_dict == {0 :2, 2: 2, 8: 2}
|
646
|
+
|
647
|
+
allSolutions = sum(allComponents, [])
|
648
|
+
|
649
|
+
allCVolumes = [s.complex_volume_numerical() for s in allSolutions]
|
650
|
+
|
651
|
+
expected_cvolume = pari('2.595387593686742138301993834077989475956329764530314161212797242812715071384508096863829303251915501 + 0.1020524924166561605528051801006522147774827678324290664524996742369032819581086580383974219370194645*I')
|
652
|
+
|
653
|
+
expected_cvolumes = [
|
654
|
+
pari(0),
|
655
|
+
expected_cvolume,
|
656
|
+
expected_cvolume.conj(),
|
657
|
+
2 * 4 * vol_tet
|
658
|
+
]
|
659
|
+
|
660
|
+
check_volumes(allCVolumes, expected_cvolumes)
|
661
|
+
|
662
|
+
|
663
|
+
def testGeometricRep(compute_solutions, print_info=False):
|
664
|
+
|
665
|
+
from snappy.ptolemy import geometricRep
|
666
|
+
|
667
|
+
M = Manifold("m019")
|
668
|
+
if compute_solutions:
|
669
|
+
sol = geometricRep.compute_geometric_solution(M)
|
670
|
+
else:
|
671
|
+
from urllib.request import pathname2url
|
672
|
+
url = pathname2url(os.path.abspath(testing_files_directory))
|
673
|
+
sol = geometricRep.retrieve_geometric_solution(
|
674
|
+
M, data_url=url, verbose = print_info)
|
675
|
+
|
676
|
+
# Make sure this is of type Ptolemy
|
677
|
+
sol['c_0011_2']
|
678
|
+
|
679
|
+
assert any(
|
680
|
+
abs(vol - 2.9441064867) < 1e-9 for vol in sol.volume_numerical())
|
681
|
+
|
682
|
+
|
683
|
+
def testSageCommandLine():
|
684
|
+
|
685
|
+
sage_eval('Manifold("m004").ptolemy_variety(3,0).compute_solutions().check_against_manifold()',
|
686
|
+
{ 'Manifold' : ManifoldGetter })
|
687
|
+
|
688
|
+
|
689
|
+
def get_precomputed_magma(variety, dir):
|
690
|
+
magma_file_name = os.path.join(dir,
|
691
|
+
variety.filename_base() + '.magma_out.bz2')
|
692
|
+
return bz2.BZ2File(magma_file_name,'r').read().decode('ascii')
|
693
|
+
|
694
|
+
|
695
|
+
def compute_using_precomputed_magma(variety, dir=testing_files_directory):
|
696
|
+
return solutions_from_magma(get_precomputed_magma(variety, dir))
|
697
|
+
|
698
|
+
|
699
|
+
def test_induced_representation():
|
700
|
+
|
701
|
+
M = ManifoldGetter("m015")
|
702
|
+
variety__sl2_c1 = M.ptolemy_variety(2, obstruction_class=1)
|
703
|
+
variety__sl3_c0 = M.ptolemy_variety(3, obstruction_class=0)
|
704
|
+
|
705
|
+
solutions__sl2_c1 = compute_using_precomputed_magma(
|
706
|
+
variety__sl2_c1, dir=testing_files_generalized_directory)
|
707
|
+
solutions__sl3_c0 = compute_using_precomputed_magma(
|
708
|
+
variety__sl3_c0, dir=testing_files_generalized_directory)
|
709
|
+
|
710
|
+
# Check that is_real
|
711
|
+
|
712
|
+
got_exception = False
|
713
|
+
try:
|
714
|
+
solutions__sl3_c0[0].cross_ratios().is_real(epsilon=1e-80)
|
715
|
+
except:
|
716
|
+
got_exception = True
|
717
|
+
assert got_exception, (
|
718
|
+
"Expected error when calling is_real on exact solution")
|
719
|
+
|
720
|
+
# For each component of sl3 c0, determine the number
|
721
|
+
# of solutions which are real vs number of all solutions
|
722
|
+
|
723
|
+
numbers_all_and_real = []
|
724
|
+
for component in solutions__sl3_c0:
|
725
|
+
number_real = 0
|
726
|
+
number_all = 0
|
727
|
+
for z in component.cross_ratios_numerical():
|
728
|
+
if z.is_real(epsilon=1e-80):
|
729
|
+
number_real += 1
|
730
|
+
number_all += 1
|
731
|
+
numbers_all_and_real.append((number_all, number_real))
|
732
|
+
|
733
|
+
# Bring into canonical form
|
734
|
+
numbers_all_and_real.sort()
|
735
|
+
|
736
|
+
expected_numbers = [
|
737
|
+
(3, 1), # component has 3 solutions, 1 of them has real cross ratios
|
738
|
+
(4, 2),
|
739
|
+
(6, 0) ]
|
740
|
+
|
741
|
+
assert numbers_all_and_real == expected_numbers, (
|
742
|
+
"Order of components and number of real solutions is off")
|
743
|
+
|
744
|
+
# Check is_induced_from_psl2
|
745
|
+
|
746
|
+
number_psl2 = 0
|
747
|
+
|
748
|
+
for component in solutions__sl3_c0:
|
749
|
+
if component.cross_ratios().is_induced_from_psl2():
|
750
|
+
number_psl2 += 1
|
751
|
+
|
752
|
+
assert number_psl2 == 1, "Only one component can come from psl2"
|
753
|
+
|
754
|
+
number_psl2 = 0
|
755
|
+
|
756
|
+
for component in solutions__sl3_c0:
|
757
|
+
is_induced_from_psl2 = [z.is_induced_from_psl2(epsilon=1e-80)
|
758
|
+
for z in component.cross_ratios_numerical()]
|
759
|
+
if any(is_induced_from_psl2):
|
760
|
+
number_psl2 += 1
|
761
|
+
assert all(is_induced_from_psl2), "Mixed up is_induced_from_psl2"
|
762
|
+
|
763
|
+
assert number_psl2 == 1, (
|
764
|
+
"Only one component can come from psl2 (numerically)")
|
765
|
+
|
766
|
+
# Check that induced_representation for sl3 throws error
|
767
|
+
got_exception = False
|
768
|
+
try:
|
769
|
+
solutions__sl3_c0[0].cross_ratios().induced_representation(3)
|
770
|
+
except:
|
771
|
+
got_exception = True
|
772
|
+
assert got_exception, (
|
773
|
+
"Expected error when calling induced_representation on sl3")
|
774
|
+
|
775
|
+
# Check that induced_representation(3) works for m015
|
776
|
+
|
777
|
+
m015_volume = pari("2.828122088330783162763898809276634942770981317300649477043520327258802548322471630936947017929999108")
|
778
|
+
|
779
|
+
z = solutions__sl2_c1[0].cross_ratios().induced_representation(3)
|
780
|
+
assert z.is_induced_from_psl2(), (
|
781
|
+
"induced_representation failed to be detected as being induced")
|
782
|
+
|
783
|
+
assert z.check_against_manifold, (
|
784
|
+
"induced_representation fails to be valid")
|
785
|
+
|
786
|
+
for v in z.volume_numerical():
|
787
|
+
assert v.abs() < 1e-80 or (v.abs() - 4 * m015_volume).abs() < 1e-80, (
|
788
|
+
"Did not get expected voluem for induced representation")
|
789
|
+
|
790
|
+
for z in solutions__sl2_c1[0].cross_ratios_numerical():
|
791
|
+
v = z.induced_representation(3).volume_numerical()
|
792
|
+
assert v.abs() < 1e-80 or (v.abs() - 4 * m015_volume).abs() < 1e-80, (
|
793
|
+
"Did not get expected voluem for induced representation")
|
794
|
+
|
795
|
+
|
796
|
+
def test_induced_sl4_representation():
|
797
|
+
M = Manifold("m004")
|
798
|
+
|
799
|
+
z_gl2 = ptolemy.CrossRatios.from_snappy_manifold(M)
|
800
|
+
z_gl4 = z_gl2.induced_representation(4)
|
801
|
+
|
802
|
+
G = M.fundamental_group()
|
803
|
+
|
804
|
+
mat = z_gl4.evaluate_word(G.relators()[0], G)
|
805
|
+
|
806
|
+
for i, row in enumerate(mat):
|
807
|
+
for j, entry in enumerate(row):
|
808
|
+
if i == j:
|
809
|
+
assert abs(entry - 1) < 1e-9
|
810
|
+
else:
|
811
|
+
assert abs(entry) < 1e-9
|
812
|
+
|
813
|
+
|
814
|
+
def test_num_obstruction_class_match():
|
815
|
+
from snappy import OrientableCuspedCensus
|
816
|
+
|
817
|
+
for M in (list(OrientableCuspedCensus()[0:5]) +
|
818
|
+
list(OrientableCuspedCensus()[10000:10005])):
|
819
|
+
N = NTriangulationForPtolemy(M._to_string())
|
820
|
+
|
821
|
+
assert len(M.ptolemy_obstruction_classes()) == len(N.ptolemy_obstruction_classes())
|
822
|
+
|
823
|
+
for i in range(2,6):
|
824
|
+
assert len(M.ptolemy_generalized_obstruction_classes(i)) == len(N.ptolemy_generalized_obstruction_classes(i))
|
825
|
+
|
826
|
+
def run_ptolemy_tests_raising_exceptions(print_info=True):
|
827
|
+
if print_info:
|
828
|
+
print("Testing in sage:", _within_sage)
|
829
|
+
|
830
|
+
print("Testing in regina:", test_regina)
|
831
|
+
|
832
|
+
if test_regina:
|
833
|
+
if print_info:
|
834
|
+
print("Testing that regina agrees with snappy obstruction classes")
|
835
|
+
test_num_obstruction_class_match()
|
836
|
+
|
837
|
+
if not test_regina:
|
838
|
+
if print_info:
|
839
|
+
print("Testing Flattenings.from_tetrahedra_shapes_of_manifold...")
|
840
|
+
|
841
|
+
test_flattenings_from_tetrahedra_shapes_of_manifold()
|
842
|
+
|
843
|
+
if test_regina and not compute_solutions:
|
844
|
+
print("regina testing requires --compute")
|
845
|
+
sys.exit(1)
|
846
|
+
|
847
|
+
old_precision = pari.set_real_precision(100)
|
848
|
+
|
849
|
+
if print_info:
|
850
|
+
print("Testing induced representation...")
|
851
|
+
|
852
|
+
test_induced_representation()
|
853
|
+
|
854
|
+
if print_info:
|
855
|
+
print("Testing induced SL(4,C) representation...")
|
856
|
+
|
857
|
+
test_induced_sl4_representation()
|
858
|
+
|
859
|
+
if print_info:
|
860
|
+
print("Running manifold tests for generalized obstruction class...")
|
861
|
+
|
862
|
+
testGeneralizedObstructionClass(compute_solutions, print_info=print_info)
|
863
|
+
|
864
|
+
if not test_regina:
|
865
|
+
if print_info:
|
866
|
+
print("Testing RUR for m052__sl3_c0.rur")
|
867
|
+
|
868
|
+
testMapleLikeRur()
|
869
|
+
|
870
|
+
if print_info:
|
871
|
+
print("Testing numerical solution retrieval method...")
|
872
|
+
|
873
|
+
testNumericalSolutions()
|
874
|
+
|
875
|
+
if print_info:
|
876
|
+
print("Testing geometricRep...")
|
877
|
+
testGeometricRep(compute_solutions, print_info=print_info)
|
878
|
+
|
879
|
+
if _within_sage:
|
880
|
+
if print_info:
|
881
|
+
print("Testing in sage command line...")
|
882
|
+
testSageCommandLine()
|
883
|
+
|
884
|
+
if print_info:
|
885
|
+
print("Running manifold tests...")
|
886
|
+
|
887
|
+
# Test for a non-hyperbolic manifold
|
888
|
+
|
889
|
+
cvols = [ # Expected Complex volumes
|
890
|
+
pari('0') ]
|
891
|
+
test__3_1__2 = (ManifoldGetter("3_1"), # Manifold
|
892
|
+
2, # N = 2
|
893
|
+
cvols, # expected complex volumes
|
894
|
+
False) # No non-zero dimensional components
|
895
|
+
|
896
|
+
# Test for 4_1, amphichiral, expect zero CS
|
897
|
+
|
898
|
+
cvols = [ # Expected Complex volumes
|
899
|
+
2 * vol_tet
|
900
|
+
]
|
901
|
+
test__4_1__2 = (ManifoldGetter("4_1"), # Manifold
|
902
|
+
2, # N = 2
|
903
|
+
cvols, # expected complex volumes
|
904
|
+
False) # expect non-zero dimensional components
|
905
|
+
|
906
|
+
# N = 3
|
907
|
+
|
908
|
+
cvols = [ # Expected Complex volumes
|
909
|
+
pari(0),
|
910
|
+
2 * 4 * vol_tet
|
911
|
+
]
|
912
|
+
test__4_1__3 = (ManifoldGetter("4_1"), # Manifold
|
913
|
+
3, # N = 3
|
914
|
+
cvols, # expected complex volumes
|
915
|
+
False) # expect non-zero dimensional components
|
916
|
+
|
917
|
+
# N = 4
|
918
|
+
|
919
|
+
cvols = [ # Expected Complex volumes
|
920
|
+
2 * 10 * vol_tet,
|
921
|
+
pari('8.355502146379565994303773768814775354386025704336131822255670190659042090899812770381061831431114740 - 0.7836375483069721973241186952472609466029570462055317453592429525294418326815666413123016980810744089*I'),
|
922
|
+
pari('7.327724753417752120436828119459072886193194994253377074131984956974104158210038155834852103408920850'),
|
923
|
+
pari('4.260549384199988638895626360783795200167603461491438308495654794999595513880915593832371886868625127 + 0.1361281655780504266700965891301086052404492485996004213292764928775628027210816440355745847599247091*I'),
|
924
|
+
pari('3.276320849776062968038680855240250653840691843746753028019901828179320044237305241434903501877259688 + 0.03882948511714102091208888807575164800651790439786747350853616215556190252003379560451275222880494392*I'),
|
925
|
+
pari('3.230859569867059515989136707781810556962637199799080875515780771251800351524537196576706995730457048')
|
926
|
+
]
|
927
|
+
|
928
|
+
# amphicheiral, so complex volumes should appear in pairs
|
929
|
+
|
930
|
+
cvols = cvols + [cvol.conj() for cvol in cvols]
|
931
|
+
|
932
|
+
test__4_1__4 = (ManifoldGetter("4_1"), # Manifold
|
933
|
+
4, # N = 2
|
934
|
+
cvols, # expected complex volumes
|
935
|
+
True) # expect non-zero dimensional components
|
936
|
+
|
937
|
+
# Test for 5_2, expect non-trivial CS
|
938
|
+
# Number field has one real embedding with non-trival CS
|
939
|
+
# And one pair of complex embeddings with non-trivial CS
|
940
|
+
|
941
|
+
cvols = [ # Expected Complex volumes
|
942
|
+
pari('+ 1.113454552473924010022656943451126420312050780921075311799926598907813005362784871512051614741669817*I'),
|
943
|
+
pari('2.828122088330783162763898809276634942770981317300649477043520327258802548322471630936947017929999108 - 3.024128376509301659719951221694600993984450242270735312503300643508917708286193746506469158300472966*I')
|
944
|
+
]
|
945
|
+
test__5_2__2 = (ManifoldGetter("5_2"), # Manifold
|
946
|
+
2, # N = 2
|
947
|
+
cvols, # expected complex volumes
|
948
|
+
False) # expect no non-zero dimensional components
|
949
|
+
|
950
|
+
# m015 which is isometric to 5_2
|
951
|
+
# This example is also appearing on the website
|
952
|
+
|
953
|
+
cvols = [ # Expected Complex volumes
|
954
|
+
pari('+ 0.4033353624187061319128390413376061001062613536896471642214173008084760853375773296525240139108027276*I'),
|
955
|
+
pari('- 0.4809839906489832693266177261335698864086465799360940660069682924787703897584631354526802428925968492*I'),
|
956
|
+
pari('+ 0.6579736267392905745889660666584100756875799604827193750942232917480029881612803495334515602479034826*I'),
|
957
|
+
pari('- 0.6579736267392905745889660666584100756875799604827193750942232917480029881612803495334515602479034826*I'),
|
958
|
+
pari('6.332666642499251344664115407516762513592210378740462564820401485540596854320653136703448734707430999 + 0.6207993522147601522797880626542095445563442737585756367570704642807656925328117720905524433544779886*I'),
|
959
|
+
pari('11.31248835332313265105559523710653977108392526920259790817408130903521019328988652374778807171999643 - 0.5819750380996215835728987202562276514051516606353521858642949684456185403223688691904743288635809278*I')
|
960
|
+
]
|
961
|
+
|
962
|
+
test__m015__3 = (ManifoldGetter("m015"), # Manifold
|
963
|
+
3, # N = 3
|
964
|
+
cvols, # expected volumes
|
965
|
+
False) # expect no non-zero dimensional components
|
966
|
+
|
967
|
+
# Test for m135
|
968
|
+
# Ptolemy Variety has one non-zero dimensional component
|
969
|
+
|
970
|
+
cvols = [ # Expected Complex volumes
|
971
|
+
pari('3.66386237670887606021841405972953644309659749712668853706599247848705207910501907791742605170446042499429769047678479831614359521330343623772637894992 + 4.93480220054467930941724549993807556765684970362039531320667468811002241120960262150088670185927611591201295688701157203888617406101502336380530883900*I')
|
972
|
+
]
|
973
|
+
|
974
|
+
test__m135__2 = (ManifoldGetter("m135"), # Manifold
|
975
|
+
2, # N = 2
|
976
|
+
cvols, # expected volumes
|
977
|
+
True) # expect a non-zero dimensional component
|
978
|
+
|
979
|
+
# Test for s000
|
980
|
+
# Number field has one real embedding with non-trival CS
|
981
|
+
# And two complex embeddings with non-trivial CS
|
982
|
+
|
983
|
+
cvols = [ # Expected Complex volumes
|
984
|
+
pari('3.296902414326637335562593088559162089146991699269941951875989849869324250860299302482577730785960256 + 0.4908671850777469648812718224097607532197026477625119178645010117072332396428578681905186509136879130*I'),
|
985
|
+
pari('2.270424126345803402614201085375714538056567876339790536089272218685353247084791707534069624462050547 - 0.4107712000441024931074403997367404299427214514732528671142771778838924102954454212055598588991237349*I'),
|
986
|
+
pari('0.8061270618942289713279174295562193428686541442399728535727328789432842090598108984711933183445551654 - 0.08009598503364447177383142267302032327698119628925905075022383382334082934741244698495879201456417902*I')
|
987
|
+
]
|
988
|
+
|
989
|
+
test__s000__2 = (ManifoldGetter("s000"), # Manifold
|
990
|
+
2, # N = 2
|
991
|
+
cvols, # expected complex volumes
|
992
|
+
False) # expect non-zero dimensional components
|
993
|
+
|
994
|
+
# Test for v0000
|
995
|
+
# This also tests the case of having more than one (here two)
|
996
|
+
# cusps
|
997
|
+
|
998
|
+
cvols = [ # Expected Complex volumes
|
999
|
+
pari('3.377597408231442496961257171798882829176020069714519460350380851901055794392493960110119513942153791 + 0.3441889979504813554136570264352067044809511501367282461849580661783699588789118851518262199077361427*I'),
|
1000
|
+
pari('1.380586178282342062845519278761524817753278777803238623999221385504661588501960339341800843520223671 + 0.06704451876157525370444676522629959282378632516497136324893149116413190872188833330658100524720353406*I')
|
1001
|
+
]
|
1002
|
+
|
1003
|
+
test__v0000__2 = (ManifoldGetter("v0000"), # Manifold
|
1004
|
+
2, # N = 2
|
1005
|
+
cvols, # expected complex volumes
|
1006
|
+
False) # expect non-zero dimensional components
|
1007
|
+
|
1008
|
+
# Test for t00000
|
1009
|
+
# This also tests the case of having more than one (here two)
|
1010
|
+
# cusps
|
1011
|
+
|
1012
|
+
cvols = [ # Expected Complex volumes
|
1013
|
+
pari('1.801231981344929412976326011175173926741195258454700704383597306674496002389749200442131507334117933 - 0.5490336239273931479260463113980794374780078424892352183284248305887346671477869107359071072271699046*I'),
|
1014
|
+
pari('3.434540885902563701250335473165274495380101665474171663779718033441916041515556280543077990039279103 - 0.2258335622748003900958464044389939976977579115267501160859900439335840118881246299028850924706341411*I'),
|
1015
|
+
pari('2.781430316400743786576311128801205534982324055570742403430395886754122643539081915302290955978507418 - 0.1135489194824466736456241002458946823709871812077727407261274931826622024508518397031626436088171650*I'),
|
1016
|
+
pari('0.6223401945262803853426860070209275705147832620602921139947907237662088851273537136119288228151713940 + 0.06594907226052699343130923275995552293727798462035885627276325301997714628516294342514039299674185799*I')
|
1017
|
+
]
|
1018
|
+
|
1019
|
+
test__t00000__2 = (ManifoldGetter("t00000"), # Manifold
|
1020
|
+
2, # N = 2
|
1021
|
+
cvols, # expected complex volumes
|
1022
|
+
False) # expect non-zero dimensional components
|
1023
|
+
|
1024
|
+
# Check a big link
|
1025
|
+
# Also an example from the website
|
1026
|
+
|
1027
|
+
magma_file_name = os.path.join(testing_files_directory,
|
1028
|
+
'DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2')
|
1029
|
+
magma_file = bz2.BZ2File(magma_file_name, 'r').read().decode('ascii')
|
1030
|
+
M = get_manifold(magma_file)
|
1031
|
+
|
1032
|
+
cvols = [ # Expected complex volumes
|
1033
|
+
pari('+ 0.7322614121694386973039290771667413108310290182470824825342304051284154933661673470336385959164416421*I'),
|
1034
|
+
pari('+ 0.6559698855197901194421542799077526971594537987318704612418448259078988296037785866985260815280619566*I'),
|
1035
|
+
pari('+ 0.2247361398283578756297647616373802721002644994163825408181485469244129408530290519698535075998585820*I'),
|
1036
|
+
pari('- 0.2027422644881176424634704044404281277501368039784045126270573672316679046996639567741375438621581585*I'),
|
1037
|
+
pari('- 0.5165804080147074827389022895582362309867052040022748905555220755792330887283843134684241943604049933*I'),
|
1038
|
+
pari('- 0.6947370811282851128538476965898593866158843479399924653138487625940910866865914821776342801425993440*I'),
|
1039
|
+
pari('0.5540930202692745891960825388466975825977590423995169588735760161940190344506116205300980253997539517 + 0.4068295289298811130481298436200768517194764143946539028521976313233755795250413907401491036923026977*I'),
|
1040
|
+
pari('1.107573735539315638081527574351339252286206152514359620788778723352858972530297840033883810630372795 - 0.5969698437345460065934215233692845699554045087887375026603956452869723823599605032061849791769108861*I'),
|
1041
|
+
pari('2.930037687027569312623189945781681052278144410906236798293622026086427321638842320557907595726492995 + 0.3289208659101980133472847400704889056725461985759517831954390384444124055329869355087545294359968288*I'),
|
1042
|
+
pari('3.125178220789358723184584053682215536632004045535766511323850625359539915401419555941250425818672532 - 0.3045460696329709194663539414577718771554887499547088593863438059068830455709928110292357447645590516*I'),
|
1043
|
+
pari('4.421889017241566419690868074785716366646707154662264036268588279252613543336245268108457201245088608 + 0.6139898590804745843458673335891956572719167936270349811550161917334120397060146434004694625036091183*I'),
|
1044
|
+
pari('5.114841460302400721438106628468470523914735245629326811523719108779649554034504844499930511307337652 - 0.05922105399342951023220969900445652084832276940306885833938997476066822991673855494231393721309130829*I'),
|
1045
|
+
pari('6.222431566185758097679258799420253341029081314309961806975091338751806200485840320374430035873760649 - 0.4263260019368806638768168211894976779995931712761356294379973306148491137274105197747275282097587014*I'),
|
1046
|
+
pari('9.266495487232495996324305783134684559241087943387258046228284813849170601366096263130956023317432143 + 0.03172800820055749085258729263585301130211316529809616828980203075096987437740390637996179595789268661*I'),
|
1047
|
+
pari('11.33736073062520808632824769184286601589152410942391317127856679767752551409389094871647937428783709 - 0.5767482750608833159526763068340021498631801513808564565980389960163842898485087439099502988183940450*I'),
|
1048
|
+
pari('12.48005937399413830153052941177305767103579608241815594942757035041902652992672347868089986739774396 + 0.4828891402943609873677952178777231024869262986704386628808130740557195704279966401921665132533128189*I')
|
1049
|
+
]
|
1050
|
+
|
1051
|
+
test__morwen_link__2 = (M , # Manifold
|
1052
|
+
2, # N = 2
|
1053
|
+
cvols, # expected complex volumes
|
1054
|
+
False) # expect no non-zero dimensional components
|
1055
|
+
|
1056
|
+
test_cases = [ test__3_1__2,
|
1057
|
+
test__4_1__2,
|
1058
|
+
test__5_2__2,
|
1059
|
+
test__m135__2,
|
1060
|
+
test__s000__2,
|
1061
|
+
test__v0000__2,
|
1062
|
+
test__t00000__2,
|
1063
|
+
test__morwen_link__2,
|
1064
|
+
test__4_1__3,
|
1065
|
+
test__m015__3,
|
1066
|
+
test__4_1__4]
|
1067
|
+
|
1068
|
+
pari.set_real_precision(old_precision)
|
1069
|
+
|
1070
|
+
for manifold, N, cvols, expect_non_zero_dim in test_cases:
|
1071
|
+
|
1072
|
+
if print_info:
|
1073
|
+
print("Checking for", manifold.name(), "N = %d" % N)
|
1074
|
+
|
1075
|
+
testComputeSolutionsForManifold(
|
1076
|
+
manifold, N,
|
1077
|
+
compute_solutions=compute_solutions,
|
1078
|
+
baseline_cvolumes=cvols,
|
1079
|
+
expect_non_zero_dimensional=expect_non_zero_dim,
|
1080
|
+
print_info=print_info)
|
1081
|
+
|
1082
|
+
def run_ptolemy_tests(verbose=False, print_info=True):
|
1083
|
+
try:
|
1084
|
+
run_ptolemy_tests_raising_exceptions(
|
1085
|
+
print_info=print_info)
|
1086
|
+
return doctest.TestResults(failed=0, attempted=1)
|
1087
|
+
except Exception as e:
|
1088
|
+
print()
|
1089
|
+
print("FAILED TEST in Ptolemy. Exception is:")
|
1090
|
+
traceback.print_exc()
|
1091
|
+
print()
|
1092
|
+
return doctest.TestResults(failed=1, attempted=1)
|
1093
|
+
|
1094
|
+
run_ptolemy_tests.__name__ = ptolemy.__name__ + ' (non-doc tests)'
|
1095
|
+
|
1096
|
+
modules = [ptolemy.component,
|
1097
|
+
ptolemy.coordinates,
|
1098
|
+
ptolemy.manifoldMethods,
|
1099
|
+
ptolemy.matrix,
|
1100
|
+
ptolemy.polynomial,
|
1101
|
+
ptolemy.processFileBase,
|
1102
|
+
ptolemy.processMagmaFile,
|
1103
|
+
ptolemy.processRurFile,
|
1104
|
+
ptolemy.ptolemyObstructionClass,
|
1105
|
+
ptolemy.ptolemyVariety,
|
1106
|
+
ptolemy.rur,
|
1107
|
+
ptolemy.utilities]
|
1108
|
+
if test_regina:
|
1109
|
+
modules.append(ptolemy.reginaWrapper)
|
1110
|
+
|
1111
|
+
def run_doctests(verbose=False, print_info=True):
|
1112
|
+
return doctest_modules(
|
1113
|
+
modules,
|
1114
|
+
verbose=verbose, print_info=print_info)
|
1115
|
+
|
1116
|
+
run_doctests.__name__ = ptolemy.__name__
|
1117
|
+
|
1118
|
+
if __name__ == '__main__':
|
1119
|
+
verbose = '-v' in sys.argv[1:] or '--verbose' in sys.argv[1:]
|
1120
|
+
|
1121
|
+
result = run_doctests(verbose=verbose, print_info=True)
|
1122
|
+
if result.failed:
|
1123
|
+
sys.exit(result.failed)
|
1124
|
+
|
1125
|
+
result = run_ptolemy_tests(verbose=verbose, print_info=True)
|
1126
|
+
sys.exit(result.failed)
|