passagemath-schemes 10.6.40__cp314-cp314-macosx_13_0_arm64.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.

Potentially problematic release.


This version of passagemath-schemes might be problematic. Click here for more details.

Files changed (314) hide show
  1. passagemath_schemes/.dylibs/libflint.22.0.dylib +0 -0
  2. passagemath_schemes/.dylibs/libgmp.10.dylib +0 -0
  3. passagemath_schemes/.dylibs/libgmpxx.4.dylib +0 -0
  4. passagemath_schemes/.dylibs/libmpfr.6.dylib +0 -0
  5. passagemath_schemes/__init__.py +3 -0
  6. passagemath_schemes-10.6.40.dist-info/METADATA +204 -0
  7. passagemath_schemes-10.6.40.dist-info/METADATA.bak +205 -0
  8. passagemath_schemes-10.6.40.dist-info/RECORD +314 -0
  9. passagemath_schemes-10.6.40.dist-info/WHEEL +6 -0
  10. passagemath_schemes-10.6.40.dist-info/top_level.txt +3 -0
  11. sage/all__sagemath_schemes.py +23 -0
  12. sage/databases/all__sagemath_schemes.py +7 -0
  13. sage/databases/cremona.py +1723 -0
  14. sage/dynamics/all__sagemath_schemes.py +2 -0
  15. sage/dynamics/arithmetic_dynamics/affine_ds.py +1083 -0
  16. sage/dynamics/arithmetic_dynamics/all.py +14 -0
  17. sage/dynamics/arithmetic_dynamics/berkovich_ds.py +1101 -0
  18. sage/dynamics/arithmetic_dynamics/dynamical_semigroup.py +1543 -0
  19. sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +2426 -0
  20. sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +1169 -0
  21. sage/dynamics/arithmetic_dynamics/generic_ds.py +663 -0
  22. sage/dynamics/arithmetic_dynamics/product_projective_ds.py +339 -0
  23. sage/dynamics/arithmetic_dynamics/projective_ds.py +9558 -0
  24. sage/dynamics/arithmetic_dynamics/projective_ds_helper.cpython-314-darwin.so +0 -0
  25. sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +301 -0
  26. sage/dynamics/arithmetic_dynamics/wehlerK3.py +2576 -0
  27. sage/lfunctions/all.py +18 -0
  28. sage/lfunctions/dokchitser.py +745 -0
  29. sage/lfunctions/pari.py +818 -0
  30. sage/lfunctions/zero_sums.cpython-314-darwin.so +0 -0
  31. sage/lfunctions/zero_sums.pyx +1847 -0
  32. sage/modular/abvar/abvar.py +5135 -0
  33. sage/modular/abvar/abvar_ambient_jacobian.py +413 -0
  34. sage/modular/abvar/abvar_newform.py +244 -0
  35. sage/modular/abvar/all.py +8 -0
  36. sage/modular/abvar/constructor.py +186 -0
  37. sage/modular/abvar/cuspidal_subgroup.py +371 -0
  38. sage/modular/abvar/finite_subgroup.py +896 -0
  39. sage/modular/abvar/homology.py +720 -0
  40. sage/modular/abvar/homspace.py +998 -0
  41. sage/modular/abvar/lseries.py +415 -0
  42. sage/modular/abvar/morphism.py +935 -0
  43. sage/modular/abvar/torsion_point.py +274 -0
  44. sage/modular/abvar/torsion_subgroup.py +740 -0
  45. sage/modular/all.py +43 -0
  46. sage/modular/arithgroup/all.py +20 -0
  47. sage/modular/arithgroup/arithgroup_element.cpython-314-darwin.so +0 -0
  48. sage/modular/arithgroup/arithgroup_element.pyx +474 -0
  49. sage/modular/arithgroup/arithgroup_generic.py +1402 -0
  50. sage/modular/arithgroup/arithgroup_perm.py +2692 -0
  51. sage/modular/arithgroup/congroup.cpython-314-darwin.so +0 -0
  52. sage/modular/arithgroup/congroup.pyx +334 -0
  53. sage/modular/arithgroup/congroup_gamma.py +363 -0
  54. sage/modular/arithgroup/congroup_gamma0.py +692 -0
  55. sage/modular/arithgroup/congroup_gamma1.py +653 -0
  56. sage/modular/arithgroup/congroup_gammaH.py +1469 -0
  57. sage/modular/arithgroup/congroup_generic.py +628 -0
  58. sage/modular/arithgroup/congroup_sl2z.py +267 -0
  59. sage/modular/arithgroup/farey_symbol.cpython-314-darwin.so +0 -0
  60. sage/modular/arithgroup/farey_symbol.pyx +1066 -0
  61. sage/modular/arithgroup/tests.py +418 -0
  62. sage/modular/btquotients/all.py +4 -0
  63. sage/modular/btquotients/btquotient.py +3753 -0
  64. sage/modular/btquotients/pautomorphicform.py +2570 -0
  65. sage/modular/buzzard.py +100 -0
  66. sage/modular/congroup.py +29 -0
  67. sage/modular/congroup_element.py +13 -0
  68. sage/modular/cusps.py +1109 -0
  69. sage/modular/cusps_nf.py +1270 -0
  70. sage/modular/dims.py +569 -0
  71. sage/modular/dirichlet.py +3310 -0
  72. sage/modular/drinfeld_modform/all.py +2 -0
  73. sage/modular/drinfeld_modform/element.py +446 -0
  74. sage/modular/drinfeld_modform/ring.py +773 -0
  75. sage/modular/drinfeld_modform/tutorial.py +236 -0
  76. sage/modular/etaproducts.py +1065 -0
  77. sage/modular/hecke/algebra.py +746 -0
  78. sage/modular/hecke/all.py +20 -0
  79. sage/modular/hecke/ambient_module.py +1019 -0
  80. sage/modular/hecke/degenmap.py +119 -0
  81. sage/modular/hecke/element.py +325 -0
  82. sage/modular/hecke/hecke_operator.py +780 -0
  83. sage/modular/hecke/homspace.py +206 -0
  84. sage/modular/hecke/module.py +1767 -0
  85. sage/modular/hecke/morphism.py +174 -0
  86. sage/modular/hecke/submodule.py +989 -0
  87. sage/modular/hypergeometric_misc.cpython-314-darwin.so +0 -0
  88. sage/modular/hypergeometric_misc.pxd +4 -0
  89. sage/modular/hypergeometric_misc.pyx +166 -0
  90. sage/modular/hypergeometric_motive.py +2017 -0
  91. sage/modular/local_comp/all.py +2 -0
  92. sage/modular/local_comp/liftings.py +292 -0
  93. sage/modular/local_comp/local_comp.py +1071 -0
  94. sage/modular/local_comp/smoothchar.py +1825 -0
  95. sage/modular/local_comp/type_space.py +748 -0
  96. sage/modular/modform/all.py +30 -0
  97. sage/modular/modform/ambient.py +815 -0
  98. sage/modular/modform/ambient_R.py +177 -0
  99. sage/modular/modform/ambient_eps.py +306 -0
  100. sage/modular/modform/ambient_g0.py +124 -0
  101. sage/modular/modform/ambient_g1.py +204 -0
  102. sage/modular/modform/constructor.py +545 -0
  103. sage/modular/modform/cuspidal_submodule.py +708 -0
  104. sage/modular/modform/defaults.py +14 -0
  105. sage/modular/modform/eis_series.py +505 -0
  106. sage/modular/modform/eisenstein_submodule.py +663 -0
  107. sage/modular/modform/element.py +4131 -0
  108. sage/modular/modform/find_generators.py +59 -0
  109. sage/modular/modform/half_integral.py +154 -0
  110. sage/modular/modform/hecke_operator_on_qexp.py +247 -0
  111. sage/modular/modform/j_invariant.py +47 -0
  112. sage/modular/modform/l_series_gross_zagier.py +133 -0
  113. sage/modular/modform/l_series_gross_zagier_coeffs.cpython-314-darwin.so +0 -0
  114. sage/modular/modform/l_series_gross_zagier_coeffs.pyx +177 -0
  115. sage/modular/modform/notes.py +45 -0
  116. sage/modular/modform/numerical.py +514 -0
  117. sage/modular/modform/periods.py +14 -0
  118. sage/modular/modform/ring.py +1257 -0
  119. sage/modular/modform/space.py +1860 -0
  120. sage/modular/modform/submodule.py +118 -0
  121. sage/modular/modform/tests.py +64 -0
  122. sage/modular/modform/theta.py +110 -0
  123. sage/modular/modform/vm_basis.py +381 -0
  124. sage/modular/modform/weight1.py +220 -0
  125. sage/modular/modform_hecketriangle/abstract_ring.py +1932 -0
  126. sage/modular/modform_hecketriangle/abstract_space.py +2528 -0
  127. sage/modular/modform_hecketriangle/all.py +30 -0
  128. sage/modular/modform_hecketriangle/analytic_type.py +590 -0
  129. sage/modular/modform_hecketriangle/constructor.py +416 -0
  130. sage/modular/modform_hecketriangle/element.py +351 -0
  131. sage/modular/modform_hecketriangle/functors.py +752 -0
  132. sage/modular/modform_hecketriangle/graded_ring.py +541 -0
  133. sage/modular/modform_hecketriangle/graded_ring_element.py +2225 -0
  134. sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +3352 -0
  135. sage/modular/modform_hecketriangle/hecke_triangle_groups.py +1432 -0
  136. sage/modular/modform_hecketriangle/readme.py +1214 -0
  137. sage/modular/modform_hecketriangle/series_constructor.py +580 -0
  138. sage/modular/modform_hecketriangle/space.py +1037 -0
  139. sage/modular/modform_hecketriangle/subspace.py +423 -0
  140. sage/modular/modsym/all.py +17 -0
  141. sage/modular/modsym/ambient.py +3846 -0
  142. sage/modular/modsym/boundary.py +1420 -0
  143. sage/modular/modsym/element.py +336 -0
  144. sage/modular/modsym/g1list.py +178 -0
  145. sage/modular/modsym/ghlist.py +182 -0
  146. sage/modular/modsym/hecke_operator.py +73 -0
  147. sage/modular/modsym/manin_symbol.cpython-314-darwin.so +0 -0
  148. sage/modular/modsym/manin_symbol.pxd +5 -0
  149. sage/modular/modsym/manin_symbol.pyx +497 -0
  150. sage/modular/modsym/manin_symbol_list.py +1295 -0
  151. sage/modular/modsym/modsym.py +400 -0
  152. sage/modular/modsym/modular_symbols.py +384 -0
  153. sage/modular/modsym/p1list.cpython-314-darwin.so +0 -0
  154. sage/modular/modsym/p1list.pxd +29 -0
  155. sage/modular/modsym/p1list.pyx +1372 -0
  156. sage/modular/modsym/p1list_nf.py +1241 -0
  157. sage/modular/modsym/relation_matrix.py +591 -0
  158. sage/modular/modsym/relation_matrix_pyx.cpython-314-darwin.so +0 -0
  159. sage/modular/modsym/relation_matrix_pyx.pyx +108 -0
  160. sage/modular/modsym/space.py +2468 -0
  161. sage/modular/modsym/subspace.py +455 -0
  162. sage/modular/modsym/tests.py +375 -0
  163. sage/modular/multiple_zeta.py +2632 -0
  164. sage/modular/multiple_zeta_F_algebra.py +786 -0
  165. sage/modular/overconvergent/all.py +6 -0
  166. sage/modular/overconvergent/genus0.py +1878 -0
  167. sage/modular/overconvergent/hecke_series.py +1187 -0
  168. sage/modular/overconvergent/weightspace.py +778 -0
  169. sage/modular/pollack_stevens/all.py +4 -0
  170. sage/modular/pollack_stevens/distributions.py +874 -0
  171. sage/modular/pollack_stevens/fund_domain.py +1572 -0
  172. sage/modular/pollack_stevens/manin_map.py +859 -0
  173. sage/modular/pollack_stevens/modsym.py +1593 -0
  174. sage/modular/pollack_stevens/padic_lseries.py +417 -0
  175. sage/modular/pollack_stevens/sigma0.py +534 -0
  176. sage/modular/pollack_stevens/space.py +1076 -0
  177. sage/modular/quasimodform/all.py +3 -0
  178. sage/modular/quasimodform/element.py +845 -0
  179. sage/modular/quasimodform/ring.py +828 -0
  180. sage/modular/quatalg/all.py +3 -0
  181. sage/modular/quatalg/brandt.py +1642 -0
  182. sage/modular/ssmod/all.py +8 -0
  183. sage/modular/ssmod/ssmod.py +827 -0
  184. sage/rings/all__sagemath_schemes.py +1 -0
  185. sage/rings/polynomial/all__sagemath_schemes.py +1 -0
  186. sage/rings/polynomial/binary_form_reduce.py +585 -0
  187. sage/schemes/all.py +41 -0
  188. sage/schemes/berkovich/all.py +6 -0
  189. sage/schemes/berkovich/berkovich_cp_element.py +2582 -0
  190. sage/schemes/berkovich/berkovich_space.py +748 -0
  191. sage/schemes/curves/affine_curve.py +2928 -0
  192. sage/schemes/curves/all.py +33 -0
  193. sage/schemes/curves/closed_point.py +434 -0
  194. sage/schemes/curves/constructor.py +381 -0
  195. sage/schemes/curves/curve.py +542 -0
  196. sage/schemes/curves/plane_curve_arrangement.py +1283 -0
  197. sage/schemes/curves/point.py +463 -0
  198. sage/schemes/curves/projective_curve.py +3026 -0
  199. sage/schemes/curves/zariski_vankampen.py +1932 -0
  200. sage/schemes/cyclic_covers/all.py +2 -0
  201. sage/schemes/cyclic_covers/charpoly_frobenius.py +320 -0
  202. sage/schemes/cyclic_covers/constructor.py +137 -0
  203. sage/schemes/cyclic_covers/cycliccover_finite_field.py +1309 -0
  204. sage/schemes/cyclic_covers/cycliccover_generic.py +310 -0
  205. sage/schemes/elliptic_curves/BSD.py +1036 -0
  206. sage/schemes/elliptic_curves/Qcurves.py +592 -0
  207. sage/schemes/elliptic_curves/addition_formulas_ring.py +94 -0
  208. sage/schemes/elliptic_curves/all.py +49 -0
  209. sage/schemes/elliptic_curves/cardinality.py +609 -0
  210. sage/schemes/elliptic_curves/cm.py +1102 -0
  211. sage/schemes/elliptic_curves/constructor.py +1552 -0
  212. sage/schemes/elliptic_curves/ec_database.py +175 -0
  213. sage/schemes/elliptic_curves/ell_curve_isogeny.py +3972 -0
  214. sage/schemes/elliptic_curves/ell_egros.py +459 -0
  215. sage/schemes/elliptic_curves/ell_field.py +2836 -0
  216. sage/schemes/elliptic_curves/ell_finite_field.py +3359 -0
  217. sage/schemes/elliptic_curves/ell_generic.py +3760 -0
  218. sage/schemes/elliptic_curves/ell_local_data.py +1207 -0
  219. sage/schemes/elliptic_curves/ell_modular_symbols.py +775 -0
  220. sage/schemes/elliptic_curves/ell_number_field.py +4220 -0
  221. sage/schemes/elliptic_curves/ell_padic_field.py +107 -0
  222. sage/schemes/elliptic_curves/ell_point.py +4787 -0
  223. sage/schemes/elliptic_curves/ell_rational_field.py +7368 -0
  224. sage/schemes/elliptic_curves/ell_tate_curve.py +671 -0
  225. sage/schemes/elliptic_curves/ell_torsion.py +436 -0
  226. sage/schemes/elliptic_curves/ell_wp.py +352 -0
  227. sage/schemes/elliptic_curves/formal_group.py +760 -0
  228. sage/schemes/elliptic_curves/gal_reps.py +1459 -0
  229. sage/schemes/elliptic_curves/gal_reps_number_field.py +1669 -0
  230. sage/schemes/elliptic_curves/gp_simon.py +152 -0
  231. sage/schemes/elliptic_curves/heegner.py +7335 -0
  232. sage/schemes/elliptic_curves/height.py +2109 -0
  233. sage/schemes/elliptic_curves/hom.py +1406 -0
  234. sage/schemes/elliptic_curves/hom_composite.py +934 -0
  235. sage/schemes/elliptic_curves/hom_frobenius.py +522 -0
  236. sage/schemes/elliptic_curves/hom_scalar.py +531 -0
  237. sage/schemes/elliptic_curves/hom_sum.py +682 -0
  238. sage/schemes/elliptic_curves/hom_velusqrt.py +1290 -0
  239. sage/schemes/elliptic_curves/homset.py +271 -0
  240. sage/schemes/elliptic_curves/isogeny_class.py +1521 -0
  241. sage/schemes/elliptic_curves/isogeny_small_degree.py +2797 -0
  242. sage/schemes/elliptic_curves/jacobian.py +237 -0
  243. sage/schemes/elliptic_curves/kodaira_symbol.py +344 -0
  244. sage/schemes/elliptic_curves/kraus.py +1014 -0
  245. sage/schemes/elliptic_curves/lseries_ell.py +943 -0
  246. sage/schemes/elliptic_curves/mod5family.py +105 -0
  247. sage/schemes/elliptic_curves/mod_poly.py +197 -0
  248. sage/schemes/elliptic_curves/mod_sym_num.cpython-314-darwin.so +0 -0
  249. sage/schemes/elliptic_curves/mod_sym_num.pyx +3796 -0
  250. sage/schemes/elliptic_curves/modular_parametrization.py +305 -0
  251. sage/schemes/elliptic_curves/padic_lseries.py +1793 -0
  252. sage/schemes/elliptic_curves/padics.py +1816 -0
  253. sage/schemes/elliptic_curves/period_lattice.py +2234 -0
  254. sage/schemes/elliptic_curves/period_lattice_region.cpython-314-darwin.so +0 -0
  255. sage/schemes/elliptic_curves/period_lattice_region.pyx +722 -0
  256. sage/schemes/elliptic_curves/saturation.py +715 -0
  257. sage/schemes/elliptic_curves/sha_tate.py +1158 -0
  258. sage/schemes/elliptic_curves/weierstrass_morphism.py +1117 -0
  259. sage/schemes/elliptic_curves/weierstrass_transform.py +200 -0
  260. sage/schemes/hyperelliptic_curves/all.py +6 -0
  261. sage/schemes/hyperelliptic_curves/constructor.py +291 -0
  262. sage/schemes/hyperelliptic_curves/hyperelliptic_finite_field.py +1914 -0
  263. sage/schemes/hyperelliptic_curves/hyperelliptic_g2.py +192 -0
  264. sage/schemes/hyperelliptic_curves/hyperelliptic_generic.py +954 -0
  265. sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +1332 -0
  266. sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +84 -0
  267. sage/schemes/hyperelliptic_curves/invariants.py +410 -0
  268. sage/schemes/hyperelliptic_curves/jacobian_endomorphism_utils.py +315 -0
  269. sage/schemes/hyperelliptic_curves/jacobian_g2.py +32 -0
  270. sage/schemes/hyperelliptic_curves/jacobian_generic.py +419 -0
  271. sage/schemes/hyperelliptic_curves/jacobian_homset.py +186 -0
  272. sage/schemes/hyperelliptic_curves/jacobian_morphism.py +875 -0
  273. sage/schemes/hyperelliptic_curves/kummer_surface.py +99 -0
  274. sage/schemes/hyperelliptic_curves/mestre.py +302 -0
  275. sage/schemes/hyperelliptic_curves/monsky_washnitzer.py +3871 -0
  276. sage/schemes/jacobians/abstract_jacobian.py +277 -0
  277. sage/schemes/jacobians/all.py +2 -0
  278. sage/schemes/overview.py +161 -0
  279. sage/schemes/plane_conics/all.py +22 -0
  280. sage/schemes/plane_conics/con_field.py +1296 -0
  281. sage/schemes/plane_conics/con_finite_field.py +158 -0
  282. sage/schemes/plane_conics/con_number_field.py +456 -0
  283. sage/schemes/plane_conics/con_rational_field.py +406 -0
  284. sage/schemes/plane_conics/con_rational_function_field.py +580 -0
  285. sage/schemes/plane_conics/constructor.py +249 -0
  286. sage/schemes/plane_quartics/all.py +2 -0
  287. sage/schemes/plane_quartics/quartic_constructor.py +71 -0
  288. sage/schemes/plane_quartics/quartic_generic.py +73 -0
  289. sage/schemes/riemann_surfaces/all.py +1 -0
  290. sage/schemes/riemann_surfaces/riemann_surface.py +4117 -0
  291. sage_wheels/share/cremona/cremona_mini.db +0 -0
  292. sage_wheels/share/ellcurves/rank0 +30427 -0
  293. sage_wheels/share/ellcurves/rank1 +31871 -0
  294. sage_wheels/share/ellcurves/rank10 +6 -0
  295. sage_wheels/share/ellcurves/rank11 +6 -0
  296. sage_wheels/share/ellcurves/rank12 +1 -0
  297. sage_wheels/share/ellcurves/rank14 +1 -0
  298. sage_wheels/share/ellcurves/rank15 +1 -0
  299. sage_wheels/share/ellcurves/rank17 +1 -0
  300. sage_wheels/share/ellcurves/rank19 +1 -0
  301. sage_wheels/share/ellcurves/rank2 +2388 -0
  302. sage_wheels/share/ellcurves/rank20 +1 -0
  303. sage_wheels/share/ellcurves/rank21 +1 -0
  304. sage_wheels/share/ellcurves/rank22 +1 -0
  305. sage_wheels/share/ellcurves/rank23 +1 -0
  306. sage_wheels/share/ellcurves/rank24 +1 -0
  307. sage_wheels/share/ellcurves/rank28 +1 -0
  308. sage_wheels/share/ellcurves/rank3 +836 -0
  309. sage_wheels/share/ellcurves/rank4 +10 -0
  310. sage_wheels/share/ellcurves/rank5 +5 -0
  311. sage_wheels/share/ellcurves/rank6 +5 -0
  312. sage_wheels/share/ellcurves/rank7 +5 -0
  313. sage_wheels/share/ellcurves/rank8 +6 -0
  314. sage_wheels/share/ellcurves/rank9 +7 -0
