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.
Files changed (541) hide show
  1. snappy/CyOpenGL.cpython-310-aarch64-linux-gnu.so +0 -0
  2. snappy/SnapPy.cpython-310-aarch64-linux-gnu.so +0 -0
  3. snappy/SnapPy.ico +0 -0
  4. snappy/SnapPy.png +0 -0
  5. snappy/SnapPyHP.cpython-310-aarch64-linux-gnu.so +0 -0
  6. snappy/__init__.py +534 -0
  7. snappy/app.py +604 -0
  8. snappy/app_menus.py +372 -0
  9. snappy/browser.py +998 -0
  10. snappy/cache.py +25 -0
  11. snappy/canonical.py +249 -0
  12. snappy/cusps/__init__.py +280 -0
  13. snappy/cusps/cusp_area_matrix.py +98 -0
  14. snappy/cusps/cusp_areas_from_matrix.py +96 -0
  15. snappy/cusps/maximal_cusp_area_matrix.py +136 -0
  16. snappy/cusps/short_slopes_for_cusp.py +217 -0
  17. snappy/cusps/test.py +22 -0
  18. snappy/cusps/trig_cusp_area_matrix.py +63 -0
  19. snappy/database.py +454 -0
  20. snappy/db_utilities.py +79 -0
  21. snappy/decorated_isosig.py +717 -0
  22. snappy/dev/__init__.py +0 -0
  23. snappy/dev/extended_ptolemy/__init__.py +8 -0
  24. snappy/dev/extended_ptolemy/closed.py +106 -0
  25. snappy/dev/extended_ptolemy/complexVolumesClosed.py +149 -0
  26. snappy/dev/extended_ptolemy/direct.py +42 -0
  27. snappy/dev/extended_ptolemy/extended.py +406 -0
  28. snappy/dev/extended_ptolemy/giac_helper.py +43 -0
  29. snappy/dev/extended_ptolemy/giac_rur.py +129 -0
  30. snappy/dev/extended_ptolemy/gluing.py +46 -0
  31. snappy/dev/extended_ptolemy/phc_wrapper.py +220 -0
  32. snappy/dev/extended_ptolemy/printMatrices.py +70 -0
  33. snappy/dev/vericlosed/__init__.py +1 -0
  34. snappy/dev/vericlosed/computeApproxHyperbolicStructureNew.py +159 -0
  35. snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +90 -0
  36. snappy/dev/vericlosed/computeVerifiedHyperbolicStructure.py +111 -0
  37. snappy/dev/vericlosed/gimbalLoopFinder.py +130 -0
  38. snappy/dev/vericlosed/hyperbolicStructure.py +313 -0
  39. snappy/dev/vericlosed/krawczykCertifiedEdgeLengthsEngine.py +165 -0
  40. snappy/dev/vericlosed/oneVertexTruncatedComplex.py +122 -0
  41. snappy/dev/vericlosed/orb/__init__.py +1 -0
  42. snappy/dev/vericlosed/orb/orb_solution_for_snappea_finite_triangulation_mac +0 -0
  43. snappy/dev/vericlosed/parseVertexGramMatrixFile.py +47 -0
  44. snappy/dev/vericlosed/polishApproxHyperbolicStructure.py +61 -0
  45. snappy/dev/vericlosed/test.py +54 -0
  46. snappy/dev/vericlosed/truncatedComplex.py +176 -0
  47. snappy/dev/vericlosed/verificationError.py +58 -0
  48. snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +177 -0
  49. snappy/doc/_images/SnapPy-196.png +0 -0
  50. snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
  51. snappy/doc/_images/m125_paper_plane.jpg +0 -0
  52. snappy/doc/_images/mac.png +0 -0
  53. snappy/doc/_images/o9_00000_systole_paper_plane.jpg +0 -0
  54. snappy/doc/_images/o9_00000_systole_paper_plane_closer.jpg +0 -0
  55. snappy/doc/_images/plink-action.png +0 -0
  56. snappy/doc/_images/ubuntu.png +0 -0
  57. snappy/doc/_images/win7.png +0 -0
  58. snappy/doc/_sources/additional_classes.rst.txt +40 -0
  59. snappy/doc/_sources/bugs.rst.txt +14 -0
  60. snappy/doc/_sources/censuses.rst.txt +52 -0
  61. snappy/doc/_sources/credits.rst.txt +81 -0
  62. snappy/doc/_sources/development.rst.txt +261 -0
  63. snappy/doc/_sources/index.rst.txt +215 -0
  64. snappy/doc/_sources/installing.rst.txt +249 -0
  65. snappy/doc/_sources/manifold.rst.txt +6 -0
  66. snappy/doc/_sources/manifoldhp.rst.txt +46 -0
  67. snappy/doc/_sources/news.rst.txt +425 -0
  68. snappy/doc/_sources/other.rst.txt +25 -0
  69. snappy/doc/_sources/platonic_census.rst.txt +20 -0
  70. snappy/doc/_sources/plink.rst.txt +102 -0
  71. snappy/doc/_sources/ptolemy.rst.txt +66 -0
  72. snappy/doc/_sources/ptolemy_classes.rst.txt +42 -0
  73. snappy/doc/_sources/ptolemy_examples1.rst.txt +298 -0
  74. snappy/doc/_sources/ptolemy_examples2.rst.txt +363 -0
  75. snappy/doc/_sources/ptolemy_examples3.rst.txt +301 -0
  76. snappy/doc/_sources/ptolemy_examples4.rst.txt +61 -0
  77. snappy/doc/_sources/ptolemy_prelim.rst.txt +105 -0
  78. snappy/doc/_sources/screenshots.rst.txt +21 -0
  79. snappy/doc/_sources/snap.rst.txt +87 -0
  80. snappy/doc/_sources/snappy.rst.txt +28 -0
  81. snappy/doc/_sources/spherogram.rst.txt +103 -0
  82. snappy/doc/_sources/todo.rst.txt +47 -0
  83. snappy/doc/_sources/triangulation.rst.txt +11 -0
  84. snappy/doc/_sources/tutorial.rst.txt +49 -0
  85. snappy/doc/_sources/verify.rst.txt +210 -0
  86. snappy/doc/_sources/verify_internals.rst.txt +79 -0
  87. snappy/doc/_static/SnapPy-horizontal-128.png +0 -0
  88. snappy/doc/_static/SnapPy.ico +0 -0
  89. snappy/doc/_static/_sphinx_javascript_frameworks_compat.js +123 -0
  90. snappy/doc/_static/basic.css +906 -0
  91. snappy/doc/_static/css/badge_only.css +1 -0
  92. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  93. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  94. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  95. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  96. snappy/doc/_static/css/fonts/fontawesome-webfont.eot +0 -0
  97. snappy/doc/_static/css/fonts/fontawesome-webfont.svg +2671 -0
  98. snappy/doc/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  99. snappy/doc/_static/css/fonts/fontawesome-webfont.woff +0 -0
  100. snappy/doc/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  101. snappy/doc/_static/css/fonts/lato-bold-italic.woff +0 -0
  102. snappy/doc/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  103. snappy/doc/_static/css/fonts/lato-bold.woff +0 -0
  104. snappy/doc/_static/css/fonts/lato-bold.woff2 +0 -0
  105. snappy/doc/_static/css/fonts/lato-normal-italic.woff +0 -0
  106. snappy/doc/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  107. snappy/doc/_static/css/fonts/lato-normal.woff +0 -0
  108. snappy/doc/_static/css/fonts/lato-normal.woff2 +0 -0
  109. snappy/doc/_static/css/theme.css +4 -0
  110. snappy/doc/_static/doctools.js +149 -0
  111. snappy/doc/_static/documentation_options.js +13 -0
  112. snappy/doc/_static/file.png +0 -0
  113. snappy/doc/_static/fonts/Lato/lato-bold.eot +0 -0
  114. snappy/doc/_static/fonts/Lato/lato-bold.ttf +0 -0
  115. snappy/doc/_static/fonts/Lato/lato-bold.woff +0 -0
  116. snappy/doc/_static/fonts/Lato/lato-bold.woff2 +0 -0
  117. snappy/doc/_static/fonts/Lato/lato-bolditalic.eot +0 -0
  118. snappy/doc/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
  119. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff +0 -0
  120. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
  121. snappy/doc/_static/fonts/Lato/lato-italic.eot +0 -0
  122. snappy/doc/_static/fonts/Lato/lato-italic.ttf +0 -0
  123. snappy/doc/_static/fonts/Lato/lato-italic.woff +0 -0
  124. snappy/doc/_static/fonts/Lato/lato-italic.woff2 +0 -0
  125. snappy/doc/_static/fonts/Lato/lato-regular.eot +0 -0
  126. snappy/doc/_static/fonts/Lato/lato-regular.ttf +0 -0
  127. snappy/doc/_static/fonts/Lato/lato-regular.woff +0 -0
  128. snappy/doc/_static/fonts/Lato/lato-regular.woff2 +0 -0
  129. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
  130. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
  131. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
  132. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
  133. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
  134. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
  135. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
  136. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
  137. snappy/doc/_static/jquery.js +2 -0
  138. snappy/doc/_static/js/badge_only.js +1 -0
  139. snappy/doc/_static/js/theme.js +1 -0
  140. snappy/doc/_static/js/versions.js +228 -0
  141. snappy/doc/_static/language_data.js +192 -0
  142. snappy/doc/_static/minus.png +0 -0
  143. snappy/doc/_static/plus.png +0 -0
  144. snappy/doc/_static/pygments.css +75 -0
  145. snappy/doc/_static/searchtools.js +635 -0
  146. snappy/doc/_static/snappy_furo.css +33 -0
  147. snappy/doc/_static/snappy_sphinx_rtd_theme.css +42 -0
  148. snappy/doc/_static/sphinx_highlight.js +154 -0
  149. snappy/doc/additional_classes.html +1500 -0
  150. snappy/doc/bugs.html +132 -0
  151. snappy/doc/censuses.html +453 -0
  152. snappy/doc/credits.html +184 -0
  153. snappy/doc/development.html +385 -0
  154. snappy/doc/doc-latest/additional_classes.html +1500 -0
  155. snappy/doc/doc-latest/bugs.html +132 -0
  156. snappy/doc/doc-latest/censuses.html +453 -0
  157. snappy/doc/doc-latest/credits.html +184 -0
  158. snappy/doc/doc-latest/development.html +385 -0
  159. snappy/doc/doc-latest/genindex.html +1349 -0
  160. snappy/doc/doc-latest/index.html +287 -0
  161. snappy/doc/doc-latest/installing.html +346 -0
  162. snappy/doc/doc-latest/manifold.html +3632 -0
  163. snappy/doc/doc-latest/manifoldhp.html +180 -0
  164. snappy/doc/doc-latest/news.html +438 -0
  165. snappy/doc/doc-latest/objects.inv +0 -0
  166. snappy/doc/doc-latest/other.html +160 -0
  167. snappy/doc/doc-latest/platonic_census.html +376 -0
  168. snappy/doc/doc-latest/plink.html +210 -0
  169. snappy/doc/doc-latest/ptolemy.html +253 -0
  170. snappy/doc/doc-latest/ptolemy_classes.html +1144 -0
  171. snappy/doc/doc-latest/ptolemy_examples1.html +409 -0
  172. snappy/doc/doc-latest/ptolemy_examples2.html +471 -0
  173. snappy/doc/doc-latest/ptolemy_examples3.html +414 -0
  174. snappy/doc/doc-latest/ptolemy_examples4.html +195 -0
  175. snappy/doc/doc-latest/ptolemy_prelim.html +248 -0
  176. snappy/doc/doc-latest/py-modindex.html +165 -0
  177. snappy/doc/doc-latest/screenshots.html +141 -0
  178. snappy/doc/doc-latest/search.html +135 -0
  179. snappy/doc/doc-latest/searchindex.js +1 -0
  180. snappy/doc/doc-latest/snap.html +202 -0
  181. snappy/doc/doc-latest/snappy.html +181 -0
  182. snappy/doc/doc-latest/spherogram.html +1346 -0
  183. snappy/doc/doc-latest/todo.html +166 -0
  184. snappy/doc/doc-latest/triangulation.html +1676 -0
  185. snappy/doc/doc-latest/tutorial.html +159 -0
  186. snappy/doc/doc-latest/verify.html +330 -0
  187. snappy/doc/doc-latest/verify_internals.html +1235 -0
  188. snappy/doc/genindex.html +1349 -0
  189. snappy/doc/index.html +287 -0
  190. snappy/doc/installing.html +346 -0
  191. snappy/doc/manifold.html +3632 -0
  192. snappy/doc/manifoldhp.html +180 -0
  193. snappy/doc/news.html +438 -0
  194. snappy/doc/objects.inv +0 -0
  195. snappy/doc/other.html +160 -0
  196. snappy/doc/platonic_census.html +376 -0
  197. snappy/doc/plink.html +210 -0
  198. snappy/doc/ptolemy.html +253 -0
  199. snappy/doc/ptolemy_classes.html +1144 -0
  200. snappy/doc/ptolemy_examples1.html +409 -0
  201. snappy/doc/ptolemy_examples2.html +471 -0
  202. snappy/doc/ptolemy_examples3.html +414 -0
  203. snappy/doc/ptolemy_examples4.html +195 -0
  204. snappy/doc/ptolemy_prelim.html +248 -0
  205. snappy/doc/py-modindex.html +165 -0
  206. snappy/doc/screenshots.html +141 -0
  207. snappy/doc/search.html +135 -0
  208. snappy/doc/searchindex.js +1 -0
  209. snappy/doc/snap.html +202 -0
  210. snappy/doc/snappy.html +181 -0
  211. snappy/doc/spherogram.html +1346 -0
  212. snappy/doc/todo.html +166 -0
  213. snappy/doc/triangulation.html +1676 -0
  214. snappy/doc/tutorial.html +159 -0
  215. snappy/doc/verify.html +330 -0
  216. snappy/doc/verify_internals.html +1235 -0
  217. snappy/drilling/__init__.py +456 -0
  218. snappy/drilling/barycentric.py +103 -0
  219. snappy/drilling/constants.py +5 -0
  220. snappy/drilling/crush.py +270 -0
  221. snappy/drilling/cusps.py +125 -0
  222. snappy/drilling/debug.py +242 -0
  223. snappy/drilling/epsilons.py +6 -0
  224. snappy/drilling/exceptions.py +55 -0
  225. snappy/drilling/moves.py +620 -0
  226. snappy/drilling/peripheral_curves.py +210 -0
  227. snappy/drilling/perturb.py +188 -0
  228. snappy/drilling/shorten.py +36 -0
  229. snappy/drilling/subdivide.py +274 -0
  230. snappy/drilling/test.py +23 -0
  231. snappy/drilling/test_cases.py +132 -0
  232. snappy/drilling/tracing.py +351 -0
  233. snappy/exceptions.py +26 -0
  234. snappy/export_stl.py +120 -0
  235. snappy/exterior_to_link/__init__.py +2 -0
  236. snappy/exterior_to_link/barycentric_geometry.py +463 -0
  237. snappy/exterior_to_link/exceptions.py +6 -0
  238. snappy/exterior_to_link/geodesic_map.json +14408 -0
  239. snappy/exterior_to_link/hyp_utils.py +112 -0
  240. snappy/exterior_to_link/link_projection.py +323 -0
  241. snappy/exterior_to_link/main.py +198 -0
  242. snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
  243. snappy/exterior_to_link/mcomplex_with_link.py +687 -0
  244. snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
  245. snappy/exterior_to_link/pl_utils.py +491 -0
  246. snappy/exterior_to_link/put_in_S3.py +156 -0
  247. snappy/exterior_to_link/rational_linear_algebra.py +130 -0
  248. snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
  249. snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
  250. snappy/exterior_to_link/stored_moves.py +475 -0
  251. snappy/exterior_to_link/test.py +31 -0
  252. snappy/filedialog.py +28 -0
  253. snappy/geometric_structure/__init__.py +212 -0
  254. snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
  255. snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +691 -0
  256. snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +480 -0
  257. snappy/geometric_structure/cusp_neighborhood/exceptions.py +41 -0
  258. snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +294 -0
  259. snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +156 -0
  260. snappy/geometric_structure/cusp_neighborhood/vertices.py +35 -0
  261. snappy/geometric_structure/geodesic/__init__.py +0 -0
  262. snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
  263. snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
  264. snappy/geometric_structure/geodesic/canonical_representatives.py +52 -0
  265. snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
  266. snappy/geometric_structure/geodesic/constants.py +6 -0
  267. snappy/geometric_structure/geodesic/exceptions.py +22 -0
  268. snappy/geometric_structure/geodesic/fixed_points.py +106 -0
  269. snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
  270. snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
  271. snappy/geometric_structure/geodesic/line.py +30 -0
  272. snappy/geometric_structure/geodesic/multiplicity.py +127 -0
  273. snappy/geometric_structure/geodesic/tiles_for_geodesic.py +128 -0
  274. snappy/geometric_structure/test.py +22 -0
  275. snappy/gui.py +121 -0
  276. snappy/horoviewer.py +443 -0
  277. snappy/hyperboloid/__init__.py +212 -0
  278. snappy/hyperboloid/distances.py +259 -0
  279. snappy/hyperboloid/horoball.py +19 -0
  280. snappy/hyperboloid/line.py +35 -0
  281. snappy/hyperboloid/point.py +9 -0
  282. snappy/hyperboloid/triangle.py +29 -0
  283. snappy/info_icon.gif +0 -0
  284. snappy/infowindow.py +65 -0
  285. snappy/isometry_signature.py +389 -0
  286. snappy/len_spec/__init__.py +609 -0
  287. snappy/len_spec/geodesic_info.py +129 -0
  288. snappy/len_spec/geodesic_key_info_dict.py +116 -0
  289. snappy/len_spec/geodesic_piece.py +146 -0
  290. snappy/len_spec/geometric_structure.py +182 -0
  291. snappy/len_spec/geometry.py +136 -0
  292. snappy/len_spec/length_spectrum_geodesic_info.py +185 -0
  293. snappy/len_spec/spine.py +128 -0
  294. snappy/len_spec/test.py +24 -0
  295. snappy/len_spec/test_cases.py +69 -0
  296. snappy/len_spec/tile.py +276 -0
  297. snappy/len_spec/word.py +86 -0
  298. snappy/manifolds/HTWKnots/alternating.gz +0 -0
  299. snappy/manifolds/HTWKnots/nonalternating.gz +0 -0
  300. snappy/manifolds/__init__.py +3 -0
  301. snappy/margulis/__init__.py +332 -0
  302. snappy/margulis/cusp_neighborhood_neighborhood.py +66 -0
  303. snappy/margulis/geodesic_neighborhood.py +152 -0
  304. snappy/margulis/margulis_info.py +21 -0
  305. snappy/margulis/mu_from_neighborhood_pair.py +175 -0
  306. snappy/margulis/neighborhood.py +29 -0
  307. snappy/margulis/test.py +22 -0
  308. snappy/math_basics.py +187 -0
  309. snappy/matrix.py +525 -0
  310. snappy/number.py +657 -0
  311. snappy/numeric_output_checker.py +345 -0
  312. snappy/pari.py +41 -0
  313. snappy/phone_home.py +57 -0
  314. snappy/polyviewer.py +259 -0
  315. snappy/ptolemy/__init__.py +17 -0
  316. snappy/ptolemy/component.py +103 -0
  317. snappy/ptolemy/coordinates.py +2290 -0
  318. snappy/ptolemy/fieldExtensions.py +153 -0
  319. snappy/ptolemy/findLoops.py +473 -0
  320. snappy/ptolemy/geometricRep.py +59 -0
  321. snappy/ptolemy/homology.py +165 -0
  322. snappy/ptolemy/magma/default.magma_template +229 -0
  323. snappy/ptolemy/magma/radicalsOfPrimaryDecomposition.magma_template +79 -0
  324. snappy/ptolemy/manifoldMethods.py +395 -0
  325. snappy/ptolemy/matrix.py +350 -0
  326. snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +113 -0
  327. snappy/ptolemy/polynomial.py +856 -0
  328. snappy/ptolemy/processComponents.py +173 -0
  329. snappy/ptolemy/processFileBase.py +247 -0
  330. snappy/ptolemy/processFileDispatch.py +46 -0
  331. snappy/ptolemy/processMagmaFile.py +392 -0
  332. snappy/ptolemy/processRurFile.py +150 -0
  333. snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +102 -0
  334. snappy/ptolemy/ptolemyObstructionClass.py +64 -0
  335. snappy/ptolemy/ptolemyVariety.py +995 -0
  336. snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +140 -0
  337. snappy/ptolemy/reginaWrapper.py +698 -0
  338. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  339. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  340. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  341. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  342. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  343. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  344. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  345. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  346. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  347. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  348. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c0.magma_out.bz2 +0 -0
  349. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  350. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  351. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c1.magma_out.bz2 +0 -0
  352. snappy/ptolemy/rur.py +545 -0
  353. snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +277 -0
  354. snappy/ptolemy/test.py +1126 -0
  355. snappy/ptolemy/testing_files/3_1__sl2_c0.magma_out.bz2 +0 -0
  356. snappy/ptolemy/testing_files/3_1__sl2_c1.magma_out.bz2 +0 -0
  357. snappy/ptolemy/testing_files/4_1__sl2_c0.magma_out.bz2 +0 -0
  358. snappy/ptolemy/testing_files/4_1__sl2_c1.magma_out.bz2 +0 -0
  359. snappy/ptolemy/testing_files/4_1__sl3_c0.magma_out.bz2 +0 -0
  360. snappy/ptolemy/testing_files/4_1__sl4_c0.magma_out.bz2 +0 -0
  361. snappy/ptolemy/testing_files/4_1__sl4_c1.magma_out.bz2 +0 -0
  362. snappy/ptolemy/testing_files/5_2__sl2_c0.magma_out.bz2 +0 -0
  363. snappy/ptolemy/testing_files/5_2__sl2_c1.magma_out.bz2 +0 -0
  364. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  365. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  366. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  367. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  368. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  369. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  370. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  371. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  372. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c0.magma_out +95 -0
  373. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c1.magma_out +95 -0
  374. snappy/ptolemy/testing_files/m015__sl3_c0.magma_out.bz2 +0 -0
  375. snappy/ptolemy/testing_files/m135__sl2_c0.magma_out.bz2 +0 -0
  376. snappy/ptolemy/testing_files/m135__sl2_c1.magma_out.bz2 +0 -0
  377. snappy/ptolemy/testing_files/m135__sl2_c2.magma_out.bz2 +0 -0
  378. snappy/ptolemy/testing_files/m135__sl2_c3.magma_out.bz2 +0 -0
  379. snappy/ptolemy/testing_files/m135__sl2_c4.magma_out.bz2 +0 -0
  380. snappy/ptolemy/testing_files/m135__sl2_c5.magma_out.bz2 +0 -0
  381. snappy/ptolemy/testing_files/m135__sl2_c6.magma_out.bz2 +0 -0
  382. snappy/ptolemy/testing_files/m135__sl2_c7.magma_out.bz2 +0 -0
  383. snappy/ptolemy/testing_files/s000__sl2_c0.magma_out.bz2 +0 -0
  384. snappy/ptolemy/testing_files/s000__sl2_c1.magma_out.bz2 +0 -0
  385. snappy/ptolemy/testing_files/t00000__sl2_c0.magma_out.bz2 +0 -0
  386. snappy/ptolemy/testing_files/t00000__sl2_c1.magma_out.bz2 +0 -0
  387. snappy/ptolemy/testing_files/v0000__sl2_c0.magma_out.bz2 +0 -0
  388. snappy/ptolemy/testing_files/v0000__sl2_c1.magma_out.bz2 +0 -0
  389. snappy/ptolemy/testing_files/v0000__sl2_c2.magma_out.bz2 +0 -0
  390. snappy/ptolemy/testing_files/v0000__sl2_c3.magma_out.bz2 +0 -0
  391. snappy/ptolemy/testing_files_generalized/m003__sl2_c0.magma_out.bz2 +0 -0
  392. snappy/ptolemy/testing_files_generalized/m003__sl2_c1.magma_out.bz2 +0 -0
  393. snappy/ptolemy/testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  394. snappy/ptolemy/testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  395. snappy/ptolemy/testing_files_generalized/m004__sl2_c0.magma_out.bz2 +0 -0
  396. snappy/ptolemy/testing_files_generalized/m004__sl2_c1.magma_out.bz2 +0 -0
  397. snappy/ptolemy/testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  398. snappy/ptolemy/testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  399. snappy/ptolemy/testing_files_rur/m052__sl3_c0.rur.bz2 +0 -0
  400. snappy/ptolemy/utilities.py +236 -0
  401. snappy/raytracing/__init__.py +64 -0
  402. snappy/raytracing/additional_horospheres.py +64 -0
  403. snappy/raytracing/additional_len_spec_choices.py +63 -0
  404. snappy/raytracing/cohomology_fractal.py +197 -0
  405. snappy/raytracing/eyeball.py +124 -0
  406. snappy/raytracing/finite_raytracing_data.py +237 -0
  407. snappy/raytracing/finite_viewer.py +590 -0
  408. snappy/raytracing/geodesic_tube_info.py +174 -0
  409. snappy/raytracing/geodesics.py +246 -0
  410. snappy/raytracing/geodesics_window.py +258 -0
  411. snappy/raytracing/gui_utilities.py +293 -0
  412. snappy/raytracing/hyperboloid_navigation.py +556 -0
  413. snappy/raytracing/hyperboloid_utilities.py +234 -0
  414. snappy/raytracing/ideal_raytracing_data.py +592 -0
  415. snappy/raytracing/inside_viewer.py +974 -0
  416. snappy/raytracing/pack.py +22 -0
  417. snappy/raytracing/raytracing_data.py +126 -0
  418. snappy/raytracing/raytracing_view.py +454 -0
  419. snappy/raytracing/shaders/Eye.png +0 -0
  420. snappy/raytracing/shaders/NonGeometric.png +0 -0
  421. snappy/raytracing/shaders/__init__.py +101 -0
  422. snappy/raytracing/shaders/fragment.glsl +1744 -0
  423. snappy/raytracing/test.py +29 -0
  424. snappy/raytracing/tooltip.py +146 -0
  425. snappy/raytracing/upper_halfspace_utilities.py +98 -0
  426. snappy/raytracing/view_scale_controller.py +98 -0
  427. snappy/raytracing/zoom_slider/__init__.py +263 -0
  428. snappy/raytracing/zoom_slider/inward.png +0 -0
  429. snappy/raytracing/zoom_slider/inward18.png +0 -0
  430. snappy/raytracing/zoom_slider/outward.png +0 -0
  431. snappy/raytracing/zoom_slider/outward18.png +0 -0
  432. snappy/raytracing/zoom_slider/test.py +20 -0
  433. snappy/sage_helper.py +119 -0
  434. snappy/settings.py +407 -0
  435. snappy/shell.py +53 -0
  436. snappy/snap/__init__.py +117 -0
  437. snappy/snap/character_varieties.py +375 -0
  438. snappy/snap/find_field.py +372 -0
  439. snappy/snap/fox_milnor.py +271 -0
  440. snappy/snap/fundamental_polyhedron.py +569 -0
  441. snappy/snap/generators.py +39 -0
  442. snappy/snap/interval_reps.py +81 -0
  443. snappy/snap/kernel_structures.py +128 -0
  444. snappy/snap/mcomplex_base.py +18 -0
  445. snappy/snap/nsagetools.py +716 -0
  446. snappy/snap/peripheral/__init__.py +1 -0
  447. snappy/snap/peripheral/dual_cellulation.py +219 -0
  448. snappy/snap/peripheral/link.py +127 -0
  449. snappy/snap/peripheral/peripheral.py +159 -0
  450. snappy/snap/peripheral/surface.py +522 -0
  451. snappy/snap/peripheral/test.py +35 -0
  452. snappy/snap/polished_reps.py +335 -0
  453. snappy/snap/shapes.py +152 -0
  454. snappy/snap/slice_obs_HKL/__init__.py +194 -0
  455. snappy/snap/slice_obs_HKL/basics.py +236 -0
  456. snappy/snap/slice_obs_HKL/direct.py +217 -0
  457. snappy/snap/slice_obs_HKL/poly_norm.py +212 -0
  458. snappy/snap/slice_obs_HKL/rep_theory.py +424 -0
  459. snappy/snap/t3mlite/__init__.py +2 -0
  460. snappy/snap/t3mlite/arrow.py +243 -0
  461. snappy/snap/t3mlite/corner.py +22 -0
  462. snappy/snap/t3mlite/edge.py +172 -0
  463. snappy/snap/t3mlite/face.py +37 -0
  464. snappy/snap/t3mlite/files.py +211 -0
  465. snappy/snap/t3mlite/homology.py +53 -0
  466. snappy/snap/t3mlite/linalg.py +419 -0
  467. snappy/snap/t3mlite/mcomplex.py +1499 -0
  468. snappy/snap/t3mlite/perm4.py +320 -0
  469. snappy/snap/t3mlite/setup.py +12 -0
  470. snappy/snap/t3mlite/simplex.py +199 -0
  471. snappy/snap/t3mlite/spun.py +297 -0
  472. snappy/snap/t3mlite/surface.py +519 -0
  473. snappy/snap/t3mlite/test.py +20 -0
  474. snappy/snap/t3mlite/test_vs_regina.py +86 -0
  475. snappy/snap/t3mlite/tetrahedron.py +109 -0
  476. snappy/snap/t3mlite/vertex.py +42 -0
  477. snappy/snap/test.py +139 -0
  478. snappy/snap/utilities.py +288 -0
  479. snappy/test.py +213 -0
  480. snappy/test_cases.py +263 -0
  481. snappy/testing.py +131 -0
  482. snappy/tiling/__init__.py +2 -0
  483. snappy/tiling/dict_based_set.py +79 -0
  484. snappy/tiling/floor.py +49 -0
  485. snappy/tiling/hyperboloid_dict.py +54 -0
  486. snappy/tiling/iter_utils.py +78 -0
  487. snappy/tiling/lifted_tetrahedron.py +22 -0
  488. snappy/tiling/lifted_tetrahedron_set.py +54 -0
  489. snappy/tiling/quotient_dict.py +70 -0
  490. snappy/tiling/real_hash_dict.py +164 -0
  491. snappy/tiling/test.py +23 -0
  492. snappy/tiling/tile.py +224 -0
  493. snappy/tiling/triangle.py +33 -0
  494. snappy/tkterminal.py +920 -0
  495. snappy/twister/__init__.py +20 -0
  496. snappy/twister/main.py +646 -0
  497. snappy/twister/surfaces/S_0_1 +3 -0
  498. snappy/twister/surfaces/S_0_2 +3 -0
  499. snappy/twister/surfaces/S_0_4 +7 -0
  500. snappy/twister/surfaces/S_0_4_Lantern +8 -0
  501. snappy/twister/surfaces/S_1 +3 -0
  502. snappy/twister/surfaces/S_1_1 +4 -0
  503. snappy/twister/surfaces/S_1_2 +5 -0
  504. snappy/twister/surfaces/S_1_2_5 +6 -0
  505. snappy/twister/surfaces/S_2 +6 -0
  506. snappy/twister/surfaces/S_2_1 +8 -0
  507. snappy/twister/surfaces/S_2_heeg +10 -0
  508. snappy/twister/surfaces/S_3 +8 -0
  509. snappy/twister/surfaces/S_3_1 +10 -0
  510. snappy/twister/surfaces/S_4_1 +12 -0
  511. snappy/twister/surfaces/S_5_1 +14 -0
  512. snappy/twister/surfaces/heeg_fig8 +9 -0
  513. snappy/twister/twister_core.cpython-310-aarch64-linux-gnu.so +0 -0
  514. snappy/upper_halfspace/__init__.py +146 -0
  515. snappy/upper_halfspace/ideal_point.py +29 -0
  516. snappy/verify/__init__.py +13 -0
  517. snappy/verify/canonical.py +542 -0
  518. snappy/verify/complex_volume/__init__.py +18 -0
  519. snappy/verify/complex_volume/adjust_torsion.py +86 -0
  520. snappy/verify/complex_volume/closed.py +168 -0
  521. snappy/verify/complex_volume/compute_ptolemys.py +90 -0
  522. snappy/verify/complex_volume/cusped.py +56 -0
  523. snappy/verify/complex_volume/extended_bloch.py +201 -0
  524. snappy/verify/cusp_translations.py +85 -0
  525. snappy/verify/edge_equations.py +80 -0
  526. snappy/verify/exceptions.py +254 -0
  527. snappy/verify/hyperbolicity.py +224 -0
  528. snappy/verify/interval_newton_shapes_engine.py +523 -0
  529. snappy/verify/interval_tree.py +400 -0
  530. snappy/verify/krawczyk_shapes_engine.py +518 -0
  531. snappy/verify/real_algebra.py +286 -0
  532. snappy/verify/shapes.py +25 -0
  533. snappy/verify/square_extensions.py +1005 -0
  534. snappy/verify/test.py +72 -0
  535. snappy/verify/volume.py +128 -0
  536. snappy/version.py +2 -0
  537. snappy-3.3.dist-info/METADATA +58 -0
  538. snappy-3.3.dist-info/RECORD +541 -0
  539. snappy-3.3.dist-info/WHEEL +6 -0
  540. snappy-3.3.dist-info/entry_points.txt +2 -0
  541. snappy-3.3.dist-info/top_level.txt +28 -0
