Index: head/math/sage/files/patch-build_pkgs_giac_spkg-configure.m4 =================================================================== --- head/math/sage/files/patch-build_pkgs_giac_spkg-configure.m4 (revision 568678) +++ head/math/sage/files/patch-build_pkgs_giac_spkg-configure.m4 (revision 568679) @@ -1,11 +1,30 @@ ---- build/pkgs/giac/spkg-configure.m4.orig 2020-10-04 14:57:22 UTC +--- build/pkgs/giac/spkg-configure.m4.orig 2021-03-16 21:40:45 UTC +++ build/pkgs/giac/spkg-configure.m4 -@@ -2,7 +2,7 @@ SAGE_SPKG_CONFIGURE([giac], [ - SAGE_SPKG_DEPCHECK([pari], [ - dnl giac does not seem to reveal its patchlevel - m4_pushdef([GIAC_MIN_VERSION], [1.5.0]) +@@ -1,26 +1,8 @@ + SAGE_SPKG_CONFIGURE([giac], [ +- SAGE_SPKG_DEPCHECK([pari], [ +- dnl giac does not seem to reveal its patchlevel +- m4_pushdef([GIAC_MIN_VERSION], [1.5.0]) - m4_pushdef([GIAC_MAX_VERSION], [1.5.999]) -+ m4_pushdef([GIAC_MAX_VERSION], [1.6.1]) - AC_CACHE_CHECK([for giac >= ]GIAC_MIN_VERSION[, <= ]GIAC_MAX_VERSION, [ac_cv_path_GIAC], [ - AC_PATH_PROGS_FEATURE_CHECK([GIAC], [giac], [ - giac_version=$($ac_path_GIAC --version 2> /dev/null | tail -1) +- AC_CACHE_CHECK([for giac >= ]GIAC_MIN_VERSION[, <= ]GIAC_MAX_VERSION, [ac_cv_path_GIAC], [ +- AC_PATH_PROGS_FEATURE_CHECK([GIAC], [giac], [ +- giac_version=$($ac_path_GIAC --version 2> /dev/null | tail -1) +- AS_IF([test -n "$giac_version"], [ +- AX_COMPARE_VERSION([$giac_version], [ge], GIAC_MIN_VERSION, [ +- AX_COMPARE_VERSION([$giac_version], [le], GIAC_MAX_VERSION, [ +- ac_cv_path_GIAC="$ac_path_GIAC" +- ]) +- ]) +- ]) +- ]) +- ]) +- AS_IF([test -z "$ac_cv_path_GIAC"], +- [sage_spkg_install_giac=yes]) ++ SAGE_SPKG_DEPCHECK([glpk pari], [ + AC_CHECK_HEADER([giac/giac.h], [ + AC_SEARCH_LIBS([ConvertUTF16toUTF8], [giac], [ + ], [sage_spkg_install_giac=yes]) + ], [sage_spkg_install_giac=yes]) +- m4_popdef([GIAC_MIN_VERSION]) + ]) + ]) Index: head/math/sage/files/patch-src_sage_libs_eclib_____init____.pxd =================================================================== --- head/math/sage/files/patch-src_sage_libs_eclib_____init____.pxd (nonexistent) +++ head/math/sage/files/patch-src_sage_libs_eclib_____init____.pxd (revision 568679) @@ -0,0 +1,17 @@ +--- src/sage/libs/eclib/__init__.pxd.orig 2021-03-16 21:40:43 UTC ++++ src/sage/libs/eclib/__init__.pxd +@@ -8,9 +8,11 @@ from libcpp.pair cimport pair + from sage.libs.ntl.types cimport ZZ_c + + +-# NOTE: eclib includes have specific dependencies and must be included +-# in a specific order. So we start by listing all relevant include files +-# in the correct order. ++# NOTE: eclib used to have specific dependencies, so that they had to ++# be included in a specific order. Although this is no longer the ++# case, we start by listing all relevant include files in the correct ++# order. ++ + cdef extern from "eclib/vector.h": pass + cdef extern from "eclib/xmod.h": pass + cdef extern from "eclib/svector.h": pass Property changes on: head/math/sage/files/patch-src_sage_libs_eclib_____init____.pxd ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/math/sage/files/patch-src_sage_libs_eclib_interface.py =================================================================== --- head/math/sage/files/patch-src_sage_libs_eclib_interface.py (nonexistent) +++ head/math/sage/files/patch-src_sage_libs_eclib_interface.py (revision 568679) @@ -0,0 +1,699 @@ +--- src/sage/libs/eclib/interface.py.orig 2021-03-16 21:40:43 UTC ++++ src/sage/libs/eclib/interface.py +@@ -21,18 +21,17 @@ Check that ``eclib`` is imported as needed:: + sage: [k for k in sys.modules if k.startswith("sage.libs.eclib")] + [] + sage: EllipticCurve('11a1').mwrank_curve() +- y^2+ y = x^3 - x^2 - 10*x - 20 ++ y^2 + y = x^3 - x^2 - 10 x - 20 + sage: [k for k in sys.modules if k.startswith("sage.libs.eclib")] + ['...'] + """ +- ++import sys + from sage.structure.sage_object import SageObject + from sage.rings.all import Integer + from sage.rings.integer_ring import IntegerRing + +-from .mwrank import _Curvedata, _two_descent, _mw ++from .mwrank import _Curvedata, _two_descent, _mw, parse_point_list + +- + class mwrank_EllipticCurve(SageObject): + r""" + The :class:`mwrank_EllipticCurve` class represents an elliptic +@@ -67,7 +66,7 @@ class mwrank_EllipticCurve(SageObject): + + sage: e = mwrank_EllipticCurve([3, -4]) + sage: e +- y^2 = x^3 + 3*x - 4 ++ y^2 = x^3 + 3 x - 4 + sage: e.ainvs() + [0, 0, 0, 3, -4] + +@@ -127,6 +126,7 @@ class mwrank_EllipticCurve(SageObject): + + # place holders + self.__saturate = -2 # not yet saturated ++ self.__descent = None + + def __reduce__(self): + r""" +@@ -137,12 +137,9 @@ class mwrank_EllipticCurve(SageObject): + sage: E = mwrank_EllipticCurve([0,0,1,-7,6]) + sage: E.__reduce__() + (, ([0, 0, 1, -7, 6], False)) +- +- + """ + return mwrank_EllipticCurve, (self.__ainvs, self.__verbose) + +- + def set_verbose(self, verbose): + """ + Set the verbosity of printing of output by the :meth:`two_descent()` and +@@ -247,53 +244,27 @@ class mwrank_EllipticCurve(SageObject): + + sage: E = mwrank_EllipticCurve([0,-1,1,0,0]) + sage: E.__repr__() +- 'y^2+ y = x^3 - x^2 ' ++ 'y^2 + y = x^3 - x^2' + """ +- # TODO: Is the use (or omission) of spaces here intentional? +- a = self.ainvs() +- s = "y^2" +- if a[0] == -1: +- s += "- x*y " +- elif a[0] == 1: +- s += "+ x*y " +- elif a[0] != 0: +- s += "+ %s*x*y "%a[0] +- if a[2] == -1: +- s += " - y" +- elif a[2] == 1: +- s += "+ y" +- elif a[2] != 0: +- s += "+ %s*y"%a[2] +- s += " = x^3 " +- if a[1] == -1: +- s += "- x^2 " +- elif a[1] == 1: +- s += "+ x^2 " +- elif a[1] != 0: +- s += "+ %s*x^2 "%a[1] +- if a[3] == -1: +- s += "- x " +- elif a[3] == 1: +- s += "+ x " +- elif a[3] != 0: +- s += "+ %s*x "%a[3] +- if a[4] == -1: +- s += "-1" +- elif a[4] == 1: +- s += "+1" +- elif a[4] != 0: +- s += "+ %s"%a[4] +- s = s.replace("+ -","- ") +- return s ++ a1, a2, a3, a4, a6 = self.__ainvs ++ # we do not assume a1, a2, a3 are reduced to {0,1}, {-1,0,1}, {0,1} ++ coeff = lambda a: ''.join([" +" if a > 0 else " -", ++ " " + str(abs(a)) if abs(a) > 1 else ""]) ++ return ''.join(['y^2', ++ ' '.join([coeff(a1), 'xy']) if a1 else '', ++ ' '.join([coeff(a3), 'y']) if a3 else '', ++ ' = x^3', ++ ' '.join([coeff(a2), 'x^2']) if a2 else '', ++ ' '.join([coeff(a4), 'x']) if a4 else '', ++ ' '.join([" +" if a6 > 0 else " -", str(abs(a6))]) if a6 else '']) + +- + def two_descent(self, +- verbose = True, +- selmer_only = False, +- first_limit = 20, +- second_limit = 8, +- n_aux = -1, +- second_descent = True): ++ verbose=True, ++ selmer_only=False, ++ first_limit=20, ++ second_limit=8, ++ n_aux=-1, ++ second_descent=True): + r""" + Compute 2-descent data for this curve. + +@@ -374,16 +345,14 @@ class mwrank_EllipticCurve(SageObject): + second_limit = int(second_limit) + n_aux = int(n_aux) + second_descent = int(second_descent) # convert from bool to (int) 0 or 1 +- # TODO: Don't allow limits above some value...??? +- # (since otherwise mwrank just sets limit tiny) + self.__descent = _two_descent() + self.__descent.do_descent(self.__curve, +- verbose, +- selmer_only, +- first_limit, +- second_limit, +- n_aux, +- second_descent) ++ verbose, ++ selmer_only, ++ first_limit, ++ second_limit, ++ n_aux, ++ second_descent) + if not self.__descent.ok(): + raise RuntimeError("A 2-descent did not complete successfully.") + self.__saturate = -2 # not yet saturated +@@ -398,11 +367,9 @@ class mwrank_EllipticCurve(SageObject): + sage: E._mwrank_EllipticCurve__two_descent_data() + + """ +- try: +- return self.__descent +- except AttributeError: ++ if self.__descent is None: + self.two_descent(self.__verbose) +- return self.__descent ++ return self.__descent + + def conductor(self): + """ +@@ -565,22 +532,24 @@ class mwrank_EllipticCurve(SageObject): + R = self.__two_descent_data().regulator() + return float(R) + +- def saturate(self, bound=-1): ++ def saturate(self, bound=-1, lower=2): + """ +- Compute the saturation of the Mordell-Weil group at all +- primes up to ``bound``. ++ Compute the saturation of the Mordell-Weil group. + + INPUT: + +- - ``bound`` (int, default -1) -- Use `-1` (the default) to +- saturate at *all* primes, `0` for no saturation, or `n` (a +- positive integer) to saturate at all primes up to `n`. ++ - ``bound`` (int, default -1) -- If `-1`, saturate at *all* ++ primes by computing a bound on the saturation index, ++ otherwise saturate at all primes up to the minimum of ++ ``bound`` and the saturation index bound. + ++ - ``lower`` (int, default 2) -- Only saturate at primes not ++ less than this. ++ + EXAMPLES: + + Since the 2-descent automatically saturates at primes up to +- 20, it is not easy to come up with an example where saturation +- has any effect:: ++ 20, further saturation often has no effect:: + + sage: E = mwrank_EllipticCurve([0, 0, 0, -1002231243161, 0]) + sage: E.gens() +@@ -599,7 +568,7 @@ class mwrank_EllipticCurve(SageObject): + """ + bound = int(bound) + if self.__saturate < bound: +- self.__two_descent_data().saturate(bound) ++ self.__two_descent_data().saturate(bound, lower) + self.__saturate = bound + + def gens(self): +@@ -613,8 +582,7 @@ class mwrank_EllipticCurve(SageObject): + [[0, -1, 1]] + """ + self.saturate() +- L = eval(self.__two_descent_data().getbasis().replace(":",",")) +- return [[Integer(x), Integer(y), Integer(z)] for (x,y,z) in L] ++ return parse_point_list(self.__two_descent_data().getbasis()) + + def certain(self): + r""" +@@ -760,65 +728,37 @@ class mwrank_MordellWeil(SageObject): + sage: EQ.search(1) + P1 = [0:1:0] is torsion point, order 1 + P1 = [-3:0:1] is generator number 1 +- saturating up to 20...Checking 2-saturation +- Points have successfully been 2-saturated (max q used = 7) +- Checking 3-saturation +- Points have successfully been 3-saturated (max q used = 7) +- Checking 5-saturation +- Points have successfully been 5-saturated (max q used = 23) +- Checking 7-saturation +- Points have successfully been 7-saturated (max q used = 41) +- Checking 11-saturation +- Points have successfully been 11-saturated (max q used = 17) +- Checking 13-saturation +- Points have successfully been 13-saturated (max q used = 43) +- Checking 17-saturation +- Points have successfully been 17-saturated (max q used = 31) +- Checking 19-saturation +- Points have successfully been 19-saturated (max q used = 37) ++ saturating up to 20...Saturation index bound (for points of good reduction) = 3 ++ Reducing saturation bound from given value 20 to computed index bound 3 ++ Checking saturation at [ 2 3 ] ++ Checking 2-saturation ++ Points were proved 2-saturated (max q used = 7) ++ Checking 3-saturation ++ Points were proved 3-saturated (max q used = 7) + done + P2 = [-2:3:1] is generator number 2 +- saturating up to 20...Checking 2-saturation ++ saturating up to 20...Saturation index bound (for points of good reduction) = 4 ++ Reducing saturation bound from given value 20 to computed index bound 4 ++ Checking saturation at [ 2 3 ] ++ Checking 2-saturation + possible kernel vector = [1,1] + This point may be in 2E(Q): [14:-52:1] +- ...and it is! ++ ...and it is! + Replacing old generator #1 with new generator [1:-1:1] ++ Reducing index bound from 4 to 2 + Points have successfully been 2-saturated (max q used = 7) + Index gain = 2^1 +- Checking 3-saturation +- Points have successfully been 3-saturated (max q used = 13) +- Checking 5-saturation +- Points have successfully been 5-saturated (max q used = 67) +- Checking 7-saturation +- Points have successfully been 7-saturated (max q used = 53) +- Checking 11-saturation +- Points have successfully been 11-saturated (max q used = 73) +- Checking 13-saturation +- Points have successfully been 13-saturated (max q used = 103) +- Checking 17-saturation +- Points have successfully been 17-saturated (max q used = 113) +- Checking 19-saturation +- Points have successfully been 19-saturated (max q used = 47) +- done (index = 2). ++ done, index = 2. + Gained index 2, new generators = [ [1:-1:1] [-2:3:1] ] + P3 = [-14:25:8] is generator number 3 +- saturating up to 20...Checking 2-saturation +- Points have successfully been 2-saturated (max q used = 11) +- Checking 3-saturation +- Points have successfully been 3-saturated (max q used = 13) +- Checking 5-saturation +- Points have successfully been 5-saturated (max q used = 71) +- Checking 7-saturation +- Points have successfully been 7-saturated (max q used = 101) +- Checking 11-saturation +- Points have successfully been 11-saturated (max q used = 127) +- Checking 13-saturation +- Points have successfully been 13-saturated (max q used = 151) +- Checking 17-saturation +- Points have successfully been 17-saturated (max q used = 139) +- Checking 19-saturation +- Points have successfully been 19-saturated (max q used = 179) +- done (index = 1). ++ saturating up to 20...Saturation index bound (for points of good reduction) = 3 ++ Reducing saturation bound from given value 20 to computed index bound 3 ++ Checking saturation at [ 2 3 ] ++ Checking 2-saturation ++ Points were proved 2-saturated (max q used = 11) ++ Checking 3-saturation ++ Points were proved 3-saturated (max q used = 13) ++ done, index = 1. + P4 = [-1:3:1] = -1*P1 + -1*P2 + -1*P3 (mod torsion) + P4 = [0:2:1] = 2*P1 + 0*P2 + 1*P3 (mod torsion) + P4 = [2:13:8] = -3*P1 + 1*P2 + -1*P3 (mod torsion) +@@ -878,7 +818,7 @@ class mwrank_MordellWeil(SageObject): + sage: E = mwrank_EllipticCurve([0,0,1,-7,6]) + sage: EQ = mwrank_MordellWeil(E) + sage: EQ.__reduce__() +- (, (y^2+ y = x^3 - 7*x + 6, True, 1, 999)) ++ (, (y^2 + y = x^3 - 7 x + 6, True, 1, 999)) + """ + return mwrank_MordellWeil, (self.__curve, self.__verbose, self.__pp, self.__maxr) + +@@ -902,21 +842,20 @@ class mwrank_MordellWeil(SageObject): + """ + return "Subgroup of Mordell-Weil group: %s"%self.__mw + +- def process(self, v, sat=0): +- """ ++ def process(self, v, saturation_bound=0): ++ """Process points in the list ``v``. ++ + This function allows one to add points to a :class:`mwrank_MordellWeil` object. + +- Process points in the list ``v``, with saturation at primes up to +- ``sat``. If ``sat`` is zero (the default), do no saturation. +- + INPUT: + + - ``v`` (list of 3-tuples or lists of ints or Integers) -- a + list of triples of integers, which define points on the + curve. + +- - ``sat`` (int, default 0) -- saturate at primes up to ``sat``, or at +- *all* primes if ``sat`` is zero. ++ - ``saturation_bound`` (int, default 0) -- saturate at primes up to ++ ``saturation_bound``, or at *all* primes if ``saturation_bound`` is -1; when ``saturation_bound`` ++ is 0 (the default), do no saturation.. + + OUTPUT: + +@@ -939,11 +878,11 @@ class mwrank_MordellWeil(SageObject): + sage: EQ.points() + [[1, -1, 1], [-2, 3, 1], [-14, 25, 8]] + +- Example to illustrate the saturation parameter ``sat``:: ++ Example to illustrate the saturation parameter ``saturation_bound``:: + + sage: E = mwrank_EllipticCurve([0,0,1,-7,6]) + sage: EQ = mwrank_MordellWeil(E) +- sage: EQ.process([[1547, -2967, 343], [2707496766203306, 864581029138191, 2969715140223272], [-13422227300, -49322830557, 12167000000]], sat=20) ++ sage: EQ.process([[1547, -2967, 343], [2707496766203306, 864581029138191, 2969715140223272], [-13422227300, -49322830557, 12167000000]], saturation_bound=20) + P1 = [1547:-2967:343] is generator number 1 + ... + Gained index 5, new generators = [ [-2:3:1] [-14:25:8] [1:-1:1] ] +@@ -956,7 +895,7 @@ class mwrank_MordellWeil(SageObject): + + sage: E = mwrank_EllipticCurve([0,0,1,-7,6]) + sage: EQ = mwrank_MordellWeil(E) +- sage: EQ.process([[1547, -2967, 343], [2707496766203306, 864581029138191, 2969715140223272], [-13422227300, -49322830557, 12167000000]], sat=0) ++ sage: EQ.process([[1547, -2967, 343], [2707496766203306, 864581029138191, 2969715140223272], [-13422227300, -49322830557, 12167000000]], saturation_bound=0) + P1 = [1547:-2967:343] is generator number 1 + P2 = [2707496766203306:864581029138191:2969715140223272] is generator number 2 + P3 = [-13422227300:-49322830557:12167000000] is generator number 3 +@@ -965,55 +904,92 @@ class mwrank_MordellWeil(SageObject): + sage: EQ.regulator() + 375.42920288254555 + sage: EQ.saturate(2) # points were not 2-saturated +- saturating basis...Saturation index bound = 93 +- WARNING: saturation at primes p > 2 will not be done; +- ... ++ saturating basis...Saturation index bound (for points of good reduction) = 93 ++ Only p-saturating for p up to given value 2. ++ The resulting points may not be p-saturated for p between this and the computed index bound 93 ++ Checking saturation at [ 2 ] ++ Checking 2-saturation ++ possible kernel vector = [1,0,0] ++ This point may be in 2E(Q): [1547:-2967:343] ++ ...and it is! ++ Replacing old generator #1 with new generator [-2:3:1] ++ Reducing index bound from 93 to 46 ++ Points have successfully been 2-saturated (max q used = 11) ++ Index gain = 2^1 ++ done + Gained index 2 +- New regulator = 93.857... +- (False, 2, '[ ]') ++ New regulator = 93.85730072 ++ (True, 2, '[ ]') + sage: EQ.points() + [[-2, 3, 1], [2707496766203306, 864581029138191, 2969715140223272], [-13422227300, -49322830557, 12167000000]] + sage: EQ.regulator() + 93.85730072063639 + sage: EQ.saturate(3) # points were not 3-saturated +- saturating basis...Saturation index bound = 46 +- WARNING: saturation at primes p > 3 will not be done; +- ... ++ saturating basis...Saturation index bound (for points of good reduction) = 46 ++ Only p-saturating for p up to given value 3. ++ The resulting points may not be p-saturated for p between this and the computed index bound 46 ++ Checking saturation at [ 2 3 ] ++ Checking 2-saturation ++ Points were proved 2-saturated (max q used = 11) ++ Checking 3-saturation ++ possible kernel vector = [0,1,0] ++ This point may be in 3E(Q): [2707496766203306:864581029138191:2969715140223272] ++ ...and it is! ++ Replacing old generator #2 with new generator [-14:25:8] ++ Reducing index bound from 46 to 15 ++ Points have successfully been 3-saturated (max q used = 13) ++ Index gain = 3^1 ++ done + Gained index 3 +- New regulator = 10.428... +- (False, 3, '[ ]') ++ New regulator = 10.42858897 ++ (True, 3, '[ ]') + sage: EQ.points() + [[-2, 3, 1], [-14, 25, 8], [-13422227300, -49322830557, 12167000000]] + sage: EQ.regulator() + 10.4285889689596 + sage: EQ.saturate(5) # points were not 5-saturated +- saturating basis...Saturation index bound = 15 +- WARNING: saturation at primes p > 5 will not be done; +- ... ++ saturating basis...Saturation index bound (for points of good reduction) = 15 ++ Only p-saturating for p up to given value 5. ++ The resulting points may not be p-saturated for p between this and the computed index bound 15 ++ Checking saturation at [ 2 3 5 ] ++ Checking 2-saturation ++ Points were proved 2-saturated (max q used = 11) ++ Checking 3-saturation ++ Points were proved 3-saturated (max q used = 13) ++ Checking 5-saturation ++ possible kernel vector = [0,0,1] ++ This point may be in 5E(Q): [-13422227300:-49322830557:12167000000] ++ ...and it is! ++ Replacing old generator #3 with new generator [1:-1:1] ++ Reducing index bound from 15 to 3 ++ Points have successfully been 5-saturated (max q used = 71) ++ Index gain = 5^1 ++ done + Gained index 5 +- New regulator = 0.417... +- (False, 5, '[ ]') ++ New regulator = 0.4171435588 ++ (True, 5, '[ ]') + sage: EQ.points() + [[-2, 3, 1], [-14, 25, 8], [1, -1, 1]] + sage: EQ.regulator() + 0.417143558758384 + sage: EQ.saturate() # points are now saturated +- saturating basis...Saturation index bound = 3 ++ saturating basis...Saturation index bound (for points of good reduction) = 3 ++ Tamagawa index primes are [ ] + Checking saturation at [ 2 3 ] +- Checking 2-saturation ++ Checking 2-saturation + Points were proved 2-saturated (max q used = 11) +- Checking 3-saturation ++ Checking 3-saturation + Points were proved 3-saturated (max q used = 13) + done + (True, 1, '[ ]') + """ + if not isinstance(v, list): + raise TypeError("v (=%s) must be a list"%v) +- sat = int(sat) ++ saturation_bound = int(saturation_bound) + for P in v: +- if not isinstance(P, (list,tuple)) or len(P) != 3: ++ if not isinstance(P, (list, tuple)) or len(P) != 3: + raise TypeError("v (=%s) must be a list of 3-tuples (or 3-element lists) of ints"%v) +- self.__mw.process(P, sat) ++ self.__mw.process(P, saturation_bound) + + def regulator(self): + """ +@@ -1091,23 +1067,21 @@ class mwrank_MordellWeil(SageObject): + """ + return self.__mw.rank() + +- def saturate(self, max_prime=-1, odd_primes_only=False): +- r""" +- Saturate this subgroup of the Mordell-Weil group. ++ def saturate(self, max_prime=-1, min_prime=2): ++ r"""Saturate this subgroup of the Mordell-Weil group. + + INPUT: + +- - ``max_prime`` (int, default -1) -- saturation is performed for +- all primes up to ``max_prime``. If `-1` (the default), an ++ - ``max_prime`` (int, default -1) -- If `-1` (the default), an + upper bound is computed for the primes at which the subgroup +- may not be saturated, and this is used; however, if the +- computed bound is greater than a value set by the ``eclib`` +- library (currently 97) then no saturation will be attempted +- at primes above this. ++ may not be saturated, and saturation is performed for all ++ primes up to this bound. Otherwise, the bound used is the ++ minimum of ``max_prime`` and the computed bound. + +- - ``odd_primes_only`` (bool, default ``False``) -- only do +- saturation at odd primes. (If the points have been found +- via :meth:`two_descent` they should already be 2-saturated.) ++ - ``min_prime`` (int, default 2) -- only do saturation at ++ primes no less than this. (For example, if the points have ++ been found via :meth:`two_descent` they should already be ++ 2-saturated so a value of 3 is appropriate.) + + OUTPUT: + +@@ -1115,40 +1089,35 @@ class mwrank_MordellWeil(SageObject): + + - ``ok`` (bool) -- ``True`` if and only if the saturation was + provably successful at all primes attempted. If the default +- was used for ``max_prime`` and no warning was output about +- the computed saturation bound being too high, then ``True`` +- indicates that the subgroup is saturated at *all* +- primes. ++ was used for ``max_prime``, then ``True`` indicates that the ++ subgroup is saturated at *all* primes. + + - ``index`` (int) -- the index of the group generated by the + original points in their saturation. + + - ``unsatlist`` (list of ints) -- list of primes at which +- saturation could not be proved or achieved. Increasing the +- precision should correct this, since it happens when +- a linear combination of the points appears to be a multiple +- of `p` but cannot be divided by `p`. (Note that ``eclib`` +- uses floating point methods based on elliptic logarithms to +- divide points.) ++ saturation could not be proved or achieved. + + .. note:: + +- We emphasize that if this function returns ``True`` as the +- first return argument (``ok``), and if the default was used for the +- parameter ``max_prime``, then the points in the basis after +- calling this function are saturated at *all* primes, +- i.e., saturating at the primes up to ``max_prime`` are +- sufficient to saturate at all primes. Note that the +- function might not have needed to saturate at all primes up +- to ``max_prime``. It has worked out what prime you need to +- saturate up to, and that prime might be smaller than ``max_prime``. ++ In versions up to v20190909, ``eclib`` used floating point ++ methods based on elliptic logarithms to divide points, and ++ did not compute the precision necessary, which could casue ++ failures. Since v20210310, ``eclib`` uses exact method based ++ on division polynomials, which should mean that such ++ failures does not happen. + + .. note:: + +- Currently (May 2010), this does not remember the result of +- calling :meth:`search()`. So calling :meth:`search()` up +- to height 20 then calling :meth:`saturate()` results in +- another search up to height 18. ++ We emphasize that if this function returns ``True`` as the ++ first return argument (``ok``), and if the default was used ++ for the parameter ``max_prime``, then the points in the ++ basis after calling this function are saturated at *all* ++ primes, i.e., saturating at the primes up to ``max_prime`` ++ are sufficient to saturate at all primes. Note that the ++ function computes an upper bound for the index of ++ saturation, and does no work for primes greater than this ++ even if ``max_prime`` is larger. + + EXAMPLES:: + +@@ -1160,7 +1129,7 @@ class mwrank_MordellWeil(SageObject): + automatic saturation at this stage we set the parameter + ``sat`` to 0 (which is in fact the default):: + +- sage: EQ.process([[1547, -2967, 343], [2707496766203306, 864581029138191, 2969715140223272], [-13422227300, -49322830557, 12167000000]], sat=0) ++ sage: EQ.process([[1547, -2967, 343], [2707496766203306, 864581029138191, 2969715140223272], [-13422227300, -49322830557, 12167000000]], saturation_bound=0) + P1 = [1547:-2967:343] is generator number 1 + P2 = [2707496766203306:864581029138191:2969715140223272] is generator number 2 + P3 = [-13422227300:-49322830557:12167000000] is generator number 3 +@@ -1172,12 +1141,12 @@ class mwrank_MordellWeil(SageObject): + Now we saturate at `p=2`, and gain index 2:: + + sage: EQ.saturate(2) # points were not 2-saturated +- saturating basis...Saturation index bound = 93 +- WARNING: saturation at primes p > 2 will not be done; ++ saturating basis...Saturation index bound (for points of good reduction) = 93 ++ Only p-saturating for p up to given value 2. + ... + Gained index 2 + New regulator = 93.857... +- (False, 2, '[ ]') ++ (True, 2, '[ ]') + sage: EQ + Subgroup of Mordell-Weil group: [[-2:3:1], [2707496766203306:864581029138191:2969715140223272], [-13422227300:-49322830557:12167000000]] + sage: EQ.regulator() +@@ -1186,12 +1155,12 @@ class mwrank_MordellWeil(SageObject): + Now we saturate at `p=3`, and gain index 3:: + + sage: EQ.saturate(3) # points were not 3-saturated +- saturating basis...Saturation index bound = 46 +- WARNING: saturation at primes p > 3 will not be done; ++ saturating basis...Saturation index bound (for points of good reduction) = 46 ++ Only p-saturating for p up to given value 3. + ... + Gained index 3 + New regulator = 10.428... +- (False, 3, '[ ]') ++ (True, 3, '[ ]') + sage: EQ + Subgroup of Mordell-Weil group: [[-2:3:1], [-14:25:8], [-13422227300:-49322830557:12167000000]] + sage: EQ.regulator() +@@ -1200,12 +1169,12 @@ class mwrank_MordellWeil(SageObject): + Now we saturate at `p=5`, and gain index 5:: + + sage: EQ.saturate(5) # points were not 5-saturated +- saturating basis...Saturation index bound = 15 +- WARNING: saturation at primes p > 5 will not be done; ++ saturating basis...Saturation index bound (for points of good reduction) = 15 ++ Only p-saturating for p up to given value 5. + ... + Gained index 5 + New regulator = 0.417... +- (False, 5, '[ ]') ++ (True, 5, '[ ]') + sage: EQ + Subgroup of Mordell-Weil group: [[-2:3:1], [-14:25:8], [1:-1:1]] + sage: EQ.regulator() +@@ -1215,7 +1184,8 @@ class mwrank_MordellWeil(SageObject): + the points are now provably saturated at all primes:: + + sage: EQ.saturate() # points are now saturated +- saturating basis...Saturation index bound = 3 ++ saturating basis...Saturation index bound (for points of good reduction) = 3 ++ Tamagawa index primes are [ ] + Checking saturation at [ 2 3 ] + Checking 2-saturation + Points were proved 2-saturated (max q used = 11) +@@ -1229,7 +1199,7 @@ class mwrank_MordellWeil(SageObject): + + sage: E = mwrank_EllipticCurve([0,0,1,-7,6]) + sage: EQ = mwrank_MordellWeil(E) +- sage: EQ.process([[1547, -2967, 343], [2707496766203306, 864581029138191, 2969715140223272], [-13422227300, -49322830557, 12167000000]], sat=5) ++ sage: EQ.process([[1547, -2967, 343], [2707496766203306, 864581029138191, 2969715140223272], [-13422227300, -49322830557, 12167000000]], saturation_bound=5) + P1 = [1547:-2967:343] is generator number 1 + ... + Gained index 5, new generators = [ [-2:3:1] [-14:25:8] [1:-1:1] ] +@@ -1242,7 +1212,8 @@ class mwrank_MordellWeil(SageObject): + verify that full saturation has been done:: + + sage: EQ.saturate() +- saturating basis...Saturation index bound = 3 ++ saturating basis...Saturation index bound (for points of good reduction) = 3 ++ Tamagawa index primes are [ ] + Checking saturation at [ 2 3 ] + Checking 2-saturation + Points were proved 2-saturated (max q used = 11) +@@ -1255,8 +1226,9 @@ class mwrank_MordellWeil(SageObject): + index of the points in their saturation is at most 3, then + proves saturation at 2 and at 3, by reducing the points modulo + all primes of good reduction up to 11, respectively 13. ++ + """ +- ok, index, unsat = self.__mw.saturate(int(max_prime), odd_primes_only) ++ ok, index, unsat = self.__mw.saturate(int(max_prime), int(min_prime)) + return bool(ok), int(str(index)), unsat + + def search(self, height_limit=18, verbose=False): +@@ -1271,9 +1243,9 @@ class mwrank_MordellWeil(SageObject): + + .. note:: + +- On 32-bit machines, this *must* be < 21.48 else ++ On 32-bit machines, this *must* be < 21.48 (`31\log(2)`) else + `\exp(h_{\text{lim}}) > 2^{31}` and overflows. On 64-bit machines, it +- must be *at most* 43.668. However, this bound is a logarithmic ++ must be *at most* 43.668 (`63\log(2)`) . However, this bound is a logarithmic + bound and increasing it by just 1 increases the running time + by (roughly) `\exp(1.5)=4.5`, so searching up to even 20 + takes a very long time. +@@ -1320,8 +1292,10 @@ class mwrank_MordellWeil(SageObject): + Subgroup of Mordell-Weil group: [[4413270:10381877:27000]] + """ + height_limit = float(height_limit) +- if height_limit >= 21.4: # TODO: docstring says 21.48 (for 32-bit machines; what about 64-bit...?) +- raise ValueError("The height limit must be < 21.4.") ++ int_bits = sys.maxsize.bit_length() ++ max_height_limit = int_bits * 0.693147 # log(2.0) = 0.693147 approx ++ if height_limit >= max_height_limit: ++ raise ValueError("The height limit must be < {} = {}log(2) on a {}-bit machine.".format(max_height_limit, int_bits, int_bits+1)) + + moduli_option = 0 # Use Stoll's sieving program... see strategies in ratpoints-1.4.c + +@@ -1352,5 +1326,4 @@ class mwrank_MordellWeil(SageObject): + [[1, -1, 1], [-2, 3, 1], [-14, 25, 8]] + + """ +- L = eval(self.__mw.getbasis().replace(":",",")) +- return [[Integer(x), Integer(y), Integer(z)] for (x,y,z) in L] ++ return self.__mw.getbasis() Property changes on: head/math/sage/files/patch-src_sage_libs_eclib_interface.py ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/math/sage/files/patch-src_sage_libs_eclib_mwrank.pyx =================================================================== --- head/math/sage/files/patch-src_sage_libs_eclib_mwrank.pyx (nonexistent) +++ head/math/sage/files/patch-src_sage_libs_eclib_mwrank.pyx (revision 568679) @@ -0,0 +1,418 @@ +--- src/sage/libs/eclib/mwrank.pyx.orig 2021-03-16 21:40:43 UTC ++++ src/sage/libs/eclib/mwrank.pyx +@@ -28,6 +28,7 @@ from cysignals.signals cimport sig_on, sig_off + from sage.cpython.string cimport char_to_str, str_to_bytes + from sage.cpython.string import FS_ENCODING + from sage.libs.eclib cimport bigint, Curvedata, mw, two_descent ++from sage.rings.all import Integer + + cdef extern from "wrap.cpp": + ### misc functions ### +@@ -55,8 +56,8 @@ cdef extern from "wrap.cpp": + char* mw_getbasis(mw* m) + double mw_regulator(mw* m) + int mw_rank(mw* m) +- int mw_saturate(mw* m, bigint* index, char** unsat, +- long sat_bd, int odd_primes_only) ++ int mw_saturate(mw* m, long* index, char** unsat, ++ long sat_bd, long sat_low_bd) + void mw_search(mw* m, char* h_lim, int moduli_option, int verb) + + ### two_descent ### +@@ -67,9 +68,8 @@ cdef extern from "wrap.cpp": + long two_descent_get_rank(two_descent* t) + long two_descent_get_rank_bound(two_descent* t) + long two_descent_get_selmer_rank(two_descent* t) +- void two_descent_saturate(two_descent* t, long sat_bd) ++ void two_descent_saturate(two_descent* t, long sat_bd, long sat_low_bd) + +- + cdef object string_sigoff(char* s): + sig_off() + # Makes a python string and deletes what is pointed to by s. +@@ -445,7 +445,6 @@ cdef class _Curvedata: # cython class wrapping eclib + -1269581104000000 + """ + sig_on() +- from sage.rings.all import Integer + return Integer(string_sigoff(Curvedata_getdiscr(self.x))) + + def conductor(self): +@@ -467,7 +466,6 @@ cdef class _Curvedata: # cython class wrapping eclib + 126958110400 + """ + sig_on() +- from sage.rings.all import Integer + return Integer(string_sigoff(Curvedata_conductor(self.x))) + + def isogeny_class(self, verbose=False): +@@ -503,6 +501,36 @@ cdef class _Curvedata: # cython class wrapping eclib + + ############# _mw ################# + ++def parse_point_list(s): ++ r""" ++ Parse a string representing a list of points. ++ ++ INPUT: ++ ++ - ``s`` (string) -- string representation of a list of points, for ++ example '[]', '[[1:2:3]]', or '[[1:2:3],[4:5:6]]'. ++ ++ OUTPUT: ++ ++ (list) a list of triples of integers, for example [], [[1,2,3]], [[1,2,3],[4,5,6]]. ++ ++ EXAMPLES:: ++ ++ sage: from sage.libs.eclib.mwrank import parse_point_list ++ sage: parse_point_list('[]') ++ [] ++ sage: parse_point_list('[[1:2:3]]') ++ [[1, 2, 3]] ++ sage: parse_point_list('[[1:2:3],[4:5:6]]') ++ [[1, 2, 3], [4, 5, 6]] ++ ++ """ ++ s = s.replace(":", ",").replace(" ", "") ++ if s == '[]': ++ return [] ++ pts = s[2:-2].split('],[') ++ return [[Integer(x) for x in pt.split(",")] for pt in pts] ++ + cdef class _mw: + """ + Cython class wrapping eclib's mw class. +@@ -561,72 +589,37 @@ cdef class _mw: + sage: EQ.search(1) + P1 = [0:1:0] is torsion point, order 1 + P1 = [-3:0:1] is generator number 1 +- ... +- P4 = [12:35:27] = 1*P1 + -1*P2 + -1*P3 (mod torsion) +- +- The previous command produces the following output:: +- +- P1 = [0:1:0] is torsion point, order 1 +- P1 = [-3:0:1] is generator number 1 +- saturating up to 20...Checking 2-saturation +- Points have successfully been 2-saturated (max q used = 7) +- Checking 3-saturation +- Points have successfully been 3-saturated (max q used = 7) +- Checking 5-saturation +- Points have successfully been 5-saturated (max q used = 23) +- Checking 7-saturation +- Points have successfully been 7-saturated (max q used = 41) +- Checking 11-saturation +- Points have successfully been 11-saturated (max q used = 17) +- Checking 13-saturation +- Points have successfully been 13-saturated (max q used = 43) +- Checking 17-saturation +- Points have successfully been 17-saturated (max q used = 31) +- Checking 19-saturation +- Points have successfully been 19-saturated (max q used = 37) ++ saturating up to 20...Saturation index bound (for points of good reduction) = 3 ++ Reducing saturation bound from given value 20 to computed index bound 3 ++ Checking saturation at [ 2 3 ] ++ Checking 2-saturation ++ Points were proved 2-saturated (max q used = 7) ++ Checking 3-saturation ++ Points were proved 3-saturated (max q used = 7) + done + P2 = [-2:3:1] is generator number 2 +- saturating up to 20...Checking 2-saturation ++ saturating up to 20...Saturation index bound (for points of good reduction) = 4 ++ Reducing saturation bound from given value 20 to computed index bound 4 ++ Checking saturation at [ 2 3 ] ++ Checking 2-saturation + possible kernel vector = [1,1] + This point may be in 2E(Q): [14:-52:1] +- ...and it is! ++ ...and it is! + Replacing old generator #1 with new generator [1:-1:1] ++ Reducing index bound from 4 to 2 + Points have successfully been 2-saturated (max q used = 7) + Index gain = 2^1 +- Checking 3-saturation +- Points have successfully been 3-saturated (max q used = 13) +- Checking 5-saturation +- Points have successfully been 5-saturated (max q used = 67) +- Checking 7-saturation +- Points have successfully been 7-saturated (max q used = 53) +- Checking 11-saturation +- Points have successfully been 11-saturated (max q used = 73) +- Checking 13-saturation +- Points have successfully been 13-saturated (max q used = 103) +- Checking 17-saturation +- Points have successfully been 17-saturated (max q used = 113) +- Checking 19-saturation +- Points have successfully been 19-saturated (max q used = 47) +- done (index = 2). ++ done, index = 2. + Gained index 2, new generators = [ [1:-1:1] [-2:3:1] ] + P3 = [-14:25:8] is generator number 3 +- saturating up to 20...Checking 2-saturation +- Points have successfully been 2-saturated (max q used = 11) +- Checking 3-saturation +- Points have successfully been 3-saturated (max q used = 13) +- Checking 5-saturation +- Points have successfully been 5-saturated (max q used = 71) +- Checking 7-saturation +- Points have successfully been 7-saturated (max q used = 101) +- Checking 11-saturation +- Points have successfully been 11-saturated (max q used = 127) +- Checking 13-saturation +- Points have successfully been 13-saturated (max q used = 151) +- Checking 17-saturation +- Points have successfully been 17-saturated (max q used = 139) +- Checking 19-saturation +- Points have successfully been 19-saturated (max q used = 179) +- done (index = 1). ++ saturating up to 20...Saturation index bound (for points of good reduction) = 3 ++ Reducing saturation bound from given value 20 to computed index bound 3 ++ Checking saturation at [ 2 3 ] ++ Checking 2-saturation ++ Points were proved 2-saturated (max q used = 11) ++ Checking 3-saturation ++ Points were proved 3-saturated (max q used = 13) ++ done, index = 1. + P4 = [-1:3:1] = -1*P1 + -1*P2 + -1*P3 (mod torsion) + P4 = [0:2:1] = 2*P1 + 0*P2 + 1*P3 (mod torsion) + P4 = [2:13:8] = -3*P1 + 1*P2 + -1*P3 (mod torsion) +@@ -687,7 +680,7 @@ cdef class _mw: + sig_on() + return string_sigoff(mw_getbasis(self.x)) + +- def process(self, point, sat=0): ++ def process(self, point, saturation_bound=0): + """ + Processes the given point, adding it to the mw group. + +@@ -697,10 +690,12 @@ cdef class _mw: + An ``ArithmeticError`` is raised if the point is not on the + curve. + +- - ``sat`` (int, default 0) --saturate at primes up to ``sat``. +- No saturation is done if ``sat=0``. (Note that it is more +- efficient to add several points at once and then saturate +- just once at the end). ++ - ``saturation_bound`` (int, default 0) --saturate at primes up to ``saturation_bound``. ++ No saturation is done if ``saturation_bound=0``. If ``saturation_bound=-1`` then ++ saturation is done at all primes, by computing a bound on ++ the saturation index. Note that it is more efficient to add ++ several points at once and then saturate just once at the ++ end. + + .. NOTE:: + +@@ -746,7 +741,7 @@ cdef class _mw: + cdef _bigint x,y,z + sig_on() + x,y,z = _bigint(point[0]), _bigint(point[1]), _bigint(point[2]) +- r = mw_process(self.curve, self.x, x.x, y.x, z.x, sat) ++ r = mw_process(self.curve, self.x, x.x, y.x, z.x, saturation_bound) + sig_off() + if r != 0: + raise ArithmeticError("point (=%s) not on curve." % point) +@@ -757,8 +752,8 @@ cdef class _mw: + + OUTPUT: + +- (string) String representation of the points in the basis of +- the mw group. ++ (list) list of integer triples giving the projective ++ coordinates of the points in the basis. + + EXAMPLES:: + +@@ -768,13 +763,13 @@ cdef class _mw: + sage: EQ = _mw(E) + sage: EQ.search(3) + sage: EQ.getbasis() +- '[[0:-1:1], [-1:1:1]]' ++ [[0, -1, 1], [-1, 1, 1]] + sage: EQ.rank() + 2 + """ + sig_on() + s = string_sigoff(mw_getbasis(self.x)) +- return s ++ return parse_point_list(s) + + def regulator(self): + """ +@@ -797,7 +792,7 @@ cdef class _mw: + sage: EQ = _mw(E) + sage: EQ.search(3) + sage: EQ.getbasis() +- '[[0:-1:1], [-1:1:1]]' ++ [[0, -1, 1], [-1, 1, 1]] + sage: EQ.rank() + 2 + sage: EQ.regulator() +@@ -824,40 +819,55 @@ cdef class _mw: + sage: EQ = _mw(E) + sage: EQ.search(3) + sage: EQ.getbasis() +- '[[0:-1:1], [-1:1:1]]' ++ [[0, -1, 1], [-1, 1, 1]] + sage: EQ.rank() + 2 + """ + sig_on() + r = mw_rank(self.x) + sig_off() +- from sage.rings.all import Integer + return Integer(r) + +- def saturate(self, int sat_bd=-1, int odd_primes_only=0): ++ def saturate(self, int sat_bd=-1, int sat_low_bd=2): + """ + Saturates the current subgroup of the mw group. + + INPUT: + +- - ``sat_bnd`` (int, default -1) -- bound on primes at which to +- saturate. If -1 (default), compute a bound for the primes +- which may not be saturated, and use that. ++ - ``sat_bnd`` (int, default -1) -- upper bound on primes at ++ which to saturate. If -1 (default), compute a bound for the ++ primes which may not be saturated, and use that. Otherwise, ++ the bound used is the minumum of the value of ``sat_bnd`` ++ and the computed bound. + +- - ``odd_primes_only`` (bool, default ``False``) -- only do +- saturation at odd primes. (If the points have been found +- via 2-descent they should already be 2-saturated.) ++ - ``sat_low_bd`` (int, default 2) -- only do saturation at ++ prime not less than this. For exampe, if the points have ++ been found via 2-descent they should already be 2-saturated, ++ and ``sat_low_bd=3`` is appropriate. + + OUTPUT: + + (tuple) (success flag, index, list) The success flag will be 1 + unless something failed (usually an indication that the points +- were not saturated but the precision is not high enough to +- divide out successfully). The index is the index of the mw +- group before saturation in the mw group after. The list is a +- string representation of the primes at which saturation was +- not proved or achieved. ++ were not saturated but eclib was not able to divide out ++ successfully). The index is the index of the mw group before ++ saturation in the mw group after. The list is a string ++ representation of the primes at which saturation was not ++ proved or achieved. + ++ .. NOTE:: ++ ++ ``eclib`` will compute a bound on the saturation index. If ++ the computed saturation bound is very large and ``sat_bnd`` is ++ -1, ``eclib`` may output a warning, but will still attempt to ++ saturate up to the computed bound. If a positive value of ++ ``sat_bnd`` is given which is greater than the computed bound, ++ `p`-saturation will only be carried out for primes up to the ++ compated bound. Setting ``sat_low_bnd`` to a value greater ++ than 2 allows for saturation to be done incrementally, or for ++ exactly one prime `p` by setting both ``sat_bd`` and ++ ``sat_low_bd`` to `p`. ++ + EXAMPLES:: + + sage: from sage.libs.eclib.mwrank import _Curvedata +@@ -872,34 +882,23 @@ cdef class _mw: + sage: EQ + [[-1:1:1]] + +- If we set the saturation bound at 2, then saturation will fail:: ++ If we set the saturation bound at 2, then saturation will not ++ enlarge the basis, but the success flag is still 1 (True) ++ since we did not ask to check 3-saturation:: + + sage: EQ = _mw(E) + sage: EQ.process([494, -5720, 6859]) # 3 times another point + sage: EQ.saturate(sat_bd=2) +- Saturation index bound = 10 +- WARNING: saturation at primes p > 2 will not be done; +- points may be unsaturated at primes between 2 and index bound +- Failed to saturate MW basis at primes [ ] +- (0, 1, '[ ]') ++ (1, 1, '[ ]') + sage: EQ + [[494:-5720:6859]] + +- The following output is also seen in the preceding example:: +- +- Saturation index bound = 10 +- WARNING: saturation at primes p > 2 will not be done; +- points may be unsaturated at primes between 2 and index bound +- Failed to saturate MW basis at primes [ ] +- +- + """ +- cdef _bigint index ++ cdef long index + cdef char* s + cdef int ok + sig_on() +- index = _bigint() +- ok = mw_saturate(self.x, index.x, &s, sat_bd, odd_primes_only) ++ ok = mw_saturate(self.x, &index, &s, sat_bd, sat_low_bd) + unsat = string_sigoff(s) + return ok, index, unsat + +@@ -1094,7 +1093,6 @@ cdef class _two_descent: + sig_on() + r = two_descent_get_rank(self.x) + sig_off() +- from sage.rings.all import Integer + return Integer(r) + + def getrankbound(self): +@@ -1128,7 +1126,6 @@ cdef class _two_descent: + sig_on() + r = two_descent_get_rank_bound(self.x) + sig_off() +- from sage.rings.all import Integer + return Integer(r) + + def getselmer(self): +@@ -1161,7 +1158,6 @@ cdef class _two_descent: + sig_on() + r = two_descent_get_selmer_rank(self.x) + sig_off() +- from sage.rings.all import Integer + return Integer(r) + + def ok(self): +@@ -1222,10 +1218,21 @@ cdef class _two_descent: + """ + return two_descent_get_certain(self.x) + +- def saturate(self, saturation_bound=0): ++ def saturate(self, saturation_bound=0, lower=3): + """ + Carries out saturation of the points found by a 2-descent. + ++ INPUT: ++ ++ - ``saturation_bound`` (int) -- an upper bound on the primes ++ `p` at which `p`-saturation will be carried out, or -1, in ++ which case ``eclib`` will compute an upper bound on the ++ saturation index. ++ ++ - ``lower`` (int, default 3) -- do no `p`-saturation for `p` ++ less than this. The default is 3 since the points found ++ during 2-descent will be 2-saturated. ++ + OUTPUT: + + None. +@@ -1257,7 +1264,7 @@ cdef class _two_descent: + '[[1:-1:1], [-2:3:1], [-14:25:8]]' + """ + sig_on() +- two_descent_saturate(self.x, saturation_bound) ++ two_descent_saturate(self.x, saturation_bound, 3) + sig_off() + + def getbasis(self): Property changes on: head/math/sage/files/patch-src_sage_libs_eclib_mwrank.pyx ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/math/sage/files/patch-src_sage_libs_eclib_wrap.cpp =================================================================== --- head/math/sage/files/patch-src_sage_libs_eclib_wrap.cpp (nonexistent) +++ head/math/sage/files/patch-src_sage_libs_eclib_wrap.cpp (revision 568679) @@ -0,0 +1,29 @@ +--- src/sage/libs/eclib/wrap.cpp.orig 2021-03-16 21:40:43 UTC ++++ src/sage/libs/eclib/wrap.cpp +@@ -178,11 +178,11 @@ int mw_rank(struct mw* m) + } + + /* Returns index and unsat long array, which user must deallocate */ +-int mw_saturate(struct mw* m, bigint* index, char** unsat, +- long sat_bd, int odd_primes_only) ++int mw_saturate(struct mw* m, long* index, char** unsat, ++ long sat_bd, long sat_low_bd) + { + vector v; +- int s = m->saturate(*index, v, sat_bd, odd_primes_only); ++ int s = m->saturate(*index, v, sat_bd, sat_low_bd); + ostringstream instore; + instore << v; + *unsat = stringstream_to_char(instore); +@@ -236,9 +236,9 @@ long two_descent_get_certain(const two_descent* t) + return t->getcertain(); + } + +-void two_descent_saturate(struct two_descent* t, long sat_bd) ++void two_descent_saturate(struct two_descent* t, long sat_bd, long sat_low_bd) + { +- t->saturate(sat_bd); ++ t->saturate(sat_bd, sat_low_bd); + } + + double two_descent_regulator(struct two_descent* t) Property changes on: head/math/sage/files/patch-src_sage_libs_eclib_wrap.cpp ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property