@@ -0,0 +1,1169 @@
1
+ # sage_setup: distribution = sagemath-schemes
2
+ r"""
3
+ Sage functions to compute minimal models of rational functions
4
+ under the conjugation action of `PGL_2(QQ)`.
5
+
6
+ AUTHORS:
7
+
8
+ - Alex Molnar (May 22, 2012)
9
+
10
+ - Brian Stout, Ben Hutz (Nov 2013): Modified code to use projective
11
+ morphism functionality so that it can be included in Sage.
12
+
13
+ REFERENCES: [BM2012]_, [Mol2015]_
14
+ """
15
+
16
+ # ****************************************************************************
17
+ # Copyright (C) 2012 Alexander Molnar
18
+ #
19
+ # This program is free software: you can redistribute it and/or modify
20
+ # it under the terms of the GNU General Public License as published by
21
+ # the Free Software Foundation, either version 2 of the License, or
22
+ # (at your option) any later version.
23
+ # https://www.gnu.org/licenses/
24
+ # ****************************************************************************
25
+
26
+ from copy import copy
27
+
28
+ from sage.arith.misc import gcd
29
+ from sage.functions.hyperbolic import cosh
30
+ from sage.matrix.constructor import matrix
31
+ from sage.matrix.matrix_space import MatrixSpace
32
+ from sage.rings.cc import CC
33
+ from sage.rings.complex_mpfr import ComplexField
34
+ from sage.rings.finite_rings.integer_mod_ring import Zmod
35
+ from sage.rings.integer_ring import ZZ
36
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
37
+ from sage.rings.polynomial.binary_form_reduce import covariant_z0, epsinv
38
+ from sage.rings.rational_field import QQ
39
+ from sage.schemes.affine.affine_space import AffineSpace
40
+
41
+
42
+ def bCheck(c, v, p, b):
43
+ r"""
44
+ Compute a lower bound on the value of ``b``.
45
+
46
+ This value is needed for a transformation
47
+ `A(z) = z*p^k + b` to satisfy `ord_p(Res(\phi^A)) < ord_p(Res(\phi))` for a
48
+ rational map `\phi`. See Theorem 3.3.5 in [Molnar]_.
49
+
50
+ INPUT:
51
+
52
+ - ``c`` -- list of polynomials in `b`. See v for their use
53
+
54
+ - ``v`` -- list of rational numbers, where we are considering the inequalities
55
+ `ord_p(c[i]) > v[i]`
56
+
57
+ - ``p`` -- a prime
58
+
59
+ - ``b`` -- local variable
60
+
61
+ OUTPUT: ``bval`` -- integer; lower bound in Theorem 3.3.5
62
+
63
+ EXAMPLES::
64
+
65
+ sage: R.<b> = PolynomialRing(QQ)
66
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import bCheck
67
+ sage: bCheck(11664*b^2 + 70227*b + 76059, 15/2, 3, b)
68
+ -1
69
+ """
70
+ val = (v + 1).floor()
71
+ deg = c.degree()
72
+ coeffs = c.coefficients(sparse=False)
73
+ lcoeff = coeffs[deg]
74
+ coeffs.remove(lcoeff)
75
+ check1 = [(coeffs[i].valuation(p) - lcoeff.valuation(p))/(deg - i)
76
+ for i in range(len(coeffs)) if coeffs[i] != 0]
77
+ check2 = (val - lcoeff.valuation(p))/deg
78
+ check1.append(check2)
79
+ bval = min(check1)
80
+ return (bval).ceil()
81
+
82
+
83
+ def scale(c, v, p):
84
+ r"""
85
+ Create scaled integer polynomial with respect to prime ``p``.
86
+
87
+ Given an integral polynomial ``c``, we can write `c = p^i*c'`, where ``p`` does not
88
+ divide ``c``. Return ``c'`` and `v - i` where `i` is the smallest valuation of the
89
+ coefficients of `c`.
90
+
91
+ INPUT:
92
+
93
+ - ``c`` -- integer polynomial
94
+
95
+ - ``v`` -- integer; the bound on the exponent from :func:`blift`
96
+
97
+ - ``p`` -- a prime
98
+
99
+ OUTPUT:
100
+
101
+ - boolean -- the new exponent bound is 0 or negative
102
+
103
+ - the scaled integer polynomial
104
+
105
+ - an integer the new exponent bound
106
+
107
+ EXAMPLES::
108
+
109
+ sage: R.<b> = PolynomialRing(QQ)
110
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import scale
111
+ sage: scale(24*b^3 + 108*b^2 + 162*b + 81, 1, 3)
112
+ [False, 8*b^3 + 36*b^2 + 54*b + 27, 0]
113
+ """
114
+ scaleval = min([coeff.valuation(p) for coeff in c.coefficients()])
115
+ if scaleval > 0:
116
+ c = c/(p**scaleval)
117
+ v = v - scaleval
118
+ if v <= 0:
119
+ flag = False
120
+ else:
121
+ flag = True
122
+ return [flag, c, v]
123
+
124
+
125
+ def blift(LF, Li, p, k, S=None, all_orbits=False):
126
+ r"""
127
+ Search for a solution to the given list of inequalities.
128
+
129
+ If found, lift the solution to
130
+ an appropriate valuation. See Lemma 3.3.6 in [Molnar]_
131
+
132
+ INPUT:
133
+
134
+ - ``LF`` -- list of integer polynomials in one variable (the normalized coefficients)
135
+
136
+ - ``Li`` -- integer; the bound on coefficients
137
+
138
+ - ``p`` -- a prime
139
+
140
+ - ``k`` -- the scaling factor that makes the solution a ``p``-adic integer
141
+
142
+ - ``S`` -- polynomial ring to use
143
+
144
+ - ``all_orbits`` -- boolean; whether or not to use ``==`` in the
145
+ inequalities to find all orbits
146
+
147
+ OUTPUT:
148
+
149
+ - boolean -- whether or not the lift is successful
150
+
151
+ - integer -- the lift
152
+
153
+ EXAMPLES::
154
+
155
+ sage: R.<b> = PolynomialRing(QQ)
156
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import blift
157
+ sage: blift([8*b^3 + 12*b^2 + 6*b + 1, 48*b^2 + 483*b + 117, 72*b + 1341,
158
+ ....: -24*b^2 + 411*b + 99, -144*b + 1233, -216*b], 2, 3, 2)
159
+ [[True, 4]]
160
+ """
161
+
162
+ P = LF[0].parent()
163
+ #Determine which inequalities are trivial, and scale the rest, so that we only lift
164
+ #as many times as needed.
165
+ keepScaledIneqs = [scale(P(coeff),Li,p) for coeff in LF if coeff != 0]
166
+ keptVals = [i[2] for i in keepScaledIneqs if i[0]]
167
+ if keptVals:
168
+ # Determine the valuation to lift until.
169
+ # liftval = max(keptVals)
170
+ pass
171
+ else:
172
+ #All inequalities are satisfied.
173
+ if all_orbits:
174
+ return [[True, t] for t in range(p)]
175
+ return [[True, 1]]
176
+ if S is None:
177
+ S = PolynomialRing(Zmod(p), 'b')
178
+ keptScaledIneqs = [S(i[1]) for i in keepScaledIneqs if i[0]]
179
+ #We need a solution for each polynomial on the left hand side of the inequalities,
180
+ #so we need only find a solution for their gcd.
181
+ g = gcd(keptScaledIneqs)
182
+ rts = g.roots(multiplicities=False)
183
+ good = []
184
+ for r in rts:
185
+ #Recursively try to lift each root
186
+ r_initial = QQ(r)
187
+ newInput = P([r_initial, p])
188
+ LG = [F(newInput) for F in LF]
189
+ new_good = blift(LG, Li, p, k, S=S)
190
+ for lift,lifted in new_good:
191
+ if lift:
192
+ #Lift successful.
193
+ if not all_orbits:
194
+ return [[True, r_initial + p*lifted]]
195
+
196
+ #only need up to SL(2,ZZ) equivalence
197
+ #this helps control the size of the resulting coefficients
198
+ if r_initial + p*lifted < p**k:
199
+ good.append([True, r_initial + p*lifted])
200
+ else:
201
+ new_r = r_initial + p*lifted - p**k
202
+ while new_r > p**k:
203
+ new_r -= p**k
204
+ if [True, new_r] not in good:
205
+ good.append([True, new_r])
206
+ if good:
207
+ return good
208
+ #Lift non successful.
209
+ return [[False,0]]
210
+
211
+
212
+ def affine_minimal(vp, return_transformation=False, D=None, quick=False):
213
+ r"""
214
+ Determine if given map is affine minimal.
215
+
216
+ Given vp a scheme morphism on the projective line over the rationals,
217
+ this procedure determines if `\phi` is minimal. In particular, it determines
218
+ if the map is affine minimal, which is enough to decide if it is minimal
219
+ or not. See Proposition 2.10 in [BM2012]_.
220
+
221
+ INPUT:
222
+
223
+ - ``vp`` -- dynamical system on the projective line
224
+
225
+ - ``D`` -- list of primes, in case one only wants to check minimality
226
+ at those specific primes
227
+
228
+ - ``return_transformation`` -- boolean (default: ``False``); this
229
+ signals a return of the `PGL_2` transformation to conjugate
230
+ this map to the calculated models
231
+
232
+ - ``quick`` -- boolean value. If true the algorithm terminates once
233
+ algorithm determines F/G is not minimal, otherwise algorithm only
234
+ terminates once a minimal model has been found
235
+
236
+ OUTPUT: ``newvp`` -- dynamical system on the projective line
237
+
238
+ - ``conj`` -- linear fractional transformation which conjugates ``vp`` to ``newvp``
239
+
240
+ EXAMPLES::
241
+
242
+ sage: PS.<X,Y> = ProjectiveSpace(QQ, 1)
243
+ sage: vp = DynamicalSystem_projective([X^2 + 9*Y^2, X*Y])
244
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import affine_minimal
245
+ sage: affine_minimal(vp, True)
246
+ (
247
+ Dynamical System of Projective Space of dimension 1 over Rational Field
248
+ Defn: Defined on coordinates by sending (X : Y) to (X^2 + Y^2 : X*Y)
249
+ ,
250
+ [3 0]
251
+ [0 1]
252
+ )
253
+ """
254
+ from sage.dynamics.arithmetic_dynamics.affine_ds import DynamicalSystem_affine
255
+ BR = vp.domain().base_ring()
256
+ conj = matrix(BR, 2, 2, 1)
257
+ flag = True
258
+ vp.normalize_coordinates()
259
+ d = vp.degree()
260
+
261
+ Affvp = vp.dehomogenize(1)
262
+ R = Affvp.coordinate_ring()
263
+ if R.is_field():
264
+ #want the polynomial ring not the fraction field
265
+ R = R.ring()
266
+ F = R(Affvp[0].numerator())
267
+ G = R(Affvp[0].denominator())
268
+ if R(G.degree()) == 0 or R(F.degree()) == 0:
269
+ raise TypeError("affine minimality is only considered for maps not of the form f or 1/f for a polynomial f")
270
+
271
+ z = F.parent().gen(0)
272
+ minG = G
273
+ #If the valuation of a prime in the resultant is small enough, we can say the
274
+ #map is affine minimal at that prime without using the local minimality loop. See
275
+ #Theorem 3.2.2 in [Molnar, M.Sc. thesis]
276
+ if d % 2 == 0:
277
+ g = d
278
+ else:
279
+ g = 2*d
280
+ Res = vp.resultant()
281
+
282
+ #Some quantities needed for the local minimization loop, but we compute now
283
+ #since the value is constant, so we do not wish to compute in every local loop.
284
+ #See Theorem 3.3.3 in [Molnar, M.Sc thesis]
285
+ H = F - z * minG
286
+ A = AffineSpace(BR, 1, H.parent().variable_name())
287
+ ubRes = DynamicalSystem_affine([H/minG], domain=A).homogenize(1).resultant()
288
+ #Set the primes to check minimality at, if not already prescribed
289
+ if D is None:
290
+ D = ZZ(Res).prime_divisors()
291
+
292
+ #Check minimality at all primes in D. If D is all primes dividing
293
+ #Res(minF/minG), this is enough to show whether minF/minG is minimal or not. See
294
+ #Propositions 3.2.1 and 3.3.7 in [Molnar, M.Sc. thesis].
295
+ for p in D:
296
+ while True:
297
+ if Res.valuation(p) < g:
298
+ #The model is minimal at p
299
+ min = True
300
+ else:
301
+ #The model may not be minimal at p.
302
+ newvp,conj = Min(vp, p, ubRes, conj, all_orbits=False)
303
+ if newvp == vp:
304
+ min = True
305
+ else:
306
+ vp = newvp
307
+ Affvp = vp.dehomogenize(1)
308
+ min = False
309
+ if min:
310
+ #The model is minimal at p
311
+ break
312
+ elif F == Affvp[0].numerator() and G == Affvp[0].denominator():
313
+ #The model is minimal at p
314
+ break
315
+ else:
316
+ #The model is not minimal at p
317
+ flag = False
318
+ if quick:
319
+ break
320
+ if quick and not flag:
321
+ break
322
+
323
+ if quick: #only return whether the model is minimal
324
+ return flag
325
+
326
+ if return_transformation:
327
+ return vp, conj
328
+ return vp
329
+
330
+
331
+ def Min(Fun, p, ubRes, conj, all_orbits=False):
332
+ r"""
333
+ Local loop for :func:`affine_minimal`, where we check minimality at the prime `p`.
334
+
335
+ First we bound the possible `k` in our transformations `A = zp^k + b`.
336
+ See Theorems 3.3.2 and 3.3.3 in [Molnar]_.
337
+
338
+ INPUT:
339
+
340
+ - ``Fun`` -- a dynamical system on projective space
341
+
342
+ - ``p`` -- a prime
343
+
344
+ - ``ubRes`` -- integer; the upper bound needed for Th. 3.3.3 in [Molnar]_
345
+
346
+ - ``conj`` -- a 2x2 matrix keeping track of the conjugation
347
+
348
+ - ``all_orbits`` -- boolean; whether or not to use ``==`` in the
349
+ inequalities to find all orbits
350
+
351
+ OUTPUT:
352
+
353
+ - boolean -- ``True`` if ``Fun`` is minimal at ``p``, ``False`` otherwise
354
+
355
+ - a dynamical system on projective space minimal at ``p``
356
+
357
+ EXAMPLES::
358
+
359
+ sage: P.<x,y> = ProjectiveSpace(QQ, 1)
360
+ sage: f = DynamicalSystem_projective([149*x^2 + 39*x*y + y^2,
361
+ ....: -8*x^2 + 137*x*y + 33*y^2])
362
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import Min
363
+ sage: Min(f, 3, -27000000, matrix(QQ,[[1, 0],[0, 1]]))
364
+ [
365
+ Dynamical System of Projective Space of dimension 1 over Rational Field
366
+ Defn: Defined on coordinates by sending (x : y) to
367
+ (157*x^2 + 72*x*y + 3*y^2 : -24*x^2 + 121*x*y + 54*y^2) ,
368
+ <BLANKLINE>
369
+ [3 1]
370
+ [0 1]
371
+ ]
372
+ """
373
+ d = Fun.degree()
374
+ AffFun = Fun.dehomogenize(1)
375
+ R = AffFun.coordinate_ring()
376
+ if R.is_field():
377
+ #want the polynomial ring not the fraction field
378
+ R = R.ring()
379
+ F = R(AffFun[0].numerator())
380
+ G = R(AffFun[0].denominator())
381
+ dG = G.degree()
382
+ # all_orbits scales bounds for >= and <= if searching for orbits instead of min model
383
+ if dG > (d+1)/2:
384
+ lowerBound = (-2*(G[dG]).valuation(p)/(2*dG - d + 1) + 1).floor() - int(all_orbits)
385
+ else:
386
+ lowerBound = (-2*(F[d]).valuation(p)/(d-1) + 1).floor() - int(all_orbits)
387
+ upperBound = 2*(ubRes.valuation(p)) + int(all_orbits)
388
+
389
+ if upperBound < lowerBound:
390
+ # There are no possible transformations to reduce the resultant.
391
+ if not all_orbits:
392
+ return [Fun, conj]
393
+ return []
394
+ # Looping over each possible k, we search for transformations to reduce
395
+ # the resultant of F/G
396
+ all_found = []
397
+ k = lowerBound
398
+ Qb = PolynomialRing(QQ,'b')
399
+ b = Qb.gen(0)
400
+ Q = PolynomialRing(Qb,'z')
401
+ z = Q.gen(0)
402
+ while k <= upperBound:
403
+ A = (p**k)*z + b
404
+ Ft = Q(F(A) - b*G(A))
405
+ Gt = Q((p**k)*G(A))
406
+ Fcoeffs = Ft.coefficients(sparse=False)
407
+ Gcoeffs = Gt.coefficients(sparse=False)
408
+ coeffs = Fcoeffs + Gcoeffs
409
+ RHS = (d + 1) * k / 2
410
+ # If there is some b such that Res(phi^A) < Res(phi), we must have
411
+ # ord_p(c) > RHS for each c in coeffs.
412
+ # Make sure constant coefficients in coeffs satisfy the inequality.
413
+ if all(QQ(c).valuation(p) > RHS - int(all_orbits)
414
+ for c in coeffs if c.degree() == 0):
415
+ # Constant coefficients in coeffs have large enough valuation, so
416
+ # check the rest. We start by checking if simply picking b=0 works.
417
+ if all(c(0).valuation(p) > RHS - int(all_orbits) for c in coeffs):
418
+ # A = z*p^k satisfies the inequalities, and F/G is not minimal
419
+ # "Conjugating by", p,"^", k, "*z +", 0
420
+ newconj = matrix(QQ, 2, 2, [p**k, 0, 0, 1])
421
+ minFun = Fun.conjugate(newconj)
422
+ minFun.normalize_coordinates()
423
+ if not all_orbits:
424
+ return [minFun, conj*newconj]
425
+ all_found.append([p, k, 0])
426
+
427
+ # Otherwise we search if any value of b will work. We start by
428
+ # finding a minimum bound on the valuation of b that is necessary.
429
+ # See Theorem 3.3.5 in [Molnar, M.Sc. thesis].
430
+ bval = max(bCheck(coeff, RHS, p, b) for coeff in coeffs if coeff.degree() > 0)
431
+
432
+ # We scale the coefficients in coeffs, so that we may assume
433
+ # ord_p(b) is at least 0
434
+ scaledCoeffs = [coeff(b*(p**bval)) for coeff in coeffs]
435
+
436
+ # We now scale the inequalities, ord_p(coeff) > RHS, so that
437
+ # coeff is in ZZ[b]
438
+ scale = QQ(max(coeff.denominator() for coeff in scaledCoeffs))
439
+ normalizedCoeffs = [coeff * scale for coeff in scaledCoeffs]
440
+ scaleRHS = RHS + scale.valuation(p)
441
+
442
+ # We now search for integers that satisfy the inequality
443
+ # ord_p(coeff) > RHS. See Lemma 3.3.6 in [Molnar, M.Sc. thesis].
444
+ bound = (scaleRHS + 1 - int(all_orbits)).floor()
445
+ all_blift = blift(normalizedCoeffs, bound, p, k, all_orbits=all_orbits)
446
+
447
+ # If bool is true after lifting, we have a solution b, and F/G
448
+ # is not minimal.
449
+ for boolval, sol in all_blift:
450
+ if boolval:
451
+ #Rescale, conjugate and return new map
452
+ bsol = QQ(sol * (p**bval))
453
+ #only add 'minimal orbit element'
454
+ while bsol.abs() >= p**k:
455
+ if bsol < 0:
456
+ bsol += p**k
457
+ else:
458
+ bsol -= p**k
459
+ #"Conjugating by ", p,"^", k, "*z +", bsol
460
+ newconj = matrix(QQ, 2, 2, [p**k, bsol, 0, 1])
461
+ minFun = Fun.conjugate(newconj)
462
+
463
+ minFun.normalize_coordinates()
464
+ if not all_orbits:
465
+ return [minFun, conj*newconj]
466
+ if [p,k,bsol] not in all_found:
467
+ all_found.append([p, k, bsol])
468
+ k = k + 1
469
+ if not all_orbits:
470
+ return [Fun, conj]
471
+ return all_found
472
+
473
+ ###################################################
474
+ # algorithms from Hutz-Stoll
475
+ ###################################################
476
+
477
+ #modification of Bruin-Molnar for all representatives
478
+
479
+
480
+ def BM_all_minimal(vp, return_transformation=False, D=None):
481
+ r"""
482
+ Determine a representative in each `SL(2,\ZZ)` orbit with minimal
483
+ resultant.
484
+
485
+ This function modifies the Bruin-Molnar algorithm ([BM2012]_) to solve
486
+ in the inequalities as ``<=`` instead of ``<``. Among the list of
487
+ solutions is all conjugations that preserve the resultant. From that
488
+ list the `SL(2,\ZZ)` orbits are identified and one representative from
489
+ each orbit is returned. This function assumes that the given model is
490
+ a minimal model.
491
+
492
+ INPUT:
493
+
494
+ - ``vp`` -- a minimal model of a dynamical system on the projective line
495
+
496
+ - ``return_transformation`` -- boolean (default: ``False``); this
497
+ signals a return of the ``PGL_2`` transformation to conjugate ``vp``
498
+ to the calculated minimal model
499
+
500
+ - ``D`` -- list of primes, in case one only wants to check minimality
501
+ at those specific primes
502
+
503
+ OUTPUT:
504
+
505
+ List of pairs ``[f, m]`` where ``f`` is a dynamical system and ``m`` is a
506
+ `2 \times 2` matrix.
507
+
508
+ EXAMPLES::
509
+
510
+ sage: P.<x,y> = ProjectiveSpace(QQ,1)
511
+ sage: f = DynamicalSystem([x^3 - 13^2*y^3, x*y^2])
512
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import BM_all_minimal
513
+ sage: BM_all_minimal(f)
514
+ [Dynamical System of Projective Space of dimension 1 over Rational Field
515
+ Defn: Defined on coordinates by sending (x : y) to
516
+ (x^3 - 169*y^3 : x*y^2),
517
+ Dynamical System of Projective Space of dimension 1 over Rational Field
518
+ Defn: Defined on coordinates by sending (x : y) to
519
+ (13*x^3 - y^3 : x*y^2)]
520
+
521
+ ::
522
+
523
+ sage: P.<x,y> = ProjectiveSpace(QQ,1)
524
+ sage: f = DynamicalSystem([x^3 - 6^2*y^3, x*y^2])
525
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import BM_all_minimal
526
+ sage: BM_all_minimal(f, D=[3])
527
+ [Dynamical System of Projective Space of dimension 1 over Rational Field
528
+ Defn: Defined on coordinates by sending (x : y) to
529
+ (x^3 - 36*y^3 : x*y^2),
530
+ Dynamical System of Projective Space of dimension 1 over Rational Field
531
+ Defn: Defined on coordinates by sending (x : y) to
532
+ (3*x^3 - 4*y^3 : x*y^2)]
533
+
534
+ ::
535
+
536
+ sage: P.<x,y> = ProjectiveSpace(QQ,1)
537
+ sage: f = DynamicalSystem([x^3 - 4^2*y^3, x*y^2])
538
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import BM_all_minimal
539
+ sage: cl = BM_all_minimal(f, return_transformation=True)
540
+ sage: all(f.conjugate(m) == g for g, m in cl)
541
+ True
542
+ """
543
+ mp = copy(vp)
544
+ mp.normalize_coordinates()
545
+ BR = mp.domain().base_ring()
546
+ MS = MatrixSpace(QQ, 2)
547
+ M_Id = MS.one()
548
+ F, G = list(mp) #coordinate polys
549
+ aff_map = mp.dehomogenize(1)
550
+ f, g = aff_map[0].numerator(), aff_map[0].denominator()
551
+ z = aff_map.domain().gen(0)
552
+ Res = mp.resultant()
553
+
554
+ # because of how the bound is compute in lemma 3.3
555
+ from sage.dynamics.arithmetic_dynamics.affine_ds import DynamicalSystem_affine
556
+ h = f - z*g
557
+ A = AffineSpace(BR, 1, h.parent().variable_name())
558
+ res = DynamicalSystem_affine([h/g], domain=A).homogenize(1).resultant()
559
+
560
+ if D is None:
561
+ D = ZZ(Res).prime_divisors()
562
+
563
+ # get the conjugations for each prime independently
564
+ # these are returning (p,k,b) so that the matrix is [p^k,b,0,1]
565
+ all_pM = []
566
+ for p in D:
567
+ # all_orbits used to scale inequalities to equalities
568
+ all_pM.append(Min(mp, p, res, M_Id, all_orbits=True))
569
+ # need the identity for each prime
570
+ if [p, 0, 0] not in all_pM[-1]:
571
+ all_pM[-1].append([p, 0, 0])
572
+
573
+ #combine conjugations for all primes
574
+ all_M = [M_Id]
575
+ for prime_data in all_pM:
576
+ #these are (p,k,b) so that the matrix is [p^k,b,0,1]
577
+ new_M = []
578
+ if prime_data:
579
+ p = prime_data[0][0]
580
+ for m in prime_data:
581
+ mat = MS([m[0]**m[1], m[2], 0, 1])
582
+ new_map = mp.conjugate(mat)
583
+ new_map.normalize_coordinates()
584
+ # make sure the resultant didn't change and that it is a different SL(2,ZZ) orbit
585
+ if (mat == M_Id) or (new_map.resultant().valuation(p) == Res.valuation(p)
586
+ and mat.det() not in [1,-1]):
587
+ new_M.append(m)
588
+ if new_M:
589
+ all_M = [m1 * MS([m[0]**m[1], m[2], 0, 1])
590
+ for m1 in all_M for m in new_M]
591
+
592
+ #get all models with same resultant
593
+ all_maps = []
594
+ for M in all_M:
595
+ new_map = mp.conjugate(M)
596
+ new_map.normalize_coordinates()
597
+ if [new_map, M] not in all_maps:
598
+ all_maps.append([new_map, M])
599
+
600
+ #Split into conjugacy classes
601
+ #We just keep track of the two matrices that come from
602
+ #the original to get the conjugation that goes between these!!
603
+ classes = []
604
+ for funct, mat in all_maps:
605
+ if not classes:
606
+ classes.append([funct, mat])
607
+ else:
608
+ found = False
609
+ for Func, Mat in classes:
610
+ #get conjugation
611
+ M = mat.inverse() * Mat
612
+ assert funct.conjugate(M) == Func
613
+ if M.det() in [1,-1]:
614
+ #same SL(2,Z) orbit
615
+ found = True
616
+ break
617
+ if found is False:
618
+ classes.append([funct, mat])
619
+
620
+ if return_transformation:
621
+ return classes
622
+ else:
623
+ return [funct for funct, matr in classes]
624
+
625
+ ###################################################
626
+ # enumerative algorithms from Hutz-Stoll
627
+ ###################################################
628
+
629
+ #find minimal model
630
+
631
+
632
+ def HS_minimal(f, return_transformation=False, D=None):
633
+ r"""
634
+ Compute a minimal model for the given projective dynamical system.
635
+
636
+ This function implements the algorithm in Hutz-Stoll [HS2018]_.
637
+ A representative with minimal resultant in the conjugacy class
638
+ of ``f`` returned.
639
+
640
+ INPUT:
641
+
642
+ - ``f`` -- dynamical system on the projective line with minimal resultant
643
+
644
+ - ``return_transformation`` -- boolean (default: ``False``); this
645
+ signals a return of the `PGL_2` transformation to conjugate
646
+ this map to the calculated models
647
+
648
+ - ``D`` -- list of primes, in case one only wants to check minimality
649
+ at those specific primes
650
+
651
+ OUTPUT:
652
+
653
+ - a dynamical system
654
+ - (optional) a `2 \times 2` matrix
655
+
656
+ EXAMPLES::
657
+
658
+ sage: P.<x,y> = ProjectiveSpace(QQ,1)
659
+ sage: f = DynamicalSystem([x^3 - 6^2*y^3, x^2*y])
660
+ sage: m = matrix(QQ,2,2,[5,1,0,1])
661
+ sage: g = f.conjugate(m)
662
+ sage: g.normalize_coordinates()
663
+ sage: g.resultant().factor()
664
+ 2^4 * 3^4 * 5^12
665
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import HS_minimal
666
+ sage: HS_minimal(g).resultant().factor()
667
+ 2^4 * 3^4
668
+ sage: HS_minimal(g, D=[2]).resultant().factor()
669
+ 2^4 * 3^4 * 5^12
670
+ sage: F,m = HS_minimal(g, return_transformation=True)
671
+ sage: g.conjugate(m) == F
672
+ True
673
+ """
674
+ F = copy(f)
675
+ d = F.degree()
676
+ F.normalize_coordinates()
677
+ MS = MatrixSpace(ZZ, 2, 2)
678
+ m = MS.one()
679
+ res = ZZ(F.resultant())
680
+ if D is None:
681
+ D = res.prime_divisors()
682
+
683
+ # minimize for each prime
684
+ for p in D:
685
+ vp = res.valuation(p)
686
+ minimal = False
687
+ while not minimal:
688
+ if (d % 2 == 0 and vp < d) or (d % 2 == 1 and vp < 2 * d):
689
+ # must be minimal
690
+ minimal = True
691
+ break
692
+ minimal = True
693
+ t = MS([1, 0, 0, p])
694
+ F1 = F.conjugate(t)
695
+ F1.normalize_coordinates()
696
+ res1 = F1.resultant()
697
+ vp1 = res1.valuation(p)
698
+ if vp1 < vp: # check if smaller
699
+ F = F1
700
+ vp = vp1
701
+ m = m * t # keep track of conjugation
702
+ minimal = False
703
+ else:
704
+ # still search for smaller
705
+ for b in range(p):
706
+ t = matrix(ZZ,2,2,[p, b, 0, 1])
707
+ F1 = F.conjugate(t)
708
+ F1.normalize_coordinates()
709
+ res1 = ZZ(F1.resultant())
710
+ vp1 = res1.valuation(p)
711
+ if vp1 < vp: # check if smaller
712
+ F = F1
713
+ m = m * t # keep track of transformation
714
+ minimal = False
715
+ vp = vp1
716
+ break # exit for loop
717
+ if return_transformation:
718
+ return F, m
719
+ return F
720
+
721
+ #find all representatives of orbits for one prime
722
+
723
+
724
+ def HS_all_minimal_p(p, f, m=None, return_transformation=False):
725
+ r"""
726
+ Find a representative in each distinct `SL(2,\ZZ)` orbit with
727
+ minimal `p`-resultant.
728
+
729
+ This function implements the algorithm in Hutz-Stoll [HS2018]_.
730
+ A representatives in each distinct `SL(2,\ZZ)` orbit with minimal
731
+ valuation with respect to the prime ``p`` is returned. The input
732
+ ``f`` must have minimal resultant in its conjugacy class.
733
+
734
+ INPUT:
735
+
736
+ - ``p`` -- a prime
737
+
738
+ - ``f`` -- dynamical system on the projective line with minimal resultant
739
+
740
+ - ``m`` -- (optional) `2 \times 2` matrix associated with ``f``
741
+
742
+ - ``return_transformation`` -- boolean (default: ``False``); this
743
+ signals a return of the ``PGL_2`` transformation to conjugate ``vp``
744
+ to the calculated minimal model
745
+
746
+ OUTPUT:
747
+
748
+ List of pairs ``[f, m]`` where ``f`` is a dynamical system and ``m`` is a
749
+ `2 \times 2` matrix.
750
+
751
+ EXAMPLES::
752
+
753
+ sage: P.<x,y> = ProjectiveSpace(QQ,1)
754
+ sage: f = DynamicalSystem([x^5 - 6^4*y^5, x^2*y^3])
755
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import HS_all_minimal_p
756
+ sage: HS_all_minimal_p(2, f)
757
+ [Dynamical System of Projective Space of dimension 1 over Rational Field
758
+ Defn: Defined on coordinates by sending (x : y) to
759
+ (x^5 - 1296*y^5 : x^2*y^3),
760
+ Dynamical System of Projective Space of dimension 1 over Rational Field
761
+ Defn: Defined on coordinates by sending (x : y) to
762
+ (4*x^5 - 162*y^5 : x^2*y^3)]
763
+ sage: cl = HS_all_minimal_p(2, f, return_transformation=True)
764
+ sage: all(f.conjugate(m) == g for g, m in cl)
765
+ True
766
+ """
767
+ count = 0
768
+ prev = 0 # no exclusions
769
+ F = copy(f)
770
+ res = ZZ(F.resultant())
771
+ vp = res.valuation(p)
772
+ MS = MatrixSpace(ZZ, 2)
773
+ if m is None:
774
+ m = MS.one()
775
+ if f.degree() % 2 == 0 or vp == 0:
776
+ # there is only one orbit for even degree
777
+ # nothing to do if the prime doesn't divide the resultant
778
+ if return_transformation:
779
+ return [[f, m]]
780
+ else:
781
+ return [f]
782
+ to_do = [[F, m, prev]] # repns left to check
783
+ reps = [[F, m]] # orbit representatives for f
784
+ while to_do:
785
+ F, m, prev = to_do.pop()
786
+ # there are at most two directions preserving the resultant
787
+ if prev == 0:
788
+ count = 0
789
+ else:
790
+ count = 1
791
+ if prev != 2: # [p,a,0,1]
792
+ t = MS([1, 0, 0, p])
793
+ F1 = F.conjugate(t)
794
+ F1.normalize_coordinates()
795
+ res1 = ZZ(F1.resultant())
796
+ vp1 = res1.valuation(p)
797
+ if vp1 == vp:
798
+ count += 1
799
+ # we have a new representative
800
+ reps.append([F1, m*t])
801
+ # need to check if it has any neighbors
802
+ to_do.append([F1, m*t, 1])
803
+ for b in range(p):
804
+ if not (b == 0 and prev == 1):
805
+ t = MS([p, b, 0, 1])
806
+ F1 = F.conjugate(t)
807
+ F1.normalize_coordinates()
808
+ res1 = ZZ(F1.resultant())
809
+ vp1 = res1.valuation(p)
810
+ if vp1 == vp:
811
+ count += 1
812
+ # we have a new representative
813
+ reps.append([F1, m*t])
814
+ # need to check if it has any neighbors
815
+ to_do.append([F1, m*t, 2])
816
+ if count >= 2: # at most two neighbors
817
+ break
818
+
819
+ if return_transformation:
820
+ return reps
821
+ else:
822
+ return [funct for funct, matr in reps]
823
+
824
+ #find all representatives of orbits
825
+
826
+
827
+ def HS_all_minimal(f, return_transformation=False, D=None):
828
+ r"""
829
+ Determine a representative in each `SL(2,\ZZ)` orbit with minimal resultant.
830
+
831
+ This function implements the algorithm in Hutz-Stoll [HS2018]_.
832
+ A representative in each distinct `SL(2,\ZZ)` orbit is returned.
833
+ The input ``f`` must have minimal resultant in its conjugacy class.
834
+
835
+ INPUT:
836
+
837
+ - ``f`` -- dynamical system on the projective line with minimal resultant
838
+
839
+ - ``return_transformation`` -- boolean (default: ``False``); this
840
+ signals a return of the ``PGL_2`` transformation to conjugate ``vp``
841
+ to the calculated minimal model
842
+
843
+ - ``D`` -- list of primes, in case one only wants to check minimality
844
+ at those specific primes
845
+
846
+ OUTPUT:
847
+
848
+ List of pairs ``[f, m]``, where ``f`` is a dynamical system and ``m``
849
+ is a `2 \times 2` matrix.
850
+
851
+ EXAMPLES::
852
+
853
+ sage: P.<x,y> = ProjectiveSpace(QQ,1)
854
+ sage: f = DynamicalSystem([x^3 - 6^2*y^3, x^2*y])
855
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import HS_all_minimal
856
+ sage: HS_all_minimal(f)
857
+ [Dynamical System of Projective Space of dimension 1 over Rational Field
858
+ Defn: Defined on coordinates by sending (x : y) to
859
+ (x^3 - 36*y^3 : x^2*y),
860
+ Dynamical System of Projective Space of dimension 1 over Rational Field
861
+ Defn: Defined on coordinates by sending (x : y) to
862
+ (9*x^3 - 12*y^3 : 9*x^2*y),
863
+ Dynamical System of Projective Space of dimension 1 over Rational Field
864
+ Defn: Defined on coordinates by sending (x : y) to
865
+ (4*x^3 - 18*y^3 : 4*x^2*y),
866
+ Dynamical System of Projective Space of dimension 1 over Rational Field
867
+ Defn: Defined on coordinates by sending (x : y) to
868
+ (36*x^3 - 6*y^3 : 36*x^2*y)]
869
+ sage: HS_all_minimal(f, D=[3])
870
+ [Dynamical System of Projective Space of dimension 1 over Rational Field
871
+ Defn: Defined on coordinates by sending (x : y) to
872
+ (x^3 - 36*y^3 : x^2*y),
873
+ Dynamical System of Projective Space of dimension 1 over Rational Field
874
+ Defn: Defined on coordinates by sending (x : y) to
875
+ (9*x^3 - 12*y^3 : 9*x^2*y)]
876
+
877
+ ::
878
+
879
+ sage: P.<x,y> = ProjectiveSpace(QQ,1)
880
+ sage: f = DynamicalSystem([x^3 - 6^2*y^3, x*y^2])
881
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import HS_all_minimal
882
+ sage: cl = HS_all_minimal(f, return_transformation=True)
883
+ sage: all(f.conjugate(m) == g for g, m in cl)
884
+ True
885
+ """
886
+ MS = MatrixSpace(ZZ, 2)
887
+ m = MS.one()
888
+ F = copy(f)
889
+ F.normalize_coordinates()
890
+ if F.degree() == 1:
891
+ raise ValueError("function must be degree at least 2")
892
+ if f.degree() % 2 == 0:
893
+ #there is only one orbit for even degree
894
+ if return_transformation:
895
+ return [[f, m]]
896
+ else:
897
+ return [f]
898
+ if D is None:
899
+ res = ZZ(F.resultant())
900
+ D = res.prime_divisors()
901
+ M = [[F, m]]
902
+ for p in D:
903
+ # get p-orbits
904
+ Mp = HS_all_minimal_p(p, F, m, return_transformation=True)
905
+ # combine with previous orbits representatives
906
+ M = [[g.conjugate(t), t*s] for g,s in M for G,t in Mp]
907
+
908
+ if return_transformation:
909
+ return M
910
+ else:
911
+ return [funct for funct, matr in M]
912
+
913
+ #######################
914
+ #functionality for smallest coefficients
915
+ #
916
+ # Ben Hutz July 2018
917
+ #####################################3
918
+
919
+
920
+ def get_bound_dynamical(F, f, m=1, dynatomic=True, prec=53, emb=None):
921
+ """
922
+ The hyperbolic distance from `j` which must contain the smallest map.
923
+
924
+ This defines the maximum possible distance from `j` to the `z_0` covariant
925
+ of the associated binary form `F` in the hyperbolic 3-space
926
+ for which the map `f` could have smaller coefficients.
927
+
928
+ INPUT:
929
+
930
+ - ``F`` -- binary form of degree at least 3 with no multiple roots associated
931
+ to ``f``
932
+
933
+ - ``f`` -- a dynamical system on `P^1`
934
+
935
+ - ``m`` -- positive integer. the period used to create ``F``
936
+
937
+ - ``dynatomic`` -- boolean. whether ``F`` is the periodic points or the
938
+ formal periodic points of period ``m`` for ``f``
939
+
940
+ - ``prec`` -- positive integer. precision to use in CC
941
+
942
+ - ``emb`` -- embedding into CC
943
+
944
+ OUTPUT: a positive real number
945
+
946
+ EXAMPLES::
947
+
948
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import get_bound_dynamical
949
+ sage: P.<x,y> = ProjectiveSpace(QQ,1)
950
+ sage: f = DynamicalSystem([50*x^2 + 795*x*y + 2120*y^2, 265*x^2 + 106*y^2])
951
+ sage: get_bound_dynamical(f.dynatomic_polynomial(1), f) # needs sage.symbolic
952
+ 35.5546923182219
953
+ """
954
+ from sage.symbolic.constants import e
955
+
956
+ def coshdelta(z):
957
+ #The cosh of the hyperbolic distance from z = t+uj to j
958
+ return (z.norm() + 1)/(2*z.imag())
959
+ if F.base_ring() != ComplexField(prec=prec):
960
+ if emb is None:
961
+ compF = F.change_ring(ComplexField(prec=prec))
962
+ else:
963
+ compF = F.change_ring(emb)
964
+ else:
965
+ compF = F
966
+ n = F.degree()
967
+
968
+ z0F, thetaF = covariant_z0(compF, prec=prec, emb=emb)
969
+ d = f.degree()
970
+ hF = e**f.global_height(prec=prec)
971
+ #get precomputed constants C,k
972
+ if m == 1:
973
+ C = 4*d+2
974
+ k = 2
975
+ else:
976
+ Ck_values = {(False, 2, 2): (322, 6), (False, 2, 3): (385034, 14),
977
+ (False, 2, 4): (4088003923454, 30), (False, 3, 2): (18044, 8),
978
+ (False, 4, 2): (1761410, 10), (False, 5, 2): (269283820, 12),
979
+ (True, 2, 2): (43, 4), (True, 2, 3): (106459, 12),
980
+ (True, 2, 4): (39216735905, 24), (True, 3, 2): (1604, 6),
981
+ (True, 4, 2): (114675, 8), (True, 5, 2): (14158456, 10)}
982
+ try:
983
+ C, k = Ck_values[(dynatomic,d,m)]
984
+ except KeyError:
985
+ raise ValueError("constants not computed for this (m,d) pair")
986
+ if n == 2 and d == 2:
987
+ #bound with epsilonF = 1
988
+ bound = 2*((2*C*(hF**k))/(thetaF))
989
+ else:
990
+ bound = cosh(epsinv(F, (2**(n-1))*C*(hF**k)/thetaF, prec=prec))
991
+ return bound
992
+
993
+
994
+ def smallest_dynamical(f, dynatomic=True, start_n=1, prec=53, emb=None, algorithm='HS', check_minimal=True):
995
+ r"""
996
+ Determine the poly with smallest coefficients in `SL(2,\ZZ)` orbit of ``F``.
997
+
998
+ Smallest is in the sense of global height.
999
+ The method is the algorithm in Hutz-Stoll [HS2018]_.
1000
+ A binary form defining the periodic points is associated to ``f``.
1001
+ From this polynomial a bound on the search space can be determined.
1002
+
1003
+ ``f`` should already be a minimal model or finding the orbit
1004
+ representatives may give wrong results.
1005
+
1006
+ INPUT:
1007
+
1008
+ - ``f`` -- a dynamical system on `P^1`
1009
+
1010
+ - ``dynatomic`` -- boolean. whether ``F`` is the periodic points or the
1011
+ formal periodic points of period ``m`` for ``f``
1012
+
1013
+ - ``start_n`` -- positive integer. the period used to start trying to
1014
+ create associate binary form ``F``
1015
+
1016
+ - ``prec`` -- positive integer. precision to use in CC
1017
+
1018
+ - ``emb`` -- embedding into CC
1019
+
1020
+ - ``algorithm`` -- (optional) string; either ``'BM'`` for the Bruin-Molnar
1021
+ algorithm or ``'HS'`` for the Hutz-Stoll algorithm. If not specified,
1022
+ properties of the map are utilized to choose how to compute minimal
1023
+ orbit representatives
1024
+
1025
+ - ``check_minimal`` -- (default: ``True``), boolean, whether to check
1026
+ if this map is a minimal model
1027
+
1028
+ OUTPUT: pair [dynamical system, matrix]
1029
+
1030
+ EXAMPLES::
1031
+
1032
+ sage: from sage.dynamics.arithmetic_dynamics.endPN_minimal_model import smallest_dynamical
1033
+ sage: P.<x,y> = ProjectiveSpace(QQ,1)
1034
+ sage: f = DynamicalSystem([50*x^2 + 795*x*y + 2120*y^2, 265*x^2 + 106*y^2])
1035
+ sage: smallest_dynamical(f) # long time
1036
+ [
1037
+ Dynamical System of Projective Space of dimension 1 over Rational Field
1038
+ Defn: Defined on coordinates by sending (x : y) to
1039
+ (-480*x^2 - 1125*x*y + 1578*y^2 : 265*x^2 + 1060*x*y + 1166*y^2),
1040
+ <BLANKLINE>
1041
+ [1 2]
1042
+ [0 1]
1043
+ ]
1044
+ """
1045
+ from sage.symbolic.constants import e
1046
+
1047
+ def insert_item(pts, item, index):
1048
+ # binary insertion to maintain list of points left to consider
1049
+ N = len(pts)
1050
+ if N == 0:
1051
+ return [item]
1052
+ elif N == 1:
1053
+ if item[index] > pts[0][index]:
1054
+ pts.insert(0, item)
1055
+ else:
1056
+ pts.append(item)
1057
+ return pts
1058
+ else: # binary insertion
1059
+ left = 1
1060
+ right = N
1061
+ mid = (left + right) // 2 # these are ints so this is .floor()
1062
+ if item[index] > pts[mid][index]: # item goes into first half
1063
+ return insert_item(pts[:mid], item, index) + pts[mid:N]
1064
+ else: # item goes into second half
1065
+ return pts[:mid] + insert_item(pts[mid:N], item, index)
1066
+
1067
+ def coshdelta(z):
1068
+ # The cosh of the hyperbolic distance from z = t+uj to j
1069
+ return (z.norm() + 1)/(2*z.imag())
1070
+
1071
+ # can't be smaller if height 0
1072
+ f.normalize_coordinates()
1073
+ if f.global_height(prec=prec) == 0:
1074
+ return [f, matrix(ZZ,2,2,[1,0,0,1])]
1075
+ all_min = f.all_minimal_models(return_transformation=True, algorithm=algorithm, check_minimal=check_minimal)
1076
+
1077
+ current_min = None
1078
+ current_size = None
1079
+ # search for minimum over all orbits
1080
+ for g,M in all_min:
1081
+ PS = g.domain()
1082
+ CR = PS.coordinate_ring()
1083
+ x,y = CR.gens()
1084
+ n = start_n # sometimes you get a problem later with 0,infty as roots
1085
+ if dynatomic:
1086
+ pts_poly = g.dynatomic_polynomial(n)
1087
+ else:
1088
+ gn = g.nth_iterate_map(n)
1089
+ pts_poly = y*gn[0] - x*gn[1]
1090
+ d = ZZ(pts_poly.degree())
1091
+ max_mult = max([ex for p,ex in pts_poly.factor()])
1092
+ while ((d < 3) or (max_mult >= d/2) and (n < 5)):
1093
+ n = n+1
1094
+ if dynatomic:
1095
+ pts_poly = g.dynatomic_polynomial(n)
1096
+ else:
1097
+ gn = g.nth_iterate_map(n)
1098
+ pts_poly = y*gn[0] - x*gn[1]
1099
+ d = ZZ(pts_poly.degree())
1100
+ max_mult = max([ex for _, ex in pts_poly.factor()])
1101
+ assert (n <= 4), "n > 4, failed to find usable poly"
1102
+
1103
+ R = get_bound_dynamical(pts_poly, g, m=n, dynatomic=dynatomic, prec=prec, emb=emb)
1104
+ # search starts in fundamental domain
1105
+ G,MG = pts_poly.reduced_form(prec=prec, emb=emb, smallest_coeffs=False)
1106
+ red_g = f.conjugate(M*MG)
1107
+ if G != pts_poly:
1108
+ R2 = get_bound_dynamical(G, red_g, m=n, dynatomic=dynatomic, prec=prec, emb=emb)
1109
+ R = min(R2, R)
1110
+ red_g.normalize_coordinates()
1111
+ if red_g.global_height(prec=prec) == 0:
1112
+ return [red_g, M*MG]
1113
+
1114
+ # height
1115
+ if current_size is None:
1116
+ current_size = e**red_g.global_height(prec=prec)
1117
+ v0, th = covariant_z0(G, prec=prec, emb=emb)
1118
+ rep = 2*CC.gen(0)
1119
+ from math import isnan
1120
+ if isnan(v0.abs()):
1121
+ raise ValueError("invalid covariant: %s" % v0)
1122
+
1123
+ # get orbit
1124
+ S = matrix(ZZ,2,2,[0,-1,1,0])
1125
+ T = matrix(ZZ,2,2,[1,1,0,1])
1126
+ TI = matrix(ZZ,2,2,[1,-1,0,1])
1127
+
1128
+ count = 0
1129
+ pts = [[G, red_g, v0, rep, M*MG, coshdelta(v0), 0]] # label - 0:None, 1:S, 2:T, 3:T^(-1)
1130
+ if current_min is None:
1131
+ current_min = [G, red_g, v0, rep, M*MG, coshdelta(v0)]
1132
+ while pts != []:
1133
+ G, g, v, rep, M, D, label = pts.pop()
1134
+ # apply ST and keep z, Sz
1135
+ if D > R:
1136
+ break # all remaining pts are too far away
1137
+ # check if it is smaller. If so, we can improve the bound
1138
+ count += 1
1139
+ new_size = e**g.global_height(prec=prec)
1140
+ if new_size < current_size:
1141
+ current_min = [G, g, v, rep, M, coshdelta(v)]
1142
+ current_size = new_size
1143
+ if new_size == 1: # early exit
1144
+ return [current_min[1], current_min[4]]
1145
+ new_R = get_bound_dynamical(G, g, m=n, dynatomic=dynatomic, prec=prec, emb=emb)
1146
+ R = min(new_R, R)
1147
+
1148
+ # add new points to check
1149
+ if label != 1 and min((rep+1).norm(), (rep-1).norm()) >= 1: # don't undo S
1150
+ # the 2nd condition is equivalent to |\Re(-1/rep)| <= 1/2
1151
+ # this means that rep can have resulted from an inversion step in
1152
+ # the shift-and-invert procedure, so don't invert
1153
+
1154
+ # do inversion
1155
+ z = -1/v
1156
+ new_pt = [G.subs({x:-y, y:x}), g.conjugate(S), z, -1/rep, M*S, coshdelta(z), 1]
1157
+ pts = insert_item(pts, new_pt, 5)
1158
+ if label != 3: # don't undo T on g
1159
+ # do right shift
1160
+ z = v-1
1161
+ new_pt = [G.subs({x:x+y}), g.conjugate(TI), z, rep-1, M*TI, coshdelta(z), 2]
1162
+ pts = insert_item(pts, new_pt, 5)
1163
+ if label != 2: # don't undo TI on g
1164
+ # do left shift
1165
+ z = v+1
1166
+ new_pt = [G.subs({x:x-y}), g.conjugate(T), z, rep+1, M*T, coshdelta(z), 3]
1167
+ pts = insert_item(pts, new_pt, 5)
1168
+
1169
+ return [current_min[1], current_min[4]]