@@ -0,0 +1,162 @@
1
+ from ..snap.t3mlite.simplex import *
2
+ from ..snap.t3mlite.edge import Edge
3
+ from ..snap.t3mlite.arrow import Arrow
4
+ from ..snap.t3mlite.mcomplex import Mcomplex, VERBOSE, edge_and_arrow
5
+ from ..snap.t3mlite.tetrahedron import Tetrahedron
6
+
7
+
8
+ class McomplexWithMemory(Mcomplex):
9
+ """
10
+ A version of Mcomplex which remembers what Pachner moves have been
11
+ performed. Also, Pachner moves have additional options over the
12
+ standard Mcomplex.
13
+
14
+ >>> M = McomplexWithMemory('dLQabccbcbv') # S^3
15
+ >>> M.two_to_three(F0, M[0], must_succeed=True)
16
+ True
17
+ >>> assert M.eliminate_valence_three()
18
+ >>> M.move_memory
19
+ [('two_to_three', 6, 14, 0), ('three_to_two', 3, 7, 1)]
20
+ >>> a = M.Edges[1].get_arrow()
21
+ >>> assert M.zero_to_two(a, 4)
22
+ >>> assert M.eliminate_valence_two()
23
+ >>> M.move_memory[2:]
24
+ [('zero_to_two', 3, 7, 0, 4), ('two_to_zero', 3, 7, 3)]
25
+
26
+
27
+ >>> N = McomplexWithMemory('o9_24662')
28
+ >>> iso = N.isosig()
29
+ >>> e = [e for e in N.Edges if e.valence() == 4 and e.distinct()][0]
30
+ >>> a = e.get_arrow(); a
31
+ < E01 | F2 | tet2 >
32
+ >>> assert N.four_to_four(a)
33
+ >>> N.move_memory
34
+ [('four_to_four', 3, 11, 2)]
35
+ >>> N.rebuild(); N.isosig() != iso
36
+ True
37
+ >>> while len(N.move_memory) < 100:
38
+ ... size = N.randomize()
39
+ >>> target = N.isosig()
40
+ >>> X = McomplexWithMemory('o9_24662')
41
+ >>> X.perform_moves(N.move_memory)
42
+ >>> assert X.isosig() == target
43
+ >>> X.name
44
+ 'o9_24662'
45
+ """
46
+ def __init__(self, tetrahedron_list=None, two_zero_to_one_tet=True,
47
+ invariant_tetrahedra=None):
48
+ if isinstance(tetrahedron_list, str):
49
+ self.name = tetrahedron_list
50
+ Mcomplex.__init__(self, tetrahedron_list)
51
+ self.two_zero_to_one_tet = two_zero_to_one_tet
52
+ if invariant_tetrahedra is None:
53
+ invariant_tetrahedra = []
54
+ self.invariant_tetrahedra = invariant_tetrahedra
55
+ self.move_memory = []
56
+
57
+ def _add_to_move_memory(self, move, arrow):
58
+ if hasattr(self, 'move_memory'):
59
+ T = arrow.Tetrahedron
60
+ tet_index = self.Tetrahedra.index(T)
61
+ self.move_memory.append((move, arrow.Edge, arrow.Face, tet_index))
62
+
63
+ def _relabel_tetrahedra(self):
64
+ for i, tet in enumerate(self):
65
+ tet.Index = i
66
+
67
+ def perform_moves(self, moves, tet_stop_num=0):
68
+ """
69
+ Assumes that three_to_two, two_to_three, etc. only rebuild the
70
+ edge classes after each move and that they accept arrows as
71
+ spec for the moves.
72
+ """
73
+ t = 0
74
+ for move, edge, face, tet_index in moves:
75
+ if len(self) <= tet_stop_num:
76
+ break
77
+ t = t+1
78
+ arrow = Arrow(edge, face, self[tet_index])
79
+ move_fn = getattr(self, move)
80
+ move_fn(arrow, must_succeed=True)
81
+ self._relabel_tetrahedra()
82
+ self.rebuild()
83
+
84
+ def _face_permits_two_to_three(self, a, b):
85
+ possible, reason = Mcomplex._face_permits_two_to_three(self, a, b)
86
+ if possible:
87
+ S, T = a.Tetrahedron, b.Tetrahedron
88
+ if (S in self.invariant_tetrahedra or T in self.invariant_tetrahedra):
89
+ return False, 'Move would effect invariant tets'
90
+ return possible, reason
91
+
92
+ def _two_to_three_move_hook(self, old_arrow, new_arrows):
93
+ self._add_to_move_memory('two_to_three', old_arrow)
94
+
95
+ def _edge_permits_three_to_two(self, edge):
96
+ possible, reason = Mcomplex._edge_permits_three_to_two(self, edge)
97
+ if possible:
98
+ if any(corner.Tetrahedron in self.invariant_tetrahedra
99
+ for corner in edge.Corners):
100
+ return False, 'Edge adjacent to fixed subcomplex'
101
+ return possible, reason
102
+
103
+ def _three_to_two_move_hook(self, old_arrow, new_arrows):
104
+ self._add_to_move_memory('three_to_two', old_arrow)
105
+
106
+ def _arrow_permits_two_to_zero(self, arrow):
107
+ possible, reason = Mcomplex._arrow_permits_two_to_zero(self, arrow)
108
+ if possible:
109
+ if len(self) == 3 and not self.two_zero_to_one_tet:
110
+ return False, '2->0 move to 1 tet manifold has been blocked'
111
+ if any(corner.Tetrahedron in self.invariant_tetrahedra
112
+ for corner in arrow.axis().Corners):
113
+ return False, 'Edge adjacent to fixed subcomplex'
114
+ return possible, reason
115
+
116
+ def _two_to_zero_hook(self, old_arrow):
117
+ self._add_to_move_memory('two_to_zero', old_arrow)
118
+
119
+ def zero_to_two(self, arrow, gap):
120
+ success = Mcomplex.zero_to_two(self, arrow, gap)
121
+ if success and hasattr(self, 'move_memory'):
122
+ T = arrow.Tetrahedron
123
+ tet_index = self.Tetrahedra.index(T)
124
+ self.move_memory.append(
125
+ ('zero_to_two', arrow.Edge, arrow.Face, tet_index, gap))
126
+ return success
127
+
128
+ def _edge_permits_four_to_four(self, edge):
129
+ possible, reason = Mcomplex._edge_permits_four_to_four(self, edge)
130
+ if possible:
131
+ if any(corner.Tetrahedron in self.invariant_tetrahedra
132
+ for corner in edge.Corners):
133
+ return False, 'Edge adjacent to fixed subcomplex'
134
+ return possible, reason
135
+
136
+ def _four_to_four_move_hook(self, old_arrow, new_arrows):
137
+ self._add_to_move_memory('four_to_four', old_arrow)
138
+
139
+ def easy_simplify(self):
140
+ """
141
+ >>> M = McomplexWithMemory('zLALvwvMwLzzAQPQQkbcbeijmoomvwuvust'
142
+ ... 'wwytxtyxyahkswpmakguadppmrssxbkoxsi')
143
+ >>> N = M.copy()
144
+ >>> M.easy_simplify()
145
+ True
146
+ >>> len(M), len(M.move_memory)
147
+ (1, 25)
148
+ >>> M.rebuild(); M.isosig()
149
+ 'bkaagj'
150
+
151
+ >>> N.invariant_tetrahedra = [N[1]] # core solid torus
152
+ >>> N.easy_simplify()
153
+ True
154
+ >>> len(N), len(N.move_memory)
155
+ (15, 9)
156
+ """
157
+ return Mcomplex.easy_simplify(self)
158
+
159
+
160
+ if __name__ == '__main__':
161
+ import doctest
162
+ print(doctest.testmod())
@@ -0,0 +1,491 @@
1
+ """
2
+ The basic computation geometry predicates for points and segments in
3
+ QQ^2 and QQ^3 that needed for PL links.
4
+
5
+ The only nonstandard one is `can_straighten_bend`.
6
+ """
7
+ from .rational_linear_algebra import Matrix, Vector2, Vector3, QQ, rational_sqrt
8
+
9
+
10
+ def min_support(v):
11
+ """
12
+ >>> min_support(Vector3([0, 0, -1]))
13
+ 2
14
+ """
15
+ for i, e in enumerate(v):
16
+ if e != 0:
17
+ return i
18
+ raise ValueError('Vector is 0')
19
+
20
+
21
+ def cross_product(a, b):
22
+ return Vector3([a[1]*b[2] - a[2]*b[1], a[2]*b[0] - a[0]*b[2], a[0]*b[1] - a[1]*b[0]])
23
+
24
+
25
+ def coplanar(a, b, c, d):
26
+ """
27
+ >>> vecs = Matrix([(1, 0, 1), (-1, 0, 2), (0, 1, 0), (1, 3, 0)])
28
+ >>> coplanar(*vecs.rows())
29
+ False
30
+ >>> coplanar(vecs[0], vecs[1], vecs[2], vecs[0])
31
+ True
32
+ """
33
+ return Matrix([b - a, c - a, d - a]).det() == 0
34
+
35
+
36
+ def are_parallel(u, v):
37
+ """
38
+ >>> a = Vector3([1, 0, 0])
39
+ >>> b = Vector3([1, 1, 1])
40
+ >>> are_parallel(a, b)
41
+ False
42
+ >>> are_parallel(a, 2*a)
43
+ True
44
+ """
45
+ if u == 0 or v == 0:
46
+ return True
47
+ i = min_support(u)
48
+ if v[i] == 0:
49
+ return False
50
+ return u/u[i] == v/v[i]
51
+
52
+
53
+ def colinear(u, v, w):
54
+ return are_parallel(v - u, w - u)
55
+
56
+
57
+ def find_convex_combination(a, b, u):
58
+ """
59
+ >>> p = Vector2([0, 1])
60
+ >>> q = Vector2([1, 0])
61
+ >>> t = QQ(1)/5
62
+
63
+ This next awkward cast is required when using the PARI kernel
64
+ because of the permissive behavior of Gen.__mul__.
65
+
66
+ >>> r = Vector2((1 - t)*p + t*q)
67
+ >>> find_convex_combination(p, q, r)
68
+ 1/5
69
+ >>> find_convex_combination(p, 3*p, 2*p)
70
+ 1/2
71
+ """
72
+ if a == b:
73
+ raise ValueError('Segment is degenerate')
74
+ v, w = b - a, u - a
75
+ if not are_parallel(v, w):
76
+ raise ValueError('Point not on line')
77
+ i = min_support(v)
78
+ t = w[i]/v[i]
79
+ assert (1 - t)*a + t*b == u
80
+ return t
81
+
82
+
83
+ def point_meets_interior_of_segment(u, ab):
84
+ """
85
+ >>> p = Vector3([1, 1, 0])
86
+ >>> q = Vector3([3, -1,0])
87
+ >>> a = Vector3([2, 0, 0])
88
+ >>> b = Vector3([0, 2, 0])
89
+ >>> c = Vector3([1, 0, 0])
90
+ >>> o = Vector3([0, 0, 0])
91
+ >>> point_meets_interior_of_segment(p, (a, b))
92
+ True
93
+ >>> point_meets_interior_of_segment(q, (a, b))
94
+ False
95
+ >>> point_meets_interior_of_segment(p, (b, c))
96
+ False
97
+ >>> point_meets_interior_of_segment(2*a/3, (a, c))
98
+ True
99
+ >>> point_meets_interior_of_segment(o, (a, b))
100
+ False
101
+ """
102
+ a, b = ab
103
+ if a == b:
104
+ raise ValueError('Segment is degenerate')
105
+ if not are_parallel(b - a, u - a):
106
+ return False
107
+ t = find_convex_combination(a, b, u)
108
+ return 0 < t < 1
109
+
110
+
111
+ def is_pointy(a, b, c, threshold=QQ('3/4')):
112
+ """
113
+ Whether the angle (a, b, c) is less than pi/6. This function is
114
+ not currently used by anything.
115
+
116
+ >>> p = Vector3([ 0, 0, 1])
117
+ >>> q = Vector3([10, 0, 1])
118
+ >>> r = Vector3([0, 10, 1])
119
+ >>> s = Vector3([9, 1, 1])
120
+ >>> t = Vector3([-9, 1, 1])
121
+ >>> is_pointy(t, p, q)
122
+ False
123
+ >>> is_pointy(q, p, r)
124
+ False
125
+ >>> is_pointy(p, q, r)
126
+ False
127
+ >>> is_pointy(s, p, q)
128
+ True
129
+ >>> is_pointy(q, p, q)
130
+ True
131
+ """
132
+ v = a - b
133
+ w = c - b
134
+ dot = v*w
135
+ if dot <= 0:
136
+ return False
137
+ norms = (v*v)*(w*w)
138
+ return dot**2/norms >= threshold
139
+
140
+
141
+ def segments_meet_not_at_endpoint(ab, uv):
142
+ """
143
+ Does the interior of either segment meet any point of the other
144
+ one?
145
+
146
+ >>> p = Vector3([1, 1, 0])
147
+ >>> q = Vector3([3, -1,0])
148
+ >>> a = Vector3([2, 0, 0])
149
+ >>> b = Vector3([0, 2, 0])
150
+ >>> c = Vector3([1, 0, 0])
151
+ >>> o = Vector3([0, 0, 0])
152
+ >>> segments_meet_not_at_endpoint((p, 2*p), (2*p, 3*p))
153
+ False
154
+ >>> segments_meet_not_at_endpoint((p, 3*p), (2*p, 4*p))
155
+ True
156
+ >>> segments_meet_not_at_endpoint((p, 2*p), (3*p, q))
157
+ False
158
+ >>> segments_meet_not_at_endpoint((p, 3*p), (2*p, q))
159
+ True
160
+ >>> segments_meet_not_at_endpoint((-a, a), (b + c, -b + c))
161
+ True
162
+ >>> segments_meet_not_at_endpoint((-a, a), (a, -b + c))
163
+ False
164
+ >>> segments_meet_not_at_endpoint((o, a), (-p, p))
165
+ True
166
+ >>> segments_meet_not_at_endpoint((-p + q, p + q), (-a + q, a + q))
167
+ True
168
+
169
+ >>> b, c = Vector3([0, 0, 1]), Vector3([0, 1, 0])
170
+ >>> u, v = Vector3([-1, 0, 1]), Vector3([-1, 1, 2])/3
171
+ >>> segments_meet_not_at_endpoint((b, c), (u, v))
172
+ False
173
+ """
174
+ a, b = ab
175
+ u, v = uv
176
+ if a == b or u == v:
177
+ raise ValueError('Segment has no interior')
178
+ if not coplanar(a, b, u, v):
179
+ return False
180
+
181
+ # All four points lie in a common plane, first consider cases
182
+ # where (a, b, u) are colinear.
183
+ if colinear(a, b, u):
184
+ if colinear(a, b, v):
185
+ s = find_convex_combination(a, b, u)
186
+ t = find_convex_combination(a, b, v)
187
+ if s > t:
188
+ s, t = t, s
189
+ return not (t <= 0 or s >= 1)
190
+ else:
191
+ return point_meets_interior_of_segment(u, (a, b))
192
+ else:
193
+ if are_parallel(b - a, v - u):
194
+ # Since (a, b, u) are not colinear, these parallel lines
195
+ # are disjoint.
196
+ return False
197
+
198
+ # The lines containing ab and uv will meet in a unique point,
199
+ # so write it in terms of standard coordinates on the lines
200
+ # through (a, b) and (u, v).
201
+ M = Matrix([b - a, u - v]).transpose()
202
+ s, t = M.solve_right(u - a)
203
+
204
+ return ((0 < s < 1) and (0 <= t <= 1)) or ((0 <= s <= 1) and (0 < t < 1))
205
+
206
+
207
+ def standardize_bend_matrix(a, b, c):
208
+ a, c = a - b, c - b
209
+ n = cross_product(a, c)
210
+ M = Matrix([a, c, n]).transpose().inverse()
211
+ return M
212
+
213
+
214
+ def can_straighten_bend(arc, bend, check_embedded=True, bend_matrix=None):
215
+ """
216
+ Given a "bend" of three points (a, b, c) and an arc (u, v)
217
+ determine if we can isotope the PL arc (a, b, c) to (a, c) along
218
+ the triangle (a, b, c) without passing through (u, v).
219
+
220
+ >>> a = Vector3([-1, 0, 1])
221
+ >>> b = Vector3([ 0, 0, 1])
222
+ >>> c = Vector3([ 0, 1, 0])
223
+ >>> o = Vector3([ 0, 0, 0])
224
+ >>> u = Vector3([-1, 2, 1])
225
+ >>> can_straighten_bend((o, -a), (a, b, c))
226
+ True
227
+ >>> can_straighten_bend((o, c), (a, 2*a, 3*a))
228
+ True
229
+ >>> can_straighten_bend((o, c), (a, b, c))
230
+ True
231
+ >>> can_straighten_bend((a, (a + b + c)/3), (a, b, c))
232
+ False
233
+ >>> can_straighten_bend((c, (a + c)/2), (a, b, c))
234
+ False
235
+ >>> can_straighten_bend((c, a), (a, b, c))
236
+ False
237
+ >>> can_straighten_bend((o, u), (a, b, c))
238
+ False
239
+ >>> can_straighten_bend((a + b, a + c), (a, b, c))
240
+ True
241
+ >>> can_straighten_bend((o, a + c), (a, b, c))
242
+ False
243
+ >>> can_straighten_bend((a, c - b), (a, b, c))
244
+ True
245
+ >>> M = standardize_bend_matrix(a, b, c); M.det()
246
+ 1/2
247
+ >>> can_straighten_bend((o, -a), (a, b, c), bend_matrix=M)
248
+ True
249
+ """
250
+ u, v = arc
251
+ a, b, c = bend
252
+ if hasattr(u, 'to_3d_point'):
253
+ u, v = u.to_3d_point(), v.to_3d_point()
254
+ a, b, c = a.to_3d_point(), b.to_3d_point(), c.to_3d_point()
255
+
256
+ if u == v or a == b or a == c or b == c:
257
+ raise ValueError('Input includes 0 length segments')
258
+
259
+ if check_embedded:
260
+ if (segments_meet_not_at_endpoint((a, b), (b, c)) or
261
+ segments_meet_not_at_endpoint((a, b), (u, v)) or
262
+ segments_meet_not_at_endpoint((b, c), (u, v)) or
263
+ point_meets_interior_of_segment(b, (u, v)) or
264
+ u == b or v == b):
265
+ raise ValueError('Input not embedded')
266
+
267
+ # Some quick tests to see if the arc is far from the bend
268
+ for i in range(3):
269
+ arc_cor = (u[i], v[i])
270
+ bend_cor = (a[i], b[i], c[i])
271
+ if max(arc_cor) < min(bend_cor) or min(arc_cor) > max(bend_cor):
272
+ return True
273
+
274
+ if colinear(a, b, c):
275
+ return True
276
+ # translate b to 0 and transform so a and c are e0 and 1:
277
+ if bend_matrix is None:
278
+ bend_matrix = standardize_bend_matrix(a, b, c)
279
+ a, c = Vector3([1, 0, 0]), Vector3([0, 1, 0])
280
+ u, v = bend_matrix*(u - b), bend_matrix*(v - b)
281
+
282
+ # If both u and v strictly to the same side of the plane
283
+ # containing the bend, then done.
284
+ if u[2] * v[2] > 0:
285
+ return True
286
+
287
+ if u[2] == v[2] == 0:
288
+ # The whole arc is in the plane, and we know it is disjoint
289
+ # from the bend except possibly at the endpoints.
290
+ #
291
+ # First check if this is a closed cycle.
292
+ if (u == a and v == c) or (u == c and v == a):
293
+ return False
294
+ # Check if the points are in this 2/3-open triangle.
295
+ u_in_tri = u[0] > 0 and u[1] > 0 and u[0] + u[1] <= 1
296
+ v_in_tri = v[0] > 0 and v[1] > 0 and v[0] + v[1] <= 1
297
+ return not (u_in_tri or v_in_tri)
298
+
299
+ # Now is a unique point of intersection of the arc with said
300
+ # plane, so find it.
301
+ t = u[2]/(u[2] - v[2])
302
+ p = (1 - t)*u + t*v
303
+ assert 0 <= t <= 1 and p[2] == 0
304
+ # 2/3 open triangle check
305
+ return not (p[0] > 0 and p[1] > 0 and p[0] + p[1] <= 1)
306
+
307
+
308
+ def norm_sq(v):
309
+ return sum(x**2 for x in v)
310
+
311
+
312
+ def pall_matrix(a, b, c, d):
313
+ """
314
+ For testing, here are all 3 x 3 rational orthogonal matrices,
315
+ which Pall parameterized by four integers.
316
+ """
317
+ n = a**2 + b**2 + c**2 + d**2
318
+ assert n % 2 == 1
319
+ entries = [[a**2 + b**2 - c**2 - d**2, 2*(-a*d + b*c), 2*(a*c + b*d)],
320
+ [2*(a*d + b*c), a**2 - b**2 + c**2 - d**2, 2*(-a*b + c*d)],
321
+ [2*(-a*c + b*d), 2*(a*b + c*d), a**2 - b**2 - c**2 + d**2]]
322
+ return Matrix([[e/QQ(n) for e in row] for row in entries])
323
+
324
+
325
+ def arc_distance_sq_checked(arc_a0, arc_b0):
326
+ """
327
+ Check that all possible permutations of the data specifying the
328
+ arcs gives the same result, plus images under some orthogonal
329
+ transformations.
330
+ """
331
+ ans = arc_distance_sq(arc_a0, arc_b0)
332
+ arc_a1 = (arc_a0[1], arc_a0[0])
333
+ arc_b1 = (arc_b0[1], arc_b0[0])
334
+ mats = [pall_matrix(1, 0, 0, 0),
335
+ pall_matrix(1, -2, 3, 5),
336
+ pall_matrix(4, -1, 2, 2)]
337
+ for M in mats:
338
+ arc_a0 = (M*arc_a0[0], M*arc_a0[1])
339
+ arc_a1 = (M*arc_a1[0], M*arc_a1[1])
340
+ arc_b0 = (M*arc_b0[0], M*arc_b0[1])
341
+ arc_b1 = (M*arc_b1[0], M*arc_b1[1])
342
+ assert ans == arc_distance_sq(arc_a0, arc_b0)
343
+ assert ans == arc_distance_sq(arc_a0, arc_b1)
344
+ assert ans == arc_distance_sq(arc_a1, arc_b0)
345
+ assert ans == arc_distance_sq(arc_a1, arc_b1)
346
+ assert ans == arc_distance_sq(arc_b0, arc_a0)
347
+ assert ans == arc_distance_sq(arc_b0, arc_a1)
348
+ assert ans == arc_distance_sq(arc_b1, arc_a0)
349
+ assert ans == arc_distance_sq(arc_b1, arc_a1)
350
+ return ans
351
+
352
+
353
+ def arc_distance_sq(arc_a, arc_b):
354
+ """
355
+ >>> o = Vector3([0, 0, 0])
356
+ >>> a1 = Vector3([1, 0, 0])
357
+ >>> a2 = Vector3([2, 0, 0])
358
+ >>> a3 = Vector3([3, 0, 0])
359
+ >>> a4 = Vector3([4, 0, 0])
360
+ >>> b0 = Vector3([0, 2, 0])
361
+ >>> b1 = Vector3([1, 2, 0])
362
+ >>> b2 = Vector3([2, 2, 0])
363
+ >>> b3 = Vector3([3, 2, 0])
364
+ >>> b4 = Vector3([4, 2, 0])
365
+ >>> c1 = Vector3([0, 0, 1])
366
+ >>> arc_distance_sq_checked([o, a1], [o, b0])
367
+ 0
368
+ >>> arc_distance_sq_checked([o, a1], [c1, a1 + c1])
369
+ 1
370
+ >>> arc_b = [Vector3([1, 1, -1]), Vector3([1, 1, 1])]
371
+ >>> arc_distance_sq_checked([-c1, c1], arc_b)
372
+ 2
373
+
374
+ Now some cases were everything is on one line.
375
+
376
+ >>> arc_distance_sq_checked([o, a3], [a1, a2])
377
+ 0
378
+ >>> arc_distance_sq_checked([o, a2], [a1, a3])
379
+ 0
380
+ >>> arc_distance_sq_checked([o, a1], [a3, a4])
381
+ 4
382
+ >>> arc_distance_sq_checked([o, a1], [a1/2, 2*a1])
383
+ 0
384
+
385
+ Arcs are parallel but on distinct lines
386
+
387
+ >>> arc_distance_sq_checked([b0, b1], [a3, a4])
388
+ 8
389
+ >>> arc_distance_sq_checked([b0, b4], [a2, a3])
390
+ 4
391
+ >>> arc_distance_sq_checked([b0, b1], [a1, a2])
392
+ 4
393
+
394
+ Now some more generic cases
395
+
396
+ >>> half = 1/QQ(2)
397
+ >>> arc_b = [Vector3([0, 1, half]), Vector3([1, 0, half])]
398
+ >>> arc_distance_sq_checked([o, c1], arc_b) == half
399
+ True
400
+ >>> arc_b = [Vector3([ 1, 1, 0]), Vector3([0, 1, 0])]
401
+ >>> arc_distance_sq_checked([-a1, o], arc_b)
402
+ 1
403
+ >>> arc_b = [Vector3([-1, 1, 0]), Vector3([2, 1, 0])]
404
+ >>> arc_distance_sq_checked([o, a1], arc_b)
405
+ 1
406
+ >>> arc_b = [Vector3([-1, -1, 1]), Vector3([1, 1, 1])]
407
+ >>> arc_distance_sq_checked([-a1, a1], arc_b)
408
+ 1
409
+ >>> arc_b = [Vector3([1, 0, 1]), Vector3([2, -1, 2])]
410
+ >>> arc_distance_sq_checked([o, a2], arc_b)
411
+ 1
412
+ >>> arc_b = [Vector3([1, 0, 1]), Vector3([2, -1, 3])]
413
+ >>> arc_distance_sq_checked([o, a2], arc_b)
414
+ 1
415
+
416
+ """
417
+
418
+ # For general background on this question, see e.g.
419
+ #
420
+ # V. Lumelsky, On fast computation of distance between line segments
421
+ # https://doi.org/10.1016/0020-0190(85)90032-8
422
+ #
423
+ # See also
424
+ #
425
+ # https://github.com/CGAL/cgal/blob/master/Distance_3/include/CGAL/Distance_3/Segment_3_Segment_3.h
426
+
427
+ a0, a1 = arc_a
428
+ b0, b1 = arc_b
429
+
430
+ u = a1 - a0
431
+ v = b1 - b0
432
+ w = a0 - b0
433
+
434
+ if are_parallel(u, v) and are_parallel(u, w):
435
+ # arc_a and arc_b are contained in a common line, so find the
436
+ # coordinates of the endpoints of arc_b with respect to arc_a.
437
+ U = Matrix([u]).transpose()
438
+ t0, t1 = U.solve_right(b0 - a0)[0], U.solve_right(b1 - a0)[0]
439
+ if t0 > t1:
440
+ t0, t1 = t1, t0
441
+ if t1 < 0: # arc_b disjoint and to the left of arc_a
442
+ return t1**2 * norm_sq(u)
443
+ elif 1 < t0: # arc_b disjoint and to the right of arc_a
444
+ return (t0 - 1)**2 * norm_sq(u)
445
+ return 0 # arcs_overlap
446
+
447
+ # Now we solve for the closest point between the two lines
448
+ # generated by the arcs.
449
+
450
+ X = Matrix([[u*u, -u*v],
451
+ [u*v, -v*v]])
452
+ Y = Vector2([-u*w, -v*w])
453
+
454
+ if X.det() == 0:
455
+ # PARI doesn't like degenerate systems, but using that u and v
456
+ # are parallel so we can solve geometrically via a projection.
457
+ t, s = -(w*u)/norm_sq(u), 0
458
+ else:
459
+ t, s = X.solve_right(Y)
460
+
461
+ # If the closest points on the lines lie within the arcs, we're done.
462
+ if 0 <= t <= 1 and 0 <= s <= 1:
463
+ pA = a0 + Vector3(t*u)
464
+ pB = b0 + Vector3(s*v)
465
+ return norm_sq(pA - pB)
466
+
467
+ t = (b0-a0)*u/norm_sq(u)
468
+ s = (b1-a0)*u/norm_sq(u)
469
+ x = (a0-b0)*v/norm_sq(v)
470
+ y = (a1-b0)*v/norm_sq(v)
471
+
472
+ s = min(max(s, 0), 1)
473
+ t = min(max(t, 0), 1)
474
+ x = min(max(x, 0), 1)
475
+ y = min(max(y, 0), 1)
476
+
477
+ p = a0 + Vector3(t*u)
478
+ q = a0 + Vector3(s*u)
479
+ f = b0 + Vector3(x*v)
480
+ g = b0 + Vector3(y*v)
481
+
482
+ return min([norm_sq(p - b0), norm_sq(q - b1), norm_sq(f - a0), norm_sq(g - a1)])
483
+
484
+
485
+ def arc_distance(arc_a, arc_b):
486
+ return rational_sqrt(arc_distance_sq(arc_a, arc_b))
487
+
488
+
489
+ if __name__ == '__main__':
490
+ import doctest
491
+ print(doctest.testmod())