From b0111fc3183f5c7fb0d2003c5e13c5f55541bca0 Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Thu, 13 Jul 2023 17:53:45 +0300 Subject: [PATCH 01/82] Implement `.isogenies_degree` for EllipticCurves This supports computing (separable) isogenies of composite degree. It is generic and calls `.isogenies_prime_degree`. --- src/sage/schemes/elliptic_curves/ell_field.py | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 5a5fdf1fcb6..407ede6cd79 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -1588,6 +1588,62 @@ def isogenies_prime_degree(self, l=None, max_l=31): from .isogeny_small_degree import isogenies_prime_degree return sum([isogenies_prime_degree(self, d) for d in L], []) + def isogenies_degree(self, n): + """ + Return a list of all separable isogenies of given degree with domain + equal to ``self``, which are defined over the base field of ``self``. + + INPUT: + + - ``n`` -- an integer. + + TESTS:: + sage: E = EllipticCurve(GF(11), [1, 1]) + sage: E.isogenies_degree(23 * 19) + [Composite morphism of degree 437 = 1*19*23: + From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 + To: Elliptic Curve defined by y^2 = x^3 + 8*x + 7 over Finite Field of size 11, + Composite morphism of degree 437 = 1*19*23: + From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 + To: Elliptic Curve defined by y^2 = x^3 + 2*x + 6 over Finite Field of size 11, + Composite morphism of degree 437 = 1*19*23: + From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 + To: Elliptic Curve defined by y^2 = x^3 + 6*x + 2 over Finite Field of size 11, + Composite morphism of degree 437 = 1*19*23: + From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 + To: Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 11] + + sage: pol = PolynomialRing(QQ, 'x')([1, -3, 5, -5, 5, -3, 1]) + sage: L. = NumberField(pol) + sage: js = hilbert_class_polynomial(-23).roots(L, multiplicities=False) + sage: len(js) + 3 + sage: E = EllipticCurve(j=js[0]) + sage: len(E.isogenies_degree(2**2)) + 7 + sage: len(E.isogenies_degree(2**5)) # long time (15s) + 99 + """ + n = rings.Integer(n) + if n.is_prime(): + return self.isogenies_prime_degree(n) + + prime_divisors = sum([[p] * e for p, e in n.factor()], []) + isos = [self.isogeny(self(0))] + + for p in prime_divisors: + if len(isos) == 0: + break + + new_isos = [] + for iso in isos: + Eiso = iso.codomain() + for next_iso in Eiso.isogenies_prime_degree(p): + new_isos.append(next_iso * iso) + isos = new_isos + + return isos + def is_isogenous(self, other, field=None): """ Return whether or not self is isogenous to other. From 3f876faa666b946a3da91e7844570a7049068632 Mon Sep 17 00:00:00 2001 From: grhkm21 <83517584+grhkm21@users.noreply.github.com> Date: Mon, 6 Nov 2023 22:59:10 +0000 Subject: [PATCH 02/82] Apply suggestions from code review Thanks Lorenz for the review <3 Co-authored-by: Lorenz Panny <84067835+yyyyx4@users.noreply.github.com> --- src/sage/schemes/elliptic_curves/ell_field.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 407ede6cd79..c9d74c961f0 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -1589,7 +1589,7 @@ def isogenies_prime_degree(self, l=None, max_l=31): return sum([isogenies_prime_degree(self, d) for d in L], []) def isogenies_degree(self, n): - """ + r""" Return a list of all separable isogenies of given degree with domain equal to ``self``, which are defined over the base field of ``self``. @@ -1613,6 +1613,8 @@ def isogenies_degree(self, n): From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 To: Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 11] + :: + sage: pol = PolynomialRing(QQ, 'x')([1, -3, 5, -5, 5, -3, 1]) sage: L. = NumberField(pol) sage: js = hilbert_class_polynomial(-23).roots(L, multiplicities=False) @@ -1632,7 +1634,7 @@ def isogenies_degree(self, n): isos = [self.isogeny(self(0))] for p in prime_divisors: - if len(isos) == 0: + if not isos: break new_isos = [] From 8e0346ccc622b287727e4ed3471b0fc3f0dfce59 Mon Sep 17 00:00:00 2001 From: grhkm21 <83517584+grhkm21@users.noreply.github.com> Date: Fri, 19 Jan 2024 15:30:45 +0100 Subject: [PATCH 03/82] Update src/sage/schemes/elliptic_curves/ell_field.py Yes. Co-authored-by: Lorenz Panny <84067835+yyyyx4@users.noreply.github.com> --- src/sage/schemes/elliptic_curves/ell_field.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index c9d74c961f0..68f48edd4fc 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -1598,6 +1598,7 @@ def isogenies_degree(self, n): - ``n`` -- an integer. TESTS:: + sage: E = EllipticCurve(GF(11), [1, 1]) sage: E.isogenies_degree(23 * 19) [Composite morphism of degree 437 = 1*19*23: From 9aa101d78e8457d2bc114e5b69806c8b2b1bd64d Mon Sep 17 00:00:00 2001 From: grhkm21 <83517584+grhkm21@users.noreply.github.com> Date: Sat, 20 Jan 2024 13:28:54 +0100 Subject: [PATCH 04/82] Replace `rings.Integer` with `Integer` --- src/sage/schemes/elliptic_curves/ell_field.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 68f48edd4fc..9c9ae630679 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -229,9 +229,9 @@ def two_torsion_rank(self): sage: EllipticCurve('15a1').two_torsion_rank() 2 """ - f = self.division_polynomial(rings.Integer(2)) + f = self.division_polynomial(Integer(2)) n = len(f.roots())+1 - return rings.Integer(n).ord(rings.Integer(2)) + return Integer(n).ord(Integer(2)) def quartic_twist(self, D): r""" @@ -996,7 +996,7 @@ def division_field(self, l, names='t', map=False, **kwds): - Lorenz Panny (2022): extend to finite fields """ from sage.misc.verbose import verbose - l = rings.Integer(l) + l = Integer(l) if not l.is_prime(): raise ValueError("l must be a prime number") @@ -1627,7 +1627,7 @@ def isogenies_degree(self, n): sage: len(E.isogenies_degree(2**5)) # long time (15s) 99 """ - n = rings.Integer(n) + n = Integer(n) if n.is_prime(): return self.isogenies_prime_degree(n) From 0d48917670f52b12e52bc815ed0593dae35bf41b Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Mon, 22 Jan 2024 13:07:49 +0000 Subject: [PATCH 05/82] =?UTF-8?q?Apply=20reviews=20=F0=9F=A4=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sage/schemes/elliptic_curves/ell_field.py | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 89f2f6392a3..5e2870d1711 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -1352,9 +1352,9 @@ def isogeny_codomain(self, kernel): def isogenies_prime_degree(self, l=None, max_l=31): """ - Return a list of all separable isogenies of given prime degree(s) - with domain equal to ``self``, which are defined over the base - field of ``self``. + Return a list of all separable isogenies (up to post-composition with + isomorphisms) of given prime degree(s) with domain equal to ``self``, + which are defined over the base field of ``self``. INPUT: @@ -1638,8 +1638,9 @@ def isogenies_prime_degree(self, l=None, max_l=31): def isogenies_degree(self, n): r""" - Return a list of all separable isogenies of given degree with domain - equal to ``self``, which are defined over the base field of ``self``. + Return a list of all separable isogenies of given degree (up to + post-composition with isomorphisms) with domain equal to ``self``, which + are defined over the base field of ``self``. INPUT: @@ -1649,16 +1650,16 @@ def isogenies_degree(self, n): sage: E = EllipticCurve(GF(11), [1, 1]) sage: E.isogenies_degree(23 * 19) - [Composite morphism of degree 437 = 1*19*23: + [Composite morphism of degree 437 = 19*23: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 To: Elliptic Curve defined by y^2 = x^3 + 8*x + 7 over Finite Field of size 11, - Composite morphism of degree 437 = 1*19*23: + Composite morphism of degree 437 = 19*23: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 To: Elliptic Curve defined by y^2 = x^3 + 2*x + 6 over Finite Field of size 11, - Composite morphism of degree 437 = 1*19*23: + Composite morphism of degree 437 = 19*23: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 To: Elliptic Curve defined by y^2 = x^3 + 6*x + 2 over Finite Field of size 11, - Composite morphism of degree 437 = 1*19*23: + Composite morphism of degree 437 = 19*23: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 To: Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 11] @@ -1675,12 +1676,11 @@ def isogenies_degree(self, n): sage: len(E.isogenies_degree(2**5)) # long time (15s) 99 """ + from sage.schemes.elliptic_curves.weierstrass_morphism import identity_morphism n = Integer(n) - if n.is_prime(): - return self.isogenies_prime_degree(n) - prime_divisors = sum([[p] * e for p, e in n.factor()], []) - isos = [self.isogeny(self(0))] + prime_divisors = [p for p, e in n.factor() for _ in range(e)] + isos = [identity_morphism(self)] for p in prime_divisors: if not isos: From 91b2ff23d8b6cdb89681f6eb8d053862ed187126 Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Mon, 22 Jan 2024 23:42:28 +0000 Subject: [PATCH 06/82] Return iterator for `isogenies_degree` --- src/sage/schemes/elliptic_curves/ell_field.py | 92 ++++++++++++++----- 1 file changed, 71 insertions(+), 21 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 5e2870d1711..889617c837f 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -1636,17 +1636,55 @@ def isogenies_prime_degree(self, l=None, max_l=31): from .isogeny_small_degree import isogenies_prime_degree return sum([isogenies_prime_degree(self, d) for d in L], []) - def isogenies_degree(self, n): + def _isogenies_degree_helper(self, n, _intermediate=False): + r""" + See documentation of :meth:`isogenies_degree`. + """ + from sage.structure.factorization import Factorization + from sage.schemes.elliptic_curves.weierstrass_morphism import identity_morphism + + if not isinstance(n, Factorization): + n_fac = Integer(n).factor() + else: + n_fac = n + + if n_fac.value() == 1: + yield identity_morphism(self) + return + + p = n_fac[-1][0] + for iso in self._isogenies_degree_helper(n_fac / p, _intermediate=_intermediate): + if _intermediate: + yield iso + + Eiso = iso.codomain() + for next_iso in Eiso.isogenies_prime_degree(p): + yield next_iso * iso + + def isogenies_degree(self, n, *, iter=False, _intermediate=False): r""" Return a list of all separable isogenies of given degree (up to post-composition with isomorphisms) with domain equal to ``self``, which are defined over the base field of ``self``. + ALGORITHM: + + The prime factors `p` of `n` are processed one by one, each time + "branching" out by taking isogenies of degree `p`. + INPUT: - - ``n`` -- an integer. + - ``n`` -- integer, or its + :class:`~sage.structure.factorization.Factorization` - TESTS:: + - ``iter`` -- (bool, default: False): If set, an iterator in depth-first + traversal order will be returned. + + - ``_intermediate`` -- (bool, default: False): If set, the curves + traversed within the depth-first search are returned. This is for + internal use only. + + EXAMPLES:: sage: E = EllipticCurve(GF(11), [1, 1]) sage: E.isogenies_degree(23 * 19) @@ -1663,6 +1701,34 @@ def isogenies_degree(self, n): From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 To: Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 11] + :: + + sage: E = EllipticCurve(GF(next_prime(2^32)), j=1728) + sage: sorted([phi.codomain().j_invariant() for phi in E.isogenies_degree(11 * 17 * 19^2)]) + [1348157279, 1348157279, 1713365879, 1713365879, 3153894341, 3153894341, 3153894341, + 3153894341, 3225140514, 3225140514, 3673460198, 3673460198, 3994312564, 3994312564, + 3994312564, 3994312564] + sage: E.isogenies_degree(2^2, _intermediate=True) + [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 + Via: (u,r,s,t) = (1, 0, 0, 0), + Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 to Elliptic Curve defined by + y^2 = x^3 + 4294967307*x over Finite Field of size 4294967311, + Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 to Elliptic Curve defined by + y^2 = x^3 + 4294967307*x over Finite Field of size 4294967311, + Composite morphism of degree 4 = 2^2: + From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 + To: Elliptic Curve defined by y^2 = x^3 + 16*x over Finite Field of size 4294967311, + Composite morphism of degree 4 = 2^2: + From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 + To: Elliptic Curve defined by y^2 = x^3 + 4294967267*x + 4294967199 over Finite Field of size 4294967311, + Composite morphism of degree 4 = 2^2: + From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 + To: Elliptic Curve defined by y^2 = x^3 + 4294967267*x + 112 over Finite Field of size 4294967311] + sage: it = E.isogenies_degree(2^2, iter=True); it + + sage: list(it) == E.isogenies_degree(2^2) + True + :: sage: pol = PolynomialRing(QQ, 'x')([1, -3, 5, -5, 5, -3, 1]) @@ -1676,24 +1742,8 @@ def isogenies_degree(self, n): sage: len(E.isogenies_degree(2**5)) # long time (15s) 99 """ - from sage.schemes.elliptic_curves.weierstrass_morphism import identity_morphism - n = Integer(n) - - prime_divisors = [p for p, e in n.factor() for _ in range(e)] - isos = [identity_morphism(self)] - - for p in prime_divisors: - if not isos: - break - - new_isos = [] - for iso in isos: - Eiso = iso.codomain() - for next_iso in Eiso.isogenies_prime_degree(p): - new_isos.append(next_iso * iso) - isos = new_isos - - return isos + it = self._isogenies_degree_helper(n, _intermediate=_intermediate) + return it if iter else list(it) def is_isogenous(self, other, field=None): """ From 797181bb7bbeb57f41a444d01b31e1eb269c876d Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Mon, 12 Feb 2024 15:51:04 +0000 Subject: [PATCH 07/82] =?UTF-8?q?apply=20review=20changes=20=F0=9F=A4=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sage/schemes/elliptic_curves/ell_field.py | 102 +++++++++--------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 3e1e593f556..ee22aceea4a 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -1882,36 +1882,11 @@ def isogenies_prime_degree(self, l=None, max_l=31): from .isogeny_small_degree import isogenies_prime_degree return sum([isogenies_prime_degree(self, d) for d in L], []) - def _isogenies_degree_helper(self, n, _intermediate=False): + def isogenies_degree(self, n, *, _intermediate=False): r""" - See documentation of :meth:`isogenies_degree`. - """ - from sage.structure.factorization import Factorization - from sage.schemes.elliptic_curves.weierstrass_morphism import identity_morphism - - if not isinstance(n, Factorization): - n_fac = Integer(n).factor() - else: - n_fac = n - - if n_fac.value() == 1: - yield identity_morphism(self) - return - - p = n_fac[-1][0] - for iso in self._isogenies_degree_helper(n_fac / p, _intermediate=_intermediate): - if _intermediate: - yield iso - - Eiso = iso.codomain() - for next_iso in Eiso.isogenies_prime_degree(p): - yield next_iso * iso - - def isogenies_degree(self, n, *, iter=False, _intermediate=False): - r""" - Return a list of all separable isogenies of given degree (up to - post-composition with isomorphisms) with domain equal to ``self``, which - are defined over the base field of ``self``. + Return an iterator of all separable isogenies of given degree (up to + post-composition with isomorphisms) with domain equal to ``self``, + which are defined over the base field of ``self``. ALGORITHM: @@ -1923,9 +1898,6 @@ def isogenies_degree(self, n, *, iter=False, _intermediate=False): - ``n`` -- integer, or its :class:`~sage.structure.factorization.Factorization` - - ``iter`` -- (bool, default: False): If set, an iterator in depth-first - traversal order will be returned. - - ``_intermediate`` -- (bool, default: False): If set, the curves traversed within the depth-first search are returned. This is for internal use only. @@ -1933,7 +1905,7 @@ def isogenies_degree(self, n, *, iter=False, _intermediate=False): EXAMPLES:: sage: E = EllipticCurve(GF(11), [1, 1]) - sage: E.isogenies_degree(23 * 19) + sage: list(E.isogenies_degree(23 * 19)) [Composite morphism of degree 437 = 19*23: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 To: Elliptic Curve defined by y^2 = x^3 + 8*x + 7 over Finite Field of size 11, @@ -1954,7 +1926,28 @@ def isogenies_degree(self, n, *, iter=False, _intermediate=False): [1348157279, 1348157279, 1713365879, 1713365879, 3153894341, 3153894341, 3153894341, 3153894341, 3225140514, 3225140514, 3673460198, 3673460198, 3994312564, 3994312564, 3994312564, 3994312564] - sage: E.isogenies_degree(2^2, _intermediate=True) + sage: it = E.isogenies_degree(2^2); it + + sage: all(phi.degree() == 2^2 for phi in it) + True + + :: + + sage: pol = PolynomialRing(QQ, 'x')([1, -3, 5, -5, 5, -3, 1]) + sage: L. = NumberField(pol) + sage: js = hilbert_class_polynomial(-23).roots(L, multiplicities=False) + sage: len(js) + 3 + sage: E = EllipticCurve(j=js[0]) + sage: len(list(E.isogenies_degree(2**2))) + 7 + sage: len(list(E.isogenies_degree(2**5))) # long time (15s) + 99 + + TESTS:: + + sage: E = EllipticCurve(GF(next_prime(2^32)), j=1728) + sage: list(E.isogenies_degree(2^2, _intermediate=True)) [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 Via: (u,r,s,t) = (1, 0, 0, 0), Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 to Elliptic Curve defined by @@ -1970,26 +1963,33 @@ def isogenies_degree(self, n, *, iter=False, _intermediate=False): Composite morphism of degree 4 = 2^2: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 To: Elliptic Curve defined by y^2 = x^3 + 4294967267*x + 112 over Finite Field of size 4294967311] - sage: it = E.isogenies_degree(2^2, iter=True); it - - sage: list(it) == E.isogenies_degree(2^2) - True - :: + The following curve has no degree-`5` isogenies, so the code is quick:: - sage: pol = PolynomialRing(QQ, 'x')([1, -3, 5, -5, 5, -3, 1]) - sage: L. = NumberField(pol) - sage: js = hilbert_class_polynomial(-23).roots(L, multiplicities=False) - sage: len(js) - 3 - sage: E = EllipticCurve(j=js[0]) - sage: len(E.isogenies_degree(2**2)) - 7 - sage: len(E.isogenies_degree(2**5)) # long time (15s) - 99 + sage: E = EllipticCurve(GF(103), [3, 5]) + sage: list(E.isogenies_degree(5 * product(prime_range(7, 100)))) + [] """ - it = self._isogenies_degree_helper(n, _intermediate=_intermediate) - return it if iter else list(it) + from sage.structure.factorization import Factorization + from sage.schemes.elliptic_curves.weierstrass_morphism import identity_morphism + + if not isinstance(n, Factorization): + n_fac = Integer(n).factor() + else: + n_fac = n + + if n_fac.value() == 1: + yield identity_morphism(self) + return + + p = n_fac[-1][0] + for iso in self.isogenies_degree(n_fac / p, _intermediate=_intermediate): + if _intermediate: + yield iso + + Eiso = iso.codomain() + for next_iso in Eiso.isogenies_prime_degree(p): + yield next_iso * iso def is_isogenous(self, other, field=None): """ From f5d58340ce2213367854241bcc073c15430919cc Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Mon, 12 Feb 2024 15:53:31 +0000 Subject: [PATCH 08/82] write better code --- src/sage/schemes/elliptic_curves/ell_field.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index ee22aceea4a..62cd11d5792 100644 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -1974,16 +1974,14 @@ def isogenies_degree(self, n, *, _intermediate=False): from sage.schemes.elliptic_curves.weierstrass_morphism import identity_morphism if not isinstance(n, Factorization): - n_fac = Integer(n).factor() - else: - n_fac = n + n = Integer(n).factor() - if n_fac.value() == 1: + if n.value() == 1: yield identity_morphism(self) return - p = n_fac[-1][0] - for iso in self.isogenies_degree(n_fac / p, _intermediate=_intermediate): + p = n[-1][0] + for iso in self.isogenies_degree(n / p, _intermediate=_intermediate): if _intermediate: yield iso From e92b44d7e04df8a6650c6b0e5e8cfbff382317c1 Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Wed, 28 Aug 2024 23:46:29 +0100 Subject: [PATCH 09/82] deduplicate isogenies by equality test! --- src/sage/schemes/elliptic_curves/ell_field.py | 62 ++++++++++++++++--- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index cc070746725..112ea19e32e 100755 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -4,13 +4,13 @@ This module defines the class :class:`EllipticCurve_field`, based on :class:`EllipticCurve_generic`, for elliptic curves over general fields. """ -#***************************************************************************** +# ***************************************************************************** # Copyright (C) 2006 William Stein # # Distributed under the terms of the GNU General Public License (GPL) # # http://www.gnu.org/licenses/ -#***************************************************************************** +# ***************************************************************************** import sage.rings.abc from sage.categories.number_fields import NumberFields @@ -2016,7 +2016,7 @@ def isogenies_prime_degree(self, l=None, max_l=31): from .isogeny_small_degree import isogenies_prime_degree return sum([isogenies_prime_degree(self, d) for d in L], []) - def isogenies_degree(self, n, *, _intermediate=False): + def isogenies_degree(self, n, *, _intermediate=False, _prefix=None): r""" Return an iterator of all separable isogenies of given degree (up to post-composition with isomorphisms) with domain equal to ``self``, @@ -2065,6 +2065,21 @@ def isogenies_degree(self, n, *, _intermediate=False): sage: all(phi.degree() == 2^2 for phi in it) True + We verify that the isogenies outputted are distinct. Note that we do + not use a ``set`` or any hash-based data structure, as hashing + isogenies is slow:: + + sage: import itertools + sage: all_distinct = lambda arr: all(x != y for x, y in itertools.combinations(arr, 2)) + sage: K. = GF((19, 2)) + sage: E = EllipticCurve(K, [11*z+5, 14*z+3]) + sage: S = list(E.isogenies_degree(5^2)); len(S), all_distinct(S) + (3, True) + sage: S = list(E.isogenies_degree(5^2*11)); len(S), all_distinct(S) + (6, True) + sage: S = list(E.isogenies_degree(5^2*11^4)); len(S), all_distinct(S) # long time (2s) + (15, True) + :: sage: pol = PolynomialRing(QQ, 'x')([1, -3, 5, -5, 5, -3, 1]) @@ -2104,8 +2119,14 @@ def isogenies_degree(self, n, *, _intermediate=False): sage: list(E.isogenies_degree(5 * product(prime_range(7, 100)))) [] """ - from sage.structure.factorization import Factorization + def compute_key(phi): + """ + Data used in ``hash(phi)`` excluding the expensive `.kernel_polynomial`. + """ + return (phi.domain(), phi.codomain(), phi.scaling_factor()) + from sage.schemes.elliptic_curves.weierstrass_morphism import identity_morphism + from sage.structure.factorization import Factorization if not isinstance(n, Factorization): n = Integer(n).factor() @@ -2114,14 +2135,35 @@ def isogenies_degree(self, n, *, _intermediate=False): yield identity_morphism(self) return + if _prefix is None: + _prefix = self.identity_morphism() + p = n[-1][0] - for iso in self.isogenies_degree(n / p, _intermediate=_intermediate): + seen = {} + + def insert_seen(phi): + nonlocal seen + key = compute_key(phi) + if key not in seen: + seen[key] = [phi] + return phi + for psi in seen[key]: + if psi == phi: + return + seen[key].append(phi) + return phi + + for isog in self.isogenies_prime_degree(p): if _intermediate: - yield iso - - Eiso = iso.codomain() - for next_iso in Eiso.isogenies_prime_degree(p): - yield next_iso * iso + psi = isog * _prefix + if insert_seen(psi): + yield psi + + Eiso = isog.codomain() + for next_isog in Eiso.isogenies_degree(n / p, _intermediate=_intermediate, _prefix=isog * _prefix): + psi = next_isog * isog + if insert_seen(psi): + yield psi def is_isogenous(self, other, field=None): """ From 112a1e78c124b63a30f2699adf5636c75537afec Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Tue, 3 Sep 2024 17:15:48 +0100 Subject: [PATCH 10/82] fix docs + fix _intermediate --- src/sage/schemes/elliptic_curves/ell_field.py | 67 +++++++------ tags | 94 +++++++++++++++++++ 2 files changed, 131 insertions(+), 30 deletions(-) create mode 100644 tags diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 112ea19e32e..ab790116637 100755 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -2016,7 +2016,7 @@ def isogenies_prime_degree(self, l=None, max_l=31): from .isogeny_small_degree import isogenies_prime_degree return sum([isogenies_prime_degree(self, d) for d in L], []) - def isogenies_degree(self, n, *, _intermediate=False, _prefix=None): + def isogenies_degree(self, n, *, _intermediate=False): r""" Return an iterator of all separable isogenies of given degree (up to post-composition with isomorphisms) with domain equal to ``self``, @@ -2024,32 +2024,32 @@ def isogenies_degree(self, n, *, _intermediate=False, _prefix=None): ALGORITHM: - The prime factors `p` of `n` are processed one by one, each time - "branching" out by taking isogenies of degree `p`. + The prime factors `p` of `n` are processed one by one in decreasing + order, each time "branching" out by taking isogenies of degree `p`. INPUT: - ``n`` -- integer, or its - :class:`~sage.structure.factorization.Factorization` + :class:`~sage.structure.factorization.Factorization`. - - ``_intermediate`` -- (bool, default: False): If set, the curves - traversed within the depth-first search are returned. This is for - internal use only. + - ``_intermediate`` -- (bool, default: False): If set, the isogenies + from this curve to the curves traversed within the depth-first search + are returned. This is for internal use only. EXAMPLES:: sage: E = EllipticCurve(GF(11), [1, 1]) sage: list(E.isogenies_degree(23 * 19)) - [Composite morphism of degree 437 = 19*23: + [Composite morphism of degree 437 = 23*19: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 To: Elliptic Curve defined by y^2 = x^3 + 8*x + 7 over Finite Field of size 11, - Composite morphism of degree 437 = 19*23: - From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 - To: Elliptic Curve defined by y^2 = x^3 + 2*x + 6 over Finite Field of size 11, - Composite morphism of degree 437 = 19*23: + Composite morphism of degree 437 = 23*19: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 To: Elliptic Curve defined by y^2 = x^3 + 6*x + 2 over Finite Field of size 11, - Composite morphism of degree 437 = 19*23: + Composite morphism of degree 437 = 23*19: + From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 + To: Elliptic Curve defined by y^2 = x^3 + 2*x + 6 over Finite Field of size 11, + Composite morphism of degree 437 = 23*19: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 11 To: Elliptic Curve defined by y^2 = x^3 + 7*x + 8 over Finite Field of size 11] @@ -2057,9 +2057,8 @@ def isogenies_degree(self, n, *, _intermediate=False, _prefix=None): sage: E = EllipticCurve(GF(next_prime(2^32)), j=1728) sage: sorted([phi.codomain().j_invariant() for phi in E.isogenies_degree(11 * 17 * 19^2)]) - [1348157279, 1348157279, 1713365879, 1713365879, 3153894341, 3153894341, 3153894341, - 3153894341, 3225140514, 3225140514, 3673460198, 3673460198, 3994312564, 3994312564, - 3994312564, 3994312564] + [1348157279, 1348157279, 1713365879, 1713365879, 3153894341, 3153894341, + 3225140514, 3225140514, 3673460198, 3673460198, 3994312564, 3994312564] sage: it = E.isogenies_degree(2^2); it sage: all(phi.degree() == 2^2 for phi in it) @@ -2089,7 +2088,7 @@ def isogenies_degree(self, n, *, _intermediate=False, _prefix=None): 3 sage: E = EllipticCurve(j=js[0]) sage: len(list(E.isogenies_degree(2**2))) - 7 + 6 sage: len(list(E.isogenies_degree(2**5))) # long time (15s) 99 @@ -2099,10 +2098,8 @@ def isogenies_degree(self, n, *, _intermediate=False, _prefix=None): sage: list(E.isogenies_degree(2^2, _intermediate=True)) [Elliptic-curve endomorphism of Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 Via: (u,r,s,t) = (1, 0, 0, 0), - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 to Elliptic Curve defined by - y^2 = x^3 + 4294967307*x over Finite Field of size 4294967311, - Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 to Elliptic Curve defined by - y^2 = x^3 + 4294967307*x over Finite Field of size 4294967311, + Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 + to Elliptic Curve defined by y^2 = x^3 + 4294967307*x over Finite Field of size 4294967311, Composite morphism of degree 4 = 2^2: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 To: Elliptic Curve defined by y^2 = x^3 + 16*x over Finite Field of size 4294967311, @@ -2112,11 +2109,17 @@ def isogenies_degree(self, n, *, _intermediate=False, _prefix=None): Composite morphism of degree 4 = 2^2: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 4294967311 To: Elliptic Curve defined by y^2 = x^3 + 4294967267*x + 112 over Finite Field of size 4294967311] + sage: all(isog.domain() is E for isog in _) + True + sage: all(isog.domain() is E for isog in E.isogenies_degree(2^5, _intermediate=True)) + True - The following curve has no degree-`5` isogenies, so the code is quick:: + The following curve has no degree-`53` isogenies, so the code is quick:: sage: E = EllipticCurve(GF(103), [3, 5]) - sage: list(E.isogenies_degree(5 * product(prime_range(7, 100)))) + sage: E.isogenies_prime_degree(53) + [] + sage: list(E.isogenies_degree(product(prime_range(3, 53)) * 53)) [] """ def compute_key(phi): @@ -2135,9 +2138,6 @@ def compute_key(phi): yield identity_morphism(self) return - if _prefix is None: - _prefix = self.identity_morphism() - p = n[-1][0] seen = {} @@ -2153,16 +2153,23 @@ def insert_seen(phi): seen[key].append(phi) return phi + if _intermediate: + yield identity_morphism(self) + + # isog: self -> E1 for isog in self.isogenies_prime_degree(p): if _intermediate: - psi = isog * _prefix - if insert_seen(psi): - yield psi + if insert_seen(isog): + # self -> E1 + yield isog Eiso = isog.codomain() - for next_isog in Eiso.isogenies_degree(n / p, _intermediate=_intermediate, _prefix=isog * _prefix): + # next_isog : E1 -> E2 + for next_isog in Eiso.isogenies_degree(n / p, _intermediate=_intermediate): + # psi: self -> E2 psi = next_isog * isog if insert_seen(psi): + # self -> E2 yield psi def is_isogenous(self, other, field=None): diff --git a/tags b/tags new file mode 100644 index 00000000000..be52b140999 --- /dev/null +++ b/tags @@ -0,0 +1,94 @@ +!_TAG_EXTRA_DESCRIPTION anonymous /Include tags for non-named objects like lambda/ +!_TAG_EXTRA_DESCRIPTION fileScope /Include tags of file scope/ +!_TAG_EXTRA_DESCRIPTION pseudo /Include pseudo tags/ +!_TAG_EXTRA_DESCRIPTION subparser /Include tags generated by subparsers/ +!_TAG_FIELD_DESCRIPTION epoch /the last modified time of the input file (only for F\/file kind tag)/ +!_TAG_FIELD_DESCRIPTION file /File-restricted scoping/ +!_TAG_FIELD_DESCRIPTION input /input file/ +!_TAG_FIELD_DESCRIPTION name /tag name/ +!_TAG_FIELD_DESCRIPTION pattern /pattern/ +!_TAG_FIELD_DESCRIPTION typeref /Type and name of a variable or typedef/ +!_TAG_FIELD_DESCRIPTION!Python nameref /the original name for the tag/ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_KIND_DESCRIPTION!Python I,namespace /name referring a module defined in other file/ +!_TAG_KIND_DESCRIPTION!Python Y,unknown /name referring a class\/variable\/function\/module defined in other module/ +!_TAG_KIND_DESCRIPTION!Python c,class /classes/ +!_TAG_KIND_DESCRIPTION!Python f,function /functions/ +!_TAG_KIND_DESCRIPTION!Python i,module /modules/ +!_TAG_KIND_DESCRIPTION!Python m,member /class members/ +!_TAG_KIND_DESCRIPTION!Python v,variable /variables/ +!_TAG_KIND_DESCRIPTION!Tex B,bibitem /bibliography items/ +!_TAG_KIND_DESCRIPTION!Tex C,command /command created with \\newcommand/ +!_TAG_KIND_DESCRIPTION!Tex G,subparagraph /subparagraphs/ +!_TAG_KIND_DESCRIPTION!Tex N,counter /counter created with \\newcounter/ +!_TAG_KIND_DESCRIPTION!Tex P,paragraph /paragraphs/ +!_TAG_KIND_DESCRIPTION!Tex b,subsubsection /subsubsections/ +!_TAG_KIND_DESCRIPTION!Tex c,chapter /chapters/ +!_TAG_KIND_DESCRIPTION!Tex e,environment /environment created with \\newenvironment/ +!_TAG_KIND_DESCRIPTION!Tex i,xinput /external input files/ +!_TAG_KIND_DESCRIPTION!Tex l,label /labels/ +!_TAG_KIND_DESCRIPTION!Tex o,operator /math operator created with \\DeclareMathOperator/ +!_TAG_KIND_DESCRIPTION!Tex p,part /parts/ +!_TAG_KIND_DESCRIPTION!Tex s,section /sections/ +!_TAG_KIND_DESCRIPTION!Tex t,theorem /theorem created with \\newtheorem/ +!_TAG_KIND_DESCRIPTION!Tex u,subsection /subsections/ +!_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/ +!_TAG_OUTPUT_FILESEP slash /slash or backslash/ +!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/ +!_TAG_OUTPUT_VERSION 0.0 /current.age/ +!_TAG_PARSER_VERSION!Python 0.0 /current.age/ +!_TAG_PARSER_VERSION!Tex 0.0 /current.age/ +!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/ +!_TAG_PROC_CWD /home/grhkm/git/sage/ // +!_TAG_PROGRAM_AUTHOR Universal Ctags Team // +!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/ +!_TAG_PROGRAM_URL https://ctags.io/ /official site/ +!_TAG_PROGRAM_VERSION 6.0.0 // +!_TAG_ROLE_DESCRIPTION!Python!module imported /imported modules/ +!_TAG_ROLE_DESCRIPTION!Python!module indirectlyImported /module imported in alternative name/ +!_TAG_ROLE_DESCRIPTION!Python!module namespace /namespace from where classes\/variables\/functions are imported/ +!_TAG_ROLE_DESCRIPTION!Python!unknown imported /imported from the other module/ +!_TAG_ROLE_DESCRIPTION!Python!unknown indirectlyImported /classes\/variables\/functions\/modules imported in alternative name/ +!_TAG_ROLE_DESCRIPTION!Tex!xinput bibliography /bibliography (.bib) file/ +!_TAG_ROLE_DESCRIPTION!Tex!xinput included /external input file specified with \\include/ +!_TAG_ROLE_DESCRIPTION!Tex!xinput input /external input file specified with \\input/ +EllipticCurve_field src/sage/schemes/elliptic_curves/ell_field.py /^class EllipticCurve_field(ell_generic.EllipticCurve_generic, ProjectivePlaneCurve_field):$/;" c +Further improvements? src/sage/misc/notes/bernoulli_mod_p.tex /^\\section*{Further improvements?}$/;" s +GraphType src/sage/schemes/elliptic_curves/ell_field.py /^ from sage.graphs.digraph import DiGraph as GraphType$/;" Y member:EllipticCurve_field.isogeny_ell_graph file: nameref:unknown:DiGraph +GraphType src/sage/schemes/elliptic_curves/ell_field.py /^ from sage.graphs.graph import Graph as GraphType$/;" Y member:EllipticCurve_field.isogeny_ell_graph file: nameref:unknown:Graph +\\FF src/sage/misc/notes/bernoulli_mod_p.tex /^\\newcommand{\\FF}{\\mathbf{F}}$/;" C +\\Z src/sage/misc/notes/bernoulli_mod_p.tex /^\\newcommand{\\Z}{\\mathbf{Z}}$/;" C +\\ZZ src/sage/misc/notes/bernoulli_mod_p.tex /^\\newcommand{\\ZZ}{\\mathbf{Z}}$/;" C +_Hom_ src/sage/schemes/elliptic_curves/ell_field.py /^ def _Hom_(self, other, category=None):$/;" m class:EllipticCurve_field +__init__ src/sage/schemes/elliptic_curves/ell_field.py /^ def __init__(self, R, data, category=None):$/;" m class:EllipticCurve_field +_point src/sage/schemes/elliptic_curves/ell_field.py /^ _point = EllipticCurvePoint_field$/;" v class:EllipticCurve_field +base_field src/sage/schemes/elliptic_curves/ell_field.py /^ base_field = ell_generic.EllipticCurve_generic.base_ring$/;" v class:EllipticCurve_field +compute_key src/sage/schemes/elliptic_curves/ell_field.py /^ def compute_key(phi):$/;" f member:EllipticCurve_field.isogenies_degree file: +compute_model src/sage/schemes/elliptic_curves/ell_field.py /^def compute_model(E, name):$/;" f +descend_to src/sage/schemes/elliptic_curves/ell_field.py /^ def descend_to(self, K, f=None):$/;" m class:EllipticCurve_field +division_field src/sage/schemes/elliptic_curves/ell_field.py /^ def division_field(self, n, names='t', map=False, **kwds):$/;" m class:EllipticCurve_field +endomorphism_ring_is_commutative src/sage/schemes/elliptic_curves/ell_field.py /^ def endomorphism_ring_is_commutative(self):$/;" m class:EllipticCurve_field +ffext src/sage/schemes/elliptic_curves/ell_field.py /^ def ffext(poly):$/;" f function:point_of_order file: +genus src/sage/schemes/elliptic_curves/ell_field.py /^ def genus(self):$/;" m class:EllipticCurve_field +hasse_invariant src/sage/schemes/elliptic_curves/ell_field.py /^ def hasse_invariant(self):$/;" m class:EllipticCurve_field +insert_seen src/sage/schemes/elliptic_curves/ell_field.py /^ def insert_seen(phi):$/;" f member:EllipticCurve_field.isogenies_degree file: +is_isogenous src/sage/schemes/elliptic_curves/ell_field.py /^ def is_isogenous(self, other, field=None):$/;" m class:EllipticCurve_field +is_quadratic_twist src/sage/schemes/elliptic_curves/ell_field.py /^ def is_quadratic_twist(self, other):$/;" m class:EllipticCurve_field +is_quartic_twist src/sage/schemes/elliptic_curves/ell_field.py /^ def is_quartic_twist(self, other):$/;" m class:EllipticCurve_field +is_sextic_twist src/sage/schemes/elliptic_curves/ell_field.py /^ def is_sextic_twist(self, other):$/;" m class:EllipticCurve_field +isogenies_degree src/sage/schemes/elliptic_curves/ell_field.py /^ def isogenies_degree(self, n, *, _intermediate=False):$/;" m class:EllipticCurve_field +isogenies_prime_degree src/sage/schemes/elliptic_curves/ell_field.py /^ def isogenies_prime_degree(self, l=None, max_l=31):$/;" m class:EllipticCurve_field +isogeny src/sage/schemes/elliptic_curves/ell_field.py /^ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, algorithm=None/;" m class:EllipticCurve_field +isogeny_codomain src/sage/schemes/elliptic_curves/ell_field.py /^ def isogeny_codomain(self, kernel):$/;" m class:EllipticCurve_field +isogeny_ell_graph src/sage/schemes/elliptic_curves/ell_field.py /^ def isogeny_ell_graph(self, l, directed=True, label_by_j=False):$/;" m class:EllipticCurve_field +kernel_polynomial_from_divisor src/sage/schemes/elliptic_curves/ell_field.py /^ def kernel_polynomial_from_divisor(self, f, l, *, check=True):$/;" m class:EllipticCurve_field +kernel_polynomial_from_point src/sage/schemes/elliptic_curves/ell_field.py /^ def kernel_polynomial_from_point(self, P, *, algorithm=None):$/;" m class:EllipticCurve_field +mul_a src/sage/schemes/elliptic_curves/ell_field.py /^ mul_a = lambda x: self._multiple_x_numerator(a, x=x) \/ self._multiple_x_denominator(a, /;" f member:EllipticCurve_field.kernel_polynomial_from_divisor file: +point_of_order src/sage/schemes/elliptic_curves/ell_field.py /^def point_of_order(E, n):$/;" f +quadratic_twist src/sage/schemes/elliptic_curves/ell_field.py /^ def quadratic_twist(self, D=None):$/;" m class:EllipticCurve_field +quartic_twist src/sage/schemes/elliptic_curves/ell_field.py /^ def quartic_twist(self, D):$/;" m class:EllipticCurve_field +sextic_twist src/sage/schemes/elliptic_curves/ell_field.py /^ def sextic_twist(self, D):$/;" m class:EllipticCurve_field +two_torsion_rank src/sage/schemes/elliptic_curves/ell_field.py /^ def two_torsion_rank(self):$/;" m class:EllipticCurve_field +weierstrass_p src/sage/schemes/elliptic_curves/ell_field.py /^ def weierstrass_p(self, prec=20, algorithm=None):$/;" m class:EllipticCurve_field +x_mod src/sage/schemes/elliptic_curves/ell_field.py /^ x_mod = lambda g: g.parent().quotient(g).gen()$/;" f member:EllipticCurve_field.kernel_polynomial_from_divisor file: From 980f0e51b450bc1a58039828378635a837bb3cd3 Mon Sep 17 00:00:00 2001 From: Giorgos Mousa Date: Tue, 24 Sep 2024 20:52:48 +0300 Subject: [PATCH 11/82] Add certificate argument to `is_valid` --- src/sage/matroids/basis_exchange_matroid.pxd | 2 +- src/sage/matroids/basis_exchange_matroid.pyx | 8 ++++++- src/sage/matroids/circuits_matroid.pxd | 2 +- src/sage/matroids/circuits_matroid.pyx | 10 ++++++++- src/sage/matroids/dual_matroid.py | 9 +++++++- src/sage/matroids/flats_matroid.pxd | 2 +- src/sage/matroids/flats_matroid.pyx | 20 +++++++++++++++++- src/sage/matroids/graphic_matroid.pxd | 2 +- src/sage/matroids/graphic_matroid.pyx | 6 ++++-- src/sage/matroids/linear_matroid.pxd | 10 ++++----- src/sage/matroids/linear_matroid.pyx | 22 +++++++++++++------- src/sage/matroids/matroid.pxd | 2 +- src/sage/matroids/matroid.pyx | 12 +++++++++-- 13 files changed, 81 insertions(+), 26 deletions(-) diff --git a/src/sage/matroids/basis_exchange_matroid.pxd b/src/sage/matroids/basis_exchange_matroid.pxd index fdcfd82172f..de57ed845a9 100644 --- a/src/sage/matroids/basis_exchange_matroid.pxd +++ b/src/sage/matroids/basis_exchange_matroid.pxd @@ -90,6 +90,6 @@ cdef class BasisExchangeMatroid(Matroid): cpdef _is_isomorphism(self, other, morphism) cdef bint __is_isomorphism(self, BasisExchangeMatroid other, morphism) noexcept - cpdef bint is_valid(self) noexcept + cpdef is_valid(self, certificate=*) cdef bint nxksrd(bitset_s *b, long n, long k, bint succ) noexcept diff --git a/src/sage/matroids/basis_exchange_matroid.pyx b/src/sage/matroids/basis_exchange_matroid.pyx index 8d0dbf1c834..0ebc2749436 100644 --- a/src/sage/matroids/basis_exchange_matroid.pyx +++ b/src/sage/matroids/basis_exchange_matroid.pyx @@ -2231,7 +2231,7 @@ cdef class BasisExchangeMatroid(Matroid): return self._characteristic_setsystem()._isomorphism(other._characteristic_setsystem(), PS, PO) is not None - cpdef bint is_valid(self) noexcept: + cpdef is_valid(self, certificate=False): r""" Test if the data obey the matroid axioms. @@ -2278,6 +2278,8 @@ cdef class BasisExchangeMatroid(Matroid): if not bitset_eq(self._current_basis, BB._subsets[pointerY]): # We failed to set the current basis to Y through basis exchanges. # Therefore, the exchange axioms are violated! + if certificate: + return False, {"error": "exchange axiom failed"} return False bitset_difference(self._input, BB._subsets[pointerX], BB._subsets[pointerY]) bitset_difference(self._input2, BB._subsets[pointerY], BB._subsets[pointerX]) @@ -2292,10 +2294,14 @@ cdef class BasisExchangeMatroid(Matroid): else: y = bitset_next(self._input2, y + 1) if not foundpair: + if certificate: + return False, {"error": "exchange axiom failed"} return False x = bitset_next(self._input, x + 1) pointerY += 1 pointerX += 1 + if certificate: + return True, {} return True cdef bint nxksrd(bitset_s* b, long n, long k, bint succ) noexcept: diff --git a/src/sage/matroids/circuits_matroid.pxd b/src/sage/matroids/circuits_matroid.pxd index a3bffafce6d..d7526ee2712 100644 --- a/src/sage/matroids/circuits_matroid.pxd +++ b/src/sage/matroids/circuits_matroid.pxd @@ -34,4 +34,4 @@ cdef class CircuitsMatroid(Matroid): cpdef relabel(self, mapping) # verification - cpdef bint is_valid(self) noexcept + cpdef is_valid(self, certificate=*) diff --git a/src/sage/matroids/circuits_matroid.pyx b/src/sage/matroids/circuits_matroid.pyx index 3b3693b52f6..94af5865d80 100644 --- a/src/sage/matroids/circuits_matroid.pyx +++ b/src/sage/matroids/circuits_matroid.pyx @@ -869,7 +869,7 @@ cdef class CircuitsMatroid(Matroid): # verification - cpdef bint is_valid(self) noexcept: + cpdef is_valid(self, certificate=False): r""" Test if ``self`` obeys the matroid axioms. @@ -911,6 +911,8 @@ cdef class CircuitsMatroid(Matroid): # loop through all circuit length pairs (i, j) with i <= j for C1 in self._k_C[i]: if not C1: # the empty set can't be a circuit + if certificate: + return False, {"error": "the empty set can't be a circuit"} return False for C2 in self._k_C[j]: I12 = C1 & C2 @@ -920,10 +922,16 @@ cdef class CircuitsMatroid(Matroid): if len(C1) == len(C2): # they are the same circuit break # C1 < C2; a circuit can't be a subset of another circuit + if certificate: + return False, {"error": "a circuit can't be a subset of another circuit", "circuit 1": C1, "circuit 2": C2} return False # check circuit elimination axiom U12 = C1 | C2 for e in I12: if self._is_independent(U12 - {e}): + if certificate: + return False, {"error": "elimination axiom failed", "circuit 1": C1, "circuit 2": C2, "element": e} return False + if certificate: + return True, {} return True diff --git a/src/sage/matroids/dual_matroid.py b/src/sage/matroids/dual_matroid.py index 76ad7aaa600..d73e0643728 100644 --- a/src/sage/matroids/dual_matroid.py +++ b/src/sage/matroids/dual_matroid.py @@ -545,7 +545,7 @@ def relabel(self, mapping): M = self._matroid.relabel(mapping).dual() return M - def is_valid(self): + def is_valid(self, certificate=False): """ Test if ``self`` obeys the matroid axioms. @@ -564,4 +564,11 @@ def is_valid(self): sage: M.dual().is_valid() False """ + if certificate: + v, c = self._matroid.is_valid(certificate) + if v: + return True, {} + else: + c["error"] = "the dual matroid is not valid: " + c["error"] + return v, c return self._matroid.is_valid() diff --git a/src/sage/matroids/flats_matroid.pxd b/src/sage/matroids/flats_matroid.pxd index 23fd4ceb1ec..6eb99792794 100644 --- a/src/sage/matroids/flats_matroid.pxd +++ b/src/sage/matroids/flats_matroid.pxd @@ -24,4 +24,4 @@ cdef class FlatsMatroid(Matroid): cpdef relabel(self, mapping) # verification - cpdef bint is_valid(self) noexcept + cpdef is_valid(self, certificate=*) diff --git a/src/sage/matroids/flats_matroid.pyx b/src/sage/matroids/flats_matroid.pyx index 6842839e03f..fb0850321a6 100644 --- a/src/sage/matroids/flats_matroid.pyx +++ b/src/sage/matroids/flats_matroid.pyx @@ -539,7 +539,7 @@ cdef class FlatsMatroid(Matroid): # verification - cpdef bint is_valid(self) noexcept: + cpdef is_valid(self, certificate=False): r""" Test if ``self`` obeys the matroid axioms. @@ -644,6 +644,12 @@ cdef class FlatsMatroid(Matroid): True """ if self._L is not None: # if the lattice of flats is available + if certificate: + if not self._is_closed(self._groundset): + return False, {"error": "groundset is not a closed set"} + if not self._L.is_geometric(): + return False, {"error": "the lattice of flats is not geometric"} + return True, {} return self._is_closed(self._groundset) and self._L.is_geometric() cdef int i, j, k @@ -654,13 +660,19 @@ cdef class FlatsMatroid(Matroid): # check flats dictionary for invalid ranks and repeated flats ranks = list(self._F) if ranks != list(range(len(ranks))): + if certificate: + False, {"error": "flats dictionary has invalid ranks"} return False flats_lst = [F for i in self._F for F in self._F[i]] if len(flats_lst) != len(set(flats_lst)): + if certificate: + False, {"error": "flats dictionary has repeated flats"} return False # the groundset must be a flat if not self._is_closed(self._groundset): + if certificate: + return False, {"error": "the groundset must be a flat"} return False # a single element extension of a flat must be a subset of exactly one flat @@ -671,6 +683,8 @@ cdef class FlatsMatroid(Matroid): if F2 >= F1: cover.extend(F1 ^ F2) if len(cover) != len(F1 ^ self._groundset) or set(cover) != F1 ^ self._groundset: + if certificate: + False, {"error": "a single element extension of a flat must be a subset of exactly one flat", "flat": F1} return False # the intersection of two flats must be a flat @@ -688,6 +702,10 @@ cdef class FlatsMatroid(Matroid): if flag: break if not flag: + if certificate: + False, {"error": "the intersection of two flats must be a flat", "flat 1": F1, "flat 2": F2} return False + if certificate: + return True, {} return True diff --git a/src/sage/matroids/graphic_matroid.pxd b/src/sage/matroids/graphic_matroid.pxd index 3684ab19f0d..b9902e967d6 100644 --- a/src/sage/matroids/graphic_matroid.pxd +++ b/src/sage/matroids/graphic_matroid.pxd @@ -21,7 +21,7 @@ cdef class GraphicMatroid(Matroid): cpdef bint _is_closed(self, frozenset X) noexcept cpdef _is_isomorphic(self, other, certificate=*) cpdef _isomorphism(self, other) - cpdef bint is_valid(self) noexcept + cpdef is_valid(self, certificate=*) cpdef bint is_graphic(self) noexcept cpdef bint is_regular(self) noexcept cpdef graph(self) diff --git a/src/sage/matroids/graphic_matroid.pyx b/src/sage/matroids/graphic_matroid.pyx index 5e740e78637..48ab6875d09 100644 --- a/src/sage/matroids/graphic_matroid.pyx +++ b/src/sage/matroids/graphic_matroid.pyx @@ -1093,13 +1093,13 @@ cdef class GraphicMatroid(Matroid): """ return self.is_isomorphic(other, certificate=True)[1] - cpdef bint is_valid(self) noexcept: + cpdef is_valid(self, certificate=False): """ Test if the data obey the matroid axioms. Since a graph is used for the data, this is always the case. - OUTPUT: ``True`` + OUTPUT: ``True``, or (True, {}) EXAMPLES:: @@ -1108,6 +1108,8 @@ cdef class GraphicMatroid(Matroid): sage: M.is_valid() True """ + if certificate: + return True, {} return True cpdef bint is_graphic(self) noexcept: diff --git a/src/sage/matroids/linear_matroid.pxd b/src/sage/matroids/linear_matroid.pxd index b0890a76148..1bff3fc87dc 100644 --- a/src/sage/matroids/linear_matroid.pxd +++ b/src/sage/matroids/linear_matroid.pxd @@ -62,7 +62,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): cpdef _is_3connected_shifting(self, certificate=*) cpdef _is_4connected_shifting(self, certificate=*) - cpdef bint is_valid(self) noexcept + cpdef is_valid(self, certificate=*) cdef class BinaryMatroid(LinearMatroid): cdef tuple _b_invariant, _b_partition @@ -92,7 +92,7 @@ cdef class BinaryMatroid(LinearMatroid): cpdef relabel(self, mapping) cpdef bint is_graphic(self) noexcept - cpdef bint is_valid(self) noexcept + cpdef is_valid(self, certificate=*) cdef class TernaryMatroid(LinearMatroid): @@ -122,7 +122,7 @@ cdef class TernaryMatroid(LinearMatroid): cpdef _fast_isom_test(self, other) cpdef relabel(self, mapping) - cpdef bint is_valid(self) noexcept + cpdef is_valid(self, certificate=*) cdef class QuaternaryMatroid(LinearMatroid): cdef object _x_zero, _x_one @@ -149,7 +149,7 @@ cdef class QuaternaryMatroid(LinearMatroid): cpdef _fast_isom_test(self, other) cpdef relabel(self, mapping) - cpdef bint is_valid(self) noexcept + cpdef is_valid(self, certificate=*) cdef class RegularMatroid(LinearMatroid): cdef _bases_count, _r_invariant @@ -174,4 +174,4 @@ cdef class RegularMatroid(LinearMatroid): cpdef bint is_regular(self) noexcept cpdef bint is_graphic(self) noexcept - cpdef bint is_valid(self) noexcept + cpdef is_valid(self, certificate=*) diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index 6848604f0c8..6b61b72855e 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -2614,7 +2614,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): cochains = self.linear_coextension_cochains(F, cosimple=cosimple, fundamentals=fundamentals) return self._linear_coextensions(element, cochains) - cpdef bint is_valid(self) noexcept: + cpdef is_valid(self, certificate=False): r""" Test if the data represent an actual matroid. @@ -3862,14 +3862,14 @@ cdef class BinaryMatroid(LinearMatroid): # now self is graphic iff there is a binary vector x so that M*x = 0 and x_0 = 1, so: return BinaryMatroid(m).corank(frozenset([0])) > 0 - cpdef bint is_valid(self) noexcept: + cpdef is_valid(self, certificate=False): r""" Test if the data obey the matroid axioms. Since this is a linear matroid over the field `\GF{2}`, this is always the case. - OUTPUT: ``True`` + OUTPUT: ``True``, or (True, {}) EXAMPLES:: @@ -3877,6 +3877,8 @@ cdef class BinaryMatroid(LinearMatroid): sage: M.is_valid() True """ + if certificate: + return True, {} return True # representability @@ -4724,14 +4726,14 @@ cdef class TernaryMatroid(LinearMatroid): basis=bas, keep_initial_representation=False) - cpdef bint is_valid(self) noexcept: + cpdef is_valid(self, certificate=False): r""" Test if the data obey the matroid axioms. Since this is a linear matroid over the field `\GF{3}`, this is always the case. - OUTPUT: ``True`` + OUTPUT: ``True``, or (True, {}) EXAMPLES:: @@ -4739,6 +4741,8 @@ cdef class TernaryMatroid(LinearMatroid): sage: M.is_valid() True """ + if certificate: + return True, {} return True # representability @@ -5488,14 +5492,14 @@ cdef class QuaternaryMatroid(LinearMatroid): basis=bas, keep_initial_representation=False) - cpdef bint is_valid(self) noexcept: + cpdef is_valid(self, certificate=False): r""" Test if the data obey the matroid axioms. Since this is a linear matroid over the field `\GF{4}`, this is always the case. - OUTPUT: ``True`` + OUTPUT: ``True``, or (True, {}) EXAMPLES:: @@ -5503,6 +5507,8 @@ cdef class QuaternaryMatroid(LinearMatroid): sage: M.is_valid() # needs sage.rings.finite_rings True """ + if certificate: + return True, {} return True def __reduce__(self): @@ -6270,7 +6276,7 @@ cdef class RegularMatroid(LinearMatroid): """ return BinaryMatroid(reduced_matrix=self._reduced_representation()).is_graphic() - cpdef bint is_valid(self) noexcept: + cpdef is_valid(self, certificate=False): r""" Test if the data obey the matroid axioms. diff --git a/src/sage/matroids/matroid.pxd b/src/sage/matroids/matroid.pxd index 6218cb804f4..bbd025c1ed5 100644 --- a/src/sage/matroids/matroid.pxd +++ b/src/sage/matroids/matroid.pxd @@ -105,7 +105,7 @@ cdef class Matroid(SageObject): cpdef is_coclosed(self, X) # verification - cpdef bint is_valid(self) noexcept + cpdef is_valid(self, certificate=*) # enumeration cpdef SetSystem circuits(self, k=*) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 0384ff81a22..95cdedec300 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -2306,7 +2306,7 @@ cdef class Matroid(SageObject): # verification - cpdef bint is_valid(self) noexcept: + cpdef is_valid(self, certificate=False): r""" Test if the data obey the matroid axioms. @@ -2320,7 +2320,7 @@ cdef class Matroid(SageObject): Certain subclasses may check other axioms instead. - OUTPUT: boolean + OUTPUT: boolean, or (boolean, dictionary) EXAMPLES:: @@ -2351,16 +2351,24 @@ cdef class Matroid(SageObject): X = frozenset(Xt) rX = self._rank(X) if rX > i or rX < 0: + if certificate: + return False, {"error": "the rank must be between 0 and the set's cardinality", "set": X} return False for j in range(i, len(E) + 1): for Yt in combinations(E, j): Y = frozenset(Yt) rY = self._rank(Y) if X.issubset(Y) and rX > rY: + if certificate: + return False, {"error": "the rank function must be monotonic", "set 1": X, "set 2": Y} return False if (self._rank(X.union(Y)) + self._rank(X.intersection(Y)) > rX + rY): + if certificate: + return False, {"error": "the rank function must be submodular", "set 1": X, "set 2": Y} return False + if certificate: + return True, {} return True # enumeration From ea1da462887e9d0ea63e0af3ae0ee67c262fbf0c Mon Sep 17 00:00:00 2001 From: Giorgos Mousa Date: Wed, 25 Sep 2024 13:40:50 +0300 Subject: [PATCH 12/82] Integrate `is_valid(certificate=True)` --- src/sage/matroids/basis_exchange_matroid.pyx | 22 +++--- src/sage/matroids/circuits_matroid.pyx | 30 ++++---- src/sage/matroids/dual_matroid.py | 6 +- src/sage/matroids/flats_matroid.pyx | 75 ++++++++++---------- src/sage/matroids/graphic_matroid.pyx | 10 +-- src/sage/matroids/linear_matroid.pyx | 64 +++++++++++------ src/sage/matroids/matroid.pyx | 26 ++++--- 7 files changed, 126 insertions(+), 107 deletions(-) diff --git a/src/sage/matroids/basis_exchange_matroid.pyx b/src/sage/matroids/basis_exchange_matroid.pyx index 0ebc2749436..7cf056c4292 100644 --- a/src/sage/matroids/basis_exchange_matroid.pyx +++ b/src/sage/matroids/basis_exchange_matroid.pyx @@ -2242,7 +2242,11 @@ cdef class BasisExchangeMatroid(Matroid): * if `X` and `Y` are in `B`, and `x` is in `X - Y`, then there is a `y` in `Y - X` such that `(X - x) + y` is again a member of `B`. - OUTPUT: boolean + INPUT: + + - ``certificate`` -- boolean (default: ``False``) + + OUTPUT: boolean, or (boolean, dictionary) EXAMPLES:: @@ -2251,8 +2255,8 @@ cdef class BasisExchangeMatroid(Matroid): sage: M.is_valid() True sage: M = Matroid(groundset='abcd', bases=['ab', 'cd']) - sage: M.is_valid() - False + sage: M.is_valid(certificate=True) + (False, {'error': 'exchange axiom failed'}) TESTS: @@ -2278,9 +2282,7 @@ cdef class BasisExchangeMatroid(Matroid): if not bitset_eq(self._current_basis, BB._subsets[pointerY]): # We failed to set the current basis to Y through basis exchanges. # Therefore, the exchange axioms are violated! - if certificate: - return False, {"error": "exchange axiom failed"} - return False + return False if not certificate else (False, {"error": "exchange axiom failed"}) bitset_difference(self._input, BB._subsets[pointerX], BB._subsets[pointerY]) bitset_difference(self._input2, BB._subsets[pointerY], BB._subsets[pointerX]) x = bitset_first(self._input) @@ -2294,15 +2296,11 @@ cdef class BasisExchangeMatroid(Matroid): else: y = bitset_next(self._input2, y + 1) if not foundpair: - if certificate: - return False, {"error": "exchange axiom failed"} - return False + return False if not certificate else (False, {"error": "exchange axiom failed"}) x = bitset_next(self._input, x + 1) pointerY += 1 pointerX += 1 - if certificate: - return True, {} - return True + return True if not certificate else (True, {}) cdef bint nxksrd(bitset_s* b, long n, long k, bint succ) noexcept: """ diff --git a/src/sage/matroids/circuits_matroid.pyx b/src/sage/matroids/circuits_matroid.pyx index 94af5865d80..cd44db7772b 100644 --- a/src/sage/matroids/circuits_matroid.pyx +++ b/src/sage/matroids/circuits_matroid.pyx @@ -875,7 +875,11 @@ cdef class CircuitsMatroid(Matroid): For a matroid defined by its circuits, we check the circuit axioms. - OUTPUT: boolean + INPUT: + + - ``certificate`` -- boolean (default: ``False``) + + OUTPUT: boolean, or (boolean, dictionary) EXAMPLES:: @@ -901,8 +905,12 @@ cdef class CircuitsMatroid(Matroid): False sage: C = [[1, 2, 3], [3, 4, 5]] sage: M = Matroid(circuits=C) - sage: M.is_valid() - False + sage: M.is_valid(certificate=True) + (False, + {'circuit 1': frozenset({...}), + 'circuit 2': frozenset({...}), + 'element': 3, + 'error': 'elimination axiom failed'}) """ from itertools import combinations_with_replacement cdef int i, j @@ -911,9 +919,7 @@ cdef class CircuitsMatroid(Matroid): # loop through all circuit length pairs (i, j) with i <= j for C1 in self._k_C[i]: if not C1: # the empty set can't be a circuit - if certificate: - return False, {"error": "the empty set can't be a circuit"} - return False + return False if not certificate else (False, {"error": "the empty set can't be a circuit"}) for C2 in self._k_C[j]: I12 = C1 & C2 if not I12: # C1 and C2 are disjoint; nothing to test @@ -922,16 +928,10 @@ cdef class CircuitsMatroid(Matroid): if len(C1) == len(C2): # they are the same circuit break # C1 < C2; a circuit can't be a subset of another circuit - if certificate: - return False, {"error": "a circuit can't be a subset of another circuit", "circuit 1": C1, "circuit 2": C2} - return False + return False if not certificate else (False, {"error": "a circuit can't be a subset of another circuit", "circuit 1": C1, "circuit 2": C2}) # check circuit elimination axiom U12 = C1 | C2 for e in I12: if self._is_independent(U12 - {e}): - if certificate: - return False, {"error": "elimination axiom failed", "circuit 1": C1, "circuit 2": C2, "element": e} - return False - if certificate: - return True, {} - return True + return False if not certificate else (False, {"error": "elimination axiom failed", "circuit 1": C1, "circuit 2": C2, "element": e}) + return True if not certificate else (True, {}) diff --git a/src/sage/matroids/dual_matroid.py b/src/sage/matroids/dual_matroid.py index d73e0643728..d4dce31ddc2 100644 --- a/src/sage/matroids/dual_matroid.py +++ b/src/sage/matroids/dual_matroid.py @@ -551,7 +551,11 @@ def is_valid(self, certificate=False): For a :class:`DualMatroid`, we check its dual. - OUTPUT: boolean + INPUT: + + - ``certificate`` -- boolean (default: ``False``) + + OUTPUT: boolean, or (boolean, dictionary) EXAMPLES:: diff --git a/src/sage/matroids/flats_matroid.pyx b/src/sage/matroids/flats_matroid.pyx index fb0850321a6..ff1b21fec0c 100644 --- a/src/sage/matroids/flats_matroid.pyx +++ b/src/sage/matroids/flats_matroid.pyx @@ -548,7 +548,11 @@ cdef class FlatsMatroid(Matroid): If the lattice of flats has already been computed, we instead perform the equivalent check of whether it forms a geometric lattice. - OUTPUT: boolean + INPUT: + + - ``certificate`` -- boolean (default: ``False``) + + OUTPUT: boolean, or (boolean, dictionary) EXAMPLES:: @@ -586,8 +590,8 @@ cdef class FlatsMatroid(Matroid): ....: '06a','16b','268','369','07b','178','279','37a', ....: '0123c','89abc', ....: '0123456789abc']) - sage: M.is_valid() - False + sage: M.is_valid(certificate=True) + (False, {'error': 'the lattice of flats is not geometric'}) sage: Matroid(matroids.catalog.Fano().lattice_of_flats()).is_valid() True @@ -609,16 +613,21 @@ cdef class FlatsMatroid(Matroid): TESTS:: - sage: Matroid(flats={0: [], 1: [[0], [1]], 2: [[0, 1]]}).is_valid() # missing an intersection - False - sage: Matroid(flats={0: [[]], 2: [[0], [1]], 3: [[0, 1]]}).is_valid() # invalid ranks - False - sage: Matroid(flats={0: [[]], 1: [[0], [1]], 2: [[0], [0, 1]]}).is_valid() # duplicates - False - sage: Matroid(flats={0: [[]], 1: [[0], [1], [0, 1]]}).is_valid() - False - sage: Matroid(flats={0: [[]], 1: [[0, 1], [2]], 2: [[0], [1], [0, 1, 2]]}).is_valid() - False + sage: Matroid(flats={0: [], 1: [[0], [1]], 2: [[0, 1]]}).is_valid(certificate=True) # missing an intersection + (False, {'error': 'flats dictionary has invalid ranks'}) + sage: Matroid(flats={0: [[]], 2: [[0], [1]], 3: [[0, 1]]}).is_valid(certificate=True) # invalid ranks + (False, {'error': 'flats dictionary has invalid ranks'}) + sage: Matroid(flats={0: [[]], 1: [[0], [1]], 2: [[0], [0, 1]]}).is_valid(certificate=True) # duplicates + (False, {'error': 'flats dictionary has repeated flats'}) + sage: Matroid(flats={0: [[]], 1: [[0], [1], [0, 1]]}).is_valid(certificate=True) + (False, + {'error': 'a single element extension of a flat must be a subset of exactly one flat', + 'flat': frozenset()}) + sage: Matroid(flats={0: [[]], 1: [[0, 1], [2]], 2: [[0], [1], [0, 1, 2]]}).is_valid(certificate=True) + (False, + {'error': 'the intersection of two flats must be a flat', + 'flat 1': frozenset({0, 1}), + 'flat 2': frozenset({1})}) sage: M = Matroid(flats={0: [''], # missing an extension of flat ['5'] by '6' ....: 1: ['0','1','2','3','4','5','6','7','8','9','a','b','c'], ....: 2: ['45','46','47','4c','57','5c','67','6c','7c', @@ -626,13 +635,15 @@ cdef class FlatsMatroid(Matroid): ....: '06a','16b','268','369','07b','178','279','37a', ....: '0123c','89abc'], ....: 3: ['0123456789abc']}) - sage: M.is_valid() - False + sage: M.is_valid(certificate=True) + (False, + {'error': 'a single element extension of a flat must be a subset of exactly one flat', + 'flat': frozenset({'...'})}) sage: M = Matroid(flats=[[], [0], [1], [0], [0, 1]]) # duplicates are ignored sage: M.lattice_of_flats() Finite lattice containing 4 elements - sage: M.is_valid() - True + sage: M.is_valid(certificate=True) + (True, {}) sage: M = Matroid(flats=['', ....: '0','1','2','3','4','5','6','7','8','9','a','b','c', ....: '45','46','47','4c','56','57','5c','67','6c','7c', @@ -640,13 +651,13 @@ cdef class FlatsMatroid(Matroid): ....: '06a','16b','268','369','07b','178','279','37a', ....: '0123c','89abc', ....: '0123456789abc']) - sage: M.is_valid() - True + sage: M.is_valid(certificate=True) + (True, {}) """ if self._L is not None: # if the lattice of flats is available if certificate: if not self._is_closed(self._groundset): - return False, {"error": "groundset is not a closed set"} + return False, {"error": "the groundset must be a flat"} if not self._L.is_geometric(): return False, {"error": "the lattice of flats is not geometric"} return True, {} @@ -660,20 +671,14 @@ cdef class FlatsMatroid(Matroid): # check flats dictionary for invalid ranks and repeated flats ranks = list(self._F) if ranks != list(range(len(ranks))): - if certificate: - False, {"error": "flats dictionary has invalid ranks"} - return False + return False if not certificate else (False, {"error": "flats dictionary has invalid ranks"}) flats_lst = [F for i in self._F for F in self._F[i]] if len(flats_lst) != len(set(flats_lst)): - if certificate: - False, {"error": "flats dictionary has repeated flats"} - return False + return False if not certificate else (False, {"error": "flats dictionary has repeated flats"}) # the groundset must be a flat if not self._is_closed(self._groundset): - if certificate: - return False, {"error": "the groundset must be a flat"} - return False + return False if not certificate else (False, {"error": "the groundset must be a flat"}) # a single element extension of a flat must be a subset of exactly one flat for i in ranks[:-1]: @@ -683,9 +688,7 @@ cdef class FlatsMatroid(Matroid): if F2 >= F1: cover.extend(F1 ^ F2) if len(cover) != len(F1 ^ self._groundset) or set(cover) != F1 ^ self._groundset: - if certificate: - False, {"error": "a single element extension of a flat must be a subset of exactly one flat", "flat": F1} - return False + return False if not certificate else (False, {"error": "a single element extension of a flat must be a subset of exactly one flat", "flat": F1}) # the intersection of two flats must be a flat for i in ranks: @@ -702,10 +705,6 @@ cdef class FlatsMatroid(Matroid): if flag: break if not flag: - if certificate: - False, {"error": "the intersection of two flats must be a flat", "flat 1": F1, "flat 2": F2} - return False + return False if not certificate else (False, {"error": "the intersection of two flats must be a flat", "flat 1": F1, "flat 2": F2}) - if certificate: - return True, {} - return True + return True if not certificate else (True, {}) diff --git a/src/sage/matroids/graphic_matroid.pyx b/src/sage/matroids/graphic_matroid.pyx index 48ab6875d09..53bd8adef39 100644 --- a/src/sage/matroids/graphic_matroid.pyx +++ b/src/sage/matroids/graphic_matroid.pyx @@ -1099,7 +1099,11 @@ cdef class GraphicMatroid(Matroid): Since a graph is used for the data, this is always the case. - OUTPUT: ``True``, or (True, {}) + INPUT: + + - ``certificate`` -- boolean (default: ``False``) + + OUTPUT: ``True``, or ``(True, {})`` EXAMPLES:: @@ -1108,9 +1112,7 @@ cdef class GraphicMatroid(Matroid): sage: M.is_valid() True """ - if certificate: - return True, {} - return True + return True if not certificate else (True, {}) cpdef bint is_graphic(self) noexcept: r""" diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index 6b61b72855e..f180976979d 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -2620,7 +2620,13 @@ cdef class LinearMatroid(BasisExchangeMatroid): Since this matroid is linear, we test the representation matrix. - OUTPUT: + INPUT: + + - ``certificate`` -- boolean (default: ``False``) + + OUTPUT: boolean, or (boolean, dictionary) + + The boolean output value is: - ``True`` if the matrix is over a field. - ``True`` if the matrix is over a ring and all cross ratios are @@ -2649,19 +2655,19 @@ cdef class LinearMatroid(BasisExchangeMatroid): sage: from sage.matroids.advanced import * # LinearMatroid sage: M = LinearMatroid(ring=ZZ, reduced_matrix=Matrix(ZZ, ....: [[1, 0, 1], [1, 1, 0], [0, 1, 1]])) - sage: M.is_valid() - False + sage: M.is_valid(certificate=True) + (False, {'error': 'not all cross ratios are invertible'}) """ if self.base_ring().is_field(): - return True + return True if not certificate else (True, {}) try: CR = self.cross_ratios() except (ArithmeticError, TypeError, ValueError): - return False + return False if not certificate else (False, {"error": "can't compute cross ratios"}) for x in CR: if not x ** (-1) in self.base_ring(): - return False - return True + return False if not certificate else (False, {"error": "not all cross ratios are invertible"}) + return True if not certificate else (True, {}) # connectivity @@ -3869,7 +3875,11 @@ cdef class BinaryMatroid(LinearMatroid): Since this is a linear matroid over the field `\GF{2}`, this is always the case. - OUTPUT: ``True``, or (True, {}) + INPUT: + + - ``certificate`` -- boolean (default: ``False``) + + OUTPUT: ``True``, or ``(True, {})`` EXAMPLES:: @@ -3877,9 +3887,7 @@ cdef class BinaryMatroid(LinearMatroid): sage: M.is_valid() True """ - if certificate: - return True, {} - return True + return True if not certificate else (True, {}) # representability @@ -4733,7 +4741,11 @@ cdef class TernaryMatroid(LinearMatroid): Since this is a linear matroid over the field `\GF{3}`, this is always the case. - OUTPUT: ``True``, or (True, {}) + INPUT: + + - ``certificate`` -- boolean (default: ``False``) + + OUTPUT: ``True``, or ``(True, {})`` EXAMPLES:: @@ -4741,9 +4753,7 @@ cdef class TernaryMatroid(LinearMatroid): sage: M.is_valid() True """ - if certificate: - return True, {} - return True + return True if not certificate else (True, {}) # representability @@ -5499,7 +5509,11 @@ cdef class QuaternaryMatroid(LinearMatroid): Since this is a linear matroid over the field `\GF{4}`, this is always the case. - OUTPUT: ``True``, or (True, {}) + INPUT: + + - ``certificate`` -- boolean (default: ``False``) + + OUTPUT: ``True``, or ``(True, {})`` EXAMPLES:: @@ -5507,9 +5521,7 @@ cdef class QuaternaryMatroid(LinearMatroid): sage: M.is_valid() # needs sage.rings.finite_rings True """ - if certificate: - return True, {} - return True + return True if not certificate else (True, {}) def __reduce__(self): """ @@ -6284,7 +6296,11 @@ cdef class RegularMatroid(LinearMatroid): representation matrix is *totally unimodular*, i.e. if all square submatrices have determinant in `\{-1, 0, 1\}`. - OUTPUT: boolean + INPUT: + + - ``certificate`` -- boolean (default: ``False``) + + OUTPUT: boolean, or (boolean, dictionary) EXAMPLES:: @@ -6293,15 +6309,17 @@ cdef class RegularMatroid(LinearMatroid): ....: [0, 1, 0, 1, 0, 1, 1], ....: [0, 0, 1, 0, 1, 1, 1]]), ....: regular=True, check=False) - sage: M.is_valid() - False + sage: M.is_valid(certificate=True) + (False, {'error': 'the representation matrix is not totally unimodular'}) sage: M = Matroid(graphs.PetersenGraph()) sage: M.is_valid() True """ M = LinearMatroid(ring=QQ, reduced_matrix=self.representation(self.basis(), True, False)) CR = M.cross_ratios() - return CR.issubset(set([1])) + if CR.issubset(set([1])): + return True if not certificate else (True, {}) + return False if not certificate else (False, {"error": "the representation matrix is not totally unimodular"}) # representation diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 95cdedec300..9e1f1571db1 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -2320,6 +2320,10 @@ cdef class Matroid(SageObject): Certain subclasses may check other axioms instead. + INPUT: + + - ``certificate`` -- boolean (default: ``False``) + OUTPUT: boolean, or (boolean, dictionary) EXAMPLES:: @@ -2341,8 +2345,10 @@ cdef class Matroid(SageObject): sage: def r(X): ....: return -1 sage: M = Matroid(groundset=[0,1,2], rank_function=r) - sage: M.is_valid() - False + sage: M.is_valid(certificate=True) + (False, + {'error': "the rank must be between 0 and the set's cardinality", + 'set': frozenset()}) """ cdef int i, j, rX, rY cdef frozenset X, Y, E = self.groundset() @@ -2351,25 +2357,17 @@ cdef class Matroid(SageObject): X = frozenset(Xt) rX = self._rank(X) if rX > i or rX < 0: - if certificate: - return False, {"error": "the rank must be between 0 and the set's cardinality", "set": X} - return False + return False if not certificate else (False, {"error": "the rank must be between 0 and the set's cardinality", "set": X}) for j in range(i, len(E) + 1): for Yt in combinations(E, j): Y = frozenset(Yt) rY = self._rank(Y) if X.issubset(Y) and rX > rY: - if certificate: - return False, {"error": "the rank function must be monotonic", "set 1": X, "set 2": Y} - return False + return False if not certificate else (False, {"error": "the rank function must be monotonic", "set 1": X, "set 2": Y}) if (self._rank(X.union(Y)) + self._rank(X.intersection(Y)) > rX + rY): - if certificate: - return False, {"error": "the rank function must be submodular", "set 1": X, "set 2": Y} - return False - if certificate: - return True, {} - return True + return False if not certificate else (False, {"error": "the rank function must be submodular", "set 1": X, "set 2": Y}) + return True if not certificate else (True, {}) # enumeration From 65e107da8c8a83d740446aec7b9653fb272bc05d Mon Sep 17 00:00:00 2001 From: Kyle Hofmann Date: Thu, 8 Feb 2024 09:19:19 -0800 Subject: [PATCH 13/82] Improve root-finding for polynomials over Z/n --- .../rings/finite_rings/integer_mod_ring.py | 372 ++++++++++++++++++ .../rings/polynomial/polynomial_element.pyx | 26 +- 2 files changed, 378 insertions(+), 20 deletions(-) diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index 5117119dbf4..224440cf3cb 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -47,6 +47,8 @@ - Simon King (2011-04-21): allow to prescribe a category - Simon King (2013-09): Only allow to prescribe the category of fields + +- Kyle Hofmann (2024-02): New implementation of root-finding """ # **************************************************************************** @@ -66,6 +68,8 @@ from sage.arith.misc import primitive_root from sage.arith.misc import CRT_basis from sage.rings.ring import Field, CommutativeRing +from sage.misc.mrange import cartesian_product_iterator +import sage.rings.ring as ring import sage.rings.abc from sage.rings.finite_rings import integer_mod import sage.rings.integer as integer @@ -1547,6 +1551,374 @@ def random_element(self, bound=None): a = random.randint(0, self.order() - 1) return self(a) + @staticmethod + def _lift_residue_field_root(p, e, f, fprime, root): + """Lifts a root of f + + INPUT: + + - ``p`` -- integer, a prime number + - ``e`` -- positive integer + - ``f`` -- polynomial with coefficients in ``IntegerModRing(p**e)`` + - ``fprime`` -- derivative of ``f`` + - ``root`` -- Element of ``IntegerModRing(p)`` with ``f(root) = 0`` + + OUTPUT: iterable of roots of ``f`` modulo ``p**e``. Each root is an + ``IntegerModRing(p**e)`` element. + + TESTS:: + + sage: R = Zmod(2) + sage: S. = R[] + sage: R._lift_residue_field_root(2, 1, S.zero(), S.zero(), R(0)) + (0,) + + Lifting roots of the zero polynomial:: + + sage: R = Zmod(41) + sage: S. = R[] + sage: R._lift_residue_field_root(41, 1, S.zero(), S.zero(), R(12)) + (12,) + sage: R = Zmod(5**2) + sage: S. = R[] + sage: R._lift_residue_field_root(5, 2, S.zero(), S.zero(), R(2)) + [2, 7, 12, 17, 22] + sage: R = Zmod(2**3) + sage: S. = R[] + sage: R._lift_residue_field_root(2, 3, S.zero(), S.zero(), R(1)) + [1, 5, 3, 7] + + Trivial case where ``e == 1``:: + + sage: R = Zmod(41) + sage: S. = R[] + sage: f = x^2 - 2 + sage: R._lift_residue_field_root(41, 1, f, f.derivative(), R(17)) + (17,) + + sage: R = Zmod(43) + sage: S. = R[] + sage: f = x^43 - 3 + sage: R._lift_residue_field_root(43, 1, f, f.derivative(), R(3)) + (3,) + + Non-singular cases with one step of lifting:: + + sage: R = Zmod(2**2) + sage: S. = R[] + sage: f = x - 1 + sage: R._lift_residue_field_root(2, 2, f, f.derivative(), R(1)) + (1,) + sage: f = x - 3 + sage: R._lift_residue_field_root(2, 2, f, f.derivative(), R(1)) + (3,) + + sage: R = Zmod(4001**2) + sage: S. = R[] + sage: f = x^3 - 2 + sage: R._lift_residue_field_root(4001, 2, f, f.derivative(), R(3981)) + (5309307,) + sage: f = x^3 - 3 + sage: R._lift_residue_field_root(4001, 2, f, f.derivative(), R(1091)) + (11035849,) + + Non-singular cases with multiple steps of lifting:: + + sage: R = Zmod(2**10) + sage: S. = R[] + sage: f = x + 1 + sage: R._lift_residue_field_root(2, 10, f, f.derivative(), Zmod(2)(1)) + (1023,) + + sage: R = Zmod(2**16) + sage: S. = R[] + sage: f = x + 1 + sage: R._lift_residue_field_root(2, 16, f, f.derivative(), Zmod(2)(1)) + (65535,) + + sage: R = Zmod(7**4) + sage: S. = R[] + sage: f = x^4 - 2 + sage: R._lift_residue_field_root(7, 4, f, f.derivative(), Zmod(7)(2)) + (121,) + + Singular cases:: + + sage: R = Zmod(2**3) + sage: S. = R[] + sage: f = x^2 - 1 + sage: R._lift_residue_field_root(2, 3, f, f.derivative(), Zmod(2)(1)) + [1, 5, 3, 7] + sage: f = 2*x + sage: R._lift_residue_field_root(2, 3, f, f.derivative(), Zmod(2)(0)) + [0, 4] + + sage: R = Zmod(11**2) + sage: S. = R[] + sage: f = x^2 + 13*x + 1 + sage: R._lift_residue_field_root(11, 2, f, f.derivative(), Zmod(11)(10)) + [] + + sage: R = Zmod(11**3) + sage: S. = R[] + sage: f = x^2 + 123*x + 1 + sage: R._lift_residue_field_root(11, 3, f, f.derivative(), Zmod(11)(10)) + [10, 131, 252, 373, 494, 615, 736, 857, 978, 1099, 1220, 109, 230, 351, 472, 593, 714, 835, 956, 1077, 1198, 1319] + """ + if e == 1: + # Nothing to do + return (root,) + deriv = fprime(root) + if deriv: + # Unique lift, use Newton iteration + prec = 1 + while True: + prec = min(2*prec, e) + Zp_prec = Zmod(p**prec) + root = Zp_prec(root.lift()) + deriv = fprime(root) + step = f(root) / deriv + root -= step + if prec >= e: + return (root,) + else: + # Non-unique lift, go one power at a time + prec = 1 + new_power = 1 + new_mod = p + current_roots = (root,) + for _ in range(e - 1): + prec += 1 + new_power = new_mod + new_mod *= p + new_roots = [] + Zp_prec = Zmod(new_mod) + for rt in current_roots: + rt = Zp_prec(rt.lift()) + if f(rt): + continue + new_roots.append(rt) + for _ in range(p - 1): + rt += new_power + new_roots.append(rt) + current_roots = new_roots + + return current_roots + + def _roots_univariate_polynomial(self, f, ring=None, multiplicities=True, algorithm=None): + r""" + Return the roots of ``f`` in the ring ``ring``. + + INPUT: + + - ``f`` - a polynomial defined over this ring + + - ``ring`` - the ring to find roots in. Control flow elsewhere + ensures that the only cases we need to handle are ``self`` and + ``None``. Otherwise we raise ``NotImplementedError``. + + - ``multiplicities`` - bool (default: ``True``) if ``True`` + return list of pairs `(r, n)`, where `r` is the root and `n` is the + multiplicity. If ``False``, just return the unique roots, with no + information about multiplicities. Multiplicities are only defined + over fields, and this method raises ``NotImplementedError`` if + this is ``True`` but the ring is not a field. + + - ``algorithm`` - ignored + + EXAMPLES:: + + sage: R. = Zmod(41)[] + sage: (x^3 + x).roots() + [(0, 1), (32, 1), (9, 1)] + sage: (x^3 + x).roots(multiplicities=False) + [0, 32, 9] + sage: (x^6 + x^5 + 9*x^4 + 20*x^3 + 3*x^2 + 18*x + 7).roots() + [(19, 1), (20, 2), (21, 3)] + sage: (x^6 + x^5 + 9*x^4 + 20*x^3 + 3*x^2 + 18*x + 7).roots(multiplicities=False) + [19, 20, 21] + + We can find roots without multiplicities over a ring whose modulus is + a prime power, even a big power: + + sage: R. = Zmod(7^3)[] + sage: (x^2 + x + 1).roots(multiplicities=False) + [18, 324] + sage: R. = Zmod(2^50)[] + sage: (x + 1).roots(multiplicities=False) + [1125899906842623] + + We can also find roots without multiplicities over a ring whose modulus + is a product of primes or prime powers: + + sage: R. = Zmod(60)[] + sage: (x^2 - 1).roots(multiplicities=False) + [29, 41, 49, 1, 59, 11, 19, 31] + + We may also ask for roots modulo a quotient of the ring over which the + polynomial is defined: + + sage: R. = Zmod(120)[] + sage: (x^2 - 1).roots(multiplicities=False) + [89, 41, 49, 1, 29, 101, 109, 61, 59, 11, 19, 91, 119, 71, 79, 31] + sage: (x^2 - 1).roots(Zmod(60), multiplicities=False) + [29, 41, 49, 1, 59, 11, 19, 31] + + TESTS:: + + sage: R. = Zmod(2)[] + sage: x.roots() + [(0, 1)] + + Test polynomials with content: + + sage: R. = Zmod(4)[] + sage: (2*x).roots(multiplicities=False) + [0, 2] + + sage: R. = Zmod(6)[] + sage: (3*x).roots(multiplicities=False) + [0, 4, 2] + + Test finding roots over large prime powers: + + sage: R. = Zmod(2**16)[] + sage: (x^3 + 5).roots(multiplicities=False) + [45475] + sage: (x^2 + 46*x + 1).roots(multiplicities=False) + [421, 33189, 16805, 49573, 8613, 41381, 24997, 57765, 7725, 40493, 24109, 56877, 15917, 48685, 32301, 65069] + + sage: R. = Zmod(3**16)[] + sage: (x^2 + 2).roots(multiplicities=False) + [24620738, 18425983] + sage: (x^2 + 11*x + 1).roots(multiplicities=False) + [633836, 14982743, 29331650, 13715060, 28063967, 42412874] + sage: (x^3 + 8).roots(multiplicities=False) + [14348905, 28697812, 43046719] + + Test some larger primes: + + sage: R. = Zmod(41**4)[] + sage: (x^2 + 2).roots(multiplicities=False) + [2208905, 616856] + sage: R. = Zmod(43**4)[] + sage: (x^2 + 3).roots(multiplicities=False) + [3269879, 148922] + + We can't find roots with multiplicities in non-fields: + + sage: R. = Zmod(6)[] + sage: (x + 1).roots() + Traceback (most recent call last): + ... + NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option) + sage: R. = Zmod(8)[] + sage: (x + 1).roots() + Traceback (most recent call last): + ... + NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option) + sage: R. = Zmod(12)[] + sage: (x + 1).roots() + Traceback (most recent call last): + ... + NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option) + + The zero polynomial has every residue class as a root, but we don't + support multiplicities even over fields (they would all be infinite). + + sage: R. = Zmod(6)[] + sage: R.zero().roots() + Traceback (most recent call last): + ... + NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option) + sage: R.zero().roots(multiplicities=False) + [0, 1, 2, 3, 4, 5] + + sage: R. = Zmod(7)[] + sage: R.zero().roots() + Traceback (most recent call last): + ... + NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option) + sage: R.zero().roots(multiplicities=False) + [0, 1, 2, 3, 4, 5, 6] + + sage: R. = Zmod(8)[] + sage: R.zero().roots() + Traceback (most recent call last): + ... + NotImplementedError: root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option) + sage: R.zero().roots(multiplicities=False) + [0, 1, 2, 3, 4, 5, 6, 7] + + This method doesn't support root-finding over rings that aren't Z/nZ: + + sage: R. = Zmod(120)[] + sage: f = x^2 - 1 + sage: f.base_ring()._roots_univariate_polynomial(f, ring=RR, multiplicities=False) + Traceback (most recent call last): + ... + NotImplementedError + + Sage allows us to coerce polynomials from one modulus to another, + and that makes the following defined: + + sage: R. = Zmod(100)[] + sage: (x^2 - 1).roots(Zmod(99), multiplicities=False) == (x^2 - 1).change_ring(Zmod(99)).roots(multiplicities=False) + True + """ + + # This function only supports roots in an IntegerModRing + if ring is not self and ring is not None: + raise NotImplementedError + + deg = f.degree() + + if multiplicities: + if deg < 0 or not self.is_field(): + raise NotImplementedError( + "root finding with multiplicities for this polynomial not" + " implemented (try the multiplicities=False option)" + ) + # Roots of non-zero polynomial over finite fields by factorization + return f._roots_from_factorization(f.factor(), multiplicities) + + # Zero polynomial is a base case + if deg < 0: + # All residue classes are roots of the zero polynomial + return [*map(self, range(self.cardinality()))] + + # Finite fields are a base case + if self.is_field(): + return f._roots_from_factorization(f.factor(), False) + + # Otherwise, find roots modulo each prime power + fac = self.factored_order() + prime_power_roots = [] + for p, e in fac: + Zpe = Zmod(p**e) + fpe = f.change_ring(Zpe) + fpe_prime = fpe.derivative() + fp = fpe.change_ring(Zmod(p)) + + mod_p_roots = fp.roots(multiplicities=False) + + this_prime_power = [] + prime_power_roots.append(this_prime_power) + for root in mod_p_roots: + this_prime_power.extend( + self._lift_residue_field_root(p, e, fpe, fpe_prime, root) + ) + + # Combine using Chinese Remainder Theorem + ppwr_basis = CRT_basis([p**e for p, e in fac]) + result = [] + for res in cartesian_product_iterator(prime_power_roots): + root = self.zero() + for c, x in zip(ppwr_basis, res): + root += c*x.lift() + result.append(root) + return result + ####################################################### # Suppose for interfaces ####################################################### diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 9470d56686c..eedd742c65c 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -8989,32 +8989,18 @@ cdef class Polynomial(CommutativePolynomial): self = self//c except (AttributeError, NotImplementedError, TypeError): pass - return self._roots_from_factorization(self.factor(), multiplicities) + try: + fac = self.factor() + except ArithmeticError: + raise NotImplementedError + else: + return self._roots_from_factorization(fac, multiplicities) else: raise NotImplementedError except NotImplementedError: if K.is_finite(): if multiplicities: raise NotImplementedError("root finding with multiplicities for this polynomial not implemented (try the multiplicities=False option)") - elif isinstance(K, sage.rings.abc.IntegerModRing): - # handling via the chinese remainders theorem - N = K.cardinality() - primes = N.prime_divisors() - residue_roots = [] - for p in primes: - local_self = self.change_ring(GF(p)) - local_roots = local_self.roots(multiplicities=False) - residue_roots.append([a.lift() for a in local_roots]) - result = [] - P = ZZ.prod(primes) - for res in cartesian_product_iterator(residue_roots): - lifted = crt(list(res), primes) - candidate = lifted - for k in range(N // P): - if not self(candidate): - result.append(K(candidate)) - candidate += P - return result else: return [a for a in K if not self(a)] From dedb71940b3b1231f2079866f5eec32602f93361 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 12 Oct 2024 18:45:48 +0200 Subject: [PATCH 14/82] move method strong_orientation --- src/sage/graphs/graph.py | 117 +------------------------------- src/sage/graphs/orientations.py | 115 +++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 115 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 711ea03afc3..bbf157b7b74 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -3022,121 +3022,6 @@ def weight(x): # Orientations - @doc_index("Connectivity, orientations, trees") - def strong_orientation(self): - r""" - Return a strongly connected orientation of the current graph. - - An orientation of an undirected graph is a digraph obtained by giving an - unique direction to each of its edges. An orientation is said to be - strong if there is a directed path between each pair of vertices. See - also the :wikipedia:`Strongly_connected_component`. - - If the graph is 2-edge-connected, a strongly connected orientation - can be found in linear time. If the given graph is not 2-connected, - the orientation returned will ensure that each 2-connected component - has a strongly connected orientation. - - OUTPUT: a digraph representing an orientation of the current graph - - .. NOTE:: - - - This method assumes the graph is connected. - - This time complexity is `O(n+m)` for ``SparseGraph`` and `O(n^2)` - for ``DenseGraph`` . - - .. SEEALSO:: - - - :meth:`~sage.graphs.graph.Graph.orientations` - - :meth:`~sage.graphs.orientations.strong_orientations_iterator` - - :meth:`~sage.graphs.digraph_generators.DiGraphGenerators.nauty_directg` - - :meth:`~sage.graphs.orientations.random_orientation` - - EXAMPLES: - - For a 2-regular graph, a strong orientation gives to each vertex an - out-degree equal to 1:: - - sage: g = graphs.CycleGraph(5) - sage: g.strong_orientation().out_degree() - [1, 1, 1, 1, 1] - - The Petersen Graph is 2-edge connected. It then has a strongly connected - orientation:: - - sage: g = graphs.PetersenGraph() - sage: o = g.strong_orientation() - sage: len(o.strongly_connected_components()) - 1 - - The same goes for the CubeGraph in any dimension :: - - sage: all(len(graphs.CubeGraph(i).strong_orientation().strongly_connected_components()) == 1 for i in range(2,6)) - True - - A multigraph also has a strong orientation :: - - sage: g = Graph([(1,2),(1,2)], multiedges=True) - sage: g.strong_orientation() - Multi-digraph on 2 vertices - """ - from sage.graphs.digraph import DiGraph - d = DiGraph(multiedges=self.allows_multiple_edges()) - i = 0 - - # The algorithm works through a depth-first search. Any edge - # used in the depth-first search is oriented in the direction - # in which it has been used. All the other edges are oriented - # backward - - v = next(self.vertex_iterator()) - seen = {} - i = 1 - - # Time at which the vertices have been discovered - seen[v] = i - - # indicates the stack of edges to explore - next_ = self.edges_incident(v) - - while next_: - e = next_.pop() - - # Ignore loops - if e[0] == e[1]: - continue - - # We assume e[0] to be a `seen` vertex - e = e if seen.get(e[0], False) is not False else (e[1], e[0], e[2]) - - # If we discovered a new vertex - if seen.get(e[1], False) is False: - d.add_edge(e) - next_.extend(ee for ee in self.edges_incident(e[1]) - if ((e[0], e[1]) != (ee[0], ee[1])) and ((e[0], e[1]) != (ee[1], ee[0]))) - i += 1 - seen[e[1]] = i - - # Else, we orient the edges backward - else: - if seen[e[0]] < seen[e[1]]: - d.add_edge(e[1], e[0], e[2]) - else: - d.add_edge(e) - - # Case of multiple edges. If another edge has already been inserted, we - # add the new one in the opposite direction. - tmp = None - for e in self.multiple_edges(): - if tmp == (e[0], e[1]): - if d.has_edge(e[0], e[1]): - d.add_edge(e[1], e[0], e[2]) - else: - d.add_edge(e) - tmp = (e[0], e[1]) - - return d - @doc_index("Connectivity, orientations, trees") def minimum_outdegree_orientation(self, use_edge_labels=False, solver=None, verbose=0, *, integrality_tolerance=1e-3): @@ -9691,6 +9576,7 @@ def bipartite_double(self, extended=False): from sage.graphs.lovasz_theta import lovasz_theta from sage.graphs.partial_cube import is_partial_cube from sage.graphs.orientations import orient + from sage.graphs.orientations import strong_orientation from sage.graphs.orientations import strong_orientations_iterator from sage.graphs.orientations import random_orientation from sage.graphs.orientations import acyclic_orientations @@ -9744,6 +9630,7 @@ def bipartite_double(self, extended=False): "tutte_polynomial" : "Algorithmically hard stuff", "lovasz_theta" : "Leftovers", "orient" : "Connectivity, orientations, trees", + "strong_orientation" : "Connectivity, orientations, trees", "strong_orientations_iterator" : "Connectivity, orientations, trees", "random_orientation" : "Connectivity, orientations, trees", "acyclic_orientations" : "Connectivity, orientations, trees", diff --git a/src/sage/graphs/orientations.py b/src/sage/graphs/orientations.py index 26dc4df7722..8d173706926 100644 --- a/src/sage/graphs/orientations.py +++ b/src/sage/graphs/orientations.py @@ -14,6 +14,7 @@ :meth:`orient` | Return an oriented version of `G` according the input function `f`. :meth:`acyclic_orientations` | Return an iterator over all acyclic orientations of an undirected graph `G`. + :meth:`strong_orientation` | Return a strongly connected orientation of the graph `G`. :meth:`strong_orientations_iterator` | Return an iterator over all strong orientations of a graph `G` :meth:`random_orientation` | Return a random orientation of a graph `G` @@ -486,6 +487,120 @@ def helper(G, globO, m, k): yield D +def strong_orientation(G): + r""" + Return a strongly connected orientation of the graph `G`. + + An orientation of an undirected graph is a digraph obtained by giving an + unique direction to each of its edges. An orientation is said to be strong + if there is a directed path between each pair of vertices. See also the + :wikipedia:`Strongly_connected_component`. + + If the graph is 2-edge-connected, a strongly connected orientation can be + found in linear time. If the given graph is not 2-connected, the orientation + returned will ensure that each 2-connected component has a strongly + connected orientation. + + OUTPUT: a digraph representing an orientation of the current graph + + .. NOTE:: + + - This method assumes that the input the graph is connected. + - The time complexity is `O(n+m)` for ``SparseGraph`` and `O(n^2)` for + ``DenseGraph`` . + + .. SEEALSO:: + + - :meth:`~sage.graphs.graph.Graph.orientations` + - :meth:`~sage.graphs.orientations.strong_orientations_iterator` + - :meth:`~sage.graphs.digraph_generators.DiGraphGenerators.nauty_directg` + - :meth:`~sage.graphs.orientations.random_orientation` + + EXAMPLES: + + For a 2-regular graph, a strong orientation gives to each vertex an + out-degree equal to 1:: + + sage: g = graphs.CycleGraph(5) + sage: g.strong_orientation().out_degree() + [1, 1, 1, 1, 1] + + The Petersen Graph is 2-edge connected. It then has a strongly connected + orientation:: + + sage: g = graphs.PetersenGraph() + sage: o = g.strong_orientation() + sage: len(o.strongly_connected_components()) + 1 + + The same goes for the CubeGraph in any dimension:: + + sage: all(len(graphs.CubeGraph(i).strong_orientation().strongly_connected_components()) == 1 + ....: for i in range(2,6)) + True + + A multigraph also has a strong orientation:: + + sage: g = Graph([(1,2),(1,2)], multiedges=True) + sage: g.strong_orientation() + Multi-digraph on 2 vertices + """ + d = DiGraph(multiedges=G.allows_multiple_edges()) + i = 0 + + # The algorithm works through a depth-first search. Any edge used in the + # depth-first search is oriented in the direction in which it has been + # used. All the other edges are oriented backward + + v = next(G.vertex_iterator()) + seen = {} + i = 1 + + # Time at which the vertices have been discovered + seen[v] = i + + # indicates the stack of edges to explore + next_ = G.edges_incident(v) + + while next_: + e = next_.pop() + + # Ignore loops + if e[0] == e[1]: + continue + + # We assume e[0] to be a `seen` vertex + e = e if seen.get(e[0], False) is not False else (e[1], e[0], e[2]) + + # If we discovered a new vertex + if seen.get(e[1], False) is False: + d.add_edge(e) + next_.extend(ee for ee in G.edges_incident(e[1]) + if ((e[0], e[1]) != (ee[0], ee[1])) and ((e[0], e[1]) != (ee[1], ee[0]))) + i += 1 + seen[e[1]] = i + + # Else, we orient the edges backward + else: + if seen[e[0]] < seen[e[1]]: + d.add_edge(e[1], e[0], e[2]) + else: + d.add_edge(e) + + # Case of multiple edges. If another edge has already been inserted, we add + # the new one in the opposite direction. + tmp = None + for e in G.multiple_edges(): + if tmp == (e[0], e[1]): + if d.has_edge(e[0], e[1]): + d.add_edge(e[1], e[0], e[2]) + else: + d.add_edge(e) + tmp = (e[0], e[1]) + + return d + + def strong_orientations_iterator(G): r""" Return an iterator over all strong orientations of a graph `G`. From 74addb586aaa973b2a354544a649dc71e397efe1 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 12 Oct 2024 18:59:47 +0200 Subject: [PATCH 15/82] move method minimum_outdegree_orientation --- src/sage/graphs/graph.py | 112 +------------------------------- src/sage/graphs/orientations.py | 100 ++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 110 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index bbf157b7b74..eda27435e9c 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -3022,116 +3022,6 @@ def weight(x): # Orientations - @doc_index("Connectivity, orientations, trees") - def minimum_outdegree_orientation(self, use_edge_labels=False, solver=None, verbose=0, - *, integrality_tolerance=1e-3): - r""" - Return an orientation of ``self`` with the smallest possible maximum - outdegree. - - Given a Graph `G`, it is polynomial to compute an orientation `D` of the - edges of `G` such that the maximum out-degree in `D` is minimized. This - problem, though, is NP-complete in the weighted case [AMOZ2006]_. - - INPUT: - - - ``use_edge_labels`` -- boolean (default: ``False``) - - - When set to ``True``, uses edge labels as weights to compute the - orientation and assumes a weight of `1` when there is no value - available for a given edge. - - - When set to ``False`` (default), gives a weight of 1 to all the - edges. - - - ``solver`` -- string (default: ``None``); specifies a Mixed Integer - Linear Programming (MILP) solver to be used. If set to ``None``, the - default one is used. For more information on MILP solvers and which - default solver is used, see the method :meth:`solve - ` of the class - :class:`MixedIntegerLinearProgram - `. - - - ``verbose`` -- integer (default: 0); sets the level of - verbosity. Set to 0 by default, which means quiet. - - - ``integrality_tolerance`` -- float; parameter for use with MILP - solvers over an inexact base ring; see - :meth:`MixedIntegerLinearProgram.get_values`. - - EXAMPLES: - - Given a complete bipartite graph `K_{n,m}`, the maximum out-degree of an - optimal orientation is `\left\lceil \frac {nm} {n+m}\right\rceil`:: - - sage: g = graphs.CompleteBipartiteGraph(3,4) - sage: o = g.minimum_outdegree_orientation() # needs sage.numerical.mip - sage: max(o.out_degree()) == integer_ceil((4*3)/(3+4)) # needs sage.numerical.mip - True - """ - self._scream_if_not_simple() - if self.is_directed(): - raise ValueError("Cannot compute an orientation of a DiGraph. " - "Please convert it to a Graph if you really mean it.") - - if use_edge_labels: - from sage.rings.real_mpfr import RR - - def weight(e): - l = self.edge_label(e) - return l if l in RR else 1 - else: - def weight(e): - return 1 - - from sage.numerical.mip import MixedIntegerLinearProgram - - p = MixedIntegerLinearProgram(maximization=False, solver=solver) - degree = p.new_variable(nonnegative=True) - - # The orientation of an edge is boolean and indicates whether the edge - # uv goes from u to v ( equal to 0 ) or from v to u ( equal to 1) - orientation = p.new_variable(binary=True) - - # Whether an edge adjacent to a vertex u counts positively or - # negatively. To do so, we first fix an arbitrary extremity per edge uv. - ext = {frozenset(e): e[0] for e in self.edge_iterator(labels=False)} - - def outgoing(u, e, variable): - if u == ext[frozenset(e)]: - return variable - else: - return 1 - variable - - for u in self: - p.add_constraint(p.sum(weight(e) * outgoing(u, e, orientation[frozenset(e)]) - for e in self.edge_iterator(vertices=[u], labels=False)) - - degree['max'], max=0) - - p.set_objective(degree['max']) - - p.solve(log=verbose) - - orientation = p.get_values(orientation, convert=bool, tolerance=integrality_tolerance) - - # All the edges from self are doubled in O - # ( one in each direction ) - from sage.graphs.digraph import DiGraph - O = DiGraph(self) - - # Builds the list of edges that should be removed - edges = [] - - for e in self.edge_iterator(labels=None): - if orientation[frozenset(e)]: - edges.append(e[::-1]) - else: - edges.append(e) - - O.delete_edges(edges) - - return O - @doc_index("Connectivity, orientations, trees") def bounded_outdegree_orientation(self, bound, solver=None, verbose=False, *, integrality_tolerance=1e-3): @@ -9580,6 +9470,7 @@ def bipartite_double(self, extended=False): from sage.graphs.orientations import strong_orientations_iterator from sage.graphs.orientations import random_orientation from sage.graphs.orientations import acyclic_orientations + from sage.graphs.orientations import minimum_outdegree_orientation from sage.graphs.connectivity import bridges, cleave, spqr_tree from sage.graphs.connectivity import is_triconnected from sage.graphs.comparability import is_comparability @@ -9634,6 +9525,7 @@ def bipartite_double(self, extended=False): "strong_orientations_iterator" : "Connectivity, orientations, trees", "random_orientation" : "Connectivity, orientations, trees", "acyclic_orientations" : "Connectivity, orientations, trees", + "minimum_outdegree_orientation": "Connectivity, orientations, trees", "bridges" : "Connectivity, orientations, trees", "cleave" : "Connectivity, orientations, trees", "spqr_tree" : "Connectivity, orientations, trees", diff --git a/src/sage/graphs/orientations.py b/src/sage/graphs/orientations.py index 8d173706926..21a8a634aca 100644 --- a/src/sage/graphs/orientations.py +++ b/src/sage/graphs/orientations.py @@ -17,6 +17,7 @@ :meth:`strong_orientation` | Return a strongly connected orientation of the graph `G`. :meth:`strong_orientations_iterator` | Return an iterator over all strong orientations of a graph `G` :meth:`random_orientation` | Return a random orientation of a graph `G` + :meth:`minimum_outdegree_orientation` | Return an orientation of `G` with the smallest possible maximum outdegree. Authors @@ -872,3 +873,102 @@ def random_orientation(G): D.add_edge(v, u, l) rbits >>= 1 return D + + +def minimum_outdegree_orientation(G, use_edge_labels=False, solver=None, verbose=0, + *, integrality_tolerance=1e-3): + r""" + Return an orientation of `G` with the smallest possible maximum outdegree. + + Given a Graph `G`, it is polynomial to compute an orientation `D` of the + edges of `G` such that the maximum out-degree in `D` is minimized. This + problem, though, is NP-complete in the weighted case [AMOZ2006]_. + + INPUT: + + - ``use_edge_labels`` -- boolean (default: ``False``) + + - When set to ``True``, uses edge labels as weights to compute the + orientation and assumes a weight of `1` when there is no value available + for a given edge. + + - When set to ``False`` (default), gives a weight of 1 to all the edges. + + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear + Programming (MILP) solver to be used. If set to ``None``, the default one + is used. For more information on MILP solvers and which default solver is + used, see the method :meth:`solve + ` of the class + :class:`MixedIntegerLinearProgram + `. + + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 + by default, which means quiet. + + - ``integrality_tolerance`` -- float; parameter for use with MILP solvers + over an inexact base ring; + see :meth:`MixedIntegerLinearProgram.get_values`. + + EXAMPLES: + + Given a complete bipartite graph `K_{n,m}`, the maximum out-degree of an + optimal orientation is `\left\lceil \frac {nm} {n+m}\right\rceil`:: + + sage: g = graphs.CompleteBipartiteGraph(3,4) + sage: o = g.minimum_outdegree_orientation() # needs sage.numerical.mip + sage: max(o.out_degree()) == integer_ceil((4*3)/(3+4)) # needs sage.numerical.mip + True + """ + G._scream_if_not_simple() + if G.is_directed(): + raise ValueError("Cannot compute an orientation of a DiGraph. " + "Please convert it to a Graph if you really mean it.") + + if use_edge_labels: + from sage.rings.real_mpfr import RR + + def weight(e): + label = G.edge_label(e) + return label if label in RR else 1 + else: + def weight(e): + return 1 + + from sage.numerical.mip import MixedIntegerLinearProgram + + p = MixedIntegerLinearProgram(maximization=False, solver=solver) + degree = p.new_variable(nonnegative=True) + + # The orientation of an edge is boolean and indicates whether the edge uv + # goes from u to v ( equal to 0 ) or from v to u ( equal to 1) + orientation = p.new_variable(binary=True) + + # Whether an edge adjacent to a vertex u counts positively or negatively. To + # do so, we first fix an arbitrary extremity per edge uv. + ext = {frozenset(e): e[0] for e in G.edge_iterator(labels=False)} + + def outgoing(u, e, variable): + if u == ext[frozenset(e)]: + return variable + return 1 - variable + + for u in G: + p.add_constraint(p.sum(weight(e) * outgoing(u, e, orientation[frozenset(e)]) + for e in G.edge_iterator(vertices=[u], labels=False)) + - degree['max'], max=0) + + p.set_objective(degree['max']) + + p.solve(log=verbose) + + orientation = p.get_values(orientation, convert=bool, tolerance=integrality_tolerance) + + # All the edges from G are doubled in O ( one in each direction ) + O = DiGraph(G) + + # Builds the list of edges that should be removed + edges = (e[::-1] if orientation[frozenset(e)] else e + for e in G.edge_iterator(labels=False)) + O.delete_edges(edges) + + return O From b64eb0e63aaa70cdcff43aafab412a1537da77bf Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 12 Oct 2024 19:23:25 +0200 Subject: [PATCH 16/82] move method orientaitons and minimum_outdegree_orientation --- src/sage/graphs/graph.py | 302 +------------------------------- src/sage/graphs/orientations.py | 292 +++++++++++++++++++++++++++++- 2 files changed, 296 insertions(+), 298 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index eda27435e9c..e7a5c6fc2bc 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -3020,302 +3020,6 @@ def weight(x): g.delete_edges(e for e in g.edge_iterator(labels=False) if not b[frozenset(e)]) return g - # Orientations - - @doc_index("Connectivity, orientations, trees") - def bounded_outdegree_orientation(self, bound, solver=None, verbose=False, - *, integrality_tolerance=1e-3): - r""" - Compute an orientation of ``self`` such that every vertex `v` has - out-degree less than `b(v)` - - INPUT: - - - ``bound`` -- maximum bound on the out-degree. Can be of three - different types : - - * An integer `k`. In this case, computes an orientation whose maximum - out-degree is less than `k`. - - * A dictionary associating to each vertex its associated maximum - out-degree. - - * A function associating to each vertex its associated maximum - out-degree. - - - ``solver`` -- string (default: ``None``); specifies a Mixed Integer - Linear Programming (MILP) solver to be used. If set to ``None``, the - default one is used. For more information on MILP solvers and which - default solver is used, see the method :meth:`solve - ` of the class - :class:`MixedIntegerLinearProgram - `. - - - ``verbose`` -- integer (default: 0); sets the level of - verbosity. Set to 0 by default, which means quiet. - - - ``integrality_tolerance`` -- float; parameter for use with MILP - solvers over an inexact base ring; see - :meth:`MixedIntegerLinearProgram.get_values`. - - OUTPUT: - - A DiGraph representing the orientation if it exists. - A :exc:`ValueError` exception is raised otherwise. - - ALGORITHM: - - The problem is solved through a maximum flow : - - Given a graph `G`, we create a ``DiGraph`` `D` defined on `E(G)\cup - V(G)\cup \{s,t\}`. We then link `s` to all of `V(G)` (these edges having - a capacity equal to the bound associated to each element of `V(G)`), and - all the elements of `E(G)` to `t` . We then link each `v \in V(G)` to - each of its incident edges in `G`. A maximum integer flow of value - `|E(G)|` corresponds to an admissible orientation of `G`. Otherwise, - none exists. - - EXAMPLES: - - There is always an orientation of a graph `G` such that a vertex `v` has - out-degree at most `\lceil \frac {d(v)} 2 \rceil`:: - - sage: g = graphs.RandomGNP(40, .4) - sage: b = lambda v: integer_ceil(g.degree(v)/2) - sage: D = g.bounded_outdegree_orientation(b) - sage: all( D.out_degree(v) <= b(v) for v in g ) - True - - - Chvatal's graph, being 4-regular, can be oriented in such a way that its - maximum out-degree is 2:: - - sage: g = graphs.ChvatalGraph() - sage: D = g.bounded_outdegree_orientation(2) - sage: max(D.out_degree()) - 2 - - For any graph `G`, it is possible to compute an orientation such that - the maximum out-degree is at most the maximum average degree of `G` - divided by 2. Anything less, though, is impossible. - - sage: g = graphs.RandomGNP(40, .4) - sage: mad = g.maximum_average_degree() # needs sage.numerical.mip - - Hence this is possible :: - - sage: d = g.bounded_outdegree_orientation(integer_ceil(mad/2)) # needs sage.numerical.mip - - While this is not:: - - sage: try: # needs sage.numerical.mip - ....: g.bounded_outdegree_orientation(integer_ceil(mad/2-1)) - ....: print("Error") - ....: except ValueError: - ....: pass - - TESTS: - - As previously for random graphs, but more intensively:: - - sage: for i in range(30): # long time (up to 6s on sage.math, 2012) - ....: g = graphs.RandomGNP(40, .4) - ....: b = lambda v: integer_ceil(g.degree(v)/2) - ....: D = g.bounded_outdegree_orientation(b) - ....: if not ( - ....: all( D.out_degree(v) <= b(v) for v in g ) or - ....: D.size() != g.size()): - ....: print("Something wrong happened") - """ - self._scream_if_not_simple() - from sage.graphs.digraph import DiGraph - n = self.order() - - if not n: - return DiGraph() - - vertices = list(self) - vertices_id = {y: x for x, y in enumerate(vertices)} - - b = {} - - # Checking the input type. We make a dictionary out of it - if isinstance(bound, dict): - b = bound - else: - try: - b = dict(zip(vertices, map(bound, vertices))) - - except TypeError: - b = dict(zip(vertices, [bound]*n)) - - d = DiGraph() - - # Adding the edges (s,v) and ((u,v),t) - d.add_edges(('s', vertices_id[v], b[v]) for v in vertices) - - d.add_edges(((vertices_id[u], vertices_id[v]), 't', 1) - for u, v in self.edges(sort=False, labels=None)) - - # each v is linked to its incident edges - - for u, v in self.edge_iterator(labels=None): - u, v = vertices_id[u], vertices_id[v] - d.add_edge(u, (u, v), 1) - d.add_edge(v, (u, v), 1) - - # Solving the maximum flow - value, flow = d.flow('s', 't', value_only=False, integer=True, - use_edge_labels=True, solver=solver, verbose=verbose, - integrality_tolerance=integrality_tolerance) - - if value != self.size(): - raise ValueError("No orientation exists for the given bound") - - D = DiGraph() - D.add_vertices(vertices) - - # The flow graph may not contain all the vertices, if they are - # not part of the flow... - - for u in [x for x in range(n) if x in flow]: - - for uu, vv in flow.neighbors_out(u): - v = vv if vv != u else uu - D.add_edge(vertices[u], vertices[v]) - - # I do not like when a method destroys the embedding ;-) - D.set_pos(self.get_pos()) - - return D - - @doc_index("Connectivity, orientations, trees") - def orientations(self, data_structure=None, sparse=None): - r""" - Return an iterator over orientations of ``self``. - - An *orientation* of an undirected graph is a directed graph such that - every edge is assigned a direction. Hence there are `2^s` oriented - digraphs for a simple graph with `s` edges. - - INPUT: - - - ``data_structure`` -- one of ``'sparse'``, ``'static_sparse'``, or - ``'dense'``; see the documentation of :class:`Graph` or - :class:`DiGraph`; default is the data structure of ``self`` - - - ``sparse`` -- boolean (default: ``None``); ``sparse=True`` is an alias - for ``data_structure="sparse"``, and ``sparse=False`` is an alias for - ``data_structure="dense"``. By default (``None``), guess the most - suitable data structure. - - .. WARNING:: - - This always considers multiple edges of graphs as distinguishable, - and hence, may have repeated digraphs. - - .. SEEALSO:: - - - :meth:`~sage.graphs.graph.Graph.strong_orientation` - - :meth:`~sage.graphs.orientations.strong_orientations_iterator` - - :meth:`~sage.graphs.digraph_generators.DiGraphGenerators.nauty_directg` - - :meth:`~sage.graphs.orientations.random_orientation` - - EXAMPLES:: - - sage: G = Graph([[1,2,3], [(1, 2, 'a'), (1, 3, 'b')]], format='vertices_and_edges') - sage: it = G.orientations() - sage: D = next(it) - sage: D.edges(sort=True) - [(1, 2, 'a'), (1, 3, 'b')] - sage: D = next(it) - sage: D.edges(sort=True) - [(1, 2, 'a'), (3, 1, 'b')] - - TESTS:: - - sage: G = Graph() - sage: D = [g for g in G.orientations()] - sage: len(D) - 1 - sage: D[0] - Digraph on 0 vertices - - sage: G = Graph(5) - sage: it = G.orientations() - sage: D = next(it) - sage: D.size() - 0 - - sage: G = Graph([[1,2,'a'], [1,2,'b']], multiedges=True) - sage: len(list(G.orientations())) - 4 - - sage: G = Graph([[1,2], [1,1]], loops=True) - sage: len(list(G.orientations())) - 2 - - sage: G = Graph([[1,2],[2,3]]) - sage: next(G.orientations()) - Digraph on 3 vertices - sage: G = graphs.PetersenGraph() - sage: next(G.orientations()) - An orientation of Petersen graph: Digraph on 10 vertices - - An orientation must have the same ground set of vertices as the original - graph (:issue:`24366`):: - - sage: G = Graph(1) - sage: next(G.orientations()) - Digraph on 1 vertex - """ - if sparse is not None: - if data_structure is not None: - raise ValueError("cannot specify both 'sparse' and 'data_structure'") - data_structure = "sparse" if sparse else "dense" - if data_structure is None: - from sage.graphs.base.dense_graph import DenseGraphBackend - from sage.graphs.base.sparse_graph import SparseGraphBackend - if isinstance(self._backend, DenseGraphBackend): - data_structure = "dense" - elif isinstance(self._backend, SparseGraphBackend): - data_structure = "sparse" - else: - data_structure = "static_sparse" - - name = self.name() - if name: - name = 'An orientation of ' + name - - from sage.graphs.digraph import DiGraph - if not self.size(): - D = DiGraph(data=[self.vertices(sort=False), []], - format='vertices_and_edges', - name=name, - pos=self._pos, - multiedges=self.allows_multiple_edges(), - loops=self.allows_loops(), - data_structure=data_structure) - if hasattr(self, '_embedding'): - D._embedding = copy(self._embedding) - yield D - return - - E = [[(u, v, label), (v, u, label)] if u != v else [(u, v, label)] - for u, v, label in self.edge_iterator()] - verts = self.vertices(sort=False) - for edges in itertools.product(*E): - D = DiGraph(data=[verts, edges], - format='vertices_and_edges', - name=name, - pos=self._pos, - multiedges=self.allows_multiple_edges(), - loops=self.allows_loops(), - data_structure=data_structure) - if hasattr(self, '_embedding'): - D._embedding = copy(self._embedding) - yield D - # Coloring @doc_index("Basic methods") @@ -9466,11 +9170,13 @@ def bipartite_double(self, extended=False): from sage.graphs.lovasz_theta import lovasz_theta from sage.graphs.partial_cube import is_partial_cube from sage.graphs.orientations import orient + from sage.graphs.orientations import orientations from sage.graphs.orientations import strong_orientation from sage.graphs.orientations import strong_orientations_iterator from sage.graphs.orientations import random_orientation from sage.graphs.orientations import acyclic_orientations from sage.graphs.orientations import minimum_outdegree_orientation + from sage.graphs.orientations import bounded_outdegree_orientation from sage.graphs.connectivity import bridges, cleave, spqr_tree from sage.graphs.connectivity import is_triconnected from sage.graphs.comparability import is_comparability @@ -9520,12 +9226,14 @@ def bipartite_double(self, extended=False): "is_permutation" : "Graph properties", "tutte_polynomial" : "Algorithmically hard stuff", "lovasz_theta" : "Leftovers", - "orient" : "Connectivity, orientations, trees", + "orient": "Connectivity, orientations, trees", + "orientations": "Connectivity, orientations, trees", "strong_orientation" : "Connectivity, orientations, trees", "strong_orientations_iterator" : "Connectivity, orientations, trees", "random_orientation" : "Connectivity, orientations, trees", "acyclic_orientations" : "Connectivity, orientations, trees", "minimum_outdegree_orientation": "Connectivity, orientations, trees", + "bounded_outdegree_orientation": "Connectivity, orientations, trees", "bridges" : "Connectivity, orientations, trees", "cleave" : "Connectivity, orientations, trees", "spqr_tree" : "Connectivity, orientations, trees", diff --git a/src/sage/graphs/orientations.py b/src/sage/graphs/orientations.py index 21a8a634aca..26d67bf0457 100644 --- a/src/sage/graphs/orientations.py +++ b/src/sage/graphs/orientations.py @@ -13,12 +13,13 @@ :delim: | :meth:`orient` | Return an oriented version of `G` according the input function `f`. + :meth:`orientations` | Return an iterator over orientations of `G`. :meth:`acyclic_orientations` | Return an iterator over all acyclic orientations of an undirected graph `G`. :meth:`strong_orientation` | Return a strongly connected orientation of the graph `G`. :meth:`strong_orientations_iterator` | Return an iterator over all strong orientations of a graph `G` :meth:`random_orientation` | Return a random orientation of a graph `G` :meth:`minimum_outdegree_orientation` | Return an orientation of `G` with the smallest possible maximum outdegree. - + :meth:`bounded_outdegree_orientation` | Return an orientation of `G` such that every vertex `v` has out-degree less than `b(v)`. Authors ------- @@ -222,6 +223,132 @@ def orient(G, f, weighted=None, data_structure=None, sparse=None, return D +def orientations(G, data_structure=None, sparse=None): + r""" + Return an iterator over orientations of `G`. + + An *orientation* of an undirected graph is a directed graph such that + every edge is assigned a direction. Hence there are `2^s` oriented + digraphs for a simple graph with `s` edges. + + INPUT: + + - ``data_structure`` -- one of ``'sparse'``, ``'static_sparse'``, or + ``'dense'``; see the documentation of :class:`Graph` or :class:`DiGraph`; + default is the data structure of `G` + + - ``sparse`` -- boolean (default: ``None``); ``sparse=True`` is an alias for + ``data_structure="sparse"``, and ``sparse=False`` is an alias for + ``data_structure="dense"``. By default (``None``), guess the most suitable + data structure. + + .. WARNING:: + + This always considers multiple edges of graphs as distinguishable, and + hence, may have repeated digraphs. + + .. SEEALSO:: + + - :meth:`~sage.graphs.graph.Graph.strong_orientation` + - :meth:`~sage.graphs.orientations.strong_orientations_iterator` + - :meth:`~sage.graphs.digraph_generators.DiGraphGenerators.nauty_directg` + - :meth:`~sage.graphs.orientations.random_orientation` + + EXAMPLES:: + + sage: G = Graph([[1,2,3], [(1, 2, 'a'), (1, 3, 'b')]], format='vertices_and_edges') + sage: it = G.orientations() + sage: D = next(it) + sage: D.edges(sort=True) + [(1, 2, 'a'), (1, 3, 'b')] + sage: D = next(it) + sage: D.edges(sort=True) + [(1, 2, 'a'), (3, 1, 'b')] + + TESTS:: + + sage: G = Graph() + sage: D = [g for g in G.orientations()] + sage: len(D) + 1 + sage: D[0] + Digraph on 0 vertices + + sage: G = Graph(5) + sage: it = G.orientations() + sage: D = next(it) + sage: D.size() + 0 + + sage: G = Graph([[1,2,'a'], [1,2,'b']], multiedges=True) + sage: len(list(G.orientations())) + 4 + + sage: G = Graph([[1,2], [1,1]], loops=True) + sage: len(list(G.orientations())) + 2 + + sage: G = Graph([[1,2],[2,3]]) + sage: next(G.orientations()) + Digraph on 3 vertices + sage: G = graphs.PetersenGraph() + sage: next(G.orientations()) + An orientation of Petersen graph: Digraph on 10 vertices + + An orientation must have the same ground set of vertices as the original + graph (:issue:`24366`):: + + sage: G = Graph(1) + sage: next(G.orientations()) + Digraph on 1 vertex + """ + if sparse is not None: + if data_structure is not None: + raise ValueError("cannot specify both 'sparse' and 'data_structure'") + data_structure = "sparse" if sparse else "dense" + if data_structure is None: + from sage.graphs.base.dense_graph import DenseGraphBackend + from sage.graphs.base.sparse_graph import SparseGraphBackend + if isinstance(G._backend, DenseGraphBackend): + data_structure = "dense" + elif isinstance(G._backend, SparseGraphBackend): + data_structure = "sparse" + else: + data_structure = "static_sparse" + + name = G.name() + if name: + name = 'An orientation of ' + name + + if not G.size(): + D = DiGraph(data=[G, []], + format='vertices_and_edges', + name=name, + pos=G._pos, + multiedges=G.allows_multiple_edges(), + loops=G.allows_loops(), + data_structure=data_structure) + if hasattr(G, '_embedding'): + D._embedding = copy(G._embedding) + yield D + return + + E = [[(u, v, label), (v, u, label)] if u != v else [(u, v, label)] + for u, v, label in G.edge_iterator()] + from itertools import product + for edges in product(*E): + D = DiGraph(data=[G, edges], + format='vertices_and_edges', + name=name, + pos=G._pos, + multiedges=G.allows_multiple_edges(), + loops=G.allows_loops(), + data_structure=data_structure) + if hasattr(G, '_embedding'): + D._embedding = copy(G._embedding) + yield D + + def acyclic_orientations(G): r""" Return an iterator over all acyclic orientations of an undirected graph `G`. @@ -972,3 +1099,166 @@ def outgoing(u, e, variable): O.delete_edges(edges) return O + + +def bounded_outdegree_orientation(G, bound, solver=None, verbose=False, + *, integrality_tolerance=1e-3): + r""" + Return an orientation of `G` such that every vertex `v` has out-degree less + than `b(v)`. + + INPUT: + + - ``bound`` -- maximum bound on the out-degree. Can be of three + different types : + + * An integer `k`. In this case, computes an orientation whose maximum + out-degree is less than `k`. + + * A dictionary associating to each vertex its associated maximum + out-degree. + + * A function associating to each vertex its associated maximum + out-degree. + + - ``solver`` -- string (default: ``None``); specifies a Mixed Integer Linear + Programming (MILP) solver to be used. If set to ``None``, the default one + is used. For more information on MILP solvers and which default solver is + used, see the method :meth:`solve + ` of the class + :class:`MixedIntegerLinearProgram + `. + + - ``verbose`` -- integer (default: 0); sets the level of verbosity. Set to 0 + by default, which means quiet. + + - ``integrality_tolerance`` -- float; parameter for use with MILP solvers + over an inexact base ring; + see :meth:`MixedIntegerLinearProgram.get_values`. + + OUTPUT: + + A DiGraph representing the orientation if it exists. + A :exc:`ValueError` exception is raised otherwise. + + ALGORITHM: + + The problem is solved through a maximum flow : + + Given a graph `G`, we create a ``DiGraph`` `D` defined on `E(G)\cup V(G)\cup + \{s,t\}`. We then link `s` to all of `V(G)` (these edges having a capacity + equal to the bound associated to each element of `V(G)`), and all the + elements of `E(G)` to `t` . We then link each `v \in V(G)` to each of its + incident edges in `G`. A maximum integer flow of value `|E(G)|` corresponds + to an admissible orientation of `G`. Otherwise, none exists. + + EXAMPLES: + + There is always an orientation of a graph `G` such that a vertex `v` has + out-degree at most `\lceil \frac {d(v)} 2 \rceil`:: + + sage: g = graphs.RandomGNP(40, .4) + sage: b = lambda v: integer_ceil(g.degree(v)/2) + sage: D = g.bounded_outdegree_orientation(b) + sage: all( D.out_degree(v) <= b(v) for v in g ) + True + + Chvatal's graph, being 4-regular, can be oriented in such a way that its + maximum out-degree is 2:: + + sage: g = graphs.ChvatalGraph() + sage: D = g.bounded_outdegree_orientation(2) + sage: max(D.out_degree()) + 2 + + For any graph `G`, it is possible to compute an orientation such that + the maximum out-degree is at most the maximum average degree of `G` + divided by 2. Anything less, though, is impossible. + + sage: g = graphs.RandomGNP(40, .4) + sage: mad = g.maximum_average_degree() # needs sage.numerical.mip + + Hence this is possible :: + + sage: d = g.bounded_outdegree_orientation(integer_ceil(mad/2)) # needs sage.numerical.mip + + While this is not:: + + sage: try: # needs sage.numerical.mip + ....: g.bounded_outdegree_orientation(integer_ceil(mad/2-1)) + ....: print("Error") + ....: except ValueError: + ....: pass + + TESTS: + + As previously for random graphs, but more intensively:: + + sage: for i in range(30): # long time (up to 6s on sage.math, 2012) + ....: g = graphs.RandomGNP(40, .4) + ....: b = lambda v: integer_ceil(g.degree(v)/2) + ....: D = g.bounded_outdegree_orientation(b) + ....: if not ( + ....: all( D.out_degree(v) <= b(v) for v in g ) or + ....: D.size() != g.size()): + ....: print("Something wrong happened") + """ + G._scream_if_not_simple() + n = G.order() + + if not n: + return DiGraph() + + vertices = list(G) + vertices_id = {y: x for x, y in enumerate(vertices)} + + b = {} + + # Checking the input type. We make a dictionary out of it + if isinstance(bound, dict): + b = bound + else: + try: + b = dict(zip(vertices, map(bound, vertices))) + except TypeError: + b = dict(zip(vertices, [bound]*n)) + + d = DiGraph() + + # Adding the edges (s,v) and ((u,v),t) + d.add_edges(('s', vertices_id[v], b[v]) for v in vertices) + + d.add_edges(((vertices_id[u], vertices_id[v]), 't', 1) + for u, v in G.edges(sort=False, labels=None)) + + # each v is linked to its incident edges + + for u, v in G.edge_iterator(labels=None): + u, v = vertices_id[u], vertices_id[v] + d.add_edge(u, (u, v), 1) + d.add_edge(v, (u, v), 1) + + # Solving the maximum flow + value, flow = d.flow('s', 't', value_only=False, integer=True, + use_edge_labels=True, solver=solver, verbose=verbose, + integrality_tolerance=integrality_tolerance) + + if value != G.size(): + raise ValueError("No orientation exists for the given bound") + + D = DiGraph() + D.add_vertices(vertices) + + # The flow graph may not contain all the vertices, if they are + # not part of the flow... + + for u in [x for x in range(n) if x in flow]: + + for uu, vv in flow.neighbors_out(u): + v = vv if vv != u else uu + D.add_edge(vertices[u], vertices[v]) + + # I do not like when a method destroys the embedding ;-) + D.set_pos(G.get_pos()) + + return D From bf441fbc5b2770beca4655b63b488f8136eeaa5d Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Sat, 12 Oct 2024 18:39:33 +0100 Subject: [PATCH 17/82] apply review changes + speed up number field isogeny comparison --- src/sage/schemes/elliptic_curves/ell_field.py | 34 ++++--- src/sage/schemes/elliptic_curves/hom.py | 3 +- tags | 94 ------------------- 3 files changed, 22 insertions(+), 109 deletions(-) delete mode 100644 tags diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index ab790116637..c7aed047df2 100755 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -2079,18 +2079,25 @@ def isogenies_degree(self, n, *, _intermediate=False): sage: S = list(E.isogenies_degree(5^2*11^4)); len(S), all_distinct(S) # long time (2s) (15, True) + For curves over number fields, the number of distinct isogenies will usually be small:: + + sage: E = EllipticCurve(QQ, [0, 1, 0, -2, 0]) + sage: len(list(E.isogenies_degree(2**1))) + 3 + sage: len(list(E.isogenies_degree(2**9))) + 3 + sage: len(list(E.isogenies_degree(2**10))) + 1 + :: - sage: pol = PolynomialRing(QQ, 'x')([1, -3, 5, -5, 5, -3, 1]) + sage: pol = PolynomialRing(QQ, 'x')([529, 782, 1]) sage: L. = NumberField(pol) - sage: js = hilbert_class_polynomial(-23).roots(L, multiplicities=False) - sage: len(js) + sage: E = EllipticCurve(j=-7072/1127*a + 2016) + sage: len(list(E.isogenies_degree(2))) + 3 + sage: len(list(E.isogenies_degree(2**5))) # long time (4s) 3 - sage: E = EllipticCurve(j=js[0]) - sage: len(list(E.isogenies_degree(2**2))) - 6 - sage: len(list(E.isogenies_degree(2**5))) # long time (15s) - 99 TESTS:: @@ -2126,7 +2133,7 @@ def compute_key(phi): """ Data used in ``hash(phi)`` excluding the expensive `.kernel_polynomial`. """ - return (phi.domain(), phi.codomain(), phi.scaling_factor()) + return (phi.domain(), phi.codomain(), phi.degree(), phi.scaling_factor()) from sage.schemes.elliptic_curves.weierstrass_morphism import identity_morphism from sage.structure.factorization import Factorization @@ -2141,17 +2148,16 @@ def compute_key(phi): p = n[-1][0] seen = {} - def insert_seen(phi): - nonlocal seen + def insert_seen(phi) -> bool: key = compute_key(phi) if key not in seen: seen[key] = [phi] - return phi + return True for psi in seen[key]: if psi == phi: - return + return False seen[key].append(phi) - return phi + return True if _intermediate: yield identity_morphism(self) diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 7bf61914f9a..a570331786c 100755 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -1186,7 +1186,8 @@ def compare_via_evaluation(left, right): elif isinstance(F, number_field_base.NumberField): for _ in range(100): P = E.lift_x(F.random_element(), extend=True) - if not P.has_finite_order(): + # if not P.has_finite_order(): + if P not in P.curve().torsion_points(): return left._eval(P) == right._eval(P) else: assert False, "couldn't find a point of infinite order" diff --git a/tags b/tags deleted file mode 100644 index be52b140999..00000000000 --- a/tags +++ /dev/null @@ -1,94 +0,0 @@ -!_TAG_EXTRA_DESCRIPTION anonymous /Include tags for non-named objects like lambda/ -!_TAG_EXTRA_DESCRIPTION fileScope /Include tags of file scope/ -!_TAG_EXTRA_DESCRIPTION pseudo /Include pseudo tags/ -!_TAG_EXTRA_DESCRIPTION subparser /Include tags generated by subparsers/ -!_TAG_FIELD_DESCRIPTION epoch /the last modified time of the input file (only for F\/file kind tag)/ -!_TAG_FIELD_DESCRIPTION file /File-restricted scoping/ -!_TAG_FIELD_DESCRIPTION input /input file/ -!_TAG_FIELD_DESCRIPTION name /tag name/ -!_TAG_FIELD_DESCRIPTION pattern /pattern/ -!_TAG_FIELD_DESCRIPTION typeref /Type and name of a variable or typedef/ -!_TAG_FIELD_DESCRIPTION!Python nameref /the original name for the tag/ -!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ -!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ -!_TAG_KIND_DESCRIPTION!Python I,namespace /name referring a module defined in other file/ -!_TAG_KIND_DESCRIPTION!Python Y,unknown /name referring a class\/variable\/function\/module defined in other module/ -!_TAG_KIND_DESCRIPTION!Python c,class /classes/ -!_TAG_KIND_DESCRIPTION!Python f,function /functions/ -!_TAG_KIND_DESCRIPTION!Python i,module /modules/ -!_TAG_KIND_DESCRIPTION!Python m,member /class members/ -!_TAG_KIND_DESCRIPTION!Python v,variable /variables/ -!_TAG_KIND_DESCRIPTION!Tex B,bibitem /bibliography items/ -!_TAG_KIND_DESCRIPTION!Tex C,command /command created with \\newcommand/ -!_TAG_KIND_DESCRIPTION!Tex G,subparagraph /subparagraphs/ -!_TAG_KIND_DESCRIPTION!Tex N,counter /counter created with \\newcounter/ -!_TAG_KIND_DESCRIPTION!Tex P,paragraph /paragraphs/ -!_TAG_KIND_DESCRIPTION!Tex b,subsubsection /subsubsections/ -!_TAG_KIND_DESCRIPTION!Tex c,chapter /chapters/ -!_TAG_KIND_DESCRIPTION!Tex e,environment /environment created with \\newenvironment/ -!_TAG_KIND_DESCRIPTION!Tex i,xinput /external input files/ -!_TAG_KIND_DESCRIPTION!Tex l,label /labels/ -!_TAG_KIND_DESCRIPTION!Tex o,operator /math operator created with \\DeclareMathOperator/ -!_TAG_KIND_DESCRIPTION!Tex p,part /parts/ -!_TAG_KIND_DESCRIPTION!Tex s,section /sections/ -!_TAG_KIND_DESCRIPTION!Tex t,theorem /theorem created with \\newtheorem/ -!_TAG_KIND_DESCRIPTION!Tex u,subsection /subsections/ -!_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/ -!_TAG_OUTPUT_FILESEP slash /slash or backslash/ -!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/ -!_TAG_OUTPUT_VERSION 0.0 /current.age/ -!_TAG_PARSER_VERSION!Python 0.0 /current.age/ -!_TAG_PARSER_VERSION!Tex 0.0 /current.age/ -!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/ -!_TAG_PROC_CWD /home/grhkm/git/sage/ // -!_TAG_PROGRAM_AUTHOR Universal Ctags Team // -!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/ -!_TAG_PROGRAM_URL https://ctags.io/ /official site/ -!_TAG_PROGRAM_VERSION 6.0.0 // -!_TAG_ROLE_DESCRIPTION!Python!module imported /imported modules/ -!_TAG_ROLE_DESCRIPTION!Python!module indirectlyImported /module imported in alternative name/ -!_TAG_ROLE_DESCRIPTION!Python!module namespace /namespace from where classes\/variables\/functions are imported/ -!_TAG_ROLE_DESCRIPTION!Python!unknown imported /imported from the other module/ -!_TAG_ROLE_DESCRIPTION!Python!unknown indirectlyImported /classes\/variables\/functions\/modules imported in alternative name/ -!_TAG_ROLE_DESCRIPTION!Tex!xinput bibliography /bibliography (.bib) file/ -!_TAG_ROLE_DESCRIPTION!Tex!xinput included /external input file specified with \\include/ -!_TAG_ROLE_DESCRIPTION!Tex!xinput input /external input file specified with \\input/ -EllipticCurve_field src/sage/schemes/elliptic_curves/ell_field.py /^class EllipticCurve_field(ell_generic.EllipticCurve_generic, ProjectivePlaneCurve_field):$/;" c -Further improvements? src/sage/misc/notes/bernoulli_mod_p.tex /^\\section*{Further improvements?}$/;" s -GraphType src/sage/schemes/elliptic_curves/ell_field.py /^ from sage.graphs.digraph import DiGraph as GraphType$/;" Y member:EllipticCurve_field.isogeny_ell_graph file: nameref:unknown:DiGraph -GraphType src/sage/schemes/elliptic_curves/ell_field.py /^ from sage.graphs.graph import Graph as GraphType$/;" Y member:EllipticCurve_field.isogeny_ell_graph file: nameref:unknown:Graph -\\FF src/sage/misc/notes/bernoulli_mod_p.tex /^\\newcommand{\\FF}{\\mathbf{F}}$/;" C -\\Z src/sage/misc/notes/bernoulli_mod_p.tex /^\\newcommand{\\Z}{\\mathbf{Z}}$/;" C -\\ZZ src/sage/misc/notes/bernoulli_mod_p.tex /^\\newcommand{\\ZZ}{\\mathbf{Z}}$/;" C -_Hom_ src/sage/schemes/elliptic_curves/ell_field.py /^ def _Hom_(self, other, category=None):$/;" m class:EllipticCurve_field -__init__ src/sage/schemes/elliptic_curves/ell_field.py /^ def __init__(self, R, data, category=None):$/;" m class:EllipticCurve_field -_point src/sage/schemes/elliptic_curves/ell_field.py /^ _point = EllipticCurvePoint_field$/;" v class:EllipticCurve_field -base_field src/sage/schemes/elliptic_curves/ell_field.py /^ base_field = ell_generic.EllipticCurve_generic.base_ring$/;" v class:EllipticCurve_field -compute_key src/sage/schemes/elliptic_curves/ell_field.py /^ def compute_key(phi):$/;" f member:EllipticCurve_field.isogenies_degree file: -compute_model src/sage/schemes/elliptic_curves/ell_field.py /^def compute_model(E, name):$/;" f -descend_to src/sage/schemes/elliptic_curves/ell_field.py /^ def descend_to(self, K, f=None):$/;" m class:EllipticCurve_field -division_field src/sage/schemes/elliptic_curves/ell_field.py /^ def division_field(self, n, names='t', map=False, **kwds):$/;" m class:EllipticCurve_field -endomorphism_ring_is_commutative src/sage/schemes/elliptic_curves/ell_field.py /^ def endomorphism_ring_is_commutative(self):$/;" m class:EllipticCurve_field -ffext src/sage/schemes/elliptic_curves/ell_field.py /^ def ffext(poly):$/;" f function:point_of_order file: -genus src/sage/schemes/elliptic_curves/ell_field.py /^ def genus(self):$/;" m class:EllipticCurve_field -hasse_invariant src/sage/schemes/elliptic_curves/ell_field.py /^ def hasse_invariant(self):$/;" m class:EllipticCurve_field -insert_seen src/sage/schemes/elliptic_curves/ell_field.py /^ def insert_seen(phi):$/;" f member:EllipticCurve_field.isogenies_degree file: -is_isogenous src/sage/schemes/elliptic_curves/ell_field.py /^ def is_isogenous(self, other, field=None):$/;" m class:EllipticCurve_field -is_quadratic_twist src/sage/schemes/elliptic_curves/ell_field.py /^ def is_quadratic_twist(self, other):$/;" m class:EllipticCurve_field -is_quartic_twist src/sage/schemes/elliptic_curves/ell_field.py /^ def is_quartic_twist(self, other):$/;" m class:EllipticCurve_field -is_sextic_twist src/sage/schemes/elliptic_curves/ell_field.py /^ def is_sextic_twist(self, other):$/;" m class:EllipticCurve_field -isogenies_degree src/sage/schemes/elliptic_curves/ell_field.py /^ def isogenies_degree(self, n, *, _intermediate=False):$/;" m class:EllipticCurve_field -isogenies_prime_degree src/sage/schemes/elliptic_curves/ell_field.py /^ def isogenies_prime_degree(self, l=None, max_l=31):$/;" m class:EllipticCurve_field -isogeny src/sage/schemes/elliptic_curves/ell_field.py /^ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, algorithm=None/;" m class:EllipticCurve_field -isogeny_codomain src/sage/schemes/elliptic_curves/ell_field.py /^ def isogeny_codomain(self, kernel):$/;" m class:EllipticCurve_field -isogeny_ell_graph src/sage/schemes/elliptic_curves/ell_field.py /^ def isogeny_ell_graph(self, l, directed=True, label_by_j=False):$/;" m class:EllipticCurve_field -kernel_polynomial_from_divisor src/sage/schemes/elliptic_curves/ell_field.py /^ def kernel_polynomial_from_divisor(self, f, l, *, check=True):$/;" m class:EllipticCurve_field -kernel_polynomial_from_point src/sage/schemes/elliptic_curves/ell_field.py /^ def kernel_polynomial_from_point(self, P, *, algorithm=None):$/;" m class:EllipticCurve_field -mul_a src/sage/schemes/elliptic_curves/ell_field.py /^ mul_a = lambda x: self._multiple_x_numerator(a, x=x) \/ self._multiple_x_denominator(a, /;" f member:EllipticCurve_field.kernel_polynomial_from_divisor file: -point_of_order src/sage/schemes/elliptic_curves/ell_field.py /^def point_of_order(E, n):$/;" f -quadratic_twist src/sage/schemes/elliptic_curves/ell_field.py /^ def quadratic_twist(self, D=None):$/;" m class:EllipticCurve_field -quartic_twist src/sage/schemes/elliptic_curves/ell_field.py /^ def quartic_twist(self, D):$/;" m class:EllipticCurve_field -sextic_twist src/sage/schemes/elliptic_curves/ell_field.py /^ def sextic_twist(self, D):$/;" m class:EllipticCurve_field -two_torsion_rank src/sage/schemes/elliptic_curves/ell_field.py /^ def two_torsion_rank(self):$/;" m class:EllipticCurve_field -weierstrass_p src/sage/schemes/elliptic_curves/ell_field.py /^ def weierstrass_p(self, prec=20, algorithm=None):$/;" m class:EllipticCurve_field -x_mod src/sage/schemes/elliptic_curves/ell_field.py /^ x_mod = lambda g: g.parent().quotient(g).gen()$/;" f member:EllipticCurve_field.kernel_polynomial_from_divisor file: From 3646d2d00c3f225956fe67d6b23537b5d9b559a1 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 13 Oct 2024 10:44:57 +0200 Subject: [PATCH 18/82] #38809: move eulerian_orientation --- src/sage/graphs/generic_graph.py | 105 ------------------------------- src/sage/graphs/graph.py | 2 + src/sage/graphs/orientations.py | 100 +++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 105 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 3ae14de7877..2ac94118857 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -117,7 +117,6 @@ :widths: 30, 70 :delim: | - :meth:`~GenericGraph.eulerian_orientation` | Return a DiGraph which is an Eulerian orientation of the current graph. :meth:`~GenericGraph.eulerian_circuit` | Return a list of edges forming an Eulerian circuit if one exists. :meth:`~GenericGraph.minimum_cycle_basis` | Return a minimum weight cycle basis of the graph. :meth:`~GenericGraph.cycle_basis` | Return a list of cycles which form a basis of the cycle space of ``self``. @@ -4547,110 +4546,6 @@ def size(self): num_edges = size - # Orientations - - def eulerian_orientation(self): - r""" - Return a DiGraph which is an Eulerian orientation of the current graph. - - An Eulerian graph being a graph such that any vertex has an even degree, - an Eulerian orientation of a graph is an orientation of its edges such - that each vertex `v` verifies `d^+(v)=d^-(v)=d(v)/2`, where `d^+` and - `d^-` respectively represent the out-degree and the in-degree of a - vertex. - - If the graph is not Eulerian, the orientation verifies for any vertex - `v` that `| d^+(v)-d^-(v) | \leq 1`. - - ALGORITHM: - - This algorithm is a random walk through the edges of the graph, which - orients the edges according to the walk. When a vertex is reached which - has no non-oriented edge (this vertex must have odd degree), the walk - resumes at another vertex of odd degree, if any. - - This algorithm has complexity `O(n+m)` for ``SparseGraph`` and `O(n^2)` - for ``DenseGraph``, where `m` is the number of edges in the graph and - `n` is the number of vertices in the graph. - - EXAMPLES: - - The CubeGraph with parameter 4, which is regular of even degree, has an - Eulerian orientation such that `d^+ = d^-`:: - - sage: g = graphs.CubeGraph(4) - sage: g.degree() - [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4] - sage: o = g.eulerian_orientation() - sage: o.in_degree() - [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] - sage: o.out_degree() - [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] - - Secondly, the Petersen Graph, which is 3 regular has an orientation such - that the difference between `d^+` and `d^-` is at most 1:: - - sage: g = graphs.PetersenGraph() - sage: o = g.eulerian_orientation() - sage: o.in_degree() - [2, 2, 2, 2, 2, 1, 1, 1, 1, 1] - sage: o.out_degree() - [1, 1, 1, 1, 1, 2, 2, 2, 2, 2] - - TESTS:: - - sage: E0 = Graph(); E4 = Graph(4) # See trac #21741 - sage: E0.eulerian_orientation() - Digraph on 0 vertices - sage: E4.eulerian_orientation() - Digraph on 4 vertices - """ - from sage.graphs.digraph import DiGraph - - d = DiGraph() - d.add_vertices(self.vertex_iterator()) - - if not self.size(): - return d - - g = copy(self) - - # list of vertices of odd degree - odd = [x for x in g.vertex_iterator() if g.degree(x) % 2] - - # Picks the first vertex, which is preferably an odd one - if odd: - v = odd.pop() - else: - v = next(g.edge_iterator(labels=None))[0] - odd.append(v) - # Stops when there is no edge left - while True: - - # If there is an edge adjacent to the current one - if g.degree(v): - e = next(g.edge_iterator(v)) - g.delete_edge(e) - if e[0] != v: - e = (e[1], e[0], e[2]) - d.add_edge(e) - v = e[1] - - # The current vertex is isolated - else: - odd.remove(v) - - # jumps to another odd vertex if possible - if odd: - v = odd.pop() - # Else jumps to an even vertex which is not isolated - elif g.size(): - v = next(g.edge_iterator())[0] - odd.append(v) - # If there is none, we are done ! - else: - return d - def eulerian_circuit(self, return_vertices=False, labels=True, path=False): r""" Return a list of edges forming an Eulerian circuit if one exists. diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index e7a5c6fc2bc..00cb3875635 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -9177,6 +9177,7 @@ def bipartite_double(self, extended=False): from sage.graphs.orientations import acyclic_orientations from sage.graphs.orientations import minimum_outdegree_orientation from sage.graphs.orientations import bounded_outdegree_orientation + from sage.graphs.orientations import eulerian_orientation from sage.graphs.connectivity import bridges, cleave, spqr_tree from sage.graphs.connectivity import is_triconnected from sage.graphs.comparability import is_comparability @@ -9234,6 +9235,7 @@ def bipartite_double(self, extended=False): "acyclic_orientations" : "Connectivity, orientations, trees", "minimum_outdegree_orientation": "Connectivity, orientations, trees", "bounded_outdegree_orientation": "Connectivity, orientations, trees", + "eulerian_orientation": "Connectivity, orientations, trees", "bridges" : "Connectivity, orientations, trees", "cleave" : "Connectivity, orientations, trees", "spqr_tree" : "Connectivity, orientations, trees", diff --git a/src/sage/graphs/orientations.py b/src/sage/graphs/orientations.py index 26d67bf0457..898898d3d4d 100644 --- a/src/sage/graphs/orientations.py +++ b/src/sage/graphs/orientations.py @@ -20,6 +20,7 @@ :meth:`random_orientation` | Return a random orientation of a graph `G` :meth:`minimum_outdegree_orientation` | Return an orientation of `G` with the smallest possible maximum outdegree. :meth:`bounded_outdegree_orientation` | Return an orientation of `G` such that every vertex `v` has out-degree less than `b(v)`. + :meth:`eulerian_orientation(G)` | Return a DiGraph which is an Eulerian orientation of the graph `G`. Authors ------- @@ -1262,3 +1263,102 @@ def bounded_outdegree_orientation(G, bound, solver=None, verbose=False, D.set_pos(G.get_pos()) return D + + +def eulerian_orientation(G): + r""" + Return a DiGraph which is an Eulerian orientation of the graph `G`. + + An Eulerian graph being a graph such that any vertex has an even degree, an + Eulerian orientation of a graph is an orientation of its edges such that + each vertex `v` verifies `d^+(v)=d^-(v)=d(v)/2`, where `d^+` and `d^-` + respectively represent the out-degree and the in-degree of a vertex. + + If the graph is not Eulerian, the orientation verifies for any vertex `v` + that `| d^+(v)-d^-(v) | \leq 1`. + + ALGORITHM: + + This algorithm is a random walk through the edges of the graph, which + orients the edges according to the walk. When a vertex is reached which has + no non-oriented edge (this vertex must have odd degree), the walk resumes at + another vertex of odd degree, if any. + + This algorithm has time complexity in `O(n+m)` for ``SparseGraph`` and + `O(n^2)` for ``DenseGraph``, where `m` is the number of edges in the graph + and `n` is the number of vertices in the graph. + + EXAMPLES: + + The CubeGraph with parameter 4, which is regular of even degree, has an + Eulerian orientation such that `d^+ = d^-`:: + + sage: g = graphs.CubeGraph(4) + sage: g.degree() + [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4] + sage: o = g.eulerian_orientation() + sage: o.in_degree() + [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] + sage: o.out_degree() + [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] + + Secondly, the Petersen Graph, which is 3 regular has an orientation such + that the difference between `d^+` and `d^-` is at most 1:: + + sage: g = graphs.PetersenGraph() + sage: o = g.eulerian_orientation() + sage: o.in_degree() + [2, 2, 2, 2, 2, 1, 1, 1, 1, 1] + sage: o.out_degree() + [1, 1, 1, 1, 1, 2, 2, 2, 2, 2] + + TESTS:: + + sage: E0 = Graph(); E4 = Graph(4) # See trac #21741 + sage: E0.eulerian_orientation() + Digraph on 0 vertices + sage: E4.eulerian_orientation() + Digraph on 4 vertices + """ + d = DiGraph([G, []], format='vertices_and_edges') + + if not G.size(): + return d + + g = copy(G) + + # list of vertices of odd degree + odd = [x for x in g.vertex_iterator() if g.degree(x) % 2] + + # Picks the first vertex, which is preferably an odd one + if odd: + v = odd.pop() + else: + v = next(g.edge_iterator(labels=None))[0] + odd.append(v) + # Stops when there is no edge left + while True: + + # If there is an edge adjacent to the current one + if g.degree(v): + e = next(g.edge_iterator(v)) + g.delete_edge(e) + if e[0] != v: + e = (e[1], e[0], e[2]) + d.add_edge(e) + v = e[1] + + # The current vertex is isolated + else: + odd.remove(v) + + # jumps to another odd vertex if possible + if odd: + v = odd.pop() + # Else jumps to an even vertex which is not isolated + elif g.size(): + v = next(g.edge_iterator())[0] + odd.append(v) + # If there is none, we are done ! + else: + return d From 0cd7a07785a6248b1da19aaa76848136569866be Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 13 Oct 2024 10:47:46 +0200 Subject: [PATCH 19/82] #38809: document input --- src/sage/graphs/orientations.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/sage/graphs/orientations.py b/src/sage/graphs/orientations.py index 898898d3d4d..a104b98b948 100644 --- a/src/sage/graphs/orientations.py +++ b/src/sage/graphs/orientations.py @@ -234,6 +234,8 @@ def orientations(G, data_structure=None, sparse=None): INPUT: + - ``G`` -- an undirected graph + - ``data_structure`` -- one of ``'sparse'``, ``'static_sparse'``, or ``'dense'``; see the documentation of :class:`Graph` or :class:`DiGraph`; default is the data structure of `G` @@ -630,6 +632,10 @@ def strong_orientation(G): returned will ensure that each 2-connected component has a strongly connected orientation. + INPUT: + + - ``G`` -- an undirected graph + OUTPUT: a digraph representing an orientation of the current graph .. NOTE:: @@ -1014,6 +1020,8 @@ def minimum_outdegree_orientation(G, use_edge_labels=False, solver=None, verbose INPUT: + - ``G`` -- an undirected graph + - ``use_edge_labels`` -- boolean (default: ``False``) - When set to ``True``, uses edge labels as weights to compute the @@ -1110,6 +1118,8 @@ def bounded_outdegree_orientation(G, bound, solver=None, verbose=False, INPUT: + - ``G`` -- an undirected graph + - ``bound`` -- maximum bound on the out-degree. Can be of three different types : @@ -1277,6 +1287,10 @@ def eulerian_orientation(G): If the graph is not Eulerian, the orientation verifies for any vertex `v` that `| d^+(v)-d^-(v) | \leq 1`. + INPUT: + + - ``G`` -- an undirected graph + ALGORITHM: This algorithm is a random walk through the edges of the graph, which From 16ca85043223a5def0153e8469faadbdcc26994d Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 13 Oct 2024 13:29:17 +0200 Subject: [PATCH 20/82] #38809: make codecov happy --- src/sage/graphs/orientations.py | 76 +++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/orientations.py b/src/sage/graphs/orientations.py index a104b98b948..30f560ff5fb 100644 --- a/src/sage/graphs/orientations.py +++ b/src/sage/graphs/orientations.py @@ -304,6 +304,33 @@ def orientations(G, data_structure=None, sparse=None): sage: G = Graph(1) sage: next(G.orientations()) Digraph on 1 vertex + + Which backend? :: + + sage: next(G.orientations(data_structure='sparse', sparse=True))._backend + Traceback (most recent call last): + ... + ValueError: cannot specify both 'sparse' and 'data_structure' + sage: next(G.orientations(sparse=True))._backend + + sage: next(G.orientations(sparse=False))._backend + + sage: next(G.orientations())._backend + + sage: G = Graph(1, data_structure='dense') + sage: next(G.orientations())._backend + + sage: G = Graph(1, data_structure='static_sparse') + sage: next(G.orientations())._backend + + + Check that the embedding is copied:: + + sage: G = Graph([(0, 1), (0, 2), (1, 2)]) + sage: embedding = {0: [1, 2], 1: [2, 0], 2: [0, 1]} + sage: G.set_embedding(embedding) + sage: next(G.orientations()).get_embedding() == embedding + True """ if sparse is not None: if data_structure is not None: @@ -676,9 +703,9 @@ def strong_orientation(G): A multigraph also has a strong orientation:: - sage: g = Graph([(1,2),(1,2)], multiedges=True) + sage: g = Graph([(0, 1), (0, 2), (1, 2)] * 2, multiedges=True) sage: g.strong_orientation() - Multi-digraph on 2 vertices + Multi-digraph on 3 vertices """ d = DiGraph(multiedges=G.allows_multiple_edges()) i = 0 @@ -1054,6 +1081,32 @@ def minimum_outdegree_orientation(G, use_edge_labels=False, solver=None, verbose sage: o = g.minimum_outdegree_orientation() # needs sage.numerical.mip sage: max(o.out_degree()) == integer_ceil((4*3)/(3+4)) # needs sage.numerical.mip True + + Show the influence of edge labels on the solution:: + + sage: # needs sage.numerical.mip + sage: g = graphs.CycleGraph(4) + sage: g.add_edge(0, 2) + sage: o = g.minimum_outdegree_orientation(use_edge_labels=False) + sage: o.out_degree(labels=True) == {0: 1, 1: 2, 2: 1, 3: 1} + True + sage: _ = [g.set_edge_label(u, v, 1) for u, v in g.edge_iterator(labels=False)] + sage: o = g.minimum_outdegree_orientation(use_edge_labels=True) + sage: o.out_degree(labels=True) == {0: 1, 1: 2, 2: 1, 3: 1} + True + sage: g.set_edge_label(0, 2, 10) + sage: o = g.minimum_outdegree_orientation(use_edge_labels=True) + sage: o.out_degree(labels=True) == {0: 1, 1: 2, 2: 0, 3: 2} + True + + TESTS:: + + sage: from sage.graphs.orientations import minimum_outdegree_orientation + sage: minimum_outdegree_orientation(DiGraph()) # needs sage.numerical.mip + Traceback (most recent call last): + ... + ValueError: Cannot compute an orientation of a DiGraph. + Please convert it to a Graph if you really mean it. """ G._scream_if_not_simple() if G.is_directed(): @@ -1064,7 +1117,7 @@ def minimum_outdegree_orientation(G, use_edge_labels=False, solver=None, verbose from sage.rings.real_mpfr import RR def weight(e): - label = G.edge_label(e) + label = G.edge_label(e[0], e[1]) return label if label in RR else 1 else: def weight(e): @@ -1171,7 +1224,7 @@ def bounded_outdegree_orientation(G, bound, solver=None, verbose=False, sage: g = graphs.RandomGNP(40, .4) sage: b = lambda v: integer_ceil(g.degree(v)/2) sage: D = g.bounded_outdegree_orientation(b) - sage: all( D.out_degree(v) <= b(v) for v in g ) + sage: all(D.out_degree(v) <= b(v) for v in g) True Chvatal's graph, being 4-regular, can be oriented in such a way that its @@ -1201,6 +1254,16 @@ def bounded_outdegree_orientation(G, bound, solver=None, verbose=False, ....: except ValueError: ....: pass + The bounds can be specified in different ways:: + + sage: g = graphs.PetersenGraph() + sage: b = lambda v: integer_ceil(g.degree(v)/2) + sage: D = g.bounded_outdegree_orientation(b) + sage: b_dict = {u: b(u) for u in g} + sage: D = g.bounded_outdegree_orientation(b_dict) + sage: unique_bound = 2 + sage: D = g.bounded_outdegree_orientation(unique_bound) + TESTS: As previously for random graphs, but more intensively:: @@ -1213,6 +1276,11 @@ def bounded_outdegree_orientation(G, bound, solver=None, verbose=False, ....: all( D.out_degree(v) <= b(v) for v in g ) or ....: D.size() != g.size()): ....: print("Something wrong happened") + + Empty graph:: + + sage: Graph().bounded_outdegree_orientation(b) + Digraph on 0 vertices """ G._scream_if_not_simple() n = G.order() From 3e82d92abbfd44f29aa1172095b0f5d9b76fbc58 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 13 Oct 2024 15:15:56 +0200 Subject: [PATCH 21/82] #38809: make a test mip solver independent --- src/sage/graphs/orientations.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/sage/graphs/orientations.py b/src/sage/graphs/orientations.py index 30f560ff5fb..af9c795f535 100644 --- a/src/sage/graphs/orientations.py +++ b/src/sage/graphs/orientations.py @@ -331,6 +331,10 @@ def orientations(G, data_structure=None, sparse=None): sage: G.set_embedding(embedding) sage: next(G.orientations()).get_embedding() == embedding True + sage: G = Graph() + sage: G.set_embedding({}) + sage: next(G.orientations()).get_embedding() == {} + True """ if sparse is not None: if data_structure is not None: @@ -1085,19 +1089,18 @@ def minimum_outdegree_orientation(G, use_edge_labels=False, solver=None, verbose Show the influence of edge labels on the solution:: sage: # needs sage.numerical.mip - sage: g = graphs.CycleGraph(4) - sage: g.add_edge(0, 2) + sage: g = graphs.PetersenGraph() sage: o = g.minimum_outdegree_orientation(use_edge_labels=False) - sage: o.out_degree(labels=True) == {0: 1, 1: 2, 2: 1, 3: 1} - True + sage: max(o.out_degree()) + 2 sage: _ = [g.set_edge_label(u, v, 1) for u, v in g.edge_iterator(labels=False)] sage: o = g.minimum_outdegree_orientation(use_edge_labels=True) - sage: o.out_degree(labels=True) == {0: 1, 1: 2, 2: 1, 3: 1} - True - sage: g.set_edge_label(0, 2, 10) + sage: max(o.out_degree()) + 2 + sage: g.set_edge_label(0, 1, 100) sage: o = g.minimum_outdegree_orientation(use_edge_labels=True) - sage: o.out_degree(labels=True) == {0: 1, 1: 2, 2: 0, 3: 2} - True + sage: max(o.out_degree()) + 3 TESTS:: From adeea98a0c10df109520561261e4795ce6fa5d7b Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sun, 13 Oct 2024 15:59:13 +0200 Subject: [PATCH 22/82] add method to check whether the order of an elliptic-curve point over a number field exceeds a given number --- src/sage/schemes/elliptic_curves/ell_point.py | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index 0da080ffdbe..8b632a7bd2a 100755 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -2551,6 +2551,91 @@ def has_infinite_order(self): return False return self.order() == oo + def _has_order_at_least(self, bound, *, attempts=999): + r""" + Return ``True`` if this point definitely has order at least ``bound`` + on the elliptic curve, ``False`` if the point has smaller order, and + ``None`` if the result of this test is inconclusive. + + This method can be much faster than calling :meth:`has_infinite_order` + if all that is needed is a lower bound on the order. + + ALGORITHM: Compute the order of the point modulo various small primes + and combine that information using CRT. + + EXAMPLES:: + + sage: E = EllipticCurve('11a3') + sage: P = next(filter(bool, E.torsion_points())) + sage: P._has_order_at_least(5) + True + sage: P._has_order_at_least(6) + sage: P.order() + 5 + sage: Q = E.lift_x(10^42, extend=True) + sage: Q._has_order_at_least(10^100) + True + + :: + + sage: x = polygen(ZZ) + sage: K. = NumberField(x^2 - x + 2) + sage: E = EllipticCurve([1, a-1, a+1, -2*a-2, -5*a+7]) # 2.0.7.1-268.3-b1 + sage: P = next(filter(bool, E.torsion_points())) + sage: P._has_order_at_least(11) + True + sage: P._has_order_at_least(12) + False + sage: P.order() + 11 + sage: Q = E.lift_x(123*a + 456, extend=True) + sage: Q._has_order_at_least(10^100) + True + """ + n = getattr(self, '_order', None) + if n is not None: + return n >= bound + + from sage.sets.primes import Primes + from sage.rings.finite_rings.finite_field_constructor import GF + if self.curve().base_field().absolute_degree() > 1: + K = self.curve().base_field().absolute_field('T') + _, iso = K.structure() + E = self.curve().change_ring(iso) + P = self.change_ring(iso) + poly = lambda elt: elt.polynomial() + else: + K, E, P = QQ, self.curve(), self + poly = lambda elt: QQ['x'](elt) + assert P.curve() is E + + n = ZZ.one() + no_progress = 0 + for p in Primes(): + f,_ = K.defining_polynomial().change_ring(GF(p)).factor()[0] + F = GF(p).extension(f,'t') + red = lambda elt: F(f.parent()(poly(elt)).change_ring(GF(p)) % f) + + try: + Ered = E.change_ring(red) + Pred = Ered(*map(red, P)) + except (ZeroDivisionError, ArithmeticError): + continue + + o = Pred.order() + if not o.divides(n): + n = n.lcm(o) + no_progress = 0 + else: + no_progress += 1 + + if n >= bound: + return True + if no_progress >= attempts: + return + + assert False # unreachable unless there are only finitely many primes + def is_on_identity_component(self, embedding=None): r""" Return ``True`` iff this point is on the identity component of From 7973a21e8eecbd9a1b7896f4d996559f60ee467f Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Mon, 14 Oct 2024 01:48:04 +0200 Subject: [PATCH 23/82] when comparing elliptic-curve morphisms over number fields, check for minimum order rather than infinite order --- src/sage/schemes/elliptic_curves/hom.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 7bf61914f9a..50ac748d2a2 100755 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -1175,9 +1175,9 @@ def compare_via_evaluation(left, right): E = left.domain() F = E.base_ring() + d = left.degree() if isinstance(F, finite_field_base.FiniteField): q = F.cardinality() - d = left.degree() e = integer_floor(1 + 2 * (2*d.sqrt() + 1).log(q)) # from Hasse bound e = next(i for i, n in enumerate(E.count_points(e+1), 1) if n > 4*d) EE = E.base_extend(F.extension(e, 'U')) # named extension is faster @@ -1186,10 +1186,10 @@ def compare_via_evaluation(left, right): elif isinstance(F, number_field_base.NumberField): for _ in range(100): P = E.lift_x(F.random_element(), extend=True) - if not P.has_finite_order(): + if P._has_order_at_least(4*d + 1): return left._eval(P) == right._eval(P) else: - assert False, "couldn't find a point of infinite order" + assert False, "couldn't find a point of large enough order" else: raise NotImplementedError('not implemented for this base field') From 61ca75b259fe374156806c7aaec336fc4b794990 Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Tue, 15 Oct 2024 15:37:31 +0100 Subject: [PATCH 24/82] Apply Lorenz's number field patch for faster torsion point check Co-authored-by: Lorenz Panny --- src/sage/schemes/elliptic_curves/ell_field.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 308d2028290..b8463105257 100755 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -2100,6 +2100,14 @@ def isogenies_degree(self, n, *, _intermediate=False): sage: len(list(E.isogenies_degree(2**5))) # long time (4s) 3 + :: + + sage: pol = PolynomialRing(QQ, 'x')([1, -3, 5, -5, 5, -3, 1]) + sage: L. = NumberField(pol) + sage: js = hilbert_class_polynomial(-23).roots(L, multiplicities=False) + sage: E = EllipticCurve(j=choice(js)) + sage: len(list(E.isogenies_degree(2^3))) # long time (9s) + TESTS:: sage: E = EllipticCurve(GF(next_prime(2^32)), j=1728) From 7810dbcdb89578970cbd598476ec65918aaeca13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 16 Oct 2024 22:08:00 +0200 Subject: [PATCH 25/82] a few simplified isinstance (ruff SIM101) --- src/sage/calculus/calculus.py | 2 +- src/sage/calculus/functions.py | 6 +++--- src/sage/coding/reed_muller_code.py | 13 +++---------- src/sage/functions/transcendental.py | 2 +- src/sage/matroids/constructor.py | 2 +- src/sage/modular/abvar/abvar_ambient_jacobian.py | 2 +- src/sage/modular/abvar/torsion_subgroup.py | 8 ++++---- src/sage/modular/dirichlet.py | 11 +++++++---- src/sage/modular/modform/constructor.py | 4 ++-- src/sage/modular/modform/hecke_operator_on_qexp.py | 2 +- .../modular/modform_hecketriangle/abstract_space.py | 4 ++-- src/sage/modular/overconvergent/genus0.py | 2 +- src/sage/modular/overconvergent/hecke_series.py | 4 ++-- src/sage/numerical/optimize.py | 2 +- src/sage/plot/plot3d/plot3d.py | 4 +++- src/sage/quadratic_forms/quadratic_form.py | 4 ++-- src/sage/quadratic_forms/ternary_qf.py | 2 +- src/sage/schemes/affine/affine_space.py | 2 +- src/sage/schemes/berkovich/berkovich_cp_element.py | 2 +- src/sage/schemes/elliptic_curves/ell_field.py | 2 +- src/sage/schemes/generic/algebraic_scheme.py | 4 ++-- src/sage/schemes/plane_conics/constructor.py | 2 +- src/sage/schemes/projective/projective_space.py | 2 +- src/sage/schemes/toric/fano_variety.py | 2 +- src/sage/sets/set.py | 2 +- 25 files changed, 45 insertions(+), 47 deletions(-) diff --git a/src/sage/calculus/calculus.py b/src/sage/calculus/calculus.py index 65a075a2e1f..6dd8c1f671b 100644 --- a/src/sage/calculus/calculus.py +++ b/src/sage/calculus/calculus.py @@ -2220,7 +2220,7 @@ def _is_function(v): x^2 + 1 """ # note that Sage variables are callable, so we only check the type - return isinstance(v, Function) or isinstance(v, FunctionType) + return isinstance(v, (Function, FunctionType)) def symbolic_expression_from_maxima_string(x, equals_sub=False, maxima=maxima): diff --git a/src/sage/calculus/functions.py b/src/sage/calculus/functions.py index c044cc0a968..46479be8b0b 100644 --- a/src/sage/calculus/functions.py +++ b/src/sage/calculus/functions.py @@ -139,12 +139,12 @@ def jacobian(functions, variables): [ 0 e^x] """ if isinstance(functions, Matrix) and (functions.nrows() == 1 - or functions.ncols() == 1): + or functions.ncols() == 1): functions = functions.list() - elif not (isinstance(functions, (tuple, list)) or isinstance(functions, Vector)): + elif not isinstance(functions, (tuple, list, Vector)): functions = [functions] - if not isinstance(variables, (tuple, list)) and not isinstance(variables, Vector): + if not isinstance(variables, (tuple, list, Vector)): variables = [variables] return matrix([[diff(f, v) for v in variables] for f in functions]) diff --git a/src/sage/coding/reed_muller_code.py b/src/sage/coding/reed_muller_code.py index 64258f48927..e690534c5e3 100644 --- a/src/sage/coding/reed_muller_code.py +++ b/src/sage/coding/reed_muller_code.py @@ -584,16 +584,11 @@ def __init__(self, code): ... ValueError: the code has to be a Reed-Muller code """ - if not ( - isinstance( - code, - QAryReedMullerCode) or isinstance( - code, - BinaryReedMullerCode)): + if not isinstance(code, (QAryReedMullerCode, BinaryReedMullerCode)): raise ValueError("the code has to be a Reed-Muller code") super().__init__(code) - def _repr_(self): + def _repr_(self) -> str: r""" Return a string representation of ``self``. @@ -775,9 +770,7 @@ def __init__(self, code, polynomial_ring=None): ... ValueError: The Polynomial ring should be on Finite Field of size 59 and should have 3 variables """ - if not ( - isinstance(code, QAryReedMullerCode) - or isinstance(code, BinaryReedMullerCode)): + if not isinstance(code, (QAryReedMullerCode, BinaryReedMullerCode)): raise ValueError("the code has to be a Reed-Muller code") super().__init__(code) if polynomial_ring is None: diff --git a/src/sage/functions/transcendental.py b/src/sage/functions/transcendental.py index 7cfa2640473..55e24a44cbd 100644 --- a/src/sage/functions/transcendental.py +++ b/src/sage/functions/transcendental.py @@ -449,7 +449,7 @@ def zeta_symmetric(s): - I copied the definition of xi from http://web.viu.ca/pughg/RiemannZeta/RiemannZetaLong.html """ - if not (isinstance(s, ComplexNumber) or isinstance(s, RealNumber)): + if not isinstance(s, (ComplexNumber, RealNumber)): s = ComplexField()(s) R = s.parent() diff --git a/src/sage/matroids/constructor.py b/src/sage/matroids/constructor.py index a71674e2987..8548b2bfede 100644 --- a/src/sage/matroids/constructor.py +++ b/src/sage/matroids/constructor.py @@ -815,7 +815,7 @@ def Matroid(groundset=None, data=None, **kwds): key = 'matroid' elif isinstance(data, str): key = 'revlex' - elif isinstance(data, dict) or isinstance(data, FiniteLatticePoset): + elif isinstance(data, (dict, FiniteLatticePoset)): key = 'flats' elif data is None: raise TypeError("no input data given for Matroid()") diff --git a/src/sage/modular/abvar/abvar_ambient_jacobian.py b/src/sage/modular/abvar/abvar_ambient_jacobian.py index 1a7c1e82370..7674b41807a 100644 --- a/src/sage/modular/abvar/abvar_ambient_jacobian.py +++ b/src/sage/modular/abvar/abvar_ambient_jacobian.py @@ -409,7 +409,7 @@ def newform_decomposition(self, names=None): if self.dimension() == 0: return [] G = self.group() - if not (isinstance(G, Gamma0_class) or isinstance(G, Gamma1_class)): + if not isinstance(G, (Gamma0_class, Gamma1_class)): return [S.newform(names=names) for S in self.decomposition()] Gtype = G.parent() N = G.level() diff --git a/src/sage/modular/abvar/torsion_subgroup.py b/src/sage/modular/abvar/torsion_subgroup.py index 84ee1abe795..6ae7bff58c7 100644 --- a/src/sage/modular/abvar/torsion_subgroup.py +++ b/src/sage/modular/abvar/torsion_subgroup.py @@ -468,7 +468,7 @@ def multiple_of_order(self, maxp=None, proof=True): return self._multiple_of_order_proof_false # The Gamma0 and Gamma1 case - if all((isinstance(G, Gamma0_class) or isinstance(G, Gamma1_class) for G in A.groups())): + if all(isinstance(G, (Gamma0_class, Gamma1_class)) for G in A.groups()): self._multiple_of_order = self.multiple_of_order_using_frobp() return self._multiple_of_order @@ -566,13 +566,13 @@ def multiple_of_order_using_frobp(self, maxp=None): pass A = self.abelian_variety() if A.dimension() == 0: - T = ZZ(1) + T = ZZ.one() self.__multiple_of_order_using_frobp = T return T - if not all((isinstance(G, Gamma0_class) or isinstance(G, Gamma1_class) for G in A.groups())): + if not all(isinstance(G, (Gamma0_class, Gamma1_class)) for G in A.groups()): raise NotImplementedError("torsion multiple only implemented for Gamma0 and Gamma1") - bnd = ZZ(0) + bnd = ZZ.zero() N = A.level() cnt = 0 if maxp is None: diff --git a/src/sage/modular/dirichlet.py b/src/sage/modular/dirichlet.py index 1f6a7a94444..c261a84e8de 100644 --- a/src/sage/modular/dirichlet.py +++ b/src/sage/modular/dirichlet.py @@ -1386,7 +1386,8 @@ def gauss_sum(self, a=1): elif isinstance(K, sage.rings.abc.AlgebraicField): L = K zeta = L.zeta(m) - elif isinstance(K, sage.rings.abc.NumberField_cyclotomic) or isinstance(K, RationalField): + elif isinstance(K, (sage.rings.abc.NumberField_cyclotomic, + RationalField)): chi = chi.minimize_base_ring() n = lcm(m, G.zeta_order()) L = CyclotomicField(n) @@ -1467,7 +1468,8 @@ def phi(t): from sage.rings.complex_mpfr import ComplexField CC = ComplexField(prec) phi = CC.coerce_map_from(K) - elif isinstance(K, sage.rings.abc.NumberField_cyclotomic) or isinstance(K, RationalField): + elif isinstance(K, (sage.rings.abc.NumberField_cyclotomic, + RationalField)): phi = K.complex_embedding(prec) CC = phi.codomain() else: @@ -1688,8 +1690,9 @@ def kloosterman_sum_numerical(self, prec=53, a=1, b=0): """ G = self.parent() K = G.base_ring() - if not (isinstance(K, sage.rings.abc.NumberField_cyclotomic) or isinstance(K, RationalField)): - raise NotImplementedError("Kloosterman sums only currently implemented when the base ring is a cyclotomic field or QQ.") + if not isinstance(K, (sage.rings.abc.NumberField_cyclotomic, + RationalField)): + raise NotImplementedError("Kloosterman sums only currently implemented when the base ring is a cyclotomic field or QQ") phi = K.complex_embedding(prec) CC = phi.codomain() g = 0 diff --git a/src/sage/modular/modform/constructor.py b/src/sage/modular/modform/constructor.py index ffe19d3d708..425015535c6 100644 --- a/src/sage/modular/modform/constructor.py +++ b/src/sage/modular/modform/constructor.py @@ -310,8 +310,8 @@ def ModularForms(group=1, if base_ring is None: base_ring = QQ - if isinstance(group, dirichlet.DirichletCharacter) \ - or isinstance(group, arithgroup.CongruenceSubgroupBase): + if isinstance(group, (dirichlet.DirichletCharacter, + arithgroup.CongruenceSubgroupBase)): level = group.level() else: level = group diff --git a/src/sage/modular/modform/hecke_operator_on_qexp.py b/src/sage/modular/modform/hecke_operator_on_qexp.py index 346a073f20a..5133c7612c9 100644 --- a/src/sage/modular/modform/hecke_operator_on_qexp.py +++ b/src/sage/modular/modform/hecke_operator_on_qexp.py @@ -88,7 +88,7 @@ def hecke_operator_on_qexp(f, n, k, eps=None, # ZZ can coerce to GF(p), but QQ can't. eps = DirichletGroup(1, base_ring=ZZ)[0] if check: - if not (isinstance(f, PowerSeries) or isinstance(f, ModularFormElement)): + if not isinstance(f, (PowerSeries, ModularFormElement)): raise TypeError("f (=%s) must be a power series or modular form" % f) if not isinstance(eps, DirichletCharacter): raise TypeError("eps (=%s) must be a Dirichlet character" % eps) diff --git a/src/sage/modular/modform_hecketriangle/abstract_space.py b/src/sage/modular/modform_hecketriangle/abstract_space.py index 89c86ca41c2..79352b97ffe 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_space.py +++ b/src/sage/modular/modform_hecketriangle/abstract_space.py @@ -263,14 +263,14 @@ def _element_constructor_(self, el): return self.construct_quasi_form(el) if isinstance(el, FreeModuleElement) and (self.module() is P or self.ambient_module() is P): return self.element_from_ambient_coordinates(el) - if (not self.is_ambient()) and (isinstance(el, list) or isinstance(el, tuple) or isinstance(el, FreeModuleElement)) and len(el) == self.rank(): + if not self.is_ambient() and isinstance(el, (list, tuple, FreeModuleElement)) and len(el) == self.rank(): try: return self.element_from_coordinates(el) except (ArithmeticError, TypeError): pass if self.ambient_module() and self.ambient_module().has_coerce_map_from(P): return self.element_from_ambient_coordinates(self.ambient_module()(el)) - if (isinstance(el,list) or isinstance(el, tuple)) and len(el) == self.degree(): + if isinstance(el, (list, tuple)) and len(el) == self.degree(): try: return self.element_from_ambient_coordinates(el) except (ArithmeticError, TypeError): diff --git a/src/sage/modular/overconvergent/genus0.py b/src/sage/modular/overconvergent/genus0.py index 2576c9ddc18..e1df5066186 100644 --- a/src/sage/modular/overconvergent/genus0.py +++ b/src/sage/modular/overconvergent/genus0.py @@ -278,7 +278,7 @@ def OverconvergentModularForms(prime, weight, radius, base_ring=QQ, prec=20, cha Space of 3-adic 1/2-overconvergent modular forms of weight-character (3, 3, [-1]) over Rational Field """ - if isinstance(prime, Gamma0_class) or isinstance(prime, Gamma1_class): + if isinstance(prime, (Gamma0_class, Gamma1_class)): prime = prime.level() else: prime = ZZ(prime) diff --git a/src/sage/modular/overconvergent/hecke_series.py b/src/sage/modular/overconvergent/hecke_series.py index 0b1502d2d9a..455e9e1bad2 100644 --- a/src/sage/modular/overconvergent/hecke_series.py +++ b/src/sage/modular/overconvergent/hecke_series.py @@ -1152,9 +1152,9 @@ def hecke_series(p, N, klist, m, modformsring=False, weightbound=6): oneweight = False # convert single weight to list - if ((isinstance(klist, int)) or (isinstance(klist, Integer))): + if isinstance(klist, (int, Integer)): klist = [klist] - oneweight = True # input is single weight + oneweight = True # input is single weight # algorithm may finish with false output unless: is_valid_weight_list(klist, p) diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py index 7b3d0456147..098fe0ce95f 100644 --- a/src/sage/numerical/optimize.py +++ b/src/sage/numerical/optimize.py @@ -577,7 +577,7 @@ def minimize_constrained(func,cons,x0,gradient=None,algorithm='default', **args) min = optimize.fmin_tnc(f, x0, approx_grad=True, bounds=cons, messages=0, **args)[0] elif isinstance(cons[0], (function_type, Expression)): min = optimize.fmin_cobyla(f, x0, cons, **args) - elif isinstance(cons, function_type) or isinstance(cons, Expression): + elif isinstance(cons, (function_type, Expression)): min = optimize.fmin_cobyla(f, x0, cons, **args) return vector(RDF, min) diff --git a/src/sage/plot/plot3d/plot3d.py b/src/sage/plot/plot3d/plot3d.py index 3b583082a9a..ac3dbf15316 100644 --- a/src/sage/plot/plot3d/plot3d.py +++ b/src/sage/plot/plot3d/plot3d.py @@ -319,7 +319,9 @@ def to_cartesian(self, func, params=None): from sage.structure.element import Expression from sage.rings.real_mpfr import RealNumber from sage.rings.integer import Integer - if params is not None and (isinstance(func, Expression) or isinstance(func, RealNumber) or isinstance(func, Integer)): + if params is not None and isinstance(func, (Expression, + RealNumber, + Integer)): return self.transform(**{ self.dep_var: func, self.indep_vars[0]: params[0], diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index 88df6dfcb9c..e303b3292c3 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -1051,9 +1051,9 @@ def __call__(self, v): Q2 = QuadraticForm(self.base_ring(), m) return QFEvaluateMatrix(self, v, Q2) - elif (isinstance(v, Vector) or isinstance(v, (list, tuple))): + elif isinstance(v, (Vector, list, tuple)): # Check the vector/tuple/list has the correct length - if not (len(v) == n): + if len(v) != n: raise TypeError(f"your vector needs to have length {n}") # TO DO: Check that the elements can be coerced into the base ring of Q -- on first elt. diff --git a/src/sage/quadratic_forms/ternary_qf.py b/src/sage/quadratic_forms/ternary_qf.py index 79436ff4f77..dbc73a90f34 100644 --- a/src/sage/quadratic_forms/ternary_qf.py +++ b/src/sage/quadratic_forms/ternary_qf.py @@ -234,7 +234,7 @@ def __call__(self, v): M[1, 2], M[0, 2], M[0, 1]]) else: return QuadraticForm(ZZ, v.transpose() * self.matrix() * v) - elif (isinstance(v, Vector) or isinstance(v, (list, tuple))): + elif isinstance(v, (Vector, list, tuple)): # Check that v has length 3 if len(v) != 3: raise TypeError("your vector needs to have length 3") diff --git a/src/sage/schemes/affine/affine_space.py b/src/sage/schemes/affine/affine_space.py index b21ac4a7de6..42aeae0e2f9 100755 --- a/src/sage/schemes/affine/affine_space.py +++ b/src/sage/schemes/affine/affine_space.py @@ -109,7 +109,7 @@ def AffineSpace(n, R=None, names=None, ambient_projective_space=None, ... NameError: variable names passed to AffineSpace conflict with names in ring """ - if (isinstance(n, MPolynomialRing_base) or isinstance(n, PolynomialRing_general)) and R is None: + if isinstance(n, (MPolynomialRing_base, PolynomialRing_general)) and R is None: R = n if names is not None: # Check for the case that the user provided a variable name diff --git a/src/sage/schemes/berkovich/berkovich_cp_element.py b/src/sage/schemes/berkovich/berkovich_cp_element.py index cf232a02a71..8e9ee08d2f3 100755 --- a/src/sage/schemes/berkovich/berkovich_cp_element.py +++ b/src/sage/schemes/berkovich/berkovich_cp_element.py @@ -92,7 +92,7 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= # if radius is a list or a tuple, this is a type 4 point if isinstance(radius, (list, tuple)): if error_check: - if not (isinstance(center, list) or isinstance(center, tuple)): + if not isinstance(center, (list, tuple)): raise TypeError("center was passed a list but radius was not a list") if len(radius) != len(center): raise ValueError("the same number of centers and radii " diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index a63dbf57809..a8ea1779005 100755 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -1461,7 +1461,7 @@ def isogeny(self, kernel, codomain=None, degree=None, model=None, check=True, al if kernel is not None: # Check for multiple points or point of known order - kernel_is_list = isinstance(kernel, list) or isinstance(kernel, tuple) + kernel_is_list = isinstance(kernel, (list, tuple)) if kernel_is_list and kernel[0] in self and len(kernel) > 1: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite return EllipticCurveHom_composite(self, kernel, codomain=codomain, model=model, velu_sqrt_bound=velu_sqrt_bound) diff --git a/src/sage/schemes/generic/algebraic_scheme.py b/src/sage/schemes/generic/algebraic_scheme.py index 9a0afa5fb93..a0257a065fd 100755 --- a/src/sage/schemes/generic/algebraic_scheme.py +++ b/src/sage/schemes/generic/algebraic_scheme.py @@ -934,9 +934,9 @@ def __init__(self, A, polynomials, category=None): if isinstance(polynomials, Ideal_generic): I = polynomials polynomials = I.gens() - if I.ring() is R: # Otherwise we will recompute I later after + if I.ring() is R: # Otherwise we will recompute I later after self.__I = I # converting generators to the correct ring - if isinstance(polynomials, tuple) or isinstance(polynomials, PolynomialSequence_generic) or is_iterator(polynomials): + if isinstance(polynomials, (tuple, PolynomialSequence_generic)) or is_iterator(polynomials): polynomials = list(polynomials) elif not isinstance(polynomials, list): # Looks like we got a single polynomial diff --git a/src/sage/schemes/plane_conics/constructor.py b/src/sage/schemes/plane_conics/constructor.py index 38652c9c555..a08089522c2 100755 --- a/src/sage/schemes/plane_conics/constructor.py +++ b/src/sage/schemes/plane_conics/constructor.py @@ -240,7 +240,7 @@ def Conic(base_field, F=None, names=None, unique=True): return ProjectiveConic_rational_field(P2, F) if isinstance(base_field, NumberField): return ProjectiveConic_number_field(P2, F) - if isinstance(base_field, FractionField_generic) and (isinstance(base_field.ring(), PolynomialRing_general) or isinstance(base_field.ring(), MPolynomialRing_base)): + if isinstance(base_field, FractionField_generic) and isinstance(base_field.ring(), (PolynomialRing_general, MPolynomialRing_base)): return ProjectiveConic_rational_function_field(P2, F) return ProjectiveConic_field(P2, F) diff --git a/src/sage/schemes/projective/projective_space.py b/src/sage/schemes/projective/projective_space.py index 9f010391eec..89d4f28f48b 100755 --- a/src/sage/schemes/projective/projective_space.py +++ b/src/sage/schemes/projective/projective_space.py @@ -248,7 +248,7 @@ def ProjectiveSpace(n, R=None, names=None): sage: P.gens() == R.gens() True """ - if (isinstance(n, MPolynomialRing_base) or isinstance(n, PolynomialRing_general)) and R is None: + if isinstance(n, (MPolynomialRing_base, PolynomialRing_general)) and R is None: if names is not None: # Check for the case that the user provided a variable name # That does not match what we wanted to use from R diff --git a/src/sage/schemes/toric/fano_variety.py b/src/sage/schemes/toric/fano_variety.py index 77a14643e4b..220b055cef0 100755 --- a/src/sage/schemes/toric/fano_variety.py +++ b/src/sage/schemes/toric/fano_variety.py @@ -1585,7 +1585,7 @@ def add_variables(field, variables): if isinstance(field, FractionField_generic): # Q(a) ---> Q(a, b) rather than Q(a)(b) R = field.ring() - if isinstance(R, PolynomialRing_general) or isinstance(R, MPolynomialRing_base): + if isinstance(R, (PolynomialRing_general, MPolynomialRing_base)): new_variables = list(R.variable_names()) for v in variables: if v not in new_variables: diff --git a/src/sage/sets/set.py b/src/sage/sets/set.py index 55d5639e706..65278661572 100644 --- a/src/sage/sets/set.py +++ b/src/sage/sets/set.py @@ -492,7 +492,7 @@ def __init__(self, X, category=None): and 'Integer Ring' """ from sage.rings.integer import Integer - if isinstance(X, int) or isinstance(X, Integer): + if isinstance(X, (int, Integer)): # The coercion model will try to call Set_object(0) raise ValueError('underlying object cannot be an integer') From bb99f71d6c88380937b5945105b98d6c066e4c75 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Thu, 17 Oct 2024 01:49:47 +0200 Subject: [PATCH 26/82] skip primes appearing in the denominator of the defining polynomial of a number field --- src/sage/schemes/elliptic_curves/ell_point.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index 8b632a7bd2a..f5d5ee7a41a 100755 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -2612,7 +2612,10 @@ def _has_order_at_least(self, bound, *, attempts=999): n = ZZ.one() no_progress = 0 for p in Primes(): - f,_ = K.defining_polynomial().change_ring(GF(p)).factor()[0] + try: + f,_ = K.defining_polynomial().change_ring(GF(p)).factor()[0] + except ZeroDivisionError: + continue F = GF(p).extension(f,'t') red = lambda elt: F(f.parent()(poly(elt)).change_ring(GF(p)) % f) From c3c28d3cbf4d79cdc43a9042e9befb044de600ad Mon Sep 17 00:00:00 2001 From: grhkm21 <83517584+grhkm21@users.noreply.github.com> Date: Thu, 17 Oct 2024 00:51:59 +0100 Subject: [PATCH 27/82] Update src/sage/schemes/elliptic_curves/ell_field.py oops Co-authored-by: Sebastian A. Spindler <153911337+S17A05@users.noreply.github.com> --- src/sage/schemes/elliptic_curves/ell_field.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index b8463105257..18fcffa891d 100755 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -2107,6 +2107,7 @@ def isogenies_degree(self, n, *, _intermediate=False): sage: js = hilbert_class_polynomial(-23).roots(L, multiplicities=False) sage: E = EllipticCurve(j=choice(js)) sage: len(list(E.isogenies_degree(2^3))) # long time (9s) + 10 TESTS:: From 85a0f0d07b194730285df03c22f233946873ca62 Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Thu, 17 Oct 2024 11:23:40 +0100 Subject: [PATCH 28/82] add tiny speedups for number fields with known possible torsion point groups --- src/sage/schemes/elliptic_curves/ell_field.py | 6 +++--- src/sage/schemes/elliptic_curves/ell_point.py | 8 +++++++- src/sage/schemes/elliptic_curves/hom.py | 3 ++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_field.py b/src/sage/schemes/elliptic_curves/ell_field.py index 18fcffa891d..d6528a31d58 100755 --- a/src/sage/schemes/elliptic_curves/ell_field.py +++ b/src/sage/schemes/elliptic_curves/ell_field.py @@ -2085,9 +2085,9 @@ def isogenies_degree(self, n, *, _intermediate=False): sage: E = EllipticCurve(QQ, [0, 1, 0, -2, 0]) sage: len(list(E.isogenies_degree(2**1))) 3 - sage: len(list(E.isogenies_degree(2**9))) + sage: len(list(E.isogenies_degree(2**5))) 3 - sage: len(list(E.isogenies_degree(2**10))) + sage: len(list(E.isogenies_degree(2**8))) # long time (8s) 1 :: @@ -2097,7 +2097,7 @@ def isogenies_degree(self, n, *, _intermediate=False): sage: E = EllipticCurve(j=-7072/1127*a + 2016) sage: len(list(E.isogenies_degree(2))) 3 - sage: len(list(E.isogenies_degree(2**5))) # long time (4s) + sage: len(list(E.isogenies_degree(2**5))) 3 :: diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index f5d5ee7a41a..e420a43a5ab 100755 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -2598,15 +2598,21 @@ def _has_order_at_least(self, bound, *, attempts=999): from sage.sets.primes import Primes from sage.rings.finite_rings.finite_field_constructor import GF - if self.curve().base_field().absolute_degree() > 1: + field_deg = self.curve().base_field().absolute_degree() + if field_deg > 1: K = self.curve().base_field().absolute_field('T') _, iso = K.structure() E = self.curve().change_ring(iso) P = self.change_ring(iso) poly = lambda elt: elt.polynomial() + if field_deg == 2: + # Kamienny-Kenku-Momose + bound = min(bound, 18 + 1) else: K, E, P = QQ, self.curve(), self poly = lambda elt: QQ['x'](elt) + # Mazur + bound = min(bound, 12 + 1) assert P.curve() is E n = ZZ.one() diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 50ac748d2a2..9e0081a5aca 100755 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -1186,7 +1186,8 @@ def compare_via_evaluation(left, right): elif isinstance(F, number_field_base.NumberField): for _ in range(100): P = E.lift_x(F.random_element(), extend=True) - if P._has_order_at_least(4*d + 1): + if P._has_order_at_least(4*d + 1, attempts=50): + # if P.height(precision=250) == 0: # slow sometimes return left._eval(P) == right._eval(P) else: assert False, "couldn't find a point of large enough order" From 9e1ed90ceaba504b8ddbf4552daa0843087a4a70 Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Thu, 17 Oct 2024 11:28:27 +0100 Subject: [PATCH 29/82] adding fast paths that won't change much --- src/sage/schemes/elliptic_curves/ell_point.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index e420a43a5ab..77d9f6e981d 100755 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -2599,6 +2599,7 @@ def _has_order_at_least(self, bound, *, attempts=999): from sage.sets.primes import Primes from sage.rings.finite_rings.finite_field_constructor import GF field_deg = self.curve().base_field().absolute_degree() + print("field_deg:", field_deg) if field_deg > 1: K = self.curve().base_field().absolute_field('T') _, iso = K.structure() @@ -2615,6 +2616,10 @@ def _has_order_at_least(self, bound, *, attempts=999): bound = min(bound, 12 + 1) assert P.curve() is E + if bound <= 20: + # fast path for testing small orders + return not any((P * i).is_zero() for i in range(1, bound)) + n = ZZ.one() no_progress = 0 for p in Primes(): @@ -2642,6 +2647,7 @@ def _has_order_at_least(self, bound, *, attempts=999): return True if no_progress >= attempts: return + print("n:", n) assert False # unreachable unless there are only finitely many primes From 6d3cb137748dc3f3868ea082331b6e11e21290da Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 18 Sep 2024 10:55:20 -0400 Subject: [PATCH 30/82] src/sage/misc/gperftools.py: update for python3 C functions take bytes, not python strings. Without this, the profiler tries to write to "/", fails, and proceeds to do very little. --- src/sage/misc/gperftools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/gperftools.py b/src/sage/misc/gperftools.py index 8e89dadef6d..ade90910f54 100644 --- a/src/sage/misc/gperftools.py +++ b/src/sage/misc/gperftools.py @@ -162,7 +162,7 @@ def start(self): self._previous_sigprof_handler = self._libc().signal(SIGPROF, SIG_DFL) profiler = self._libprofiler() self._t_start = time.time() - rc = profiler.ProfilerStart(self.filename()) + rc = profiler.ProfilerStart(str.encode(self.filename())) if rc < 0: raise ValueError('profiler failed to start') From 7c161ed3e80c112c467675d00de2a4edbddf760e Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 18 Sep 2024 10:56:56 -0400 Subject: [PATCH 31/82] src/sage/misc/gperftools.py: replace libc shenanigans with cysignals When the profiler is starting, this module goes to a lot of trouble to do... exactly what cysignals is designed to do. And cysignals does not fail on musl. So let's use cysignals instead? --- src/sage/misc/gperftools.py | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/src/sage/misc/gperftools.py b/src/sage/misc/gperftools.py index ade90910f54..056a09d6f97 100644 --- a/src/sage/misc/gperftools.py +++ b/src/sage/misc/gperftools.py @@ -100,28 +100,6 @@ def _repr_(self): """ return 'Profiler logging to {0}'.format(self.filename()) - def _libc(self): - """ - Return libc. - - OUTPUT: a ctypes shared library handle - - EXAMPLES:: - - sage: from sage.misc.gperftools import Profiler - sage: Profiler()._libc() - - """ - global libc - if libc is not None: - return libc - name = find_library('c') - if name: - libc = ctypes.CDLL(name) - return libc - else: - raise ImportError('failed to open libc') - def _libprofiler(self): """ Return libprofiler. @@ -159,7 +137,8 @@ def start(self): PROFILE: interrupts/evictions/bytes = ... """ from signal import SIGPROF, SIG_DFL - self._previous_sigprof_handler = self._libc().signal(SIGPROF, SIG_DFL) + from cysignals.pysignals import setossignal + self._previous_sigprof_handler = setossignal(SIGPROF, SIG_DFL) profiler = self._libprofiler() self._t_start = time.time() rc = profiler.ProfilerStart(str.encode(self.filename())) From 1b1cdefec0730e0cae1b7f524cd3f5a9a214f195 Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Thu, 17 Oct 2024 13:48:10 +0100 Subject: [PATCH 32/82] remove debug --- src/sage/schemes/elliptic_curves/ell_point.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index 77d9f6e981d..e420a43a5ab 100755 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -2599,7 +2599,6 @@ def _has_order_at_least(self, bound, *, attempts=999): from sage.sets.primes import Primes from sage.rings.finite_rings.finite_field_constructor import GF field_deg = self.curve().base_field().absolute_degree() - print("field_deg:", field_deg) if field_deg > 1: K = self.curve().base_field().absolute_field('T') _, iso = K.structure() @@ -2616,10 +2615,6 @@ def _has_order_at_least(self, bound, *, attempts=999): bound = min(bound, 12 + 1) assert P.curve() is E - if bound <= 20: - # fast path for testing small orders - return not any((P * i).is_zero() for i in range(1, bound)) - n = ZZ.one() no_progress = 0 for p in Primes(): @@ -2647,7 +2642,6 @@ def _has_order_at_least(self, bound, *, attempts=999): return True if no_progress >= attempts: return - print("n:", n) assert False # unreachable unless there are only finitely many primes From 38791fa5e964dea6fc524bfaa47a96d26a0e1938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 17 Oct 2024 18:49:03 +0200 Subject: [PATCH 33/82] let the category setup handle the ideals --- src/sage/categories/fields.py | 20 +++ src/sage/categories/rings.py | 98 ++++++++----- src/sage/rings/number_field/number_field.py | 5 +- .../rings/polynomial/multi_polynomial_ring.py | 28 ---- src/sage/rings/ring.pyx | 129 ------------------ 5 files changed, 88 insertions(+), 192 deletions(-) diff --git a/src/sage/categories/fields.py b/src/sage/categories/fields.py index dafa795f94f..9e4238c31a0 100644 --- a/src/sage/categories/fields.py +++ b/src/sage/categories/fields.py @@ -458,6 +458,26 @@ def fraction_field(self): """ return self + def ideal(self, *gens, **kwds): + """ + Return the ideal generated by gens. + + EXAMPLES:: + + sage: QQ.ideal(2) + Principal ideal (1) of Rational Field + sage: QQ.ideal(0) + Principal ideal (0) of Rational Field + """ + if len(gens) == 1 and isinstance(gens[0], (list, tuple)): + gens = gens[0] + if not isinstance(gens, (list, tuple)): + gens = [gens] + for x in gens: + if not self(x).is_zero(): + return self.unit_ideal() + return self.zero_ideal() + def _squarefree_decomposition_univariate_polynomial(self, f): r""" Return the square-free decomposition of ``f`` over this field. diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 781f1a1462b..7a80a32e2d8 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -12,12 +12,14 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** from functools import reduce +from types import GeneratorType from sage.misc.cachefunc import cached_method from sage.misc.lazy_import import LazyImport from sage.categories.category_with_axiom import CategoryWithAxiom from sage.categories.rngs import Rngs from sage.structure.element import Element +from sage.structure.parent import Parent class Rings(CategoryWithAxiom): @@ -815,32 +817,34 @@ def ideal(self, *args, **kwds): """ Create an ideal of this ring. - .. NOTE:: + INPUT: - The code is copied from the base class - :class:`~sage.rings.ring.Ring`. This is - because there are rings that do not inherit - from that class, such as matrix algebras. - See :issue:`7797`. + - an element or a list/tuple/sequence of elements, the generators - INPUT: + - ``coerce`` -- boolean (default: ``True``); whether to first coerce + the elements into this ring. This must be a keyword + argument. Only set it to ``False`` if you are certain that each + generator is already in the ring. - - an element or a list/tuple/sequence of elements - - ``coerce`` -- boolean (default: ``True``); - first coerce the elements into this ring - - ``side`` -- (optional) string, one of ``'twosided'`` - (default), ``'left'``, ``'right'``; determines - whether the resulting ideal is twosided, a left - ideal or a right ideal + - ``ideal_class`` -- callable (default: ``self._ideal_class_()``); + this must be a keyword argument. A constructor for ideals, taking + the ring as the first argument and then the generators. + Usually a subclass of :class:`~sage.rings.ideal.Ideal_generic` or + :class:`~sage.rings.noncommutative_ideals.Ideal_nc`. - EXAMPLES:: + - Further named arguments (such as ``side`` in the case of + non-commutative rings) are forwarded to the ideal class. + + The keyword ``side`` can be one of ``'twosided'``, + ``'left'``, ``'right'``. It determines whether + the resulting ideal is twosided, a left ideal or a right ideal. + + EXAMPLES: + + Matrix rings:: sage: # needs sage.modules sage: MS = MatrixSpace(QQ, 2, 2) - sage: isinstance(MS, Ring) - False - sage: MS in Rings() - True sage: MS.ideal(2) Twosided Ideal ( @@ -858,6 +862,36 @@ def ideal(self, *args, **kwds): [0 0] ) of Full MatrixSpace of 2 by 2 dense matrices over Rational Field + + Polynomial rings:: + + sage: R. = QQ[] + sage: R.ideal(x,y) + Ideal (x, y) of Multivariate Polynomial Ring in x, y over Rational Field + sage: R.ideal(x+y^2) + Ideal (y^2 + x) of Multivariate Polynomial Ring in x, y over Rational Field + sage: R.ideal( [x^3,y^3+x^3] ) + Ideal (x^3, x^3 + y^3) of Multivariate Polynomial Ring in x, y over Rational Field + + Non-commutative rings:: + + sage: A = SteenrodAlgebra(2) # needs sage.combinat sage.modules + sage: A.ideal(A.1, A.2^2) # needs sage.combinat sage.modules + Twosided Ideal (Sq(2), Sq(2,2)) of mod 2 Steenrod algebra, milnor basis + sage: A.ideal(A.1, A.2^2, side='left') # needs sage.combinat sage.modules + Left Ideal (Sq(2), Sq(2,2)) of mod 2 Steenrod algebra, milnor basis + + TESTS: + + Make sure that :issue:`11139` is fixed:: + + sage: R. = QQ[] + sage: R.ideal([]) + Principal ideal (0) of Univariate Polynomial Ring in x over Rational Field + sage: R.ideal(()) + Principal ideal (0) of Univariate Polynomial Ring in x over Rational Field + sage: R.ideal() + Principal ideal (0) of Univariate Polynomial Ring in x over Rational Field """ if 'coerce' in kwds: coerce = kwds['coerce'] @@ -866,8 +900,7 @@ def ideal(self, *args, **kwds): coerce = True from sage.rings.ideal import Ideal_generic - from types import GeneratorType - if len(args) == 0: + if not args: gens = [self(0)] else: gens = args @@ -888,27 +921,26 @@ def ideal(self, *args, **kwds): break elif isinstance(first, (list, tuple, GeneratorType)): gens = first + elif isinstance(first, Parent) and self.has_coerce_map_from(first): + gens = first.gens() # we have a ring as argument else: - try: - if self.has_coerce_map_from(first): - gens = first.gens() # we have a ring as argument - elif isinstance(first, Element): - gens = [first] - else: - raise ArithmeticError("there is no coercion from %s to %s" % (first, self)) - except TypeError: # first may be a ring element - pass break - if coerce: + + if len(gens) == 0: + gens = [self.zero()] + elif coerce: gens = [self(g) for g in gens] + from sage.categories.principal_ideal_domains import PrincipalIdealDomains if self in PrincipalIdealDomains(): # Use GCD algorithm to obtain a principal ideal g = gens[0] if len(gens) == 1: try: - g = g.gcd(g) # note: we set g = gcd(g, g) to "canonicalize" the generator: make polynomials monic, etc. - except (AttributeError, NotImplementedError): + # note: we set g = gcd(g, g) to "canonicalize" the generator: + # make polynomials monic, etc. + g = g.gcd(g) + except (AttributeError, NotImplementedError, IndexError): pass else: for h in gens[1:]: diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index bb16476980e..4a424c36279 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -3534,7 +3534,7 @@ def ideal(self, *gens, **kwds): try: return self.fractional_ideal(*gens, **kwds) except ValueError: - return Ring.ideal(self, gens, **kwds) + return self.zero_ideal() def idealchinese(self, ideals, residues): r""" @@ -3600,9 +3600,10 @@ def idealchinese(self, ideals, residues): def fractional_ideal(self, *gens, **kwds): r""" Return the ideal in `\mathcal{O}_K` generated by ``gens``. + This overrides the :class:`sage.rings.ring.Field` method to use the :class:`sage.rings.ring.Ring` one instead, since - we're not really concerned with ideals in a field but in its ring + we are not concerned with ideals in a field but in its ring of integers. INPUT: diff --git a/src/sage/rings/polynomial/multi_polynomial_ring.py b/src/sage/rings/polynomial/multi_polynomial_ring.py index 41cc1fb7c87..43f1c0f6294 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring.py +++ b/src/sage/rings/polynomial/multi_polynomial_ring.py @@ -949,31 +949,3 @@ def is_field(self, proof=True): if self.ngens() == 0: return self.base_ring().is_field(proof) return False - - def ideal(self, *gens, **kwds): - """ - Create an ideal in this polynomial ring. - """ - do_coerce = False - if len(gens) == 1: - from sage.rings.ideal import Ideal_generic - if isinstance(gens[0], Ideal_generic): - if gens[0].ring() is self: - return gens[0] - gens = gens[0].gens() - elif isinstance(gens[0], (list, tuple)): - gens = gens[0] - if not self._has_singular: - # pass through - MPolynomialRing_base.ideal(self, gens, **kwds) - - from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal - - if isinstance(gens, (sage.interfaces.abc.SingularElement, sage.interfaces.abc.Macaulay2Element)): - gens = list(gens) - do_coerce = True - elif not isinstance(gens, (list, tuple)): - gens = [gens] - if ('coerce' in kwds and kwds['coerce']) or do_coerce: - gens = [self(x) for x in gens] # this will even coerce from singular ideals correctly! - return MPolynomialIdeal(self, gens, **kwds) diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index d139c1449c5..d964201a095 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -361,115 +361,6 @@ cdef class Ring(ParentWithGens): # initialisation has finished. return self._category or _Rings - def ideal(self, *args, **kwds): - """ - Return the ideal defined by ``x``, i.e., generated by ``x``. - - INPUT: - - - ``*x`` -- list or tuple of generators (or several input arguments) - - - ``coerce`` -- boolean (default: ``True``); this must be a keyword - argument. Only set it to ``False`` if you are certain that each - generator is already in the ring. - - - ``ideal_class`` -- callable (default: ``self._ideal_class_()``); - this must be a keyword argument. A constructor for ideals, taking - the ring as the first argument and then the generators. - Usually a subclass of :class:`~sage.rings.ideal.Ideal_generic` or - :class:`~sage.rings.noncommutative_ideals.Ideal_nc`. - - - Further named arguments (such as ``side`` in the case of - non-commutative rings) are forwarded to the ideal class. - - EXAMPLES:: - - sage: R. = QQ[] - sage: R.ideal(x,y) - Ideal (x, y) of Multivariate Polynomial Ring in x, y over Rational Field - sage: R.ideal(x+y^2) - Ideal (y^2 + x) of Multivariate Polynomial Ring in x, y over Rational Field - sage: R.ideal( [x^3,y^3+x^3] ) - Ideal (x^3, x^3 + y^3) of Multivariate Polynomial Ring in x, y over Rational Field - - Here is an example over a non-commutative ring:: - - sage: A = SteenrodAlgebra(2) # needs sage.combinat sage.modules - sage: A.ideal(A.1, A.2^2) # needs sage.combinat sage.modules - Twosided Ideal (Sq(2), Sq(2,2)) of mod 2 Steenrod algebra, milnor basis - sage: A.ideal(A.1, A.2^2, side='left') # needs sage.combinat sage.modules - Left Ideal (Sq(2), Sq(2,2)) of mod 2 Steenrod algebra, milnor basis - - TESTS: - - Make sure that :issue:`11139` is fixed:: - - sage: R. = QQ[] - sage: R.ideal([]) - Principal ideal (0) of Univariate Polynomial Ring in x over Rational Field - sage: R.ideal(()) - Principal ideal (0) of Univariate Polynomial Ring in x over Rational Field - sage: R.ideal() - Principal ideal (0) of Univariate Polynomial Ring in x over Rational Field - """ - if 'coerce' in kwds: - coerce = kwds['coerce'] - del kwds['coerce'] - else: - coerce = True - - from sage.rings.ideal import Ideal_generic - from sage.structure.parent import Parent - gens = args - while isinstance(gens, (list, tuple)) and len(gens) == 1: - first = gens[0] - if isinstance(first, Ideal_generic): - R = first.ring() - m = self.convert_map_from(R) - if m is not None: - gens = [m(g) for g in first.gens()] - coerce = False - else: - m = R.convert_map_from(self) - if m is not None: - raise NotImplementedError - else: - raise TypeError - break - elif isinstance(first, (list, tuple)): - gens = first - elif isinstance(first, Parent) and self.has_coerce_map_from(first): - gens = first.gens() # we have a ring as argument - else: - break - - if len(gens) == 0: - gens = [self.zero()] - - if coerce: - gens = [self(g) for g in gens] - if self in PrincipalIdealDomains(): - # Use GCD algorithm to obtain a principal ideal - g = gens[0] - if len(gens) == 1: - try: - # note: we set g = gcd(g, g) to "canonicalize" the generator: make polynomials monic, etc. - g = g.gcd(g) - except (AttributeError, NotImplementedError, IndexError): - pass - else: - for h in gens[1:]: - g = g.gcd(h) - gens = [g] - if 'ideal_class' in kwds: - C = kwds['ideal_class'] - del kwds['ideal_class'] - else: - C = self._ideal_class_(len(gens)) - if len(gens) == 1 and isinstance(gens[0], (list, tuple)): - gens = gens[0] - return C(self, gens, **kwds) - def __mul__(self, x): """ Return the ideal ``x*R`` generated by ``x``, where ``x`` is either an @@ -1382,26 +1273,6 @@ cdef class Field(CommutativeRing): return y.is_zero() return True - def ideal(self, *gens, **kwds): - """ - Return the ideal generated by gens. - - EXAMPLES:: - - sage: QQ.ideal(2) - Principal ideal (1) of Rational Field - sage: QQ.ideal(0) - Principal ideal (0) of Rational Field - """ - if len(gens) == 1 and isinstance(gens[0], (list, tuple)): - gens = gens[0] - if not isinstance(gens, (list, tuple)): - gens = [gens] - for x in gens: - if not self(x).is_zero(): - return self.unit_ideal() - return self.zero_ideal() - def integral_closure(self): """ Return this field, since fields are integrally closed in their From 9bc8d5aa515d2f1c9a895f134aab1e078ebd53f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 17 Oct 2024 20:35:19 +0200 Subject: [PATCH 34/82] fix doctest in doc/ --- src/doc/en/thematic_tutorials/coercion_and_categories.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index 8db70ca5e3e..dc273e46faa 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -128,7 +128,6 @@ This base class provides a lot more methods than a general parent:: 'fraction_field', 'gen', 'gens', - 'ideal', 'integral_closure', 'is_commutative', 'is_field', From 69e7af663abafd7deebd68c6f396ba5a363b9381 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Tue, 22 Oct 2024 16:47:19 +0700 Subject: [PATCH 35/82] Remove redundant modulo operation in vector_modn_dense --- src/sage/modules/vector_modn_dense.pyx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/sage/modules/vector_modn_dense.pyx b/src/sage/modules/vector_modn_dense.pyx index 79e27b5b3b9..4c7d933321e 100644 --- a/src/sage/modules/vector_modn_dense.pyx +++ b/src/sage/modules/vector_modn_dense.pyx @@ -168,8 +168,22 @@ cdef class Vector_modn_dense(free_module_element.FreeModuleElement): self._init(parent.degree(), parent, parent.base_ring().order()) def __init__(self, parent, x, coerce=True, copy=True): + """ + Create an element. + + Note that ``coerce=False`` is dangerous:: + + sage: V = VectorSpace(GF(7), 3) + sage: v = V([2, 9, -5], coerce=False) + sage: v[0] == v[1] + False + sage: v[0]+1 == v[1]+1 + True + sage: v[0] == v[2] + False + """ cdef Py_ssize_t i - cdef mod_int a, p + cdef mod_int a if isinstance(x, xrange): x = tuple(x) if isinstance(x, (list, tuple)): @@ -177,10 +191,9 @@ cdef class Vector_modn_dense(free_module_element.FreeModuleElement): raise TypeError("x must be a list of the right length") if coerce: R = parent.base_ring() - p = R.order() for i from 0 <= i < self._degree: a = int(R(x[i])) - self._entries[i] = a % p + self._entries[i] = a else: for i from 0 <= i < self._degree: self._entries[i] = x[i] From 326c57718ac93ec2fb3d88d03e345e30a927cc8b Mon Sep 17 00:00:00 2001 From: dcoudert Date: Wed, 23 Oct 2024 16:39:20 +0200 Subject: [PATCH 36/82] fix issue #38832 --- src/sage/graphs/bipartite_graph.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/bipartite_graph.py b/src/sage/graphs/bipartite_graph.py index 45e4c67747d..1be201822c5 100644 --- a/src/sage/graphs/bipartite_graph.py +++ b/src/sage/graphs/bipartite_graph.py @@ -2633,11 +2633,29 @@ class by some canonization function `c`. If `G` and `H` are graphs, sage: C.right {4, 5, 6} + TESTS: + + Check that :issue:`38832` is fixed:: + + sage: B = BipartiteGraph(matrix([[1, 1], [1, 1]])) + sage: C = B.canonical_label() + sage: C.left, C.right + ({0, 1}, {2, 3}) + sage: B.canonical_label(certificate=True) + (Bipartite graph on 4 vertices, {0: 0, 1: 1, 2: 2, 3: 3}) + sage: C = B.canonical_label(edge_labels=True) + sage: C.left, C.right + ({0, 1}, {2, 3}) + sage: B.allow_multiple_edges(True) + sage: B.add_edges(G.edges()) + sage: C = B.canonical_label() + sage: C.left, C.right + ({0, 1}, {2, 3}) + .. SEEALSO:: :meth:`~sage.graphs.generic_graph.GenericGraph.canonical_label()` """ - if certificate: C, cert = GenericGraph.canonical_label(self, partition=partition, certificate=certificate, @@ -2669,6 +2687,8 @@ class by some canonization function `c`. If `G` and `H` are graphs, cert = {v: c[G_to[relabeling[v]]] for v in self} else: + if partition is None: + partition = self.bipartition() G_vertices = list(chain(*partition)) G_to = {u: i for i, u in enumerate(G_vertices)} H = Graph(len(G_vertices)) From 864bcdb57320edd29cb26f7a32d5bfa8b92746cc Mon Sep 17 00:00:00 2001 From: dcoudert Date: Wed, 23 Oct 2024 17:39:38 +0200 Subject: [PATCH 37/82] #38842: fix doctests --- src/sage/graphs/bipartite_graph.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/graphs/bipartite_graph.py b/src/sage/graphs/bipartite_graph.py index 1be201822c5..240b62c7c96 100644 --- a/src/sage/graphs/bipartite_graph.py +++ b/src/sage/graphs/bipartite_graph.py @@ -2641,13 +2641,14 @@ class by some canonization function `c`. If `G` and `H` are graphs, sage: C = B.canonical_label() sage: C.left, C.right ({0, 1}, {2, 3}) - sage: B.canonical_label(certificate=True) - (Bipartite graph on 4 vertices, {0: 0, 1: 1, 2: 2, 3: 3}) + sage: C, certificate = B.canonical_label(certificate=True) + sage: C.left, C.right + ({0, 1}, {2, 3}) sage: C = B.canonical_label(edge_labels=True) sage: C.left, C.right ({0, 1}, {2, 3}) sage: B.allow_multiple_edges(True) - sage: B.add_edges(G.edges()) + sage: B.add_edges(B.edges()) sage: C = B.canonical_label() sage: C.left, C.right ({0, 1}, {2, 3}) From ddad107c93659448b0f0715c9382c699ebd21fdf Mon Sep 17 00:00:00 2001 From: dcoudert Date: Wed, 23 Oct 2024 18:04:07 +0200 Subject: [PATCH 38/82] #38842: make doctests more robusts --- src/sage/graphs/bipartite_graph.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/sage/graphs/bipartite_graph.py b/src/sage/graphs/bipartite_graph.py index 240b62c7c96..e21ec47e9cf 100644 --- a/src/sage/graphs/bipartite_graph.py +++ b/src/sage/graphs/bipartite_graph.py @@ -2638,20 +2638,16 @@ class by some canonization function `c`. If `G` and `H` are graphs, Check that :issue:`38832` is fixed:: sage: B = BipartiteGraph(matrix([[1, 1], [1, 1]])) - sage: C = B.canonical_label() - sage: C.left, C.right - ({0, 1}, {2, 3}) - sage: C, certificate = B.canonical_label(certificate=True) - sage: C.left, C.right - ({0, 1}, {2, 3}) - sage: C = B.canonical_label(edge_labels=True) - sage: C.left, C.right - ({0, 1}, {2, 3}) + sage: B.canonical_label() + Bipartite graph on 4 vertices + sage: B.canonical_label(certificate=True)[0] + Bipartite graph on 4 vertices + sage: B.canonical_label(edge_labels=True) + Bipartite graph on 4 vertices sage: B.allow_multiple_edges(True) sage: B.add_edges(B.edges()) - sage: C = B.canonical_label() - sage: C.left, C.right - ({0, 1}, {2, 3}) + sage: B.canonical_label() + Bipartite multi-graph on 4 vertices .. SEEALSO:: From 8114639c181d6f6d95e3b6194827da2b7e82f6e4 Mon Sep 17 00:00:00 2001 From: Kyle Hofmann Date: Wed, 23 Oct 2024 18:49:32 -0700 Subject: [PATCH 39/82] Add algorithm description --- src/doc/en/reference/references/index.rst | 3 ++ .../rings/finite_rings/integer_mod_ring.py | 48 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 59b28d9e9be..9a2366df552 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -2917,6 +2917,9 @@ REFERENCES: "Pyjamask" https://csrc.nist.gov/CSRC/media/Projects/Lightweight-Cryptography/documents/round-1/spec-doc/Pyjamask-spec.pdf +.. [Gouvea] Fernando Q. Gouvêa, *$p$-adic Numbers: An Introduction*, + Third Edition. Springer Nature Switzerland AG, 2020. + .. [GJK+2014] Dimitar Grantcharov, Ji Hye Jung, Seok-Jin Kang, Masaki Kashiwara, Myungho Kim. *Crystal bases for the quantum queer superalgebra and semistandard decomposition tableaux.*; Trans. Amer. Math. Soc., diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index 224440cf3cb..f86b2a6e0bd 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -1717,15 +1717,55 @@ def _roots_univariate_polynomial(self, f, ring=None, multiplicities=True, algori ensures that the only cases we need to handle are ``self`` and ``None``. Otherwise we raise ``NotImplementedError``. - - ``multiplicities`` - bool (default: ``True``) if ``True`` - return list of pairs `(r, n)`, where `r` is the root and `n` is the + - ``multiplicities`` - bool (default: ``True``). If ``True``, return + list of pairs `(r, n)`, where `r` is a root and `n` is its multiplicity. If ``False``, just return the unique roots, with no information about multiplicities. Multiplicities are only defined - over fields, and this method raises ``NotImplementedError`` if - this is ``True`` but the ring is not a field. + over fields, and this method raises ``NotImplementedError`` if this + is ``True`` but the ring is not a field. - ``algorithm`` - ignored + ALGORITHM: + + The algorithm is adapted from [Gouvea], section 4.5, and [Coh1993], + section 3.5.3. It is a combination of the Chinese Remainder Theorem + and Hensel's lemma. As a base case, if $N$ is prime, then we find + roots by factoring $f$. If $N$ is a prime power $p^e$, then we find + roots modulo $p$ and lift them. Finally, for general $N$, we first + factor the modulus $N$ into prime powers, list all roots modulo those + prime powers, and combine the roots using the Chinese Remainder + Theorem. + + Suppose that we are trying to find roots modulo $p^e$ and that $r$ is + a root of $f(x)$ modulo $p$. The easy case is when $f'(r) \not\equiv + 0 \pmod{p}$, for then Hensel's lemma implies that there is a unique + $r_e \in \mathbf{Z}/p^e\mathbf{Z}$ with $r_e \equiv r \pmod{p}$. + Moreover, this $r_e$ can be found by applying Newton's method for + numerically approximating roots. Each iteration of Newton's method + doubles the precision to which the root is known. + + But if $f'(r) \equiv 0 \pmod{p}$, then this is no longer true. In + fact, in this case roots modulo $p^e$ are not the same as $p$-adic + roots, and finding all the latter does not guarantee that we have + found all the former. For example, if $f(x) = 2x$ and $p = 2$, then + there is only one $p$-adic root, namely zero. But the roots of $2x + \equiv 0 \pmod{2^k}$ are $0$ and $2^{k-1}$; the former lifts to two + roots modulo $2^{k+1}$, namely $0$ and $2^k$, while the latter does + not lift at all. We handle this case by lifting one power at a time. + While we can no longer use Newton's method to solve for a lift, the + Taylor series it is based on still yields constraints on the roots + modulo $p^{k+1}$: If $r_k$ is a root of $f$ modulo $p^k$, then either + every lift of $r_k$ to $\mathbf{Z}/p^{k+1}\mathbf{Z}$ is a root of $f$ + modulo $p^{k+1}$ or none of them are. Consequently we may find roots + modulo $p^e$ by lifting one power at a time. + + When $f'(r) \equiv 0 \pmod{p}$, Hensel's lemma still applies once we + are close enough to a $p$-adic root (see [Gouvea], problem 120). + However, it seems delicate to use this to find all roots modulo $p^e$ + (consider our earlier example of $f(x) = 2x$). For that reason, this + method presently does not attempt to apply Hensel's lemma in this way. + EXAMPLES:: sage: R. = Zmod(41)[] From 515f3cb9c4d244e5a6fa1bb43948e8f385bdfe5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 24 Oct 2024 11:35:17 +0200 Subject: [PATCH 40/82] default value for format should be None in tikz method of graph --- src/sage/graphs/generic_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 862c4ee15a0..cb22e9e0d9c 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -939,7 +939,7 @@ def _latex_(self): return self.latex_options().latex() - def tikz(self, format='dot2tex', edge_labels=None, + def tikz(self, format=None, edge_labels=None, color_by_label=False, prog='dot', rankdir='down', standalone_config=None, usepackage=None, usetikzlibrary=None, macros=None, From 64c66bbc9cc7fbd6cbcfdc1aec68451b83dde9fb Mon Sep 17 00:00:00 2001 From: Kyle Hofmann Date: Thu, 24 Oct 2024 18:15:47 -0700 Subject: [PATCH 41/82] Apply suggestions from code review Co-authored-by: Vincent Macri --- src/doc/en/reference/references/index.rst | 2 +- src/sage/rings/finite_rings/integer_mod_ring.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 2e2e75d483b..3d548b48511 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -2921,7 +2921,7 @@ REFERENCES: "Pyjamask" https://csrc.nist.gov/CSRC/media/Projects/Lightweight-Cryptography/documents/round-1/spec-doc/Pyjamask-spec.pdf -.. [Gouvea] Fernando Q. Gouvêa, *$p$-adic Numbers: An Introduction*, +.. [Gou2020] Fernando Q. Gouvêa, *$p$-adic Numbers: An Introduction*, Third Edition. Springer Nature Switzerland AG, 2020. .. [GJK+2014] Dimitar Grantcharov, Ji Hye Jung, Seok-Jin Kang, Masaki Kashiwara, diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index f86b2a6e0bd..345492c280c 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -1728,7 +1728,7 @@ def _roots_univariate_polynomial(self, f, ring=None, multiplicities=True, algori ALGORITHM: - The algorithm is adapted from [Gouvea], section 4.5, and [Coh1993], + The algorithm is adapted from [Gou2020]_, section 4.5, and [Coh1993]_, section 3.5.3. It is a combination of the Chinese Remainder Theorem and Hensel's lemma. As a base case, if $N$ is prime, then we find roots by factoring $f$. If $N$ is a prime power $p^e$, then we find From f319e36cffe32988f70eaba0e076f2ffb944c01d Mon Sep 17 00:00:00 2001 From: Kyle Hofmann Date: Thu, 24 Oct 2024 19:03:09 -0700 Subject: [PATCH 42/82] Formatting changes; improve exposition --- .../rings/finite_rings/integer_mod_ring.py | 60 ++++++++++--------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index 345492c280c..4987484d643 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -1730,41 +1730,45 @@ def _roots_univariate_polynomial(self, f, ring=None, multiplicities=True, algori The algorithm is adapted from [Gou2020]_, section 4.5, and [Coh1993]_, section 3.5.3. It is a combination of the Chinese Remainder Theorem - and Hensel's lemma. As a base case, if $N$ is prime, then we find - roots by factoring $f$. If $N$ is a prime power $p^e$, then we find - roots modulo $p$ and lift them. Finally, for general $N$, we first - factor the modulus $N$ into prime powers, list all roots modulo those + and Hensel's lemma. As a base case, if `N` is prime, then we find + roots by factoring `f`. If `N` is a prime power `p^e`, then we find + roots modulo `p` and lift them. Finally, for general `N`, we first + factor the modulus `N` into prime powers, list all roots modulo those prime powers, and combine the roots using the Chinese Remainder Theorem. - Suppose that we are trying to find roots modulo $p^e$ and that $r$ is - a root of $f(x)$ modulo $p$. The easy case is when $f'(r) \not\equiv - 0 \pmod{p}$, for then Hensel's lemma implies that there is a unique - $r_e \in \mathbf{Z}/p^e\mathbf{Z}$ with $r_e \equiv r \pmod{p}$. - Moreover, this $r_e$ can be found by applying Newton's method for + Suppose that we are trying to find roots modulo `p^e` and that `r` is + a root of `f(x)` modulo `p`. The easy case is when `f'(r) \not\equiv + 0 \pmod{p}`, for then Hensel's lemma implies that there is a unique + `r_e \in \mathbf{Z}/p^e\mathbf{Z}` with `r_e \equiv r \pmod{p}`. + Moreover, this `r_e` can be found by applying Newton's method for numerically approximating roots. Each iteration of Newton's method doubles the precision to which the root is known. - But if $f'(r) \equiv 0 \pmod{p}$, then this is no longer true. In - fact, in this case roots modulo $p^e$ are not the same as $p$-adic + But if `f'(r) \equiv 0 \pmod{p}`, then this is no longer true. In + fact, in this case roots modulo `p^e` are not the same as `p`-adic roots, and finding all the latter does not guarantee that we have - found all the former. For example, if $f(x) = 2x$ and $p = 2$, then - there is only one $p$-adic root, namely zero. But the roots of $2x - \equiv 0 \pmod{2^k}$ are $0$ and $2^{k-1}$; the former lifts to two - roots modulo $2^{k+1}$, namely $0$ and $2^k$, while the latter does - not lift at all. We handle this case by lifting one power at a time. - While we can no longer use Newton's method to solve for a lift, the - Taylor series it is based on still yields constraints on the roots - modulo $p^{k+1}$: If $r_k$ is a root of $f$ modulo $p^k$, then either - every lift of $r_k$ to $\mathbf{Z}/p^{k+1}\mathbf{Z}$ is a root of $f$ - modulo $p^{k+1}$ or none of them are. Consequently we may find roots - modulo $p^e$ by lifting one power at a time. - - When $f'(r) \equiv 0 \pmod{p}$, Hensel's lemma still applies once we - are close enough to a $p$-adic root (see [Gouvea], problem 120). - However, it seems delicate to use this to find all roots modulo $p^e$ - (consider our earlier example of $f(x) = 2x$). For that reason, this - method presently does not attempt to apply Hensel's lemma in this way. + found all the former. For example, if `f(x) = 2x` and `p = 2`, then + there is only one `p`-adic root, namely zero. But the solutions of + `2x \equiv 0 \pmod{2^k}` are `0` and `2^{k-1}`; the former lifts to + two roots modulo `2^{k+1}`, namely `0` and `2^k`, while the latter + does not lift at all. We handle this case by lifting one power at a + time. While we can no longer use Newton's method to solve for a lift, + the Taylor series it is based on still yields constraints on the roots + modulo `p^{k+1}`: If `r_k` is a root of `f` modulo `p^k`, then either + every lift of `r_k` to `\mathbf{Z}/p^{k+1}\mathbf{Z}` is a root of `f` + modulo `p^{k+1}` or none of them are. Consequently we may find roots + modulo `p^e` by lifting one power at a time. + + When `f'(r) \equiv 0 \pmod{p}`, an alternative approach is to change + variables, factor out the root, and then factor out powers of `p`. + This has the advantage that it will eventually reach a situation where + the lift converges quadratically, but it is not presently implemented. + A different form of Hensel's lemma applies once we are close enough to + a `p`-adic root (see [Gou2020]_, problem 120), but it seems delicate + to use it directly to find all roots modulo `p^e` (consider our + earlier example of `f(x) = 2x`), so we do not presently attempt to + apply Hensel's lemma in this way. EXAMPLES:: From 02f96fedb2cb8732c3f50771c2202e7e141a6918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Janek?= <106813190+janekj2727@users.noreply.github.com> Date: Fri, 25 Oct 2024 13:37:37 +0200 Subject: [PATCH 43/82] Add conversion dictionaries to trig.py Add conversion of tan, cot, sec and csc functions to trig.py --- src/sage/functions/trig.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/sage/functions/trig.py b/src/sage/functions/trig.py index f912dd79e8f..c60aada0243 100644 --- a/src/sage/functions/trig.py +++ b/src/sage/functions/trig.py @@ -261,7 +261,9 @@ def __init__(self): sage: tan(2+I).imag().n() # needs sage.symbolic 1.16673625724092 """ - GinacFunction.__init__(self, 'tan', latex_name=r"\tan") + GinacFunction.__init__(self, 'tan', latex_name=r"\tan", + conversions=dict(maxima='tan', mathematica='Tan', + giac='tan', fricas='tan', sympy='tan')) tan = Function_tan() @@ -349,7 +351,9 @@ def __init__(self): sage: cot(1.+I) # needs sage.symbolic 0.217621561854403 - 0.868014142895925*I """ - GinacFunction.__init__(self, 'cot', latex_name=r"\cot") + GinacFunction.__init__(self, 'cot', latex_name=r"\cot", + conversions=dict(maxima='cot', mathematica='Cot', + giac='cot', fricas='cot', sympy='cot')) def _eval_numpy_(self, x): """ @@ -421,7 +425,9 @@ def __init__(self): sage: sec(complex(1,1)) # rel tol 1e-15 # needs sage.rings.complex_double (0.49833703055518686+0.5910838417210451j) """ - GinacFunction.__init__(self, 'sec', latex_name=r"\sec") + GinacFunction.__init__(self, 'sec', latex_name=r"\sec", + conversions=dict(maxima='sec', mathematica='Sec', + giac='sec', fricas='sec', sympy='sec')) def _eval_numpy_(self, x): """ @@ -493,7 +499,9 @@ def __init__(self): sage: csc(complex(1,1)) # rel tol 1e-15 # needs sage.rings.complex_double (0.6215180171704284-0.30393100162842646j) """ - GinacFunction.__init__(self, 'csc', latex_name=r"\csc") + GinacFunction.__init__(self, 'csc', latex_name=r"\csc", + conversions=dict(maxima='csc', mathematica='Csc', + giac='csc', fricas='csc', sympy='csc')) def _eval_numpy_(self, x): """ From efc94b46adee141357a781265fc1f2e131df073b Mon Sep 17 00:00:00 2001 From: Vincent Macri Date: Fri, 25 Oct 2024 12:46:02 -0600 Subject: [PATCH 44/82] Add LaTeX representation for function fields --- .../function_field/function_field_polymod.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/function_field/function_field_polymod.py b/src/sage/rings/function_field/function_field_polymod.py index de6cbf47a6c..c5e6d459d7f 100644 --- a/src/sage/rings/function_field/function_field_polymod.py +++ b/src/sage/rings/function_field/function_field_polymod.py @@ -560,6 +560,7 @@ def degree(self, base=None): return ZZ(1) return self._polynomial.degree() * self.base_field().degree(base) + def _repr_(self): """ Return the string representation of the function field. @@ -571,7 +572,22 @@ def _repr_(self): sage: L._repr_() 'Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x' """ - return "Function field in %s defined by %s" % (self.variable_name(), self._polynomial) + return (f"Function field in {self.variable_name()} defined by " + f"{self._polynomial}") + + def _latex_(self): + r""" + Return the LaTeX representation of the function field. + + EXAMPLES:: + + sage: K. = FunctionField(QQ); R. = K[] + sage: L. = K.extension(y^5 - (x^3 + 2*x*y + 1/x)) + sage: latex(L) + \text{Function field in } y \text{ defined by } y^{5} - 2 x y + \frac{-x^{4} - 1}{x} + """ + return (fr"\text{{Function field in }} {self.variable_name()} " + fr"\text{{ defined by }} {self._polynomial._latex_()}") def base_field(self): """ From 95c394f2eeae5fc33e9ac86fee5ad6af8be1da45 Mon Sep 17 00:00:00 2001 From: Vincent Macri Date: Fri, 25 Oct 2024 12:49:18 -0600 Subject: [PATCH 45/82] Remove blank line --- src/sage/rings/function_field/function_field_polymod.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/rings/function_field/function_field_polymod.py b/src/sage/rings/function_field/function_field_polymod.py index c5e6d459d7f..7edf21e0cf8 100644 --- a/src/sage/rings/function_field/function_field_polymod.py +++ b/src/sage/rings/function_field/function_field_polymod.py @@ -560,7 +560,6 @@ def degree(self, base=None): return ZZ(1) return self._polynomial.degree() * self.base_field().degree(base) - def _repr_(self): """ Return the string representation of the function field. From 04b9da9b85961fcd72a6a0cf8612b22fb6550962 Mon Sep 17 00:00:00 2001 From: Kyle Hofmann Date: Fri, 25 Oct 2024 18:20:08 -0700 Subject: [PATCH 46/82] Apply suggestions from code review Co-authored-by: Vincent Macri --- src/sage/rings/finite_rings/integer_mod_ring.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index 4987484d643..4381b17f645 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -1740,7 +1740,7 @@ def _roots_univariate_polynomial(self, f, ring=None, multiplicities=True, algori Suppose that we are trying to find roots modulo `p^e` and that `r` is a root of `f(x)` modulo `p`. The easy case is when `f'(r) \not\equiv 0 \pmod{p}`, for then Hensel's lemma implies that there is a unique - `r_e \in \mathbf{Z}/p^e\mathbf{Z}` with `r_e \equiv r \pmod{p}`. + `r_e \in \Zmod{p^e}` with `r_e \equiv r \pmod{p}`. Moreover, this `r_e` can be found by applying Newton's method for numerically approximating roots. Each iteration of Newton's method doubles the precision to which the root is known. @@ -1756,7 +1756,7 @@ def _roots_univariate_polynomial(self, f, ring=None, multiplicities=True, algori time. While we can no longer use Newton's method to solve for a lift, the Taylor series it is based on still yields constraints on the roots modulo `p^{k+1}`: If `r_k` is a root of `f` modulo `p^k`, then either - every lift of `r_k` to `\mathbf{Z}/p^{k+1}\mathbf{Z}` is a root of `f` + every lift of `r_k` to `\Zmod{p^{k + 1}}` is a root of `f` modulo `p^{k+1}` or none of them are. Consequently we may find roots modulo `p^e` by lifting one power at a time. From 61c02408110bdcba546c23a0a7ca773dae1c564b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 26 Oct 2024 13:23:18 +0200 Subject: [PATCH 47/82] various small details in combinat --- src/sage/combinat/alternating_sign_matrix.py | 7 +++---- src/sage/combinat/lr_tableau.py | 11 ++++++----- .../combinat/multiset_partition_into_sets_ordered.py | 6 +++--- src/sage/combinat/output.py | 6 +++--- src/sage/combinat/shard_order.py | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/sage/combinat/alternating_sign_matrix.py b/src/sage/combinat/alternating_sign_matrix.py index 230c9a8aae7..69a529054af 100644 --- a/src/sage/combinat/alternating_sign_matrix.py +++ b/src/sage/combinat/alternating_sign_matrix.py @@ -262,13 +262,12 @@ def to_monotone_triangle(self): True """ n = self._matrix.nrows() - triangle = [None] * n - prev = zero_vector(ZZ, n) + triangle = [0] * n + add_row = zero_vector(ZZ, n) for j, row in enumerate(self._matrix): - add_row = row + prev + add_row = row + add_row triangle[n - 1 - j] = [i + 1 for i in range(n - 1, -1, -1) if add_row[i] == 1] - prev = add_row return MonotoneTriangles(n)(triangle) @combinatorial_map(name='rotate counterclockwise') diff --git a/src/sage/combinat/lr_tableau.py b/src/sage/combinat/lr_tableau.py index 9a5e7a0ef03..5952f911a74 100644 --- a/src/sage/combinat/lr_tableau.py +++ b/src/sage/combinat/lr_tableau.py @@ -28,7 +28,7 @@ # http://www.gnu.org/licenses/ #**************************************************************************** -from itertools import zip_longest +from itertools import zip_longest, accumulate from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.combinat.tableau import SemistandardTableau, SemistandardTableaux @@ -277,14 +277,15 @@ def is_littlewood_richardson(t, heights): False """ from sage.combinat.words.word import Word - partial = [sum(heights[i] for i in range(j)) for j in range(len(heights)+1)] try: w = t.to_word() except AttributeError: # Not an instance of Tableau w = sum(reversed(t), []) + + partial = list(accumulate(heights, initial=0)) for i in range(len(heights)): subword = Word([j for j in w if partial[i]+1 <= j <= partial[i+1]], - alphabet=list(range(partial[i]+1,partial[i+1]+1))) + alphabet=list(range(partial[i]+1, partial[i+1]+1))) if not subword.is_yamanouchi(): return False return True @@ -305,5 +306,5 @@ def _tableau_join(t1, t2, shift=0): sage: _tableau_join([[1,2]],[[None,None,2],[3]],shift=5) [[1, 2, 7], [8]] """ - return [list(row1) + [e2+shift for e2 in row2 if e2 is not None] - for (row1, row2) in zip_longest(t1, t2, fillvalue=[])] + return [list(row1) + [e2 + shift for e2 in row2 if e2 is not None] + for row1, row2 in zip_longest(t1, t2, fillvalue=[])] diff --git a/src/sage/combinat/multiset_partition_into_sets_ordered.py b/src/sage/combinat/multiset_partition_into_sets_ordered.py index aae1cd569a2..211837f0b05 100755 --- a/src/sage/combinat/multiset_partition_into_sets_ordered.py +++ b/src/sage/combinat/multiset_partition_into_sets_ordered.py @@ -251,8 +251,8 @@ def _repr_normal(self): string_parts = (str(sorted(k)) for k in self) else: string_parts = (str(sorted(k, key=str)) for k in self) - string_parts = ", ".join(string_parts).replace("[","{").replace("]","}") - return "[" + string_parts + "]" + string = ", ".join(string_parts).replace("[", "{").replace("]", "}") + return "[" + string + "]" def _repr_tight(self): r""" @@ -670,7 +670,7 @@ def split_blocks(self, k=2): if not self: return {tuple([self]*k): 1} - out = {} + out: dict[tuple, int] = {} for t in product(*[_split_block(block, k) for block in self]): tt = tuple([P([l for l in c if l]) for c in zip(*t)]) out[tt] = out.get(tt, 0) + 1 diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index 1e2725448f9..3a369e7005d 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -738,7 +738,7 @@ def get_len(e): st += ' ' if E_box: st_num = str_tab[k-j][j] - ln_left = int((len(st_num) - (len(st_num) % 2))/2) + ln_left = len(st_num) // 2 st += st_num.rjust(row_height - 1 - ln_left + len(st_num), ' ').ljust(diag_length, ' ') else: st += ' ' * diag_length @@ -761,12 +761,12 @@ def get_len(e): import re mm = min(len(re.search('^ +', l)[0]) for l in str_list) - 1 str_list = [l[mm:].rstrip() for l in str_list] - while str_list[-1] == '': + while not str_list[-1]: str_list.pop() return "\n".join(str_list) -def box_exists(tab, i, j): +def box_exists(tab, i, j) -> bool: r""" Return ``True`` if ``tab[i][j]`` exists and is not ``None``; in particular this allows for `tab[i][j]` to be ``''`` or ``0``. diff --git a/src/sage/combinat/shard_order.py b/src/sage/combinat/shard_order.py index f9081ef77dc..002983ef747 100644 --- a/src/sage/combinat/shard_order.py +++ b/src/sage/combinat/shard_order.py @@ -88,7 +88,7 @@ def __init__(self, p): Digraph on 3 vertices """ self.runs = p.decreasing_runs(as_tuple=True) - self.run_indices = [None] * (len(p) + 1) + self.run_indices = [0] * (len(p) + 1) for i, bloc in enumerate(self.runs): for j in bloc: self.run_indices[j] = i From 471d5551e74dc86c02051def347433f77634b72f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 26 Oct 2024 21:41:12 +0200 Subject: [PATCH 48/82] autopep8 fixes for E302 in matrix,rings,groups,dynamics --- .../dynamics/arithmetic_dynamics/affine_ds.py | 2 ++ .../dynamics/arithmetic_dynamics/berkovich_ds.py | 1 + .../endPN_automorphism_group.py | 14 ++++++++++++++ .../arithmetic_dynamics/endPN_minimal_model.py | 9 +++++++++ .../dynamics/arithmetic_dynamics/projective_ds.py | 2 ++ src/sage/dynamics/cellular_automata/elementary.py | 1 + src/sage/dynamics/cellular_automata/glca.py | 1 + .../dynamics/complex_dynamics/mandel_julia.py | 2 ++ src/sage/dynamics/finite_dynamical_system.py | 3 +++ .../dynamics/finite_dynamical_system_catalog.py | 3 +++ src/sage/dynamics/surface_dynamics_deprecation.py | 1 + src/sage/groups/abelian_gps/abelian_aut.py | 3 +++ src/sage/groups/abelian_gps/abelian_group_gap.py | 6 ++++++ src/sage/groups/finitely_presented_named.py | 6 ++++++ src/sage/groups/fqf_orthogonal.py | 1 + src/sage/groups/indexed_free_group.py | 2 ++ src/sage/groups/libgap_group.py | 1 + .../groups/matrix_gps/finitely_generated_gap.py | 1 + src/sage/groups/matrix_gps/heisenberg.py | 1 + src/sage/groups/matrix_gps/homset.py | 1 + src/sage/groups/matrix_gps/morphism.py | 1 + src/sage/groups/matrix_gps/named_group_gap.py | 1 + src/sage/groups/perm_gps/cubegroup.py | 2 ++ src/sage/matrix/benchmark.py | 15 +++++++++++++++ .../matrix/matrix_integer_dense_saturation.py | 3 +++ src/sage/matrix/matrix_space.py | 1 + src/sage/rings/asymptotic/growth_group.py | 1 + .../rings/asymptotic/growth_group_cartesian.py | 2 ++ src/sage/rings/complex_interval_field.py | 2 ++ src/sage/rings/finite_rings/conway_polynomials.py | 4 ++++ .../rings/finite_rings/finite_field_pari_ffelt.py | 1 + src/sage/rings/finite_rings/galois_group.py | 2 ++ src/sage/rings/finite_rings/homset.py | 1 + src/sage/rings/finite_rings/maps_finite_field.py | 3 +++ src/sage/rings/function_field/constructor.py | 1 + src/sage/rings/function_field/divisor.py | 2 ++ .../drinfeld_modules/charzero_drinfeld_module.py | 1 + .../drinfeld_modules/drinfeld_module.py | 1 + src/sage/rings/function_field/valuation.py | 1 + src/sage/rings/function_field/valuation_ring.py | 1 + src/sage/rings/ideal.py | 5 +++++ src/sage/rings/lazy_series.py | 3 +++ src/sage/rings/lazy_series_ring.py | 4 ++++ src/sage/rings/monomials.py | 1 + src/sage/rings/polynomial/complex_roots.py | 1 + src/sage/rings/polynomial/ideal.py | 1 + .../rings/polynomial/laurent_polynomial_ideal.py | 1 + .../rings/polynomial/laurent_polynomial_ring.py | 5 +++++ .../polynomial/laurent_polynomial_ring_base.py | 1 + src/sage/rings/polynomial/msolve.py | 3 +++ .../rings/polynomial/multi_polynomial_ideal.py | 2 ++ .../rings/polynomial/multi_polynomial_sequence.py | 2 ++ src/sage/rings/polynomial/ore_function_element.py | 1 + .../polynomial/polynomial_element_generic.py | 3 +++ .../rings/polynomial/polynomial_quotient_ring.py | 1 + src/sage/rings/polynomial/term_order.py | 1 + src/sage/rings/qqbar_decorators.py | 1 + src/sage/rings/quotient_ring.py | 1 + src/sage/rings/ring_extension_homset.py | 1 + 59 files changed, 145 insertions(+) diff --git a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py index c2ad0f04cea..2096d734c85 100644 --- a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py @@ -884,6 +884,7 @@ def degree(self): """ return self.as_scheme_morphism().degree() + class DynamicalSystem_affine_field(DynamicalSystem_affine, SchemeMorphism_polynomial_affine_space_field): @cached_method @@ -985,6 +986,7 @@ def reduce_base_field(self): """ return self.as_scheme_morphism().reduce_base_field().as_dynamical_system() + class DynamicalSystem_affine_finite_field(DynamicalSystem_affine_field, SchemeMorphism_polynomial_affine_space_finite_field): diff --git a/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py b/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py index 0c27d8e2bde..f84ab7e94ed 100644 --- a/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py @@ -960,6 +960,7 @@ def __call__(self, x, type_3_pole_check=True): new_radius = max(new_radius, p**(-valuation/prime.absolute_ramification_index())*r**i) return self.domain()(new_center, new_radius) + class DynamicalSystem_Berkovich_affine(DynamicalSystem_Berkovich): r""" A dynamical system of the affine Berkovich line over `\CC_p`. diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py index 76ba5864fe6..196da8a081a 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py @@ -335,6 +335,7 @@ def height_bound(polynomial): return (6*(L2norm_sq)**3) + def PGL_repn(rational_function): r""" Take a linear fraction transformation and represent it as a 2x2 matrix. @@ -365,6 +366,7 @@ def PGL_repn(rational_function): g = rational_function.denominator() return matrix(F, 2, [f[1], f[0], g[1], g[0]]) + def PGL_order(A): r""" Find the multiplicative order of a linear fractional transformation that @@ -402,6 +404,7 @@ def PGL_order(A): return n + def CRT_helper(automorphisms, moduli): r""" Lift the given list of automorphisms to `Zmod(M)`. @@ -449,6 +452,7 @@ def CRT_helper(automorphisms, moduli): return autos, modulus*moduli[0] + def CRT_automorphisms(automorphisms, order_elts, degree, moduli): r""" Compute a maximal list of automorphisms over `Zmod(M)`. @@ -495,6 +499,7 @@ def CRT_automorphisms(automorphisms, order_elts, degree, moduli): # get list of CRT'ed automorphisms return CRT_helper(degree_d_autos, moduli) + def valid_automorphisms(automorphisms_CRT, rational_function, ht_bound, M, return_functions=False): r""" @@ -904,6 +909,7 @@ def automorphism_group_FF(rational_function, absolute=False, iso_type=False, ret else: return G, which_group(G[1]) + def field_descent(sigma, y): r""" Function for descending an element in a field `E` to a subfield `F`. @@ -961,6 +967,7 @@ def field_descent(sigma, y): return x + F(quotient)*a**(steps) + def rational_function_coefficient_descent(rational_function, sigma, poly_ring): r""" Function for descending the coefficients of a rational function from field `E` @@ -1059,6 +1066,7 @@ def rational_function_coerce(rational_function, sigma, S_polys): else: return S_polys([sigma(a) for a in f]) / S_polys([sigma(b) for b in g]) + def rational_function_reduce(rational_function): r""" Force Sage to divide out common factors in numerator and denominator @@ -1084,6 +1092,7 @@ def rational_function_reduce(rational_function): comm_factor = gcd(F,G) return (F.quo_rem(comm_factor)[0]) / (G.quo_rem(comm_factor)[0]) + def three_stable_points(rational_function, invariant_list): r""" Implementation of Algorithm 1 for automorphism groups from @@ -1157,6 +1166,7 @@ def three_stable_points(rational_function, invariant_list): automorphisms.append(s) return automorphisms + def automorphism_group_FF_alg2(rational_function): r""" Implementation of algorithm for determining the absolute automorphism @@ -1455,6 +1465,7 @@ def order_p_automorphisms(rational_function, pre_image): return automorphisms_p + def automorphisms_fixing_pair(rational_function, pair, quad): r""" Compute the set of automorphisms with order prime to the characteristic @@ -1535,6 +1546,7 @@ def automorphisms_fixing_pair(rational_function, pair, quad): return list(set(automorphisms_prime_to_p)) + def automorphism_group_FF_alg3(rational_function): r""" Implementation of Algorithm 3 in the paper by Faber/Manes/Viray [FMV]_ @@ -2125,6 +2137,7 @@ def greedy_independence_check(P, repeated_mult, point_to_mult): if len(source) == n+2: return source, corresponding + def conjugating_set_helper(f, g, num_cpus, source, possible_targets): r""" Return the set of elements in PGL over the base ring @@ -2270,6 +2283,7 @@ def find_conjugations_arrangement(tuples): Conj = find_conjugations_subset(product(*subset_iterators)) return Conj + def is_conjugate_helper(f, g, num_cpus, source, possible_targets): r""" Return if ``f`` is conjugate to ``g``. diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py b/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py index c8528c4821f..902f83b55ae 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py @@ -473,6 +473,8 @@ def Min(Fun, p, ubRes, conj, all_orbits=False): ################################################### #modification of Bruin-Molnar for all representatives + + def BM_all_minimal(vp, return_transformation=False, D=None): r""" Determine a representative in each `SL(2,\ZZ)` orbit with minimal @@ -623,6 +625,8 @@ def BM_all_minimal(vp, return_transformation=False, D=None): ################################################### #find minimal model + + def HS_minimal(f, return_transformation=False, D=None): r""" Compute a minimal model for the given projective dynamical system. @@ -713,6 +717,8 @@ def HS_minimal(f, return_transformation=False, D=None): return F #find all representatives of orbits for one prime + + def HS_all_minimal_p(p, f, m=None, return_transformation=False): r""" Find a representative in each distinct `SL(2,\ZZ)` orbit with @@ -814,6 +820,8 @@ def HS_all_minimal_p(p, f, m=None, return_transformation=False): return [funct for funct, matr in reps] #find all representatives of orbits + + def HS_all_minimal(f, return_transformation=False, D=None): r""" Determine a representative in each `SL(2,\ZZ)` orbit with minimal resultant. @@ -906,6 +914,7 @@ def HS_all_minimal(f, return_transformation=False, D=None): # Ben Hutz July 2018 #####################################3 + def get_bound_dynamical(F, f, m=1, dynatomic=True, prec=53, emb=None): """ The hyperbolic distance from `j` which must contain the smallest map. diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index a74efd9129a..8cd24f6611d 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -7026,6 +7026,7 @@ def Lattes_to_curve(self, return_conjugation=False, check_lattes=False): return (M, E) return E + class DynamicalSystem_projective_field(DynamicalSystem_projective, SchemeMorphism_polynomial_projective_space_field): @@ -9117,6 +9118,7 @@ def is_newton(self, return_conjugation=False): else: return Npoly.derivative(z) == (z - N_aff[0]).denominator() + class DynamicalSystem_projective_finite_field(DynamicalSystem_projective_field, SchemeMorphism_polynomial_projective_space_finite_field): diff --git a/src/sage/dynamics/cellular_automata/elementary.py b/src/sage/dynamics/cellular_automata/elementary.py index 51f959ed237..1c91687db8c 100644 --- a/src/sage/dynamics/cellular_automata/elementary.py +++ b/src/sage/dynamics/cellular_automata/elementary.py @@ -25,6 +25,7 @@ lazy_import("sage.plot.matrix_plot", "matrix_plot") from sage.misc.constant_function import ConstantFunction + class ElementaryCellularAutomata(SageObject): r""" Elementary cellular automata. diff --git a/src/sage/dynamics/cellular_automata/glca.py b/src/sage/dynamics/cellular_automata/glca.py index ea84884755b..929f1131456 100644 --- a/src/sage/dynamics/cellular_automata/glca.py +++ b/src/sage/dynamics/cellular_automata/glca.py @@ -20,6 +20,7 @@ from sage.typeset.ascii_art import AsciiArt from sage.typeset.unicode_art import UnicodeArt + class GraftalLaceCellularAutomata(SageObject): r""" Graftal Lace Cellular Automata (GLCA). diff --git a/src/sage/dynamics/complex_dynamics/mandel_julia.py b/src/sage/dynamics/complex_dynamics/mandel_julia.py index f21ffca80e4..b95040c2da2 100644 --- a/src/sage/dynamics/complex_dynamics/mandel_julia.py +++ b/src/sage/dynamics/complex_dynamics/mandel_julia.py @@ -58,6 +58,7 @@ EPS = 0.00001 + def mandelbrot_plot(f=None, **kwds): r""" Plot of the Mandelbrot set for a one parameter family of polynomial maps. @@ -498,6 +499,7 @@ def kneading_sequence(theta): KS_str = ''.join(KS) + '*' return KS_str + def julia_plot(f=None, **kwds): r""" Plots the Julia set of a given polynomial ``f``. Users can specify whether diff --git a/src/sage/dynamics/finite_dynamical_system.py b/src/sage/dynamics/finite_dynamical_system.py index d6cfc29feb7..441a498f608 100644 --- a/src/sage/dynamics/finite_dynamical_system.py +++ b/src/sage/dynamics/finite_dynamical_system.py @@ -678,6 +678,7 @@ def is_homomesic(self, h, average=None, find_average=False, elements=None): return True return orbavgs[0] == average + class InvertibleDiscreteDynamicalSystem(DiscreteDynamicalSystem): r""" An invertible discrete dynamical system. @@ -969,6 +970,7 @@ def inverse_evolution_default(self, x): """ return self.orbit(x)[-1] + class FiniteDynamicalSystem(DiscreteDynamicalSystem): r""" A finite discrete dynamical system. @@ -1113,6 +1115,7 @@ def cycles(self): break return cycs + class InvertibleFiniteDynamicalSystem(InvertibleDiscreteDynamicalSystem, FiniteDynamicalSystem): r""" An invertible finite discrete dynamical system. diff --git a/src/sage/dynamics/finite_dynamical_system_catalog.py b/src/sage/dynamics/finite_dynamical_system_catalog.py index 74217178a29..c00083f56c4 100755 --- a/src/sage/dynamics/finite_dynamical_system_catalog.py +++ b/src/sage/dynamics/finite_dynamical_system_catalog.py @@ -28,6 +28,7 @@ FiniteDynamicalSystem, InvertibleDiscreteDynamicalSystem, \ InvertibleFiniteDynamicalSystem + def permutation(pi, invertible=True): r""" Return the invertible finite discrete dynamical system @@ -64,6 +65,7 @@ def permutation(pi, invertible=True): X = range(1, n+1) return InvertibleFiniteDynamicalSystem(X, pi, inverse=pi.inverse(), create_tuple=True) + def one_line(xs): r""" Return the finite discrete dynamical system @@ -148,6 +150,7 @@ def bitstring_rotation(n, ones=None): psi = lambda x: (x[-1],) + x[:-1] return InvertibleFiniteDynamicalSystem(X, phi, inverse=psi) + def striker_sweep(E, predicate, elements, lazy=False): r""" Return the invertible finite discrete dynamical system diff --git a/src/sage/dynamics/surface_dynamics_deprecation.py b/src/sage/dynamics/surface_dynamics_deprecation.py index 9da8f1d0be3..8f6e37fe1b2 100644 --- a/src/sage/dynamics/surface_dynamics_deprecation.py +++ b/src/sage/dynamics/surface_dynamics_deprecation.py @@ -9,6 +9,7 @@ "information at\n" \ " http://www.labri.fr/perso/vdelecro/surface-dynamics/latest/" + def surface_dynamics_deprecation(name): r""" TESTS:: diff --git a/src/sage/groups/abelian_gps/abelian_aut.py b/src/sage/groups/abelian_gps/abelian_aut.py index 7108f311a48..89551916589 100644 --- a/src/sage/groups/abelian_gps/abelian_aut.py +++ b/src/sage/groups/abelian_gps/abelian_aut.py @@ -205,6 +205,7 @@ def matrix(self): m.set_immutable() return m + class AbelianGroupAutomorphismGroup_gap(CachedRepresentation, GroupMixinLibGAP, Group, @@ -407,6 +408,7 @@ def is_subgroup_of(self, G): return False return G.gap().IsSubsemigroup(self).sage() + class AbelianGroupAutomorphismGroup(AbelianGroupAutomorphismGroup_gap): r""" The full automorphism group of a finite abelian group. @@ -467,6 +469,7 @@ def _repr_(self): """ return "Full group of automorphisms of %s" % self.domain() + class AbelianGroupAutomorphismGroup_subgroup(AbelianGroupAutomorphismGroup_gap): r""" Groups of automorphisms of abelian groups. diff --git a/src/sage/groups/abelian_gps/abelian_group_gap.py b/src/sage/groups/abelian_gps/abelian_group_gap.py index 199aa935f56..0c0d6a5f49b 100644 --- a/src/sage/groups/abelian_gps/abelian_group_gap.py +++ b/src/sage/groups/abelian_gps/abelian_group_gap.py @@ -39,6 +39,7 @@ from sage.structure.unique_representation import UniqueRepresentation from sage.categories.groups import Groups + class AbelianGroupElement_gap(ElementLibGAP): r""" An element of an abelian group via libgap. @@ -184,6 +185,7 @@ def order(self): """ return self.gap().Order().sage() + class AbelianGroupElement_polycyclic(AbelianGroupElement_gap): r""" An element of an abelian group using the GAP package ``Polycyclic``. @@ -220,6 +222,7 @@ def exponents(self): """ return tuple(self.gap().Exponents().sage()) + class AbelianGroup_gap(UniqueRepresentation, GroupMixinLibGAP, ParentLibGAP, AbelianGroupBase): r""" Finitely generated abelian groups implemented in GAP. @@ -620,6 +623,7 @@ def subgroup(self, gens): gens = tuple([self(g) for g in gens]) return AbelianGroupSubgroup_gap(self.ambient(), gens) + class AbelianGroupGap(AbelianGroup_gap): r""" Abelian groups implemented using GAP. @@ -730,6 +734,7 @@ def __reduce__(self): """ return AbelianGroupGap, (self.gens_orders(),) + class AbelianGroupSubgroup_gap(AbelianGroup_gap): r""" Subgroups of abelian groups with GAP. @@ -879,6 +884,7 @@ def retract(self, x): """ return self(x) + class AbelianGroupQuotient_gap(AbelianGroup_gap): r""" Quotients of abelian groups by a subgroup. diff --git a/src/sage/groups/finitely_presented_named.py b/src/sage/groups/finitely_presented_named.py index 8b07c5af7df..940d761ef49 100644 --- a/src/sage/groups/finitely_presented_named.py +++ b/src/sage/groups/finitely_presented_named.py @@ -202,6 +202,7 @@ def FinitelyGeneratedAbelianPresentation(int_list): ret_rls = ret_rls + [x[0]**(-1)*x[1]**(-1)*x[0]*x[1] for x in gen_pairs] return FinitelyPresentedGroup(F, tuple(ret_rls)) + def FinitelyGeneratedHeisenbergPresentation(n=1, p=0): r""" Return a finite presentation of the Heisenberg group. @@ -292,6 +293,7 @@ def commutator(a, b): rls += [w**p for w in F.gens()] return FinitelyPresentedGroup(F, tuple(rls)) + def DihedralPresentation(n): r""" Build the Dihedral group of order `2n` as a finitely presented group. @@ -327,6 +329,7 @@ def DihedralPresentation(n): rls = F([1])**n, F([2])**2, (F([1])*F([2]))**2 return FinitelyPresentedGroup( F, rls ) + def DiCyclicPresentation(n): r""" Build the dicyclic group of order `4n`, for `n \geq 2`, as a finitely @@ -455,6 +458,7 @@ def QuaternionPresentation(): rls = F([1])**4, F([2,2,-1,-1]), F([1,2,1,-2]) return FinitelyPresentedGroup(F, rls) + def AlternatingPresentation(n): r""" Build the Alternating group of order `n!/2` as a finitely presented group. @@ -521,6 +525,7 @@ def KleinFourPresentation(): rls = F([1])**2, F([2])**2, F([-1])*F([-2])*F([1])*F([2]) return FinitelyPresentedGroup(F, rls) + def BinaryDihedralPresentation(n): r""" Build a binary dihedral group of order `4n` as a finitely presented group. @@ -561,6 +566,7 @@ def BinaryDihedralPresentation(n): rls = (x**-2 * y**2, x**-2 * z**n, x**-2 * x*y*z) return FinitelyPresentedGroup(F, rls) + def CactusPresentation(n): r""" Build the `n`-fruit cactus group as a finitely presented group. diff --git a/src/sage/groups/fqf_orthogonal.py b/src/sage/groups/fqf_orthogonal.py index 5da64f03212..e5ebd06ccdb 100644 --- a/src/sage/groups/fqf_orthogonal.py +++ b/src/sage/groups/fqf_orthogonal.py @@ -381,6 +381,7 @@ def _repr_(self): """ return "Group of isometries of \n%s\ngenerated by %s elements" % (self.invariant_form(), len(self.gens())) + class ActionOnFqf(Action): r""" Action on a finite quadratic module. diff --git a/src/sage/groups/indexed_free_group.py b/src/sage/groups/indexed_free_group.py index ad484532f13..67a3308d787 100644 --- a/src/sage/groups/indexed_free_group.py +++ b/src/sage/groups/indexed_free_group.py @@ -137,6 +137,7 @@ def group_generators(self): gens = group_generators + class IndexedFreeGroup(IndexedGroup, Group): """ An indexed free group. @@ -297,6 +298,7 @@ def to_word_list(self): return [ (k, sign(e)) for k,e in self._sorted_items() for dummy in range(abs(e))] + class IndexedFreeAbelianGroup(IndexedGroup, AbelianGroup): """ An indexed free abelian group. diff --git a/src/sage/groups/libgap_group.py b/src/sage/groups/libgap_group.py index 09889de4af5..81c7b9dd1df 100644 --- a/src/sage/groups/libgap_group.py +++ b/src/sage/groups/libgap_group.py @@ -36,6 +36,7 @@ from sage.groups.libgap_wrapper import ParentLibGAP, ElementLibGAP from sage.groups.libgap_mixin import GroupMixinLibGAP + class GroupLibGAP(GroupMixinLibGAP, Group, ParentLibGAP): Element = ElementLibGAP diff --git a/src/sage/groups/matrix_gps/finitely_generated_gap.py b/src/sage/groups/matrix_gps/finitely_generated_gap.py index d3403f22f40..70f409b2b54 100644 --- a/src/sage/groups/matrix_gps/finitely_generated_gap.py +++ b/src/sage/groups/matrix_gps/finitely_generated_gap.py @@ -924,6 +924,7 @@ def invariants_of_degree(self, deg, chi=None, R=None): break return list(inv) + def _new_invariant_is_linearly_independent(F, invariants): """ EXAMPLES:: diff --git a/src/sage/groups/matrix_gps/heisenberg.py b/src/sage/groups/matrix_gps/heisenberg.py index f101c27153b..ed71925c5ed 100644 --- a/src/sage/groups/matrix_gps/heisenberg.py +++ b/src/sage/groups/matrix_gps/heisenberg.py @@ -26,6 +26,7 @@ from sage.rings.integer_ring import ZZ from copy import copy + class HeisenbergGroup(UniqueRepresentation, FinitelyGeneratedMatrixGroup_gap): r""" The Heisenberg group of degree `n`. diff --git a/src/sage/groups/matrix_gps/homset.py b/src/sage/groups/matrix_gps/homset.py index b9d25ae0727..02818275424 100644 --- a/src/sage/groups/matrix_gps/homset.py +++ b/src/sage/groups/matrix_gps/homset.py @@ -21,6 +21,7 @@ from sage.misc.lazy_import import lazy_import from sage.misc.superseded import deprecation + def is_MatrixGroupHomset(x): r""" Test whether ``x`` is a matrix group homset. diff --git a/src/sage/groups/matrix_gps/morphism.py b/src/sage/groups/matrix_gps/morphism.py index e2fc2e0fd59..e73ba7e945a 100644 --- a/src/sage/groups/matrix_gps/morphism.py +++ b/src/sage/groups/matrix_gps/morphism.py @@ -15,6 +15,7 @@ from sage.misc.lazy_import import lazy_import + def to_libgap(x): """ Helper to convert ``x`` to a LibGAP matrix or matrix group diff --git a/src/sage/groups/matrix_gps/named_group_gap.py b/src/sage/groups/matrix_gps/named_group_gap.py index 699e351f06d..926ae0649a0 100644 --- a/src/sage/groups/matrix_gps/named_group_gap.py +++ b/src/sage/groups/matrix_gps/named_group_gap.py @@ -18,6 +18,7 @@ from sage.groups.matrix_gps.matrix_group_gap import MatrixGroup_gap from sage.groups.matrix_gps.named_group import NamedMatrixGroup_generic + class NamedMatrixGroup_gap(NamedMatrixGroup_generic, MatrixGroup_gap): def __init__(self, degree, base_ring, special, sage_name, latex_string, diff --git a/src/sage/groups/perm_gps/cubegroup.py b/src/sage/groups/perm_gps/cubegroup.py index 8eadbac39f1..7603da471f9 100644 --- a/src/sage/groups/perm_gps/cubegroup.py +++ b/src/sage/groups/perm_gps/cubegroup.py @@ -128,6 +128,7 @@ ######################################################### # written by Tom Boothby, placed in the public domain + def xproj(x, y, z, r): r""" Return the `x`-projection of `(x,y,z)` rotated by `r`. @@ -347,6 +348,7 @@ def create_poly(face, color): 32: "rbd", } + def index2singmaster(facet): """ Translate index used (eg, 43) to Singmaster facet notation (eg, diff --git a/src/sage/matrix/benchmark.py b/src/sage/matrix/benchmark.py index 8567f869511..b411de7d119 100644 --- a/src/sage/matrix/benchmark.py +++ b/src/sage/matrix/benchmark.py @@ -121,6 +121,7 @@ def report_ZZ(**kwds): # Integer Nullspace + def nullspace_ZZ(n=200, min=0, max=2**32, system='sage'): """ Nullspace over ZZ: @@ -240,6 +241,7 @@ def rank_ZZ(n=700, min=0, max=9, system='sage'): else: raise ValueError('unknown system "%s"' % system) + def rank2_ZZ(n=400, min=0, max=2**64, system='sage'): """ Rank 2 over ZZ: @@ -281,6 +283,7 @@ def rank2_ZZ(n=400, min=0, max=2**64, system='sage'): # Smith Form + def smithform_ZZ(n=128, min=0, max=9, system='sage'): """ Smith Form over ZZ: @@ -366,6 +369,7 @@ def matrix_multiply_ZZ(n=300, min=-9, max=9, system='sage', times=1): else: raise ValueError('unknown system "%s"' % system) + def matrix_add_ZZ(n=200, min=-9, max=9, system='sage', times=50): """ Matrix addition over ZZ @@ -413,6 +417,7 @@ def matrix_add_ZZ(n=200, min=-9, max=9, system='sage', times=50): else: raise ValueError('unknown system "%s"' % system) + def matrix_add_ZZ_2(n=200, bits=16, system='sage', times=50): """ Matrix addition over ZZ. @@ -435,6 +440,7 @@ def matrix_add_ZZ_2(n=200, bits=16, system='sage', times=50): b = 2**bits return matrix_add_ZZ(n=n, min=-b, max=b,system=system, times=times) + def det_ZZ(n=200, min=1, max=100, system='sage'): """ Dense integer determinant over ZZ. @@ -602,6 +608,7 @@ def report_GF(p=16411, **kwds): # Nullspace over GF + def nullspace_GF(n=300, p=16411, system='sage'): """ Given a n+1 x n matrix over GF(p) with random @@ -679,6 +686,7 @@ def charpoly_GF(n=100, p=16411, system='sage'): else: raise ValueError('unknown system "%s"' % system) + def matrix_add_GF(n=1000, p=16411, system='sage',times=100): """ Given two n x n matrix over GF(p) with random entries, add them. @@ -805,6 +813,7 @@ def rank_GF(n=500, p=16411, system='sage'): else: raise ValueError('unknown system "%s"' % system) + def rank2_GF(n=500, p=16411, system='sage'): """ Rank over GF(p): Given a (n + 10) x n matrix over GF(p) with @@ -842,6 +851,7 @@ def rank2_GF(n=500, p=16411, system='sage'): else: raise ValueError('unknown system "%s"' % system) + def det_GF(n=400, p=16411 , system='sage'): """ Dense determinant over GF(p). @@ -905,6 +915,7 @@ def hilbert_matrix(n): # Reduced row echelon form over QQ + def echelon_QQ(n=100, min=0, max=9, system='sage'): """ Given a n x (2*n) matrix over QQ with random integer entries @@ -945,6 +956,7 @@ def echelon_QQ(n=100, min=0, max=9, system='sage'): # Invert a matrix over QQ. + def inverse_QQ(n=100, min=0, max=9, system='sage'): """ Given a n x n matrix over QQ with random integer entries @@ -1067,6 +1079,8 @@ def det_hilbert_QQ(n=80, system='sage'): return float(magma.eval('s')) # inverse of Hilbert matrix + + def invert_hilbert_QQ(n=40, system='sage'): """ Run the benchmark for calculating the inverse of the hilbert @@ -1101,6 +1115,7 @@ def invert_hilbert_QQ(n=40, system='sage'): magma.eval(code) return float(magma.eval('s')) + def MatrixVector_QQ(n=1000,h=100,system='sage',times=1): """ Compute product of square ``n`` matrix by random vector with num and diff --git a/src/sage/matrix/matrix_integer_dense_saturation.py b/src/sage/matrix/matrix_integer_dense_saturation.py index b537b041e08..fdd812597f5 100644 --- a/src/sage/matrix/matrix_integer_dense_saturation.py +++ b/src/sage/matrix/matrix_integer_dense_saturation.py @@ -68,6 +68,7 @@ def p_saturation(A, p, proof=True): H = H.stack(C).hermite_form(include_zero_rows=False, proof=proof) verbose("done saturating", tm) + def random_sublist_of_size(k, n): """ INPUT: @@ -181,6 +182,7 @@ def solve_system_with_difficult_last_row(B, A): verbose("Done getting linear combinations.", tm) return X + def saturation(A, proof=True, p=0, max_dets=5): r""" Compute a saturation matrix of `A`. @@ -283,6 +285,7 @@ def saturation(A, proof=True, p=0, max_dets=5): C = solve_system_with_difficult_last_row(B, A) return C.change_ring(ZZ)._insert_zero_columns(zero_cols) + def index_in_saturation(A, proof=True): r""" The index of A in its saturation. diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 267a818c433..2ba59292d54 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -2664,6 +2664,7 @@ def _from_dict(self, d, coerce=True, remove_zeros=True): """ return self.element_class(self, d, coerce=coerce) + def dict_to_list(entries, nrows, ncols): r""" Given a dictionary of coordinate tuples, return the list given by diff --git a/src/sage/rings/asymptotic/growth_group.py b/src/sage/rings/asymptotic/growth_group.py index cf9cf74ca70..ca2afc2b92c 100644 --- a/src/sage/rings/asymptotic/growth_group.py +++ b/src/sage/rings/asymptotic/growth_group.py @@ -3671,6 +3671,7 @@ def non_growth_group(self): J = ImaginaryGroup(self.base()) return self._non_growth_group_class_(J, self._var_) + class MonomialGrowthGroupFunctor(AbstractGrowthGroupFunctor): r""" A :class:`construction functor ` diff --git a/src/sage/rings/asymptotic/growth_group_cartesian.py b/src/sage/rings/asymptotic/growth_group_cartesian.py index 0bdb3d4a1eb..19bb7d975a6 100644 --- a/src/sage/rings/asymptotic/growth_group_cartesian.py +++ b/src/sage/rings/asymptotic/growth_group_cartesian.py @@ -253,6 +253,8 @@ def create_object(self, version, args, **kwds): from sage.combinat.posets.cartesian_product import CartesianProductPoset from .growth_group import GenericGrowthGroup + + class GenericProduct(CartesianProductPoset, GenericGrowthGroup): r""" A Cartesian product of growth groups. diff --git a/src/sage/rings/complex_interval_field.py b/src/sage/rings/complex_interval_field.py index 0b6981cf07b..c090d6cdae2 100644 --- a/src/sage/rings/complex_interval_field.py +++ b/src/sage/rings/complex_interval_field.py @@ -49,6 +49,8 @@ from sage.structure.parent import Parent cache = {} + + def ComplexIntervalField(prec=53, names=None): """ Return the complex interval field with real and imaginary parts having diff --git a/src/sage/rings/finite_rings/conway_polynomials.py b/src/sage/rings/finite_rings/conway_polynomials.py index ff5873ee14b..70a851990ad 100644 --- a/src/sage/rings/finite_rings/conway_polynomials.py +++ b/src/sage/rings/finite_rings/conway_polynomials.py @@ -64,6 +64,7 @@ def conway_polynomial(p, n): except KeyError: raise RuntimeError("requested Conway polynomial not in database.") + def exists_conway_polynomial(p, n): """ Check whether the Conway polynomial of degree `n` over ``GF(p)`` @@ -99,6 +100,7 @@ def exists_conway_polynomial(p, n): except ImportError: return False + class PseudoConwayLattice(WithEqualityById, SageObject): r""" A pseudo-Conway lattice over a given finite prime field. @@ -328,6 +330,7 @@ def _find_pow_of_frobenius(p, n, x, y): raise RuntimeError("No appropriate power of Frobenius found") return mod(i, n) + def _crt_non_coprime(running, a): """ Extension of the ``crt`` method of ``IntegerMod`` to the case of @@ -361,6 +364,7 @@ def _crt_non_coprime(running, a): a_modulus = a_val_unit[1] return (running % running_modulus).crt(a % a_modulus) + def _frobenius_shift(K, generators, check_only=False): """ Given a field `K` of degree `n` over ``GF(p)`` and a dictionary diff --git a/src/sage/rings/finite_rings/finite_field_pari_ffelt.py b/src/sage/rings/finite_rings/finite_field_pari_ffelt.py index 9549dbc94b4..6bc637c94b3 100644 --- a/src/sage/rings/finite_rings/finite_field_pari_ffelt.py +++ b/src/sage/rings/finite_rings/finite_field_pari_ffelt.py @@ -21,6 +21,7 @@ from .finite_field_base import FiniteField from .finite_field_constructor import GF + class FiniteField_pari_ffelt(FiniteField): """ Finite fields whose cardinality is a prime power (not a prime), diff --git a/src/sage/rings/finite_rings/galois_group.py b/src/sage/rings/finite_rings/galois_group.py index 32e23a40c44..1cdd70fcbb2 100644 --- a/src/sage/rings/finite_rings/galois_group.py +++ b/src/sage/rings/finite_rings/galois_group.py @@ -8,6 +8,7 @@ from sage.rings.integer_ring import ZZ from sage.rings.finite_rings.hom_finite_field import FiniteFieldHomomorphism_generic, FrobeniusEndomorphism_finite_field + class GaloisGroup_GFElement(AbelianGroupElement): def as_hom(self): r""" @@ -52,6 +53,7 @@ def fixed_field(self): """ return self.as_hom().fixed_field() + class GaloisGroup_GF(GaloisGroup_cyc): r""" The Galois group of a finite field. diff --git a/src/sage/rings/finite_rings/homset.py b/src/sage/rings/finite_rings/homset.py index 6c15d725f43..617f9da0086 100644 --- a/src/sage/rings/finite_rings/homset.py +++ b/src/sage/rings/finite_rings/homset.py @@ -43,6 +43,7 @@ from sage.rings.morphism import RingHomomorphism_im_gens from sage.structure.sequence import Sequence + class FiniteFieldHomset(RingHomset_generic): """ Set of homomorphisms with domain a given finite field. diff --git a/src/sage/rings/finite_rings/maps_finite_field.py b/src/sage/rings/finite_rings/maps_finite_field.py index e68bd5c7b94..dff8679dd1e 100644 --- a/src/sage/rings/finite_rings/maps_finite_field.py +++ b/src/sage/rings/finite_rings/maps_finite_field.py @@ -21,6 +21,7 @@ from sage.categories.morphism import Morphism + class FiniteFieldVectorSpaceIsomorphism(Morphism): """ Base class of the vector space isomorphism between a finite field @@ -70,6 +71,7 @@ def is_surjective(self): """ return True + class MorphismVectorSpaceToFiniteField(FiniteFieldVectorSpaceIsomorphism): """ Isomorphisms from vector spaces to finite fields. @@ -130,6 +132,7 @@ def _call_(self, v): w[i*n:(i+1)*n] = v[i]._vector_() return E(w * self._C) + class MorphismFiniteFieldToVectorSpace(FiniteFieldVectorSpaceIsomorphism): """ Isomorphisms from finite fields to vector spaces diff --git a/src/sage/rings/function_field/constructor.py b/src/sage/rings/function_field/constructor.py index a316c384bd1..098da7b59da 100644 --- a/src/sage/rings/function_field/constructor.py +++ b/src/sage/rings/function_field/constructor.py @@ -39,6 +39,7 @@ from sage.structure.factory import UniqueFactory + class FunctionFieldFactory(UniqueFactory): """ Return the function field in one variable with constant field ``F``. The diff --git a/src/sage/rings/function_field/divisor.py b/src/sage/rings/function_field/divisor.py index 13247abe3b0..8c72b4cdb98 100644 --- a/src/sage/rings/function_field/divisor.py +++ b/src/sage/rings/function_field/divisor.py @@ -74,6 +74,7 @@ from .place import PlaceSet + def divisor(field, data): """ Construct a divisor from the data. @@ -98,6 +99,7 @@ def divisor(field, data): divisor_group = field.divisor_group() return divisor_group.element_class(divisor_group, data) + def prime_divisor(field, place, m=1): """ Construct a prime divisor from the place. diff --git a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index d183848f296..06a0afdaa41 100644 --- a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -31,6 +31,7 @@ lazy_import('sage.rings.lazy_series_ring', 'LazyPowerSeriesRing') + class DrinfeldModule_charzero(DrinfeldModule): r""" This class implements Drinfeld `\mathbb{F}_q[T]`-modules defined diff --git a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py index d225820ab18..c4ad9f1376d 100644 --- a/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/drinfeld_module.py @@ -46,6 +46,7 @@ lazy_import('sage.rings.ring_extension', 'RingExtension_generic') + class DrinfeldModule(Parent, UniqueRepresentation): r""" This class implements Drinfeld `\mathbb{F}_q[T]`-modules. diff --git a/src/sage/rings/function_field/valuation.py b/src/sage/rings/function_field/valuation.py index a192a76beb6..e92600e55b6 100644 --- a/src/sage/rings/function_field/valuation.py +++ b/src/sage/rings/function_field/valuation.py @@ -157,6 +157,7 @@ from sage.rings.valuation.trivial_valuation import TrivialValuation from sage.rings.valuation.mapped_valuation import FiniteExtensionFromLimitValuation, MappedValuation_base + class FunctionFieldValuationFactory(UniqueFactory): r""" Create a valuation on ``domain`` corresponding to ``prime``. diff --git a/src/sage/rings/function_field/valuation_ring.py b/src/sage/rings/function_field/valuation_ring.py index e1fe9751b0b..9269d21ea2d 100644 --- a/src/sage/rings/function_field/valuation_ring.py +++ b/src/sage/rings/function_field/valuation_ring.py @@ -72,6 +72,7 @@ from sage.categories.homset import Hom from sage.categories.rings import Rings + class FunctionFieldValuationRing(UniqueRepresentation, Parent): """ Base class for valuation rings of function fields. diff --git a/src/sage/rings/ideal.py b/src/sage/rings/ideal.py index 4208c63c55c..dc785891828 100644 --- a/src/sage/rings/ideal.py +++ b/src/sage/rings/ideal.py @@ -1457,6 +1457,7 @@ def divides(self, other): return self.gen().divides(other.gen()) raise NotImplementedError + class Ideal_pid(Ideal_principal): """ An ideal of a principal ideal domain. @@ -1694,6 +1695,7 @@ def residue_field(self): return ZZ.residue_field(self, check=False) raise NotImplementedError("residue_field() is only implemented for ZZ and rings of integers of number fields.") + class Ideal_fractional(Ideal_generic): """ Fractional ideal of a ring. @@ -1717,6 +1719,7 @@ def _repr_(self): # constructors for standard (benchmark) ideals, written uppercase as # these are constructors + def Cyclic(R, n=None, homog=False, singular=None): """ Ideal of cyclic ``n``-roots from 1-st ``n`` variables of ``R`` if ``R`` is @@ -1782,6 +1785,7 @@ def Cyclic(R, n=None, homog=False, singular=None): I = singular.cyclic(n).homog(R2.gen(n-1)) return R2.ideal(I).change_ring(R) + def Katsura(R, n=None, homog=False, singular=None): r""" `n`-th katsura ideal of `R` if `R` is coercible to @@ -1832,6 +1836,7 @@ def Katsura(R, n=None, homog=False, singular=None): I = singular.katsura(n).homog(R2.gen(n-1)) return R2.ideal(I).change_ring(R) + def FieldIdeal(R): r""" Let ``q = R.base_ring().order()`` and `(x_0,...,x_n)` ``= R.gens()`` then diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 8520ad33f68..b48e0e6bc38 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -4866,6 +4866,7 @@ def _format_series(self, formatter, format_strings=False): return strformat("O({})".format(formatter(z**m))) return formatter(poly) + strformat(" + O({})".format(formatter(z**m))) + class LazyPowerSeries(LazyCauchyProductSeries): r""" A Taylor series where the coefficients are computed lazily. @@ -6149,6 +6150,7 @@ def _floordiv_(self, other): left._approximate_order += 1 return super()._floordiv_(other) + class LazyPowerSeries_gcd_mixin: """ A lazy power series that also implements the GCD algorithm. @@ -6266,6 +6268,7 @@ def xgcd(self, f): unit = ~unit return (x**val, unit, unit) + class LazyCompletionGradedAlgebraElement(LazyCauchyProductSeries): """ An element of a completion of a graded algebra that is computed lazily. diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index ee3e463e988..7c61f8861b3 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -93,6 +93,7 @@ from types import GeneratorType + class LazySeriesRing(UniqueRepresentation, Parent): """ Abstract base class for lazy series. @@ -1233,6 +1234,7 @@ def _test_revert(self, **options): # we want to test at least 2 elements tester.assertGreater(count, 1, msg="only %s elements in %s.some_elements() have a compositional inverse" % (count, self)) + class LazyLaurentSeriesRing(LazySeriesRing): r""" The ring of lazy Laurent series. @@ -3040,6 +3042,7 @@ def some_elements(self): ###################################################################### + class LazySymmetricFunctions(LazyCompletionGradedAlgebra): """ The ring of lazy symmetric functions. @@ -3417,6 +3420,7 @@ def _monomial(self, c, n): except (ValueError, TypeError): return '({})/{}^{}'.format(self.base_ring()(c), n, self.variable_name()) + def _skip_leading_zeros(iterator): """ Return an iterator which discards all leading zeros. diff --git a/src/sage/rings/monomials.py b/src/sage/rings/monomials.py index ed154ab8c06..b10d599b6b3 100644 --- a/src/sage/rings/monomials.py +++ b/src/sage/rings/monomials.py @@ -1,5 +1,6 @@ "Monomials" + def _monomials(gens, R, n, i): """ Given two lists ``gens`` and ``n`` of exactly the same length, diff --git a/src/sage/rings/polynomial/complex_roots.py b/src/sage/rings/polynomial/complex_roots.py index 0c94bac6035..42cf47cad86 100644 --- a/src/sage/rings/polynomial/complex_roots.py +++ b/src/sage/rings/polynomial/complex_roots.py @@ -90,6 +90,7 @@ def interval_roots(p, rts, prec): return irts + def intervals_disjoint(intvs): """ Given a list of complex intervals, check whether they are pairwise diff --git a/src/sage/rings/polynomial/ideal.py b/src/sage/rings/polynomial/ideal.py index 9eba00860b5..bf575cb0339 100644 --- a/src/sage/rings/polynomial/ideal.py +++ b/src/sage/rings/polynomial/ideal.py @@ -19,6 +19,7 @@ from sage.rings.ideal import Ideal_pid + class Ideal_1poly_field(Ideal_pid): """ An ideal in a univariate polynomial ring over a field. diff --git a/src/sage/rings/polynomial/laurent_polynomial_ideal.py b/src/sage/rings/polynomial/laurent_polynomial_ideal.py index ae21901fee1..0403526ae15 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ideal.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ideal.py @@ -26,6 +26,7 @@ from sage.structure.richcmp import op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE from sage.arith.misc import GCD + class LaurentPolynomialIdeal( Ideal_generic ): def __init__(self, ring, gens, coerce=True, hint=None): r""" diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index 40b09bbfb6e..2e4cf5ce6ea 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -77,6 +77,8 @@ def is_LaurentPolynomialRing(R): _cache = {} + + def LaurentPolynomialRing(base_ring, *args, **kwds): r""" Return the globally unique univariate or multivariate Laurent polynomial @@ -251,6 +253,7 @@ def LaurentPolynomialRing(base_ring, *args, **kwds): _cache[R] = P return P + def _split_dict_(D, indices, group_by=None): r""" Split the dictionary ``D`` by ``indices`` and ``group_by``. @@ -331,6 +334,7 @@ def extract(T, indices): else: return result + def _split_laurent_polynomial_dict_(P, M, d): r""" Helper function for splitting a multivariate Laurent polynomial @@ -391,6 +395,7 @@ def value(d, R): return sum(P({k: 1}) * value(v, P) for k, v in D.items()).monomial_coefficients() + def from_fraction_field(L, x): r""" Helper function to construct a Laurent polynomial from an element of its diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py index b4f4f13289e..d9984a656b1 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py @@ -30,6 +30,7 @@ from sage.structure.parent import Parent from sage.combinat.integer_vector import IntegerVectors + class LaurentPolynomialRing_generic(CommutativeRing, Parent): """ Laurent polynomial ring (base class). diff --git a/src/sage/rings/polynomial/msolve.py b/src/sage/rings/polynomial/msolve.py index fb22236fba9..d261bfd70b9 100644 --- a/src/sage/rings/polynomial/msolve.py +++ b/src/sage/rings/polynomial/msolve.py @@ -33,6 +33,7 @@ from sage.rings.real_mpfi import RealIntervalField_class, RealIntervalField from sage.structure.sequence import Sequence + def _run_msolve(ideal, options): r""" Internal utility function @@ -63,6 +64,7 @@ def _run_msolve(ideal, options): return msolve_out.stdout + def groebner_basis_degrevlex(ideal, proof=True): r""" Compute a degrevlex Gröbner basis using msolve @@ -111,6 +113,7 @@ def groebner_basis_degrevlex(ideal, proof=True): gbasis = sage_eval(msolve_out[:-2], locals=drlpolring.gens_dict()) return Sequence(gbasis) + def variety(ideal, ring, *, proof=True): r""" Compute the variety of a zero-dimensional ideal using msolve. diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 222da435df2..8e358652be3 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -450,6 +450,7 @@ def _groebner_basis_magma(self, deg_bound=None, prot=False, magma=magma_default) B = PolynomialSequence([R(e) for e in mgb], R, immutable=True) return B + class MPolynomialIdeal_singular_base_repr: @require_field def syzygy_module(self): @@ -3493,6 +3494,7 @@ def _reduce_using_macaulay2(self, f): R = self.ring() return R(k) + class NCPolynomialIdeal(MPolynomialIdeal_singular_repr, Ideal_nc): def __init__(self, ring, gens, coerce=True, side='left'): r""" diff --git a/src/sage/rings/polynomial/multi_polynomial_sequence.py b/src/sage/rings/polynomial/multi_polynomial_sequence.py index 37381c084ac..ff1ec275633 100644 --- a/src/sage/rings/polynomial/multi_polynomial_sequence.py +++ b/src/sage/rings/polynomial/multi_polynomial_sequence.py @@ -377,6 +377,7 @@ def PolynomialSequence(arg1, arg2=None, immutable=False, cr=False, cr_str=None): elif K.degree() > 1: return PolynomialSequence_gf2e(parts, ring, immutable=immutable, cr=cr, cr_str=cr_str) + class PolynomialSequence_generic(Sequence_generic): def __init__(self, parts, ring, immutable=False, cr=False, cr_str=None): """ @@ -1257,6 +1258,7 @@ def is_groebner(self, singular=singular): """ return self.ideal().basis_is_groebner() + class PolynomialSequence_gf2(PolynomialSequence_generic): r""" Polynomial Sequences over `\GF{2}`. diff --git a/src/sage/rings/polynomial/ore_function_element.py b/src/sage/rings/polynomial/ore_function_element.py index fd871fa3b76..d858838f53c 100644 --- a/src/sage/rings/polynomial/ore_function_element.py +++ b/src/sage/rings/polynomial/ore_function_element.py @@ -715,6 +715,7 @@ def _call_(self, x): return numerator.leading_coefficient() / denominator.leading_coefficient() raise TypeError(f"{x} is not a constant function") + class OreFunctionBaseringInjection(Morphism): r""" Representation of the canonical homomorphism from a field `k` into a Ore diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index c3df26200e2..7bbd4e611a9 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -1049,6 +1049,7 @@ def number_of_terms(self): """ return len(self.__coeffs) + class Polynomial_generic_domain(Polynomial, IntegralDomainElement): def __init__(self, parent, is_gen=False, construct=False): Polynomial.__init__(self, parent, is_gen=is_gen) @@ -1082,6 +1083,7 @@ def is_unit(self): return False return self[0].is_unit() + class Polynomial_generic_field(Polynomial_singular_repr, Polynomial_generic_domain, EuclideanDomainElement): @@ -1588,6 +1590,7 @@ def _roots(self, secure, minval, hint): class Polynomial_generic_dense_cdv(Polynomial_generic_dense_inexact, Polynomial_generic_cdv): pass + class Polynomial_generic_sparse_cdv(Polynomial_generic_sparse, Polynomial_generic_cdv): pass diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index e12977e8464..027a8997067 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -262,6 +262,7 @@ def create_object(self, version, key): PolynomialQuotientRing = PolynomialQuotientRingFactory("PolynomialQuotientRing") + def is_PolynomialQuotientRing(x): from sage.misc.superseded import deprecation deprecation(38266, diff --git a/src/sage/rings/polynomial/term_order.py b/src/sage/rings/polynomial/term_order.py index 1bed10ba867..cd5cad00f8f 100644 --- a/src/sage/rings/polynomial/term_order.py +++ b/src/sage/rings/polynomial/term_order.py @@ -539,6 +539,7 @@ 'block' : block_description, } + class TermOrder(SageObject): """ A term order. diff --git a/src/sage/rings/qqbar_decorators.py b/src/sage/rings/qqbar_decorators.py index 7343a0b9b08..9abca887218 100644 --- a/src/sage/rings/qqbar_decorators.py +++ b/src/sage/rings/qqbar_decorators.py @@ -14,6 +14,7 @@ from sage.misc.decorators import decorator_keywords, sage_wraps + @decorator_keywords def handle_AA_and_QQbar(func): r""" diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index 4cf3979265f..f98322c2183 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -1545,6 +1545,7 @@ def _contains_(self, other): J = R.cover_ring().ideal(Igens) return other.lift() in J + class QuotientRingIdeal_principal(ideal.Ideal_principal, QuotientRingIdeal_generic): r""" Specialized class for principal quotient-ring ideals. diff --git a/src/sage/rings/ring_extension_homset.py b/src/sage/rings/ring_extension_homset.py index d2c13a11f0e..1ba55906d9c 100644 --- a/src/sage/rings/ring_extension_homset.py +++ b/src/sage/rings/ring_extension_homset.py @@ -20,6 +20,7 @@ from sage.rings.homset import RingHomset_generic from sage.rings.ring_extension_morphism import RingExtensionHomomorphism + class RingExtensionHomset(RingHomset_generic): r""" A generic class for homsets between ring extensions. From 20f7e3f0b46bd3cd4220efb53ba2a5cac6132aa0 Mon Sep 17 00:00:00 2001 From: Giorgos Mousa Date: Sat, 26 Oct 2024 22:51:26 +0300 Subject: [PATCH 49/82] `build/pkgs/matroid_database`: mark as math --- build/pkgs/matroid_database/math | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 build/pkgs/matroid_database/math diff --git a/build/pkgs/matroid_database/math b/build/pkgs/matroid_database/math new file mode 100644 index 00000000000..e69de29bb2d From 86088b599a1138c183c216de5dfa2b938bfde218 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 27 Oct 2024 01:37:39 +0200 Subject: [PATCH 50/82] Fix test if SAGE_ROOT is not defined --- src/sage/env.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/env.py b/src/sage/env.py index c6fb123cc72..2be366c6f3e 100644 --- a/src/sage/env.py +++ b/src/sage/env.py @@ -11,7 +11,7 @@ sage: module_name = "sage.all" # hide .all import from the linter sage: cmd = f"from {module_name} import SAGE_ROOT, SAGE_LOCAL;" sage: cmd += "from os.path import samefile;" - sage: cmd += f"s1 = samefile(SAGE_ROOT, '{SAGE_ROOT}');" + sage: cmd += f"s1 = samefile(SAGE_ROOT, '{SAGE_ROOT}') if SAGE_ROOT else True;" sage: cmd += f"s2 = samefile(SAGE_LOCAL, '{SAGE_LOCAL}');" sage: cmd += "print(s1 and s2);" sage: out = check_output([sys.executable, "-c", cmd], env=env).decode().strip() # long time From 8530f6d1908bf7215b1a3b7ce8fe9cc408839d51 Mon Sep 17 00:00:00 2001 From: Gareth Ma Date: Sun, 27 Oct 2024 01:27:19 +0100 Subject: [PATCH 51/82] Make comments more explicit (review) Co-authored-by: Sebastian Spindler --- src/sage/schemes/elliptic_curves/ell_point.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/ell_point.py b/src/sage/schemes/elliptic_curves/ell_point.py index e420a43a5ab..f3e2c6225ad 100755 --- a/src/sage/schemes/elliptic_curves/ell_point.py +++ b/src/sage/schemes/elliptic_curves/ell_point.py @@ -2611,7 +2611,8 @@ def _has_order_at_least(self, bound, *, attempts=999): else: K, E, P = QQ, self.curve(), self poly = lambda elt: QQ['x'](elt) - # Mazur + # Mazur / Ogg's torsion conjecture + # Torsion points can only have order <= 12, so order of > 12 -> infinite order bound = min(bound, 12 + 1) assert P.curve() is E From 68196350db3bbd771576cdaa9ee8b62aa356b624 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sun, 27 Oct 2024 09:38:12 +0700 Subject: [PATCH 52/82] Minor change --- src/sage/modules/vector_modn_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/modules/vector_modn_dense.pyx b/src/sage/modules/vector_modn_dense.pyx index 4c7d933321e..e21360964ba 100644 --- a/src/sage/modules/vector_modn_dense.pyx +++ b/src/sage/modules/vector_modn_dense.pyx @@ -184,7 +184,7 @@ cdef class Vector_modn_dense(free_module_element.FreeModuleElement): """ cdef Py_ssize_t i cdef mod_int a - if isinstance(x, xrange): + if isinstance(x, range): x = tuple(x) if isinstance(x, (list, tuple)): if len(x) != self._degree: From 246955a2759e70c6916bdf0fc456210bd589477f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 27 Oct 2024 09:38:06 +0100 Subject: [PATCH 53/82] remove some unused variables --- src/sage/algebras/down_up_algebra.py | 4 +--- src/sage/algebras/lie_algebras/affine_lie_algebra.py | 5 +---- src/sage/algebras/lie_algebras/center_uea.py | 1 - src/sage/algebras/lie_algebras/classical_lie_algebra.py | 1 - src/sage/categories/filtered_modules_with_basis.py | 1 - .../categories/finite_dimensional_algebras_with_basis.py | 1 - .../finite_dimensional_lie_algebras_with_basis.py | 8 ++++---- src/sage/categories/simplicial_sets.py | 3 --- src/sage/categories/triangular_kac_moody_algebras.py | 1 - src/sage/geometry/lattice_polytope.py | 2 +- src/sage/homology/homology_vector_space_with_basis.py | 3 +-- src/sage/knots/knotinfo.py | 1 - src/sage/libs/gap/test_long.py | 2 +- src/sage/matroids/matroids_plot_helpers.py | 1 - src/sage/modular/drinfeld_modform/ring.py | 2 -- src/sage/modules/with_basis/representation.py | 5 ++--- .../drinfeld_modules/charzero_drinfeld_module.py | 1 - src/sage/rings/lazy_series_ring.py | 1 - src/sage/schemes/curves/projective_curve.py | 1 - 19 files changed, 11 insertions(+), 33 deletions(-) diff --git a/src/sage/algebras/down_up_algebra.py b/src/sage/algebras/down_up_algebra.py index 1bb35730014..48e24c4fa2d 100644 --- a/src/sage/algebras/down_up_algebra.py +++ b/src/sage/algebras/down_up_algebra.py @@ -806,7 +806,6 @@ def is_weight_vector(self): P = self.parent() R = P.base_ring() - weights = P._weights def get_wt(n): if not n: @@ -853,9 +852,8 @@ def weight(self): P = self.parent() R = P.base_ring() V = FreeModule(R, 2) - weights = P._weights it = iter(self._monomial_coefficients) n = next(it) if not n: return V([P._weights[0], R.zero()]) - return V([P._weights[n], P._weights[n-1]]) + return V([P._weights[n], P._weights[n - 1]]) diff --git a/src/sage/algebras/lie_algebras/affine_lie_algebra.py b/src/sage/algebras/lie_algebras/affine_lie_algebra.py index a637322e4d7..02fefb8e623 100644 --- a/src/sage/algebras/lie_algebras/affine_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/affine_lie_algebra.py @@ -838,10 +838,9 @@ def _test_classical_subalgebra(self, **options): tester = self._tester(**options) B = self.basis() roots = set(self._g._Q.roots()) - ac = list(self._g._Q.simple_coroots()) from sage.misc.misc import some_tuples for r, s in some_tuples(roots, 2, tester._max_runs): - ret = B[r,0].bracket(B[s,0]) + ret = B[r, 0].bracket(B[s, 0]) if r + s in roots: tester.assertEqual(list(ret.support()), [(r+s, 0)], f"obtained [{r}, {s}] == {ret}") elif r == -s: @@ -1125,7 +1124,6 @@ def __init__(self, cartan_type): Q = finite_ct.relabel({n-i: i for i in range(n)}).root_system().root_lattice() self._roots = tuple(Q.roots()) self._ac = tuple(Q.simple_coroots()) - CP = cartesian_product([range(3)] * n) if cartan_type.rank() == 2: self._short_roots = self._roots + tuple(2*r for r in Q.roots()) else: @@ -1200,7 +1198,6 @@ def __iter__(self): finite_ct = finite_ct.relabel({n-i: i for i in range(n)}) else: finite_ct = self._cartan_type.classical() - Q = finite_ct.root_system().root_lattice() P = self._facade_for[0] for i in ZZ: if i % 2: diff --git a/src/sage/algebras/lie_algebras/center_uea.py b/src/sage/algebras/lie_algebras/center_uea.py index 54057bc9735..2799356a4c4 100644 --- a/src/sage/algebras/lie_algebras/center_uea.py +++ b/src/sage/algebras/lie_algebras/center_uea.py @@ -419,7 +419,6 @@ def __iter__(self): n = len(self._gen_degrees) wts = sorted(self._gen_degrees.values(), reverse=True) while True: - total = 0 for exps in intvecwt_iterator(deg, wts): yield self.element_class(self, {n-1-i: e for i, e in enumerate(exps) if e}) deg += 1 diff --git a/src/sage/algebras/lie_algebras/classical_lie_algebra.py b/src/sage/algebras/lie_algebras/classical_lie_algebra.py index 15badc6881f..e4e2eb75e68 100644 --- a/src/sage/algebras/lie_algebras/classical_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/classical_lie_algebra.py @@ -2359,7 +2359,6 @@ def _construct_struct_coeffs(self, R, p_roots): for ii, ca in r._monomial_coefficients.items() for jj, cb in s._monomial_coefficients.items()) s_coeffs[r, s] = {r+s: coeff} - ht = sum(r.coefficients()) + sum(s.coefficients()) s_coeffs[-r, -s] = {-r-s: -coeff} if r - s in p_roots_set or s - r in p_roots_set: coeff = R.prod((-1)**(ca*cb) if (ii, jj) in self._epsilon or ii == jj else 1 diff --git a/src/sage/categories/filtered_modules_with_basis.py b/src/sage/categories/filtered_modules_with_basis.py index 454f31e5070..256203abc3f 100644 --- a/src/sage/categories/filtered_modules_with_basis.py +++ b/src/sage/categories/filtered_modules_with_basis.py @@ -1197,7 +1197,6 @@ def hilbert_series(self, prec=None): from collections import defaultdict from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - R = self.base_ring() PR = PolynomialRing(ZZ, 't') dims = defaultdict(ZZ) for b in self.basis(): diff --git a/src/sage/categories/finite_dimensional_algebras_with_basis.py b/src/sage/categories/finite_dimensional_algebras_with_basis.py index f4a31b557f9..187fe3d675a 100644 --- a/src/sage/categories/finite_dimensional_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_algebras_with_basis.py @@ -207,7 +207,6 @@ def root_fcn(s, x): s = 1 n = self.dimension() B = [b.on_left_matrix() for b in self.basis()] - I = B[0].parent().one() while s <= n: # we use that p_{AB}(x) = p_{BA}(x) here data = [[None]*(len(B)+1) for _ in B] diff --git a/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py b/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py index 6f27e3fa33d..4e5212885ce 100644 --- a/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py @@ -605,13 +605,13 @@ def normalizer_basis(self, S): sc[k[1], k[0]] = -v X = self.basis().keys() d = len(X) - ret = [] t = m.nrows() c_mat = matrix(self.base_ring(), - [[sum(m[i,j] * sc[x,xp][k] for j, xp in enumerate(X) - if (x, xp) in sc) + [[sum(m[i, j] * sc[x, xp][k] + for j, xp in enumerate(X) if (x, xp) in sc) for x in X] - + [0]*(i*t) + [-m[j,k] for j in range(t)] + [0]*((t-i-1)*t) + + [0]*(i*t) + [-m[j, k] for j in range(t)] + + [0]*((t-i-1)*t) for i in range(t) for k in range(d)]) C = c_mat.right_kernel().basis_matrix() return [self.from_vector(c[:d]) for c in C] diff --git a/src/sage/categories/simplicial_sets.py b/src/sage/categories/simplicial_sets.py index 65e526d8688..76030be831b 100644 --- a/src/sage/categories/simplicial_sets.py +++ b/src/sage/categories/simplicial_sets.py @@ -499,7 +499,6 @@ def covering_map(self, character): for g in G: cell = AbstractSimplex(d, name="({}, {})".format(s, g)) cells_dict[(s, g)] = cell - fd = [] faces = self.faces(s) f0 = faces[0] for h in G: @@ -612,7 +611,6 @@ def _canonical_twisting_operator(self): Quotient of Univariate Laurent Polynomial Ring in F1 over Integer Ring by the ideal (-1 + F1^2) """ G, d = self._universal_cover_dict() - phi = G.abelianization_map() abelG, R, I, images = G.abelianization_to_algebra(ZZ) QRP = R.quotient_ring(I) res = {} @@ -908,7 +906,6 @@ def twisted_homology(self, n, reduced=False): singred = singular_function("reduce") singlift = singular_function("lift") G, d = self._universal_cover_dict() - phi = G.abelianization_map() abelG, R, I, images = G.abelianization_to_algebra(ZZ) CC = self.twisted_chain_complex() M1 = CC.differential(n).T diff --git a/src/sage/categories/triangular_kac_moody_algebras.py b/src/sage/categories/triangular_kac_moody_algebras.py index d6541107a0f..26b94d34b9d 100644 --- a/src/sage/categories/triangular_kac_moody_algebras.py +++ b/src/sage/categories/triangular_kac_moody_algebras.py @@ -365,7 +365,6 @@ def _transpose_basis_mapping(self): alphacheck[1]: alphacheck[1], alphacheck[2]: alphacheck[2]} """ - Q = self.cartan_type().root_system().root_lattice() K = self.basis().keys() deg_map = {} ret = {} diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 857eadba882..1af31240182 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -591,7 +591,7 @@ def _sage_input_(self, sib, coerced): """ if self._ambient is not self: raise NotImplementedError - data = self._vertices + _ = self._vertices return sib.name('LatticePolytope')(sib(self._vertices), compute_vertices=False) def __contains__(self, point): diff --git a/src/sage/homology/homology_vector_space_with_basis.py b/src/sage/homology/homology_vector_space_with_basis.py index 64d3186fea7..60f2ccc77f2 100644 --- a/src/sage/homology/homology_vector_space_with_basis.py +++ b/src/sage/homology/homology_vector_space_with_basis.py @@ -690,10 +690,9 @@ def _acted_upon_(self, a, self_on_left): if m <= n: return self.parent().zero() - if not self_on_left: # i.e., module element on left + if not self_on_left: # i.e., module element on left a = a.antipode() P = self.parent() - B = list(P.basis(m-n)) return P._from_dict({x.support()[0]: self.eval(a * x) for x in sorted(self.parent().dual().basis(m-n))}) diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index b0ff60eefa5..8c246ba8097 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -1353,7 +1353,6 @@ def cosmetic_crossing_conjecture_verified(self): return True if not cosmetic_crossing or cosmetic_crossing == 'Unknown': return False - verified = not knotinfo_bool(cosmetic_crossing) if not knotinfo_bool(cosmetic_crossing): return True raise AssertionError(f'{self} is a counterexample to the cosmetic crossing conjecture') diff --git a/src/sage/libs/gap/test_long.py b/src/sage/libs/gap/test_long.py index 262db5ad287..c92ff9d5223 100644 --- a/src/sage/libs/gap/test_long.py +++ b/src/sage/libs/gap/test_long.py @@ -15,7 +15,7 @@ def test_loop_1(): """ libgap.collect() for i in range(10000): - G = libgap.CyclicGroup(2) + _ = libgap.CyclicGroup(2) def test_loop_2(): diff --git a/src/sage/matroids/matroids_plot_helpers.py b/src/sage/matroids/matroids_plot_helpers.py index 5f09905844b..8cfea95f12e 100644 --- a/src/sage/matroids/matroids_plot_helpers.py +++ b/src/sage/matroids/matroids_plot_helpers.py @@ -859,7 +859,6 @@ def geomrep(M1, B1=None, lineorders1=None, pd=None, sp=False): pl = [list(x) for x in pts2.values()] lims = tracklims([None, None, None, None], [pt[0] for pt in pl], [pt[1] for pt in pl]) - j = 0 for ll in trilines: if len(ll) >= 3: ptsx, ptsy, x_i, y_i = createline(pts2, ll, lineorders1) diff --git a/src/sage/modular/drinfeld_modform/ring.py b/src/sage/modular/drinfeld_modform/ring.py index c383cf94266..43c41058fe2 100644 --- a/src/sage/modular/drinfeld_modform/ring.py +++ b/src/sage/modular/drinfeld_modform/ring.py @@ -581,8 +581,6 @@ def coefficient_forms(self, a=None): ... TypeError: unable to convert a to an element in Fq[T] """ - K = self._base_ring - T = K.gen() if a is None: return [self._generator_coefficient_form(i) for i in range(1, self.rank() + 1)] diff --git a/src/sage/modules/with_basis/representation.py b/src/sage/modules/with_basis/representation.py index 7e67d3ec750..5271c7a6b38 100644 --- a/src/sage/modules/with_basis/representation.py +++ b/src/sage/modules/with_basis/representation.py @@ -685,8 +685,8 @@ def subrepresentation(self, gens, check=True, already_echelonized=False, 5 """ if not is_closed and gens: - R = self.base_ring() - repr_mats = [self.representation_matrix(g) for g in self._semigroup.gens()] + repr_mats = [self.representation_matrix(g) + for g in self._semigroup.gens()] amb_dim = self.dimension() SM = matrix([v._vector_() for v in gens]) SM.echelonize() @@ -2892,7 +2892,6 @@ def __init__(self, V, shape): keys = list(V.basis().keys()) ambient = tensor([V]*d) - I = ambient.indices() cla = SymmetricGroupAlgebra(R, SymmetricGroup(d)).young_symmetrizer(shape) mc = cla.monomial_coefficients(copy=False) gens = [ambient.sum_of_terms((tuple([k[i-1] for i in p.tuple()]), coeff) diff --git a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py index d183848f296..e38bb1e583f 100644 --- a/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py +++ b/src/sage/rings/function_field/drinfeld_modules/charzero_drinfeld_module.py @@ -317,7 +317,6 @@ def logarithm(self, name='z'): True """ L = LazyPowerSeriesRing(self._base, name) - zero = self._base.zero() q = self._Fq.cardinality() def coeff_log(k): diff --git a/src/sage/rings/lazy_series_ring.py b/src/sage/rings/lazy_series_ring.py index ee3e463e988..e4317161a38 100644 --- a/src/sage/rings/lazy_series_ring.py +++ b/src/sage/rings/lazy_series_ring.py @@ -2612,7 +2612,6 @@ def taylor(self, f): BR = R.base_ring() args = f.arguments() subs = {str(va): ZZ.zero() for va in args} - gens = R.gens() ell = len(subs) from sage.combinat.integer_vector import integer_vectors_nk_fast_iter from sage.arith.misc import factorial diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index 77c94b61c04..0729c5a98ad 100755 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -2521,7 +2521,6 @@ def _map_from_function_field(self): sage: C.function(C._map_from_function_field(f)) == f True """ - F = self._function_field S = self.ambient_space().coordinate_ring() phi = self._open_affine._nonsingular_model[2] i = self._open_affine_index From e15036f84877884ecc811905f6bb2d76fe852132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 27 Oct 2024 10:26:12 +0100 Subject: [PATCH 54/82] some spaces around % in pyx files --- .../coding/codecan/autgroup_can_label.pyx | 2 +- .../rigged_partition.pyx | 12 +++--- src/sage/groups/group.pyx | 2 +- .../perm_gps/partn_ref/data_structures.pyx | 38 +++++++++---------- .../perm_gps/partn_ref/refinement_python.pyx | 2 +- .../groups/perm_gps/permgroup_element.pyx | 4 +- .../semimonomial_transformation.pyx | 4 +- src/sage/libs/coxeter3/coxeter.pyx | 3 +- src/sage/libs/eclib/homspace.pyx | 2 +- src/sage/libs/eclib/mat.pyx | 2 +- src/sage/libs/eclib/mwrank.pyx | 2 +- src/sage/libs/eclib/newforms.pyx | 2 +- src/sage/libs/giac/giac.pyx | 29 +++++++------- src/sage/libs/libecm.pyx | 2 +- src/sage/libs/pari/convert_sage.pyx | 2 +- src/sage/matrix/misc.pyx | 6 +-- src/sage/misc/c3_controlled.pyx | 4 +- src/sage/misc/cachefunc.pyx | 6 +-- src/sage/misc/constant_function.pyx | 2 +- src/sage/misc/function_mangling.pyx | 2 +- src/sage/misc/lazy_list.pyx | 4 +- src/sage/misc/persist.pyx | 4 +- src/sage/modules/free_module_element.pyx | 4 +- src/sage/modules/vector_integer_dense.pyx | 2 +- src/sage/modules/vector_mod2_dense.pyx | 8 ++-- src/sage/modules/vector_modn_sparse.pyx | 4 +- src/sage/modules/vector_rational_sparse.pyx | 2 +- .../modules/with_basis/indexed_element.pyx | 15 ++++---- .../numerical/backends/glpk_graph_backend.pyx | 4 +- src/sage/plot/complex_plot.pyx | 2 +- src/sage/plot/plot3d/base.pyx | 12 +++--- src/sage/plot/plot3d/shapes.pyx | 6 +-- src/sage/rings/complex_interval.pyx | 10 ++--- src/sage/sets/finite_set_map_cy.pyx | 2 +- src/sage/stats/time_series.pyx | 6 +-- src/sage/structure/coerce.pyx | 4 +- src/sage/structure/coerce_actions.pyx | 6 +-- 37 files changed, 112 insertions(+), 111 deletions(-) diff --git a/src/sage/coding/codecan/autgroup_can_label.pyx b/src/sage/coding/codecan/autgroup_can_label.pyx index e54e64a20a9..b6496249786 100644 --- a/src/sage/coding/codecan/autgroup_can_label.pyx +++ b/src/sage/coding/codecan/autgroup_can_label.pyx @@ -223,7 +223,7 @@ class LinearCodeAutGroupCanLabel: from sage.coding.linear_code import LinearCode, AbstractLinearCode if not isinstance(C, AbstractLinearCode): - raise TypeError("%s is not a linear code"%C) + raise TypeError("%s is not a linear code" % C) self.C = C mat = C.generator_matrix() diff --git a/src/sage/combinat/rigged_configurations/rigged_partition.pyx b/src/sage/combinat/rigged_configurations/rigged_partition.pyx index 84d98c90f3e..c8dc350bd73 100644 --- a/src/sage/combinat/rigged_configurations/rigged_partition.pyx +++ b/src/sage/combinat/rigged_configurations/rigged_partition.pyx @@ -191,7 +191,7 @@ cdef class RiggedPartition(SageObject): from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations if RiggedConfigurations.options.convention == 'English': - ret_string += "\\cline{2-%s} "%(1+num_cols) + latex(self.vacancy_numbers[0]) + ret_string += "\\cline{2-%s} " % (1+num_cols) + latex(self.vacancy_numbers[0]) for i, row_len in enumerate(self._list): ret_string += " &" + "\\phantom{|}&"*row_len @@ -210,7 +210,7 @@ cdef class RiggedPartition(SageObject): ret_string += "\n\\end{array}\n}" else: for i, row_len in enumerate(reversed(self._list)): - ret_string += "\\cline{2-%s} "%(1 + row_len) + latex(self.vacancy_numbers[-i-1]) + ret_string += "\\cline{2-%s} " % (1 + row_len) + latex(self.vacancy_numbers[-i-1]) ret_string += " &" + "\\phantom{|}&"*row_len if num_cols == row_len: @@ -220,7 +220,7 @@ cdef class RiggedPartition(SageObject): ret_string += "}{l}{" + latex(self.rigging[-i-1]) + "}" ret_string += " \\\\\n" - ret_string += "\\cline{2-%s}\n\\end{array}\n}"%(1 + num_cols) + ret_string += "\\cline{2-%s}\n\\end{array}\n}" % (1 + num_cols) return ret_string @@ -645,7 +645,7 @@ cdef class RiggedPartitionTypeB(RiggedPartition): ret_string = "{\n\\begin{array}[t]{r|" + "c|"*num_cols + "l}\n" if RiggedConfigurations.options.convention == 'English': - ret_string += "\\cline{2-%s} "%(1+num_cols) + latex(self.vacancy_numbers[0]) + ret_string += "\\cline{2-%s} " % (1+num_cols) + latex(self.vacancy_numbers[0]) for i, row_len in enumerate(self._list): ret_string += " &" + box_str*row_len @@ -663,7 +663,7 @@ cdef class RiggedPartitionTypeB(RiggedPartition): ret_string += "\n\\end{array}\n}" else: for i, row_len in enumerate(reversed(self._list)): - ret_string += "\\cline{2-%s} "%(1 + row_len) + ret_string += "\\cline{2-%s} " % (1 + row_len) ret_string += latex(self.vacancy_numbers[-i-1]) ret_string += " &" + box_str*row_len @@ -674,6 +674,6 @@ cdef class RiggedPartitionTypeB(RiggedPartition): ret_string += "}{l}{" + latex(self.rigging[-i-1]) + "}" ret_string += " \\\\\n" - ret_string += "\\cline{2-%s}\n\\end{array}\n}"%(1 + num_cols) + ret_string += "\\cline{2-%s}\n\\end{array}\n}" % (1 + num_cols) return ret_string diff --git a/src/sage/groups/group.pyx b/src/sage/groups/group.pyx index b5047594a9c..d004cdf98e2 100644 --- a/src/sage/groups/group.pyx +++ b/src/sage/groups/group.pyx @@ -110,7 +110,7 @@ cdef class Group(Parent): if not isinstance(category, tuple): category = (category,) if not any(cat.is_subcategory(Groups()) for cat in category): - raise ValueError("%s is not a subcategory of %s"%(category, Groups())) + raise ValueError("%s is not a subcategory of %s" % (category, Groups())) Parent.__init__(self, base=base, category=category) def is_abelian(self): diff --git a/src/sage/groups/perm_gps/partn_ref/data_structures.pyx b/src/sage/groups/perm_gps/partn_ref/data_structures.pyx index 28672d00038..919deebd0de 100644 --- a/src/sage/groups/perm_gps/partn_ref/data_structures.pyx +++ b/src/sage/groups/perm_gps/partn_ref/data_structures.pyx @@ -145,9 +145,9 @@ def OP_represent(int n, merges, perm): print("Finding:") for i in range(n): j = OP_find(OP, i) - s = "%d -> %d"%(i, j) + s = "%d -> %d" % (i, j) if i == j: - s += ", root: size=%d, mcr=%d, rank=%d"%\ + s += ", root: size=%d, mcr=%d, rank=%d" % \ (OP.size[i], OP.mcr[i], OP.rank[i]) print(s) print("Allocating array to test merge_perm.") @@ -165,9 +165,9 @@ def OP_represent(int n, merges, perm): print("Finding:") for i in range(n): j = OP_find(OP, i) - s = "%d -> %d"%(i, j) + s = "%d -> %d" % (i, j) if i == j: - s += ", root: size=%d, mcr=%d, rank=%d"%\ + s += ", root: size=%d, mcr=%d, rank=%d" % \ (OP.size[i], OP.mcr[i], OP.rank[i]) print(s) print("Deallocating OrbitPartition.") @@ -474,7 +474,7 @@ def PS_represent(partition, splits): print(PS.entries[i], PS.levels[i], i, n) good = False if not (PS.entries[n-1] == n-1 and PS.levels[n-1] == -1): - print("Failed at i = %d!"%(n-1)) + print("Failed at i = %d!" % (n-1)) good = False if not PS.degree == n or not PS.depth == 0: print("Incorrect degree or depth!") @@ -486,8 +486,8 @@ def PS_represent(partition, splits): print("Creating PartitionStack from partition %s." % partition) PS = PS_from_list(partition) print("PartitionStack's data:") - print("entries -> %s"%[PS.entries[i] for i in range(n)]) - print("levels -> %s"%[PS.levels[i] for i in range(n)]) + print("entries -> %s" % [PS.entries[i] for i in range(n)]) + print("levels -> %s" % [PS.levels[i] for i in range(n)]) print("depth = %d, degree = %d" % (PS.depth,PS.degree)) PS_print(PS) print("Checking PS_is_discrete:") @@ -506,7 +506,7 @@ def PS_represent(partition, splits): good = True for i in range(n): if PS.entries[i] != PS2.entries[i] or PS.levels[i] != PS2.levels[i]: - print("Failed at i = %d!"%i) + print("Failed at i = %d!" % i) good = False if PS.degree != PS2.degree or PS.depth != PS2.depth: print("Failure with degree or depth!") @@ -517,7 +517,7 @@ def PS_represent(partition, splits): PS_clear(PS2) PS_print(PS2) for s in splits: - print("Splitting point %d from original:"%s) + print("Splitting point %d from original:" % s) print(PS_split_point(PS, s)) PS_print(PS) print("Getting permutation from PS2->PS:") @@ -528,7 +528,7 @@ def PS_represent(partition, splits): print("Finding first smallest:") bitset_init(b, n) i = PS_first_smallest(PS, b) - print("Minimal element is %d, bitset is:"%i) + print("Minimal element is %d, bitset is:" % i) print(bitset_string(b)) bitset_free(b) print("Finding element 1:") @@ -1187,7 +1187,7 @@ cdef bint SC_is_giant(int n, int num_perms, int *perms, float p, bitset_t suppor # get a bit lost in the group, so our random elements are more random: SC_identify(perm, n) for i from 0 <= i < 10: - SC_mult_perms(perm, perm, perms + n*(rand()%num_perms), n) + SC_mult_perms(perm, perm, perms + n*(rand() % num_perms), n) # look for elements with cycles of prime length q, m/2 < q < m-2 num_steps = ceil(-log(1-p)*log(m)/log(2)) @@ -1203,7 +1203,7 @@ cdef bint SC_is_giant(int n, int num_perms, int *perms, float p, bitset_t suppor sig_free(perm) OP_dealloc(OP) return True - SC_mult_perms(perm, perm, perms + n*(rand()%num_perms), n) + SC_mult_perms(perm, perm, perms + n*(rand() % num_perms), n) OP_dealloc(OP) sig_free(perm) return False @@ -1421,21 +1421,21 @@ def SC_test_list_perms(list L, int n, int limit, bint gap, bint limit_complain, m = bitset_len(giant_support) from sage.arith.misc import factorial if not (order == factorial(m) or order == factorial(m)/2): - print("SC_is_giant failed: %s %s"%(str(L), order)) + print("SC_is_giant failed: %s %s" % (str(L), order)) raise AssertionError if order == factorial(n): SC_dealloc(SC) SC = SC_symmetric_group(n) SC_order(SC,0,order.value) if not order == factorial(n): - print("SC_symmetric_group failed: %s %s"%(str(L), order)) + print("SC_symmetric_group failed: %s %s" % (str(L), order)) raise AssertionError elif order == factorial(n)/2: SC_dealloc(SC) SC = SC_alternating_group(n) SC_order(SC,0,order.value) if not order == factorial(n)/2: - print("SC_alternating_group failed: %s %s"%(str(L), order)) + print("SC_alternating_group failed: %s %s" % (str(L), order)) raise AssertionError order2 = Integer(0) SC_order(SCC,0,order2.value) @@ -1540,8 +1540,8 @@ def SC_test_list_perms(list L, int n, int limit, bint gap, bint limit_complain, if SC_is_giant(n, len(L), perm, 0.9, giant_support): from sage.arith.misc import factorial m = bitset_len(giant_support) - if order != factorial(m) and order != factorial(m)/2: - print("SC_is_giant failed: %s %s"%(str(L), order)) + if order != factorial(m) and order != factorial(m)//2: + print("SC_is_giant failed: %s %s" % (str(L), order)) raise AssertionError if order != G.order(): print("FAIL {}".format(L)) @@ -1572,13 +1572,13 @@ def SC_test_list_perms(list L, int n, int limit, bint gap, bint limit_complain, if bool(SC_says) != bool(gap_says): print("FAIL {}".format(L)) print('element {}'.format(permy)) - print('GAP says %d, SC_contains(modify=0) says %d'%(gap_says, SC_says)) + print('GAP says %d, SC_contains(modify=0) says %d' % (gap_says, SC_says)) raise AssertionError SC_says = SC_contains(SC, 0, perm, 1) if bool(SC_says) != bool(gap_says): print("FAIL {}".format(L)) print('element {}'.format(permy)) - print('GAP says %d, SC_contains(modify=0) says %d'%(gap_says, SC_says)) + print('GAP says %d, SC_contains(modify=0) says %d' % (gap_says, SC_says)) raise AssertionError SC_random_element(SC, 0, perm) for j from 0 <= j < n: diff --git a/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx b/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx index 0623c237b76..3a58fc0b9f6 100644 --- a/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx +++ b/src/sage/groups/perm_gps/partn_ref/refinement_python.pyx @@ -78,7 +78,7 @@ cdef class PythonPartitionStack: sage: P # implicit doctest PythonPartitionStack of degree 7 and depth 0. """ - return "PythonPartitionStack of degree %d and depth %d."%(self.c_ps.degree, self.c_ps.depth) + return "PythonPartitionStack of degree %d and depth %d." % (self.c_ps.degree, self.c_ps.depth) def display(self): """ diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index b0150295f1f..24e4f6263f5 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -1126,7 +1126,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): ... AssertionError: (1,3,5)(2,4,6) and [1, 2, 3, 4, 5, 6, 7] should have the same length """ - assert len(x) == self.n, '%s and %s should have the same length'%(self, x) + assert len(x) == self.n, '%s and %s should have the same length' % (self, x) return [ x[self.perm[i]] for i in range(self.n) ] cpdef ClonableIntArray _act_on_array_on_position(self, ClonableIntArray x): @@ -1146,7 +1146,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement): cdef int i cdef ClonableIntArray y cdef int l = self.n - assert x._len == l, '%s and %s should have the same length'%(self, x) + assert x._len == l, '%s and %s should have the same length' % (self, x) y = x.clone() for i in range(l): y._list[i] = x._list[self.perm[i]] diff --git a/src/sage/groups/semimonomial_transformations/semimonomial_transformation.pyx b/src/sage/groups/semimonomial_transformations/semimonomial_transformation.pyx index 72042533883..f3abbd13129 100644 --- a/src/sage/groups/semimonomial_transformations/semimonomial_transformation.pyx +++ b/src/sage/groups/semimonomial_transformations/semimonomial_transformation.pyx @@ -243,8 +243,8 @@ cdef class SemimonomialTransformation(MultiplicativeGroupElement): sage: SemimonomialTransformationGroup(F, 4).an_element() # indirect doctest ((a, 1, 1, 1); (1,4,3,2), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> 2*a + 1) """ - return "(%s; %s, %s)"%(self.v, self.perm.cycle_string(), - self.get_autom()) + return "(%s; %s, %s)" % (self.v, self.perm.cycle_string(), + self.get_autom()) cpdef _richcmp_(left, _right, int op): """ diff --git a/src/sage/libs/coxeter3/coxeter.pyx b/src/sage/libs/coxeter3/coxeter.pyx index 6f8a651e7eb..cd3e05307c3 100644 --- a/src/sage/libs/coxeter3/coxeter.pyx +++ b/src/sage/libs/coxeter3/coxeter.pyx @@ -423,7 +423,8 @@ cdef class CoxGroup(SageObject): sage: W = CoxGroup(['A', 5]); W Coxeter group of type A and rank 5 """ - return "Coxeter group of type %s and rank %s"%(self.type(), self.rank()) + return "Coxeter group of type %s and rank %s" % (self.type(), + self.rank()) def __iter__(self): """ diff --git a/src/sage/libs/eclib/homspace.pyx b/src/sage/libs/eclib/homspace.pyx index a502062ff79..f4baaee280a 100644 --- a/src/sage/libs/eclib/homspace.pyx +++ b/src/sage/libs/eclib/homspace.pyx @@ -71,7 +71,7 @@ cdef class ModularSymbols: sage: CremonaModularSymbols(37, cuspidal=True).__repr__() 'Cremona Cuspidal Modular Symbols space of dimension 4 for Gamma_0(37) of weight 2 with sign 0' """ - return "Cremona %sModular Symbols space of dimension %s for Gamma_0(%s) of weight 2 with sign %s"%( + return "Cremona %sModular Symbols space of dimension %s for Gamma_0(%s) of weight 2 with sign %s" % ( 'Cuspidal ' if self.is_cuspidal() else '', self.dimension(), self.level(), self.sign()) diff --git a/src/sage/libs/eclib/mat.pyx b/src/sage/libs/eclib/mat.pyx index a5ef4f45c68..bfdeb6ae5c1 100644 --- a/src/sage/libs/eclib/mat.pyx +++ b/src/sage/libs/eclib/mat.pyx @@ -49,7 +49,7 @@ cdef class Matrix: [-1 1 1 -1 0] [ 0 -1 0 0 0] """ - return "%s x %s Cremona matrix over Rational Field"%(self.nrows(), self.ncols()) + return "%s x %s Cremona matrix over Rational Field" % (self.nrows(), self.ncols()) def str(self): r""" diff --git a/src/sage/libs/eclib/mwrank.pyx b/src/sage/libs/eclib/mwrank.pyx index 6765ac296ed..5bc54a04cdc 100644 --- a/src/sage/libs/eclib/mwrank.pyx +++ b/src/sage/libs/eclib/mwrank.pyx @@ -208,7 +208,7 @@ cdef class _bigint: if s.isdigit() or s[0] == "-" and s[1:].isdigit(): self.x = str_to_bigint(str_to_bytes(s)) else: - raise ValueError("invalid _bigint: %r"%x) + raise ValueError("invalid _bigint: %r" % x) def __dealloc__(self): """ diff --git a/src/sage/libs/eclib/newforms.pyx b/src/sage/libs/eclib/newforms.pyx index d2af433a801..c067ef6acb9 100644 --- a/src/sage/libs/eclib/newforms.pyx +++ b/src/sage/libs/eclib/newforms.pyx @@ -237,7 +237,7 @@ cdef class ECModularSymbol: sage: M = ECModularSymbol(E, 0); M Modular symbol with sign 0 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 + x^2 - 2*x over Rational Field """ - return "Modular symbol with sign %s over Rational Field attached to %s"%(self.sign, self._E) + return "Modular symbol with sign %s over Rational Field attached to %s" % (self.sign, self._E) def __call__(self, r, sign=None, base_at_infinity=True): r""" diff --git a/src/sage/libs/giac/giac.pyx b/src/sage/libs/giac/giac.pyx index 4094307f0fd..aeeee3185fa 100644 --- a/src/sage/libs/giac/giac.pyx +++ b/src/sage/libs/giac/giac.pyx @@ -646,7 +646,7 @@ cdef class GiacSetting(Pygen): l = Pygen('cas_setup()').eval() pl = [ i for i in l ] pl[6] = value - Pygen('cas_setup(%s)'%(pl)).eval() + Pygen('cas_setup(%s)' % pl).eval() property sqrtflag: r""" @@ -662,7 +662,7 @@ cdef class GiacSetting(Pygen): pl[9]=1 else: pl[9]=0 - Pygen('cas_setup(%s)'%(pl)).eval() + Pygen('cas_setup(%s)' % pl).eval() property complexflag: r""" @@ -690,7 +690,7 @@ cdef class GiacSetting(Pygen): pl[2] = 1 else: pl[2] = 0 - Pygen('cas_setup(%s)'%(pl)).eval() + Pygen('cas_setup(%s)' % pl).eval() property eval_level: r""" @@ -716,7 +716,7 @@ cdef class GiacSetting(Pygen): l = Pygen('cas_setup()').eval() pl = [ i for i in l ] pl[7] = [l[7][0],l[7][1],l[7][2], value] - Pygen('cas_setup(%s)'%(pl)).eval() + Pygen('cas_setup(%s)' % pl).eval() property proba_epsilon: r""" @@ -740,7 +740,7 @@ cdef class GiacSetting(Pygen): l = Pygen('cas_setup()').eval() pl = [ i for i in l ] pl[5] = [l[5][0],value] - Pygen('cas_setup(%s)'%(pl)).eval() + Pygen('cas_setup(%s)' % pl).eval() property epsilon: r""" @@ -763,7 +763,7 @@ cdef class GiacSetting(Pygen): l = Pygen('cas_setup()').eval() pl = [ i for i in l ] pl[5] = [value,l[5][1]] - Pygen('cas_setup(%s)'%(pl)).eval() + Pygen('cas_setup(%s)' % pl).eval() property threads: r""" @@ -773,7 +773,7 @@ cdef class GiacSetting(Pygen): return (self.cas_setup()[7][0])._val def __set__(self,value): - Pygen('threads:=%s'%(str(value))).eval() + Pygen('threads:=%s' % str(value)).eval() ######################################################## # # @@ -958,7 +958,7 @@ cdef class Pygen(GiacMethods_base): sig_off() return _wrap_gen(result) else: - raise IndexError('list index %s out of range'%(i)) + raise IndexError('list index %s out of range' % i) else: if isinstance(i, slice): sig_on() @@ -978,17 +978,18 @@ cdef class Pygen(GiacMethods_base): raise TypeError('gen indexes are not yet implemented') # Here we add support to formal variable indexes: else: - cmd='%s[%s]'%(self,i) - ans=Pygen(cmd).eval() + cmd = '%s[%s]' % (self, i) + ans = Pygen(cmd).eval() # if the answer is a string, it must be an error message because self is not a list or a string if (ans._type == 12): - raise TypeError("Error executing code in Giac\nCODE:\n\t%s\nGiac ERROR:\n\t%s"%(cmd, ans)) + raise TypeError("Error executing code in Giac\nCODE:\n\t%s\nGiac ERROR:\n\t%s" % (cmd, ans)) return ans def __setitem__(self, key, value): """ Set the value of a coefficient of a giac vector or matrix or list. - Warning: It is an in place affectation. + + Warning: It is an in place affectation. TESTS:: @@ -1028,9 +1029,9 @@ cdef class Pygen(GiacMethods_base): sig_on() cdef gen g = gen(encstring23('GIACPY_TMP_NAME050268070969290100291003'),context_ptr) GIAC_sto((self).gptr[0],g,1,context_ptr) - g=gen(encstring23('GIACPY_TMP_NAME050268070969290100291003[%s]'%(str(key))),context_ptr) + g = gen(encstring23('GIACPY_TMP_NAME050268070969290100291003[%s]' % str(key)), context_ptr) v=((Pygen(value).eval())).gptr[0] - GIAC_sto(v,g,1,context_ptr) + GIAC_sto(v, g, 1, context_ptr) Pygen('purge(GIACPY_TMP_NAME050268070969290100291003):;').eval() sig_off() return diff --git a/src/sage/libs/libecm.pyx b/src/sage/libs/libecm.pyx index 9d53d7284d4..6e0fc8668a5 100644 --- a/src/sage/libs/libecm.pyx +++ b/src/sage/libs/libecm.pyx @@ -169,7 +169,7 @@ def ecmfactor(number, double B1, verbose=False, sigma=0): sage_int_sigma = Integer(sigma) if number <= 1: - raise ValueError("Input number (%s) must be greater than 1"%number) + raise ValueError("Input number (%s) must be greater than 1" % number) if verbose: print("Performing one curve with B1=%1.0f" % B1) diff --git a/src/sage/libs/pari/convert_sage.pyx b/src/sage/libs/pari/convert_sage.pyx index 64386bcf632..e26238d7c38 100644 --- a/src/sage/libs/pari/convert_sage.pyx +++ b/src/sage/libs/pari/convert_sage.pyx @@ -379,7 +379,7 @@ cpdef set_integer_from_gen(Integer self, Gen x): sig_on() x = new_gen(FF_to_FpXQ_i((x).g)) else: - raise TypeError("Unable to coerce PARI %s to an Integer"%x) + raise TypeError("Unable to coerce PARI %s to an Integer" % x) # Now we have a true PARI integer, convert it to Sage INT_to_mpz(self.value, (x).g) diff --git a/src/sage/matrix/misc.pyx b/src/sage/matrix/misc.pyx index 17277336e3c..de0afe6c9e7 100644 --- a/src/sage/matrix/misc.pyx +++ b/src/sage/matrix/misc.pyx @@ -209,7 +209,7 @@ def matrix_rational_echelon_form_multimodular(Matrix self, height_guess=None, pr from sage.structure.proof.proof import get_flag proof = get_flag(proof, "linear_algebra") - verbose("Multimodular echelon algorithm on %s x %s matrix"%(self._nrows, self._ncols), caller_name="multimod echelon") + verbose("Multimodular echelon algorithm on %s x %s matrix" % (self._nrows, self._ncols), caller_name="multimod echelon") cdef Matrix E if self._nrows == 0 or self._ncols == 0: return self, () @@ -219,7 +219,7 @@ def matrix_rational_echelon_form_multimodular(Matrix self, height_guess=None, pr height = self.height() if height_guess is None: height_guess = 10000000*(height+100) - tm = verbose("height_guess = %s"%height_guess, level=2, caller_name="multimod echelon") + tm = verbose("height_guess = %s" % height_guess, level=2, caller_name="multimod echelon") if proof: M = self._ncols * height_guess * height + 1 @@ -244,7 +244,7 @@ def matrix_rational_echelon_form_multimodular(Matrix self, height_guess=None, pr problem = problem + 1 if problem > 50: verbose("echelon multi-modular possibly not converging?", caller_name="multimod echelon") - t = verbose("echelon modulo p=%s (%.2f%% done)"%( + t = verbose("echelon modulo p=%s (%.2f%% done)" % ( p, 100*float(len(str(prod))) / len(str(M))), level=2, caller_name="multimod echelon") # We use denoms=False, since we made self integral by calling clear_denom above. diff --git a/src/sage/misc/c3_controlled.pyx b/src/sage/misc/c3_controlled.pyx index 81f66f0c680..e072d5f2ae9 100644 --- a/src/sage/misc/c3_controlled.pyx +++ b/src/sage/misc/c3_controlled.pyx @@ -656,7 +656,7 @@ def C3_merge(list lists): break if not next_item_found: # No head is available - raise ValueError("Cannot merge the items %s."%', '.join(repr(head) for head in heads)) + raise ValueError("Cannot merge the items %s." % ', '.join(repr(head) for head in heads)) return out @@ -1353,7 +1353,7 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): super_classes = tuple(self._from_value(base).cls for base in self._bases_controlled) if not super_classes: super_classes = (object,) - return dynamic_class("%s.cls"%self, super_classes) + return dynamic_class("%s.cls" % self, super_classes) @cached_method def all_bases(self): diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx index f78b390e031..f5fc873e5a9 100644 --- a/src/sage/misc/cachefunc.pyx +++ b/src/sage/misc/cachefunc.pyx @@ -3509,9 +3509,9 @@ class FileCache(): sage: print(N[len(dir):]) foo-1_2 """ - a,k = key - kwdstr = '_'.join(['%s-%s'%x for x in k]) - argstr = '_'.join(['%s'%x for x in a]) + a, k = key + kwdstr = '_'.join('%s-%s' % x for x in k) + argstr = '_'.join('%s' % x for x in a) if kwdstr and argstr: keystr = kwdstr + '.' + argstr else: diff --git a/src/sage/misc/constant_function.pyx b/src/sage/misc/constant_function.pyx index 59cb785883d..2e9c3d9fe44 100644 --- a/src/sage/misc/constant_function.pyx +++ b/src/sage/misc/constant_function.pyx @@ -94,7 +94,7 @@ cdef class ConstantFunction(SageObject): sage: ConstantFunction(1) The constant function (...) -> 1 """ - return "The constant function (...) -> %s"%self._value + return "The constant function (...) -> %s" % self._value def __call__(self, *args): """ diff --git a/src/sage/misc/function_mangling.pyx b/src/sage/misc/function_mangling.pyx index 79e508f19b8..fc9241ca79d 100644 --- a/src/sage/misc/function_mangling.pyx +++ b/src/sage/misc/function_mangling.pyx @@ -157,7 +157,7 @@ cdef class ArgumentFixer: sage: g = ArgumentFixer(number_of_partitions); g # needs sage.combinat Argument Fixer of """ - return "Argument Fixer of %s"%self.f + return "Argument Fixer of %s" % self.f def fix_to_named(self, *args,**kwargs): """ diff --git a/src/sage/misc/lazy_list.pyx b/src/sage/misc/lazy_list.pyx index ca65a92fc88..65d397996fc 100644 --- a/src/sage/misc/lazy_list.pyx +++ b/src/sage/misc/lazy_list.pyx @@ -823,8 +823,8 @@ cdef class lazy_list_generic(): stop = self.start + stop * self.step if stop > self.stop: stop = self.stop - if stop != PY_SSIZE_T_MAX and stop%step != start%step: - stop = stop - (stop-start)%step + step + if stop != PY_SSIZE_T_MAX and stop % step != start % step: + stop = stop - (stop - start) % step + step if stop <= start: return empty_lazy_list diff --git a/src/sage/misc/persist.pyx b/src/sage/misc/persist.pyx index 55540dc27b7..a89db8557d1 100644 --- a/src/sage/misc/persist.pyx +++ b/src/sage/misc/persist.pyx @@ -1232,7 +1232,7 @@ def db(name): The database directory is ``$HOME/.sage/db``. """ from sage.misc.misc import SAGE_DB - return load('%s/%s'%(SAGE_DB,name)) + return load('%s/%s' % (SAGE_DB, name)) def db_save(x, name=None): @@ -1245,4 +1245,4 @@ def db_save(x, name=None): x.db(name) except AttributeError: from sage.misc.misc import SAGE_DB - save(x, '%s/%s'%(SAGE_DB,name)) + save(x, '%s/%s' % (SAGE_DB, name)) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 3f397404988..4aaaa354d66 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -2241,7 +2241,7 @@ cdef class FreeModuleElement(Vector): # abstract base class sage: maple(v) # optional - maple Vector[row](3, [x^2+2,2*x+1,-2*x^2+4*x]) """ - return "Vector[row](%s)"%(str(self.list())) + return "Vector[row](%s)" % str(self.list()) def degree(self): """ @@ -2695,7 +2695,7 @@ cdef class FreeModuleElement(Vector): # abstract base class return self._parent.coordinate_ring().zero() return self._dot_product_(r) if self._degree != r._degree: - raise ArithmeticError("degrees (%s and %s) must be the same"%(self.degree(), right.degree())) + raise ArithmeticError("degrees (%s and %s) must be the same" % (self.degree(), right.degree())) # Base rings are not equal => use dot product with coercion return self._dot_product_coerce_(r) diff --git a/src/sage/modules/vector_integer_dense.pyx b/src/sage/modules/vector_integer_dense.pyx index 3605f4cf865..9517b8487d8 100644 --- a/src/sage/modules/vector_integer_dense.pyx +++ b/src/sage/modules/vector_integer_dense.pyx @@ -325,7 +325,7 @@ cdef class Vector_integer_dense(free_module_element.FreeModuleElement): name = singular._next_var_name() values = str(self.list())[1:-1] - singular.eval("intvec %s = %s"%(name, values)) + singular.eval("intvec %s = %s" % (name, values)) from sage.interfaces.singular import SingularElement return SingularElement(singular, 'foobar', name, True) diff --git a/src/sage/modules/vector_mod2_dense.pyx b/src/sage/modules/vector_mod2_dense.pyx index 35286c51457..ca14af9b313 100644 --- a/src/sage/modules/vector_mod2_dense.pyx +++ b/src/sage/modules/vector_mod2_dense.pyx @@ -201,13 +201,13 @@ cdef class Vector_mod2_dense(free_module_element.FreeModuleElement): xi = x[i] if isinstance(xi, (IntegerMod_int, int, Integer)): # the if/else statement is because in some compilers, (-1)%2 is -1 - mzd_write_bit(self._entries, 0, i, 1 if xi%2 else 0) + mzd_write_bit(self._entries, 0, i, 1 if xi % 2 else 0) elif isinstance(xi, Rational): if not (xi.denominator() % 2): raise ZeroDivisionError("inverse does not exist") mzd_write_bit(self._entries, 0, i, 1 if (xi.numerator() % 2) else 0) else: - mzd_write_bit(self._entries, 0, i, xi%2) + mzd_write_bit(self._entries, 0, i, xi % 2) elif x != 0: raise TypeError("can't initialize vector from nonzero non-list") elif self._degree: @@ -502,8 +502,8 @@ def unpickle_v0(parent, entries, degree, is_immutable): for i in range(degree): if isinstance(entries[i], (IntegerMod_int, int, Integer)): xi = entries[i] - mzd_write_bit(v._entries, 0, i, xi%2) + mzd_write_bit(v._entries, 0, i, xi % 2) else: - mzd_write_bit(v._entries, 0, i, entries[i]%2) + mzd_write_bit(v._entries, 0, i, entries[i] % 2) v._is_immutable = int(is_immutable) return v diff --git a/src/sage/modules/vector_modn_sparse.pyx b/src/sage/modules/vector_modn_sparse.pyx index a6b59ae9ca5..58ccb2415d4 100644 --- a/src/sage/modules/vector_modn_sparse.pyx +++ b/src/sage/modules/vector_modn_sparse.pyx @@ -251,7 +251,7 @@ cdef int add_c_vector_modint_init(c_vector_modint* sum, c_vector_modint* v, while i < v.num_nonzero or j < w.num_nonzero: if i >= v.num_nonzero: # just copy w in z.positions[k] = w.positions[j] - z.entries[k] = (multiple*w.entries[j])%v.p + z.entries[k] = (multiple * w.entries[j]) % v.p j = j + 1 k = k + 1 elif j >= w.num_nonzero: # just copy v in @@ -265,7 +265,7 @@ cdef int add_c_vector_modint_init(c_vector_modint* sum, c_vector_modint* v, i = i + 1 k = k + 1 elif v.positions[i] > w.positions[j]: # copy entry from w in - s = (multiple*w.entries[j])%v.p + s = (multiple * w.entries[j]) % v.p if s != 0: z.positions[k] = w.positions[j] z.entries[k] = s diff --git a/src/sage/modules/vector_rational_sparse.pyx b/src/sage/modules/vector_rational_sparse.pyx index fcdaf2b7cf8..f4a7d4b52f8 100644 --- a/src/sage/modules/vector_rational_sparse.pyx +++ b/src/sage/modules/vector_rational_sparse.pyx @@ -267,7 +267,7 @@ cdef int add_mpq_vector_init(mpq_vector* sum, Initialize sum and set sum = v + multiple*w. """ if v.degree != w.degree: - print("Can't add vectors of degree %s and %s"%(v.degree, w.degree)) + print("Can't add vectors of degree %s and %s" % (v.degree, w.degree)) raise ArithmeticError("The vectors must have the same degree.") cdef Py_ssize_t nz, i, j, k, do_multiply diff --git a/src/sage/modules/with_basis/indexed_element.pyx b/src/sage/modules/with_basis/indexed_element.pyx index 47e2fe1cc6f..73917208342 100644 --- a/src/sage/modules/with_basis/indexed_element.pyx +++ b/src/sage/modules/with_basis/indexed_element.pyx @@ -405,7 +405,7 @@ cdef class IndexedFreeModuleElement(ModuleElement): pass for monomial, c in terms: - b = repr_monomial(monomial) # PCR + b = repr_monomial(monomial) # PCR if c != 0: break_points = [] coeff = coeff_repr(c, False) @@ -416,17 +416,17 @@ cdef class IndexedFreeModuleElement(ModuleElement): coeff = "-" elif b._l > 0: if one_basis is not None and len(coeff) > 0 and monomial == one_basis and strip_one: - b = empty_ascii_art # "" + b = empty_ascii_art # "" else: b = AsciiArt([scalar_mult]) + b if not first: if len(coeff) > 0 and coeff[0] == "-": - coeff = " - %s"%coeff[1:] + coeff = " - %s" % coeff[1:] else: - coeff = " + %s"%coeff + coeff = " + %s" % coeff break_points = [2] else: - coeff = "%s"%coeff + coeff = "%s" % coeff if coeff: chunks.append(AsciiArt([coeff], break_points)) if b._l: @@ -435,10 +435,9 @@ cdef class IndexedFreeModuleElement(ModuleElement): s = ascii_art(*chunks) if first: return AsciiArt(["0"]) - elif s == empty_ascii_art: + if s == empty_ascii_art: return AsciiArt(["1"]) - else: - return s + return s def _unicode_art_(self): r""" diff --git a/src/sage/numerical/backends/glpk_graph_backend.pyx b/src/sage/numerical/backends/glpk_graph_backend.pyx index 2a89dfe0bd1..ca3907e2fdb 100644 --- a/src/sage/numerical/backends/glpk_graph_backend.pyx +++ b/src/sage/numerical/backends/glpk_graph_backend.pyx @@ -840,7 +840,7 @@ cdef class GLPKGraphBackend(): cdef int i = self._find_vertex(vert) if i < 0: - raise RuntimeError("Vertex %s does not exist."%(vert)) + raise RuntimeError("Vertex %s does not exist." % vert) cdef int num[2] num[1] = i + 1 @@ -880,7 +880,7 @@ cdef class GLPKGraphBackend(): verts_val = [self._find_vertex(v) for v in verts] if -1 in verts_val: i = verts_val.index(-1) - raise RuntimeError("Vertex %s does not exist."%(verts[i])) + raise RuntimeError("Vertex %s does not exist." % verts[i]) cdef int * num = check_allocarray(len(verts_val) + 1, sizeof(int)) cdef int ndel = len(verts_val) diff --git a/src/sage/plot/complex_plot.pyx b/src/sage/plot/complex_plot.pyx index 124209f257e..0552a51ff19 100644 --- a/src/sage/plot/complex_plot.pyx +++ b/src/sage/plot/complex_plot.pyx @@ -826,7 +826,7 @@ class ComplexPlot(GraphicPrimitive): sage: isinstance(complex_plot(lambda z: z, (-1,1), (-1,1))[0]._repr_(), str) True """ - return "ComplexPlot defined by a %s x %s data grid"%(self.x_count, self.y_count) + return "ComplexPlot defined by a %s x %s data grid" % (self.x_count, self.y_count) def _render_on_subplot(self, subplot): """ diff --git a/src/sage/plot/plot3d/base.pyx b/src/sage/plot/plot3d/base.pyx index 0f3cca16607..f1a9ac7c49b 100644 --- a/src/sage/plot/plot3d/base.pyx +++ b/src/sage/plot/plot3d/base.pyx @@ -975,7 +975,7 @@ cdef class Graphics3d(SageObject): %s -"""%(self.viewpoint().x3d_str(), self.x3d_str()) +""" % (self.viewpoint().x3d_str(), self.x3d_str()) ################ TACHYON ################ @@ -1249,7 +1249,7 @@ end_scene""".format( f.write('set labelOffset 0 0\n') # Set the scene background color - f.write('background [%s,%s,%s]\n'%tuple([int(a*255) for a in background])) + f.write('background [%s,%s,%s]\n' % tuple(int(a*255) for a in background)) if spin: f.write('spin ON\n') else: @@ -2619,11 +2619,11 @@ class TransformGroup(Graphics3dGroup): """ s = "" """ - return ""%self.pos + return "" % self.pos cdef class PrimitiveObject(Graphics3d): diff --git a/src/sage/plot/plot3d/shapes.pyx b/src/sage/plot/plot3d/shapes.pyx index 48369a64a07..4acab1a14eb 100644 --- a/src/sage/plot/plot3d/shapes.pyx +++ b/src/sage/plot/plot3d/shapes.pyx @@ -483,7 +483,7 @@ cdef class Cylinder(ParametricSurface): Base %s %s %s Apex %s %s %s Rad %s - %s """%(base[0], base[1], base[2], top[0], top[1], top[2], rad, self.texture.id) + %s """ % (base[0], base[1], base[2], top[0], top[1], top[2], rad, self.texture.id) if self.closed: normal = (0,0,1) if transform is not None: @@ -866,7 +866,7 @@ cdef class Sphere(ParametricSurface): sage: Sphere(12).x3d_geometry() "" """ - return ""%(self.radius) + return "" % (self.radius) def tachyon_repr(self, render_params): r""" @@ -1111,7 +1111,7 @@ class Text(PrimitiveObject): sage: Text("Hi").x3d_geometry() "" """ - return ""%self.string + return "" % self.string def obj_repr(self, render_params): """ diff --git a/src/sage/rings/complex_interval.pyx b/src/sage/rings/complex_interval.pyx index c9273384788..e8e528e1453 100644 --- a/src/sage/rings/complex_interval.pyx +++ b/src/sage/rings/complex_interval.pyx @@ -250,14 +250,14 @@ cdef class ComplexIntervalFieldElement(FieldElement): s = self.real().str(base=base, style=style) if not self.imag().is_zero(): y = self.imag() - if s!="": + if s: if y < 0: - s = s+" - " + s += " - " y = -y else: - s = s+" + " - s = s+"%s*I"%y.str(base=base, style=style) - if len(s) == 0: + s += " + " + s += "%s*I" % y.str(base=base, style=style) + if not s: s = "0" return s diff --git a/src/sage/sets/finite_set_map_cy.pyx b/src/sage/sets/finite_set_map_cy.pyx index 335e4cfb5e7..f41450d5842 100644 --- a/src/sage/sets/finite_set_map_cy.pyx +++ b/src/sage/sets/finite_set_map_cy.pyx @@ -355,7 +355,7 @@ cdef class FiniteSetMap_MN(ClonableIntArray): n = self._parent._n assert self._len == m, "Wrong number of values" for i in range(m): - assert 0 <= self._list[i] < n, "Wrong value self(%i) = %i"%(i, self._list[i]) + assert 0 <= self._list[i] < n, "Wrong value self(%i) = %i" % (i, self._list[i]) if hasattr(self._parent, 'check_element'): self._parent.check_element(self) diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index e4845126012..0baad597dde 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -307,10 +307,10 @@ cdef class TimeSeries: if len(self) > max_print: v0 = self[:max_print//2] v1 = self[-max_print//2:] - return '[' + ', '.join(format%x for x in v0) + ' ... ' + \ - ', '.join(format%x for x in v1) + ']' + return '[' + ', '.join(format % x for x in v0) + ' ... ' + \ + ', '.join(format % x for x in v1) + ']' else: - return '[' + ', '.join(format%x for x in self) + ']' + return '[' + ', '.join(format % x for x in self) + ']' def __len__(self): r""" diff --git a/src/sage/structure/coerce.pyx b/src/sage/structure/coerce.pyx index 7ee41f74a04..cc2f1124cb4 100644 --- a/src/sage/structure/coerce.pyx +++ b/src/sage/structure/coerce.pyx @@ -1271,7 +1271,7 @@ cdef class CoercionModel: if not isinstance(y, Element): op_name = op.__name__ - mul_method = getattr(y, '__r%s__'%op_name, None) + mul_method = getattr(y, '__r%s__' % op_name, None) if mul_method is not None: res = mul_method(x) if res is not None and res is not NotImplemented: @@ -1425,7 +1425,7 @@ cdef class CoercionModel: except Exception: self._record_exception() - raise TypeError("no common canonical parent for objects with parents: '%s' and '%s'"%(xp, yp)) + raise TypeError("no common canonical parent for objects with parents: '%s' and '%s'" % (xp, yp)) cpdef coercion_maps(self, R, S): r""" diff --git a/src/sage/structure/coerce_actions.pyx b/src/sage/structure/coerce_actions.pyx index b25abdf328a..17bbd397c98 100644 --- a/src/sage/structure/coerce_actions.pyx +++ b/src/sage/structure/coerce_actions.pyx @@ -370,18 +370,18 @@ cdef class ModuleAction(Action): # At this point, we can assert it is safe to call _Xmul_ the_ring = G if self.connecting is None else self.connecting.codomain() the_set = S if self.extended_base is None else self.extended_base - assert the_ring is the_set.base(), "BUG in coercion model\n Apparently there are two versions of\n %s\n in the cache."%the_ring + assert the_ring is the_set.base(), "BUG in coercion model\n Apparently there are two versions of\n %s\n in the cache." % the_ring if not check: return if g is None: g = G.an_element() if parent(g) is not G: - raise CoercionException("The parent of %s is not %s but %s"%(g,G,parent(g))) + raise CoercionException("The parent of %s is not %s but %s" % (g, G, parent(g))) if a is None: a = S.an_element() if parent(a) is not S: - raise CoercionException("The parent of %s is not %s but %s"%(a,S,parent(a))) + raise CoercionException("The parent of %s is not %s but %s" % (a, S, parent(a))) if not isinstance(g, Element) or not isinstance(a, ModuleElement): raise CoercionException("not an Element acting on a ModuleElement") res = self.act(g, a) From a88db612d981a91b417cc06f259244cddd0ead37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 27 Oct 2024 13:44:25 +0100 Subject: [PATCH 55/82] really remove --- src/sage/geometry/lattice_polytope.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 1af31240182..2869dcc7442 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -591,7 +591,6 @@ def _sage_input_(self, sib, coerced): """ if self._ambient is not self: raise NotImplementedError - _ = self._vertices return sib.name('LatticePolytope')(sib(self._vertices), compute_vertices=False) def __contains__(self, point): From 1f82f2340f7c3e0bcc03c9e2f41320f52760da18 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 27 Oct 2024 14:37:05 +0100 Subject: [PATCH 56/82] Fix testing of installed rst files --- src/sage/doctest/control.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index f34d3ef5caa..fff35be8307 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -282,13 +282,14 @@ def skipfile(filename, tested_optional_tags=False, *, sage: skipfile(filename, True) False """ - if filename.endswith('.rst.txt'): - ext = '.rst.txt' if filename.endswith('__main__.py'): if log: log(f"Skipping '{filename}' because it is a __main__.py file") return True - _ , ext = os.path.splitext(filename) + if filename.endswith('.rst.txt'): + ext = '.rst.txt' + else: + _ , ext = os.path.splitext(filename) # .rst.txt appear in the installed documentation in subdirectories named "_sources" if ext not in ('.py', '.pyx', '.pxd', '.pxi', '.sage', '.spyx', '.rst', '.tex', '.rst.txt'): if log: From f32a751eb1cbbf908c93f2cdb2b32ccdb13ed6ad Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 27 Oct 2024 18:23:09 +0100 Subject: [PATCH 57/82] Fix build of coxeter3 extension with meson --- src/sage/libs/coxeter3/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/libs/coxeter3/meson.build b/src/sage/libs/coxeter3/meson.build index 83cbd2b46cd..ee51998f27d 100644 --- a/src/sage/libs/coxeter3/meson.build +++ b/src/sage/libs/coxeter3/meson.build @@ -17,7 +17,7 @@ foreach name, pyx : extension_data_cpp subdir: 'sage/libs/coxeter3', install: true, override_options: ['cython_language=cpp'], - include_directories: [], + include_directories: [inc_cpython], dependencies: [py_dep, cysignals, coxeter3], ) endforeach From 32971da87ac346371ec599c8e852767e13d8df68 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sun, 27 Oct 2024 18:44:26 +0100 Subject: [PATCH 58/82] Fix duplicate install of config.py in meson build --- src/sage/meson.build | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/meson.build b/src/sage/meson.build index 687ac549c10..7179555ec27 100644 --- a/src/sage/meson.build +++ b/src/sage/meson.build @@ -86,7 +86,6 @@ foreach package : no_processing endforeach py.install_sources( - config_file, 'all.py', 'all__sagemath_bliss.py', 'all__sagemath_categories.py', From 92de1331a5c63e597dbb7a55a8be0e679810e068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 28 Oct 2024 11:45:20 +0100 Subject: [PATCH 59/82] some doc in fields Co-authored-by: Martin Rubey --- src/sage/categories/fields.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/sage/categories/fields.py b/src/sage/categories/fields.py index 9e4238c31a0..a855cee05ac 100644 --- a/src/sage/categories/fields.py +++ b/src/sage/categories/fields.py @@ -462,12 +462,25 @@ def ideal(self, *gens, **kwds): """ Return the ideal generated by gens. + INPUT: + + - an element or a list/tuple/sequence of elements, the generators + + Any named arguments are ignored. EXAMPLES:: sage: QQ.ideal(2) Principal ideal (1) of Rational Field sage: QQ.ideal(0) Principal ideal (0) of Rational Field + + TESTS:: + + sage: QQ.ideal(2, 4) + Principal ideal (1) of Rational Field + + sage: QQ.ideal([2, 4]) + Principal ideal (1) of Rational Field """ if len(gens) == 1 and isinstance(gens[0], (list, tuple)): gens = gens[0] From 553300e6f7c926cc6fbdcc02f94feb70122f519e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 28 Oct 2024 11:50:34 +0100 Subject: [PATCH 60/82] fix details in fields.py --- src/sage/categories/fields.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/sage/categories/fields.py b/src/sage/categories/fields.py index a855cee05ac..e1f5c3d68f6 100644 --- a/src/sage/categories/fields.py +++ b/src/sage/categories/fields.py @@ -193,7 +193,7 @@ def _call_(self, x): class ParentMethods: - def is_field( self, proof=True ): + def is_field(self, proof=True): r""" Return ``True`` as ``self`` is a field. @@ -460,13 +460,14 @@ def fraction_field(self): def ideal(self, *gens, **kwds): """ - Return the ideal generated by gens. + Return the ideal generated by ``gens``. INPUT: - an element or a list/tuple/sequence of elements, the generators Any named arguments are ignored. + EXAMPLES:: sage: QQ.ideal(2) @@ -474,18 +475,16 @@ def ideal(self, *gens, **kwds): sage: QQ.ideal(0) Principal ideal (0) of Rational Field - TESTS:: + TESTS:: sage: QQ.ideal(2, 4) Principal ideal (1) of Rational Field sage: QQ.ideal([2, 4]) - Principal ideal (1) of Rational Field + Principal ideal (1) of Rational Field """ if len(gens) == 1 and isinstance(gens[0], (list, tuple)): gens = gens[0] - if not isinstance(gens, (list, tuple)): - gens = [gens] for x in gens: if not self(x).is_zero(): return self.unit_ideal() @@ -618,7 +617,7 @@ def quo_rem(self, other): raise ZeroDivisionError return (self/other, self.parent().zero()) - def is_unit( self ): + def is_unit(self): r""" Return ``True`` if ``self`` has a multiplicative inverse. @@ -635,7 +634,7 @@ def is_unit( self ): # Of course, in general gcd and lcm in a field are not very interesting. # However, they should be implemented! @coerce_binop - def gcd(self,other): + def gcd(self, other): """ Greatest common divisor. From d0b6b14132bbcdf05cc346600d88b2a4021b2639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 28 Oct 2024 13:36:56 +0100 Subject: [PATCH 61/82] Update src/sage/categories/rings.py Co-authored-by: Martin Rubey --- src/sage/categories/rings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 7a80a32e2d8..1fd41b17662 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -926,7 +926,7 @@ def ideal(self, *args, **kwds): else: break - if len(gens) == 0: + if not gens: gens = [self.zero()] elif coerce: gens = [self(g) for g in gens] From 94949db67a38ed03fdd5b4919f9744f964dbff6c Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Mon, 28 Oct 2024 08:45:27 -0400 Subject: [PATCH 62/82] src/sage/parallel/map_reduce.py: fixup start_workers() test case In commit a1818838 I made this test wait a bit longer (to be more robust under load) and added a "long time" to the corresponding start_workers() line. But, further down, there's another test that calls finish(), which needs the workers to be started. Without a "long time" on the finish(), it can fail sans --long. To fix it, we combine the two tests that call start_workers() and finish(), and then mark the whole thing "long time". The finish() is supposed to delete the workers created in setup_workers() as well, so there's not much point in trying to make the "long time" more fine-grained than that. --- src/sage/parallel/map_reduce.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index 303f7405416..a182a136a2f 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -1133,18 +1133,16 @@ def start_workers(self): TESTS:: + sage: # long time sage: from sage.parallel.map_reduce import RESetMapReduce sage: def children(x): ....: print(f"Starting: {x}", flush=True) ....: return [] sage: S = RESetMapReduce(roots=[1, 2], children=children) sage: S.setup_workers(2) - sage: S.start_workers(); sleep(float(5)) # long time + sage: S.start_workers(); sleep(float(5)) Starting: ... Starting: ... - - Cleanup:: - sage: S.finish() """ if self._nprocess == 0: From 0568216a1568cfc9bc5bfb86cfe4ad6d744793c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 28 Oct 2024 15:12:51 +0100 Subject: [PATCH 63/82] remove unused case --- src/sage/categories/rings.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 7a80a32e2d8..e5b829a5982 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -921,8 +921,6 @@ def ideal(self, *args, **kwds): break elif isinstance(first, (list, tuple, GeneratorType)): gens = first - elif isinstance(first, Parent) and self.has_coerce_map_from(first): - gens = first.gens() # we have a ring as argument else: break From 770d5e8271098070fd5a8f3cb95f82bd35a0a47c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 28 Oct 2024 17:20:19 +0100 Subject: [PATCH 64/82] minor details in piecewise functions --- src/sage/functions/piecewise.py | 43 +++++++++++++++++---------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/sage/functions/piecewise.py b/src/sage/functions/piecewise.py index 56b900437a5..fc69057ef6f 100644 --- a/src/sage/functions/piecewise.py +++ b/src/sage/functions/piecewise.py @@ -673,39 +673,40 @@ def piecewise_add(self, parameters, variable, other): funcs = [] contains_lower = False contains_upper = False - for i in range(len(points)-1): + for i in range(len(points) - 1): + a, b = points[i], points[i + 1] try: - contains_lower = (self.domain().contains(points[i]) or - other.domain().contains(points[i])) and not contains_upper - contains_upper = (self.domain().contains(points[i+1]) or - other.domain().contains(points[i+1])) + contains_lower = (self.domain().contains(a) or + other.domain().contains(a)) and not contains_upper + contains_upper = (self.domain().contains(b) or + other.domain().contains(b)) if contains_lower: if contains_upper: - rs = RealSet.closed(points[i], points[i+1]) + rs = RealSet.closed(a, b) else: - rs = RealSet.closed_open(points[i], points[i+1]) + rs = RealSet.closed_open(a, b) else: if contains_upper: - rs = RealSet.open_closed(points[i], points[i+1]) + rs = RealSet.open_closed(a, b) else: - rs = RealSet.open(points[i], points[i+1]) - point = (points[i+1] + points[i])/2 + rs = RealSet.open(a, b) + point = (b + a) / 2 except ValueError: - if points[i] == minus_infinity and points[i+1] == infinity: + if a == minus_infinity and b == infinity: rs = RealSet.open(minus_infinity, infinity) point = 0 - elif points[i] == minus_infinity: + elif a == minus_infinity: if contains_lower: - rs = RealSet.unbounded_below_closed(points[i+1]) + rs = RealSet.unbounded_below_closed(b) else: - rs = RealSet.unbounded_below_open(points[i+1]) - point = points[i+1]-1 - elif points[i+1] == infinity: + rs = RealSet.unbounded_below_open(b) + point = b - 1 + elif b == infinity: if contains_upper: - rs = RealSet.unbounded_above_closed(points[i]) + rs = RealSet.unbounded_above_closed(a) else: - rs = RealSet.unbounded_above_open(points[i]) - point = points[i]+1 + rs = RealSet.unbounded_above_open(a) + point = a + 1 else: raise try: @@ -1160,17 +1161,17 @@ def laplace(self, parameters, variable, x='x', s='t'): (s + 1)*e^(-s)/s^2 + 2*e^(-s)/s - 1/s^2 """ from sage.symbolic.assumptions import assume, forget - from sage.functions.log import exp x = SR.var(x) s = SR.var(s) assume(s > 0) + exp_sx = (-s * x).exp() result = 0 for domain, f in parameters: for interval in domain: a = interval.lower() b = interval.upper() - result += (SR(f)*exp(-s*x)).integral(x, a, b) + result += (SR(f) * exp_sx).integral(x, a, b) forget(s > 0) return result From 24eda2a704ddaccd7519c8404c28e199728ab8cd Mon Sep 17 00:00:00 2001 From: M Bussonnier Date: Mon, 28 Oct 2024 17:28:26 +0100 Subject: [PATCH 65/82] Update Pypi.io domain (301 permanent redirect). Which itself redirect pypi.io/(*) to pypi.org/$1, anything under /package/ redirect directly to files.pythonhosted.org. Pypi.io is legacy/was temporary so it's a nice things to maybe one day let the pypa inrfa team to stop supporting it. ; the pypi.org -> files.pythonhosted just avoids an extra redirect, --- build/pkgs/alabaster/checksums.ini | 2 +- build/pkgs/anyio/checksums.ini | 2 +- build/pkgs/appdirs/checksums.ini | 2 +- build/pkgs/appnope/checksums.ini | 2 +- build/pkgs/argon2_cffi/checksums.ini | 2 +- build/pkgs/argon2_cffi_bindings/checksums.ini | 2 +- build/pkgs/arrow/checksums.ini | 2 +- build/pkgs/asttokens/checksums.ini | 2 +- build/pkgs/async_lru/checksums.ini | 2 +- build/pkgs/attrs/checksums.ini | 2 +- build/pkgs/babel/checksums.ini | 2 +- build/pkgs/beautifulsoup4/checksums.ini | 2 +- build/pkgs/beniget/checksums.ini | 2 +- build/pkgs/bleach/checksums.ini | 2 +- build/pkgs/cachetools/checksums.ini | 2 +- build/pkgs/calver/checksums.ini | 2 +- build/pkgs/certifi/checksums.ini | 2 +- build/pkgs/cffi/checksums.ini | 2 +- build/pkgs/chardet/checksums.ini | 2 +- build/pkgs/charset_normalizer/checksums.ini | 2 +- build/pkgs/colorama/checksums.ini | 2 +- build/pkgs/comm/checksums.ini | 2 +- build/pkgs/contourpy/checksums.ini | 2 +- build/pkgs/conway_polynomials/checksums.ini | 2 +- build/pkgs/cppy/checksums.ini | 2 +- build/pkgs/cvxopt/checksums.ini | 2 +- build/pkgs/cvxpy/checksums.ini | 2 +- build/pkgs/cylp/checksums.ini | 2 +- build/pkgs/cypari/checksums.ini | 2 +- build/pkgs/cysignals/checksums.ini | 2 +- build/pkgs/cython/checksums.ini | 2 +- build/pkgs/database_cubic_hecke/checksums.ini | 2 +- build/pkgs/database_knotinfo/checksums.ini | 2 +- build/pkgs/dateutil/checksums.ini | 2 +- build/pkgs/debugpy/checksums.ini | 2 +- build/pkgs/decorator/checksums.ini | 2 +- build/pkgs/defusedxml/checksums.ini | 2 +- build/pkgs/distlib/checksums.ini | 2 +- build/pkgs/docutils/checksums.ini | 2 +- build/pkgs/ecos_python/checksums.ini | 2 +- build/pkgs/editables/checksums.ini | 2 +- build/pkgs/entrypoints/checksums.ini | 2 +- build/pkgs/exceptiongroup/checksums.ini | 2 +- build/pkgs/execnet/checksums.ini | 2 +- build/pkgs/executing/checksums.ini | 2 +- build/pkgs/fastjsonschema/checksums.ini | 2 +- build/pkgs/filelock/checksums.ini | 2 +- build/pkgs/flit_core/checksums.ini | 2 +- build/pkgs/fonttools/checksums.ini | 2 +- build/pkgs/fpylll/checksums.ini | 2 +- build/pkgs/fqdn/checksums.ini | 2 +- build/pkgs/furo/checksums.ini | 2 +- build/pkgs/gast/checksums.ini | 2 +- build/pkgs/gmpy2/checksums.ini | 2 +- build/pkgs/gnumake_tokenpool/checksums.ini | 2 +- build/pkgs/h11/checksums.ini | 2 +- build/pkgs/hatchling/checksums.ini | 2 +- build/pkgs/httpcore/checksums.ini | 2 +- build/pkgs/httpx/checksums.ini | 2 +- build/pkgs/idna/checksums.ini | 2 +- build/pkgs/imagesize/checksums.ini | 2 +- build/pkgs/importlib_metadata/checksums.ini | 2 +- build/pkgs/importlib_resources/checksums.ini | 2 +- build/pkgs/iniconfig/checksums.ini | 2 +- build/pkgs/ipykernel/checksums.ini | 2 +- build/pkgs/ipympl/checksums.ini | 2 +- build/pkgs/ipython/checksums.ini | 2 +- build/pkgs/ipywidgets/checksums.ini | 2 +- build/pkgs/isoduration/checksums.ini | 2 +- build/pkgs/jedi/checksums.ini | 2 +- build/pkgs/jinja2/checksums.ini | 2 +- build/pkgs/json5/checksums.ini | 2 +- build/pkgs/jsonpointer/checksums.ini | 2 +- build/pkgs/jsonschema/checksums.ini | 2 +- build/pkgs/jsonschema_specifications/checksums.ini | 2 +- build/pkgs/jupyter_client/checksums.ini | 2 +- build/pkgs/jupyter_core/checksums.ini | 2 +- build/pkgs/jupyter_events/checksums.ini | 2 +- build/pkgs/jupyter_jsmol/checksums.ini | 2 +- build/pkgs/jupyter_lsp/checksums.ini | 2 +- build/pkgs/jupyter_server/checksums.ini | 2 +- build/pkgs/jupyter_server_terminals/checksums.ini | 2 +- build/pkgs/jupyter_sphinx/checksums.ini | 2 +- build/pkgs/jupyterlab/checksums.ini | 2 +- build/pkgs/jupyterlab_mathjax2/checksums.ini | 2 +- build/pkgs/jupyterlab_pygments/checksums.ini | 2 +- build/pkgs/jupyterlab_server/checksums.ini | 2 +- build/pkgs/jupyterlab_widgets/checksums.ini | 2 +- build/pkgs/lrcalc_python/checksums.ini | 2 +- build/pkgs/markupsafe/checksums.ini | 2 +- build/pkgs/matplotlib/checksums.ini | 2 +- build/pkgs/matplotlib_inline/checksums.ini | 2 +- build/pkgs/matroid_database/checksums.ini | 2 +- build/pkgs/memory_allocator/checksums.ini | 2 +- build/pkgs/meson/checksums.ini | 2 +- build/pkgs/meson_python/checksums.ini | 2 +- build/pkgs/mistune/checksums.ini | 2 +- build/pkgs/nbclient/checksums.ini | 2 +- build/pkgs/nbconvert/checksums.ini | 2 +- build/pkgs/nbformat/checksums.ini | 2 +- build/pkgs/nest_asyncio/checksums.ini | 2 +- build/pkgs/networkx/checksums.ini | 2 +- build/pkgs/notebook/checksums.ini | 2 +- build/pkgs/notebook_shim/checksums.ini | 2 +- build/pkgs/numpy/checksums.ini | 2 +- build/pkgs/osqp_python/checksums.ini | 2 +- build/pkgs/overrides/checksums.ini | 2 +- build/pkgs/packaging/checksums.ini | 2 +- build/pkgs/pandocfilters/checksums.ini | 2 +- build/pkgs/pari_jupyter/checksums.ini | 2 +- build/pkgs/parso/checksums.ini | 2 +- build/pkgs/pathspec/checksums.ini | 2 +- build/pkgs/pexpect/checksums.ini | 2 +- build/pkgs/pillow/checksums.ini | 2 +- build/pkgs/pip/checksums.ini | 2 +- build/pkgs/pkgconfig/checksums.ini | 2 +- build/pkgs/platformdirs/checksums.ini | 2 +- build/pkgs/pluggy/checksums.ini | 2 +- build/pkgs/ply/checksums.ini | 2 +- build/pkgs/pplpy/checksums.ini | 2 +- build/pkgs/primecountpy/checksums.ini | 2 +- build/pkgs/prometheus_client/checksums.ini | 2 +- build/pkgs/prompt_toolkit/checksums.ini | 2 +- build/pkgs/psutil/checksums.ini | 2 +- build/pkgs/ptyprocess/checksums.ini | 2 +- build/pkgs/pure_eval/checksums.ini | 2 +- build/pkgs/py/checksums.ini | 2 +- build/pkgs/pybind11/checksums.ini | 2 +- build/pkgs/pycparser/checksums.ini | 2 +- build/pkgs/pygments/checksums.ini | 2 +- build/pkgs/pynormaliz/checksums.ini | 2 +- build/pkgs/pyparsing/checksums.ini | 2 +- build/pkgs/pyproject_api/checksums.ini | 2 +- build/pkgs/pyproject_hooks/checksums.ini | 2 +- build/pkgs/pyproject_metadata/checksums.ini | 2 +- build/pkgs/pyrsistent/checksums.ini | 2 +- build/pkgs/pyscipopt/checksums.ini | 2 +- build/pkgs/pysingular/checksums.ini | 2 +- build/pkgs/pytest/checksums.ini | 2 +- build/pkgs/pytest_mock/checksums.ini | 2 +- build/pkgs/pytest_xdist/checksums.ini | 2 +- build/pkgs/python_build/checksums.ini | 2 +- build/pkgs/python_flint/checksums.ini | 2 +- build/pkgs/python_igraph/checksums.ini | 2 +- build/pkgs/python_json_logger/checksums.ini | 2 +- build/pkgs/pythran/checksums.ini | 2 +- build/pkgs/pytz/checksums.ini | 2 +- build/pkgs/pytz_deprecation_shim/checksums.ini | 2 +- build/pkgs/pyyaml/checksums.ini | 2 +- build/pkgs/pyzmq/checksums.ini | 2 +- build/pkgs/qdldl_python/checksums.ini | 2 +- build/pkgs/referencing/checksums.ini | 2 +- build/pkgs/requests/checksums.ini | 2 +- build/pkgs/rfc3339_validator/checksums.ini | 2 +- build/pkgs/rfc3986_validator/checksums.ini | 2 +- build/pkgs/rpy2/checksums.ini | 2 +- build/pkgs/rst2ipynb/checksums.ini | 2 +- build/pkgs/sage_numerical_backends_coin/checksums.ini | 2 +- build/pkgs/sage_numerical_backends_cplex/checksums.ini | 2 +- build/pkgs/sage_numerical_backends_gurobi/checksums.ini | 2 +- build/pkgs/sagetex/checksums.ini | 2 +- build/pkgs/scipy/checksums.ini | 2 +- build/pkgs/scs/checksums.ini | 2 +- build/pkgs/send2trash/checksums.ini | 2 +- build/pkgs/setuptools/checksums.ini | 2 +- build/pkgs/setuptools_scm/checksums.ini | 2 +- build/pkgs/six/checksums.ini | 2 +- build/pkgs/sniffio/checksums.ini | 2 +- build/pkgs/snowballstemmer/checksums.ini | 2 +- build/pkgs/soupsieve/checksums.ini | 2 +- build/pkgs/sphinx/checksums.ini | 2 +- build/pkgs/sphinx_basic_ng/checksums.ini | 2 +- build/pkgs/sphinx_copybutton/checksums.ini | 2 +- build/pkgs/sphinx_inline_tabs/checksums.ini | 2 +- build/pkgs/sphinxcontrib_applehelp/checksums.ini | 2 +- build/pkgs/sphinxcontrib_devhelp/checksums.ini | 2 +- build/pkgs/sphinxcontrib_htmlhelp/checksums.ini | 2 +- build/pkgs/sphinxcontrib_jsmath/checksums.ini | 2 +- build/pkgs/sphinxcontrib_qthelp/checksums.ini | 2 +- build/pkgs/sphinxcontrib_serializinghtml/checksums.ini | 2 +- build/pkgs/sphinxcontrib_websupport/checksums.ini | 2 +- build/pkgs/stack_data/checksums.ini | 2 +- build/pkgs/symengine_py/checksums.ini | 2 +- build/pkgs/sympy/checksums.ini | 2 +- build/pkgs/terminado/checksums.ini | 2 +- build/pkgs/texttable/checksums.ini | 2 +- build/pkgs/tinycss2/checksums.ini | 2 +- build/pkgs/tomli/checksums.ini | 2 +- build/pkgs/tornado/checksums.ini | 2 +- build/pkgs/tox/checksums.ini | 2 +- build/pkgs/traitlets/checksums.ini | 2 +- build/pkgs/trove_classifiers/checksums.ini | 2 +- build/pkgs/types_python_dateutil/checksums.ini | 2 +- build/pkgs/typing_extensions/checksums.ini | 2 +- build/pkgs/tzdata/checksums.ini | 2 +- build/pkgs/tzlocal/checksums.ini | 2 +- build/pkgs/uri_template/checksums.ini | 2 +- build/pkgs/urllib3/checksums.ini | 2 +- build/pkgs/virtualenv/checksums.ini | 2 +- build/pkgs/wcwidth/checksums.ini | 2 +- build/pkgs/webcolors/checksums.ini | 2 +- build/pkgs/websocket_client/checksums.ini | 2 +- build/pkgs/wheel/checksums.ini | 2 +- build/pkgs/widgetsnbextension/checksums.ini | 2 +- build/pkgs/zipp/checksums.ini | 2 +- build/sage_bootstrap/app.py | 6 +++--- src/doc/en/developer/packaging.rst | 4 ++-- 207 files changed, 210 insertions(+), 210 deletions(-) diff --git a/build/pkgs/alabaster/checksums.ini b/build/pkgs/alabaster/checksums.ini index a58c93e8f4a..137d299783d 100644 --- a/build/pkgs/alabaster/checksums.ini +++ b/build/pkgs/alabaster/checksums.ini @@ -1,4 +1,4 @@ tarball=alabaster-VERSION-py3-none-any.whl sha1=6c86446396c69236a1542e09771e8d7b8487dcfa sha256=b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92 -upstream_url=https://pypi.io/packages/py3/a/alabaster/alabaster-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/a/alabaster/alabaster-VERSION-py3-none-any.whl diff --git a/build/pkgs/anyio/checksums.ini b/build/pkgs/anyio/checksums.ini index 6559f060ac2..54c6718bec4 100644 --- a/build/pkgs/anyio/checksums.ini +++ b/build/pkgs/anyio/checksums.ini @@ -1,4 +1,4 @@ tarball=anyio-VERSION-py3-none-any.whl sha1=f5bd548b3a14c9c93622bf04f7c6464e3f44966a sha256=c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7 -upstream_url=https://pypi.io/packages/py3/a/anyio/anyio-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/a/anyio/anyio-VERSION-py3-none-any.whl diff --git a/build/pkgs/appdirs/checksums.ini b/build/pkgs/appdirs/checksums.ini index 0d44544631d..8e218bedd50 100644 --- a/build/pkgs/appdirs/checksums.ini +++ b/build/pkgs/appdirs/checksums.ini @@ -1,4 +1,4 @@ tarball=appdirs-VERSION-py2.py3-none-any.whl sha1=fc74022712122436427f8282a47bfa430ec2db56 sha256=a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128 -upstream_url=https://pypi.io/packages/py2.py3/a/appdirs/appdirs-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/a/appdirs/appdirs-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/appnope/checksums.ini b/build/pkgs/appnope/checksums.ini index 4e49f102dd5..8a91ec591b3 100644 --- a/build/pkgs/appnope/checksums.ini +++ b/build/pkgs/appnope/checksums.ini @@ -1,4 +1,4 @@ tarball=appnope-VERSION.tar.gz sha1=4dcd80020b345a184d6da6063a69e25b1d353323 sha256=1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee -upstream_url=https://pypi.io/packages/source/a/appnope/appnope-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/a/appnope/appnope-VERSION.tar.gz diff --git a/build/pkgs/argon2_cffi/checksums.ini b/build/pkgs/argon2_cffi/checksums.ini index acfeee93d3a..503f84c348e 100644 --- a/build/pkgs/argon2_cffi/checksums.ini +++ b/build/pkgs/argon2_cffi/checksums.ini @@ -1,4 +1,4 @@ tarball=argon2-cffi-VERSION.tar.gz sha1=c16c1506de0211bdfa23d4d51e780fb4aaff5222 sha256=d384164d944190a7dd7ef22c6aa3ff197da12962bd04b17f64d4e93d934dba5b -upstream_url=https://pypi.io/packages/source/a/argon2_cffi/argon2-cffi-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/a/argon2_cffi/argon2-cffi-VERSION.tar.gz diff --git a/build/pkgs/argon2_cffi_bindings/checksums.ini b/build/pkgs/argon2_cffi_bindings/checksums.ini index b0e7ade0b5a..1d190691c09 100644 --- a/build/pkgs/argon2_cffi_bindings/checksums.ini +++ b/build/pkgs/argon2_cffi_bindings/checksums.ini @@ -1,4 +1,4 @@ tarball=argon2-cffi-bindings-VERSION.tar.gz sha1=5a9b8906d9ca73c53c2bf0a2f0a8127fda69e965 sha256=bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3 -upstream_url=https://pypi.io/packages/source/a/argon2_cffi_bindings/argon2-cffi-bindings-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/a/argon2_cffi_bindings/argon2-cffi-bindings-VERSION.tar.gz diff --git a/build/pkgs/arrow/checksums.ini b/build/pkgs/arrow/checksums.ini index 5ac9740854e..bc3fd448d7f 100644 --- a/build/pkgs/arrow/checksums.ini +++ b/build/pkgs/arrow/checksums.ini @@ -1,4 +1,4 @@ tarball=arrow-VERSION-py3-none-any.whl sha1=fd9376ef4788dc2b1c981e6b5beb9048e046c556 sha256=c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80 -upstream_url=https://pypi.io/packages/py3/a/arrow/arrow-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/a/arrow/arrow-VERSION-py3-none-any.whl diff --git a/build/pkgs/asttokens/checksums.ini b/build/pkgs/asttokens/checksums.ini index d9de4a44ea3..aabceb9def5 100644 --- a/build/pkgs/asttokens/checksums.ini +++ b/build/pkgs/asttokens/checksums.ini @@ -1,4 +1,4 @@ tarball=asttokens-VERSION-py2.py3-none-any.whl sha1=69a9448cd7fad3007a66f464f9daa35dd28183a6 sha256=051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24 -upstream_url=https://pypi.io/packages/py2.py3/a/asttokens/asttokens-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/a/asttokens/asttokens-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/async_lru/checksums.ini b/build/pkgs/async_lru/checksums.ini index f1b60406ec1..a8022baf28d 100644 --- a/build/pkgs/async_lru/checksums.ini +++ b/build/pkgs/async_lru/checksums.ini @@ -1,4 +1,4 @@ tarball=async_lru-VERSION-py3-none-any.whl sha1=99b2ea5d551cbad28e08e45f0d0b00827f9ff73d sha256=ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224 -upstream_url=https://pypi.io/packages/py3/a/async_lru/async_lru-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/a/async_lru/async_lru-VERSION-py3-none-any.whl diff --git a/build/pkgs/attrs/checksums.ini b/build/pkgs/attrs/checksums.ini index 7d271509d6d..74bf62402c0 100644 --- a/build/pkgs/attrs/checksums.ini +++ b/build/pkgs/attrs/checksums.ini @@ -1,4 +1,4 @@ tarball=attrs-VERSION-py3-none-any.whl sha1=563b272af703f8960b76f6637d009fa5fc5864d3 sha256=99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1 -upstream_url=https://pypi.io/packages/py3/a/attrs/attrs-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/a/attrs/attrs-VERSION-py3-none-any.whl diff --git a/build/pkgs/babel/checksums.ini b/build/pkgs/babel/checksums.ini index 84e9171f829..c7604abf9dd 100644 --- a/build/pkgs/babel/checksums.ini +++ b/build/pkgs/babel/checksums.ini @@ -1,4 +1,4 @@ tarball=Babel-VERSION-py3-none-any.whl sha1=7f8671a725d0bbf28618841c441af8bd7709d527 sha256=efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287 -upstream_url=https://pypi.io/packages/py3/b/babel/Babel-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/b/babel/Babel-VERSION-py3-none-any.whl diff --git a/build/pkgs/beautifulsoup4/checksums.ini b/build/pkgs/beautifulsoup4/checksums.ini index 01abdd62940..9f2536bd011 100644 --- a/build/pkgs/beautifulsoup4/checksums.ini +++ b/build/pkgs/beautifulsoup4/checksums.ini @@ -1,4 +1,4 @@ tarball=beautifulsoup4-VERSION.tar.gz sha1=d9cd72f81e7710692b8ff0a42e69bf93375b5fd3 sha256=492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da -upstream_url=https://pypi.io/packages/source/b/beautifulsoup4/beautifulsoup4-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/b/beautifulsoup4/beautifulsoup4-VERSION.tar.gz diff --git a/build/pkgs/beniget/checksums.ini b/build/pkgs/beniget/checksums.ini index b7b3d25085b..a199e02756e 100644 --- a/build/pkgs/beniget/checksums.ini +++ b/build/pkgs/beniget/checksums.ini @@ -1,4 +1,4 @@ tarball=beniget-VERSION.tar.gz sha1=0167f16d17fbd61b91e620bca07e4ec7054ce51d sha256=75554b3b8ad0553ce2f607627dad3d95c60c441189875b98e097528f8e23ac0c -upstream_url=https://pypi.io/packages/source/b/beniget/beniget-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/b/beniget/beniget-VERSION.tar.gz diff --git a/build/pkgs/bleach/checksums.ini b/build/pkgs/bleach/checksums.ini index 575b1452888..3386c286912 100644 --- a/build/pkgs/bleach/checksums.ini +++ b/build/pkgs/bleach/checksums.ini @@ -1,4 +1,4 @@ tarball=bleach-VERSION-py3-none-any.whl sha1=7ba81a446171fb840d3083afadd0c87f0b599305 sha256=3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6 -upstream_url=https://pypi.io/packages/py3/b/bleach/bleach-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/b/bleach/bleach-VERSION-py3-none-any.whl diff --git a/build/pkgs/cachetools/checksums.ini b/build/pkgs/cachetools/checksums.ini index 29f982e9277..65e1aa547ea 100644 --- a/build/pkgs/cachetools/checksums.ini +++ b/build/pkgs/cachetools/checksums.ini @@ -1,4 +1,4 @@ tarball=cachetools-VERSION-py3-none-any.whl sha1=4210b349f838f75d64da22fbef7e5dc8e494c5f6 sha256=0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945 -upstream_url=https://pypi.io/packages/py3/c/cachetools/cachetools-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/c/cachetools/cachetools-VERSION-py3-none-any.whl diff --git a/build/pkgs/calver/checksums.ini b/build/pkgs/calver/checksums.ini index 8c23449b03d..d3a4c14c1d6 100644 --- a/build/pkgs/calver/checksums.ini +++ b/build/pkgs/calver/checksums.ini @@ -1,4 +1,4 @@ tarball=calver-VERSION-py3-none-any.whl sha1=4553e3fbfc58908f3be2dd529e5991986f6a46b5 sha256=a1d7fcdd67797afc52ee36ffb8c8adf6643173864306547bfd1380cbce6310a0 -upstream_url=https://pypi.io/packages/py3/c/calver/calver-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/c/calver/calver-VERSION-py3-none-any.whl diff --git a/build/pkgs/certifi/checksums.ini b/build/pkgs/certifi/checksums.ini index ecb9291cd62..d11756ecfa1 100644 --- a/build/pkgs/certifi/checksums.ini +++ b/build/pkgs/certifi/checksums.ini @@ -1,4 +1,4 @@ tarball=certifi-VERSION-py3-none-any.whl sha1=4acb42f49aed94aeb687b33d3dcb6b564ff36fac sha256=dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1 -upstream_url=https://pypi.io/packages/py3/c/certifi/certifi-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/c/certifi/certifi-VERSION-py3-none-any.whl diff --git a/build/pkgs/cffi/checksums.ini b/build/pkgs/cffi/checksums.ini index 6b22c299649..8ae4939c66b 100644 --- a/build/pkgs/cffi/checksums.ini +++ b/build/pkgs/cffi/checksums.ini @@ -1,4 +1,4 @@ tarball=cffi-VERSION.tar.gz sha1=c42a46cd11f6153f299cf10e9c236e8b2a143c21 sha256=d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9 -upstream_url=https://pypi.io/packages/source/c/cffi/cffi-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/c/cffi/cffi-VERSION.tar.gz diff --git a/build/pkgs/chardet/checksums.ini b/build/pkgs/chardet/checksums.ini index 8bce7750395..e5efde10ffe 100644 --- a/build/pkgs/chardet/checksums.ini +++ b/build/pkgs/chardet/checksums.ini @@ -1,4 +1,4 @@ tarball=chardet-VERSION-py3-none-any.whl sha1=2facc0387556aa8a2956ef682d49fc3eae56d30a sha256=e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970 -upstream_url=https://pypi.io/packages/py3/c/chardet/chardet-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/c/chardet/chardet-VERSION-py3-none-any.whl diff --git a/build/pkgs/charset_normalizer/checksums.ini b/build/pkgs/charset_normalizer/checksums.ini index 0530b566631..627fa73f7cc 100644 --- a/build/pkgs/charset_normalizer/checksums.ini +++ b/build/pkgs/charset_normalizer/checksums.ini @@ -1,4 +1,4 @@ tarball=charset_normalizer-VERSION-py3-none-any.whl sha1=1aa12424059bec1d95d9dda38b4ff6d062dededf sha256=3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc -upstream_url=https://pypi.io/packages/py3/c/charset_normalizer/charset_normalizer-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/c/charset_normalizer/charset_normalizer-VERSION-py3-none-any.whl diff --git a/build/pkgs/colorama/checksums.ini b/build/pkgs/colorama/checksums.ini index 3332565f156..99a9ca97c72 100644 --- a/build/pkgs/colorama/checksums.ini +++ b/build/pkgs/colorama/checksums.ini @@ -1,4 +1,4 @@ tarball=colorama-VERSION-py2.py3-none-any.whl sha1=d6ab1608850fecfc0e1cf50bf93d743695c04027 sha256=4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 -upstream_url=https://pypi.io/packages/py2.py3/c/colorama/colorama-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/c/colorama/colorama-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/comm/checksums.ini b/build/pkgs/comm/checksums.ini index 34f21ec0087..66845adf128 100644 --- a/build/pkgs/comm/checksums.ini +++ b/build/pkgs/comm/checksums.ini @@ -1,4 +1,4 @@ tarball=comm-VERSION-py3-none-any.whl sha1=e7e20f9c1524a9fe059c0b6df90a68e1cd2115a9 sha256=6d52794cba11b36ed9860999cd10fd02d6b2eac177068fdd585e1e2f8a96e67a -upstream_url=https://pypi.io/packages/py3/c/comm/comm-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/c/comm/comm-VERSION-py3-none-any.whl diff --git a/build/pkgs/contourpy/checksums.ini b/build/pkgs/contourpy/checksums.ini index 2823ef85c08..236ca51affa 100644 --- a/build/pkgs/contourpy/checksums.ini +++ b/build/pkgs/contourpy/checksums.ini @@ -1,4 +1,4 @@ tarball=contourpy-VERSION.tar.gz sha1=eb8520cb7172aa8b957d8ba2d09e8f6d9a068d2a sha256=96ba37c2e24b7212a77da85004c38e7c4d155d3e72a45eeaf22c1f03f607e8ab -upstream_url=https://pypi.io/packages/source/c/contourpy/contourpy-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/c/contourpy/contourpy-VERSION.tar.gz diff --git a/build/pkgs/conway_polynomials/checksums.ini b/build/pkgs/conway_polynomials/checksums.ini index ee7479822ee..a3c4ebf5935 100644 --- a/build/pkgs/conway_polynomials/checksums.ini +++ b/build/pkgs/conway_polynomials/checksums.ini @@ -1,4 +1,4 @@ tarball=conway_polynomials-VERSION-py3-none-any.whl sha1=8d61cb30eb96dfce883a5761d08d45fcb035608a sha256=a354b4ac0a9985da75e2ac6ec6d7de2902396eff48913eeed86a962486171c28 -upstream_url=https://pypi.io/packages/py3/c/conway_polynomials/conway_polynomials-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/c/conway_polynomials/conway_polynomials-VERSION-py3-none-any.whl diff --git a/build/pkgs/cppy/checksums.ini b/build/pkgs/cppy/checksums.ini index d042532c770..93861c8add7 100644 --- a/build/pkgs/cppy/checksums.ini +++ b/build/pkgs/cppy/checksums.ini @@ -1,4 +1,4 @@ tarball=cppy-VERSION-py3-none-any.whl sha1=57304a8ceaaf7cb34e4315aa9b8084b17fc0332c sha256=c5b5eac3d3f42593a07d35275b0bc27f447b76b9ad8f27c62e3cfa286dc1988a -upstream_url=https://pypi.io/packages/py3/c/cppy/cppy-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/c/cppy/cppy-VERSION-py3-none-any.whl diff --git a/build/pkgs/cvxopt/checksums.ini b/build/pkgs/cvxopt/checksums.ini index ca2f4711f5d..bdfc701c912 100644 --- a/build/pkgs/cvxopt/checksums.ini +++ b/build/pkgs/cvxopt/checksums.ini @@ -1,4 +1,4 @@ tarball=cvxopt-VERSION.tar.gz sha1=f9c3c3fb61e87d27f05b3b66bc10734d5e6284e6 sha256=3461fa42c1b2240ba4da1d985ca73503914157fc4c77417327ed6d7d85acdbe6 -upstream_url=https://pypi.io/packages/source/c/cvxopt/cvxopt-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/c/cvxopt/cvxopt-VERSION.tar.gz diff --git a/build/pkgs/cvxpy/checksums.ini b/build/pkgs/cvxpy/checksums.ini index 025278a9b01..49a7ebfbab0 100644 --- a/build/pkgs/cvxpy/checksums.ini +++ b/build/pkgs/cvxpy/checksums.ini @@ -1,4 +1,4 @@ tarball=cvxpy-VERSION.tar.gz sha1=1ca24d9e2ee5add13b33724ab9a11e747fe4ed99 sha256=7a9ef34e3c57ff8c844d86f0a3834fb5575af19233947639de0ba577c6122e3e -upstream_url=https://pypi.io/packages/source/c/cvxpy/cvxpy-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/c/cvxpy/cvxpy-VERSION.tar.gz diff --git a/build/pkgs/cylp/checksums.ini b/build/pkgs/cylp/checksums.ini index d4f3ea9867b..6a053d1deed 100644 --- a/build/pkgs/cylp/checksums.ini +++ b/build/pkgs/cylp/checksums.ini @@ -1,4 +1,4 @@ tarball=cylp-VERSION.tar.gz sha1=22398052ca88123b77e691a0045806a030c9b259 sha256=a7ee226caa274e190338da3d24314647df7e06599ab38cdd26c005d8b8258b16 -upstream_url=https://pypi.io/packages/source/c/cylp/cylp-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/c/cylp/cylp-VERSION.tar.gz diff --git a/build/pkgs/cypari/checksums.ini b/build/pkgs/cypari/checksums.ini index d183b3c567a..1ead9490d1a 100644 --- a/build/pkgs/cypari/checksums.ini +++ b/build/pkgs/cypari/checksums.ini @@ -1,4 +1,4 @@ tarball=cypari2-VERSION.tar.gz sha1=4e9f14d218bc1cea29e03a2ceec9bf3dfbfd5eb3 sha256=817606bf661b71d33e1d012421907a4f8fb09dd81b7d3e3ae179b3978020bbf1 -upstream_url=https://pypi.io/packages/source/c/cypari2/cypari2-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/c/cypari2/cypari2-VERSION.tar.gz diff --git a/build/pkgs/cysignals/checksums.ini b/build/pkgs/cysignals/checksums.ini index 6bf5ec53eaa..8ba1030ffdf 100644 --- a/build/pkgs/cysignals/checksums.ini +++ b/build/pkgs/cysignals/checksums.ini @@ -1,4 +1,4 @@ tarball=cysignals-VERSION.tar.gz sha1=76db7aa59d55e867c83b329c017382555253af43 sha256=0f1e321e55a07f901c86a36a1e4497f6ff9dfe700681d0130a38c36e4eb238c3 -upstream_url=https://pypi.io/packages/source/c/cysignals/cysignals-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/c/cysignals/cysignals-VERSION.tar.gz diff --git a/build/pkgs/cython/checksums.ini b/build/pkgs/cython/checksums.ini index e463df31628..3eb199915d7 100644 --- a/build/pkgs/cython/checksums.ini +++ b/build/pkgs/cython/checksums.ini @@ -1,4 +1,4 @@ tarball=cython-VERSION.tar.gz sha1=f692b0c6f209b75b6bbd69bdbd57fac23785c23e sha256=7146dd2af8682b4ca61331851e6aebce9fe5158e75300343f80c07ca80b1faff -upstream_url=https://pypi.io/packages/source/c/cython/cython-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/c/cython/cython-VERSION.tar.gz diff --git a/build/pkgs/database_cubic_hecke/checksums.ini b/build/pkgs/database_cubic_hecke/checksums.ini index 8cc4e5407c4..830cae1c1eb 100644 --- a/build/pkgs/database_cubic_hecke/checksums.ini +++ b/build/pkgs/database_cubic_hecke/checksums.ini @@ -1,4 +1,4 @@ tarball=database_cubic_hecke-VERSION.tar.gz sha1=a99713c94e4108f917aa354f53edc26a60fd3808 sha256=553654a4ce987a277fe956a9a450d738bd1f58b96c45499075e28f2bca927ae9 -upstream_url=https://pypi.io/packages/source/d/database_cubic_hecke/database_cubic_hecke-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/d/database_cubic_hecke/database_cubic_hecke-VERSION.tar.gz diff --git a/build/pkgs/database_knotinfo/checksums.ini b/build/pkgs/database_knotinfo/checksums.ini index d6116d6d0d3..cbccff452f7 100644 --- a/build/pkgs/database_knotinfo/checksums.ini +++ b/build/pkgs/database_knotinfo/checksums.ini @@ -1,4 +1,4 @@ tarball=database_knotinfo-VERSION.tar.gz sha1=8bc72e561c009cc6a7c15eceedee522281fbf763 sha256=805868c8f3c30888e5866d833aec4f9ab07ad92b7b7caeb09bfec4634b28b0fd -upstream_url=https://pypi.io/packages/source/d/database_knotinfo/database_knotinfo-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/d/database_knotinfo/database_knotinfo-VERSION.tar.gz diff --git a/build/pkgs/dateutil/checksums.ini b/build/pkgs/dateutil/checksums.ini index e4cd473a834..a20d118ea27 100644 --- a/build/pkgs/dateutil/checksums.ini +++ b/build/pkgs/dateutil/checksums.ini @@ -1,4 +1,4 @@ tarball=python_dateutil-VERSION-py2.py3-none-any.whl sha1=323a8e8de7e00a254fadae9c77b1264d56525178 sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 -upstream_url=https://pypi.io/packages/py2.py3/p/python_dateutil/python_dateutil-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/p/python_dateutil/python_dateutil-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/debugpy/checksums.ini b/build/pkgs/debugpy/checksums.ini index 1879bd6e197..8d3c15e3ae0 100644 --- a/build/pkgs/debugpy/checksums.ini +++ b/build/pkgs/debugpy/checksums.ini @@ -1,4 +1,4 @@ tarball=debugpy-VERSION-py2.py3-none-any.whl sha1=cc85be805ef4f25e85bae65cf5b04badca032bb6 sha256=28acbe2241222b87e255260c76741e1fbf04fdc3b6d094fcf57b6c6f75ce1242 -upstream_url=https://pypi.io/packages/py2.py3/d/debugpy/debugpy-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/d/debugpy/debugpy-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/decorator/checksums.ini b/build/pkgs/decorator/checksums.ini index daaa14c6732..bec87842238 100644 --- a/build/pkgs/decorator/checksums.ini +++ b/build/pkgs/decorator/checksums.ini @@ -1,4 +1,4 @@ tarball=decorator-VERSION.tar.gz sha1=929f42916ac8a4aa973599d558768b8f1728db46 sha256=637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330 -upstream_url=https://pypi.io/packages/source/d/decorator/decorator-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/d/decorator/decorator-VERSION.tar.gz diff --git a/build/pkgs/defusedxml/checksums.ini b/build/pkgs/defusedxml/checksums.ini index a6da3a2e278..1faa620fcc7 100644 --- a/build/pkgs/defusedxml/checksums.ini +++ b/build/pkgs/defusedxml/checksums.ini @@ -1,4 +1,4 @@ tarball=defusedxml-VERSION.tar.gz sha1=37667af1dc1357eb96b005c4f408ad5292d77b9f sha256=1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 -upstream_url=https://pypi.io/packages/source/d/defusedxml/defusedxml-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/d/defusedxml/defusedxml-VERSION.tar.gz diff --git a/build/pkgs/distlib/checksums.ini b/build/pkgs/distlib/checksums.ini index bd456ec2028..f5fc1bc145d 100644 --- a/build/pkgs/distlib/checksums.ini +++ b/build/pkgs/distlib/checksums.ini @@ -1,4 +1,4 @@ tarball=distlib-VERSION-py2.py3-none-any.whl sha1=97ea3bb71040f0348eaea272ec17fefea5806e87 sha256=034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 -upstream_url=https://pypi.io/packages/py2.py3/d/distlib/distlib-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/d/distlib/distlib-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/docutils/checksums.ini b/build/pkgs/docutils/checksums.ini index 472701e55d7..20bc4e5c415 100644 --- a/build/pkgs/docutils/checksums.ini +++ b/build/pkgs/docutils/checksums.ini @@ -1,4 +1,4 @@ tarball=docutils-VERSION-py3-none-any.whl sha1=a2120453cdb1498128183696711261dd5f328068 sha256=dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 -upstream_url=https://pypi.io/packages/py3/d/docutils/docutils-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/d/docutils/docutils-VERSION-py3-none-any.whl diff --git a/build/pkgs/ecos_python/checksums.ini b/build/pkgs/ecos_python/checksums.ini index 1b5791948e7..60d0d8b9728 100644 --- a/build/pkgs/ecos_python/checksums.ini +++ b/build/pkgs/ecos_python/checksums.ini @@ -1,4 +1,4 @@ tarball=ecos-VERSION.tar.gz sha1=7afce63aec44522052e05fa2e1c82e12fe20fd45 sha256=f48816d73b87ae325556ea537b7c8743187311403c80e3832035224156337c4e -upstream_url=https://pypi.io/packages/source/e/ecos/ecos-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/e/ecos/ecos-VERSION.tar.gz diff --git a/build/pkgs/editables/checksums.ini b/build/pkgs/editables/checksums.ini index 6470e5fd5d2..3c0fda846a1 100644 --- a/build/pkgs/editables/checksums.ini +++ b/build/pkgs/editables/checksums.ini @@ -1,4 +1,4 @@ tarball=editables-VERSION-py3-none-any.whl sha1=7aa90de86b05d6dc1a04c219b01ca7eab09de113 sha256=61e5ffa82629e0d8bfe09bc44a07db3c1ab8ed1ce78a6980732870f19b5e7d4c -upstream_url=https://pypi.io/packages/py3/e/editables/editables-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/e/editables/editables-VERSION-py3-none-any.whl diff --git a/build/pkgs/entrypoints/checksums.ini b/build/pkgs/entrypoints/checksums.ini index 60bb1387477..529229debcc 100644 --- a/build/pkgs/entrypoints/checksums.ini +++ b/build/pkgs/entrypoints/checksums.ini @@ -1,4 +1,4 @@ tarball=entrypoints-VERSION.tar.gz sha1=ca5c5976781db7ec6e8faece06af31ff32960529 sha256=b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4 -upstream_url=https://pypi.io/packages/source/e/entrypoints/entrypoints-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/e/entrypoints/entrypoints-VERSION.tar.gz diff --git a/build/pkgs/exceptiongroup/checksums.ini b/build/pkgs/exceptiongroup/checksums.ini index d42fab6a958..70e89792f64 100644 --- a/build/pkgs/exceptiongroup/checksums.ini +++ b/build/pkgs/exceptiongroup/checksums.ini @@ -1,4 +1,4 @@ tarball=exceptiongroup-VERSION-py3-none-any.whl sha1=fd04443cb88d35ee59387ba20f62761ea5546a7d sha256=3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b -upstream_url=https://pypi.io/packages/py3/e/exceptiongroup/exceptiongroup-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/e/exceptiongroup/exceptiongroup-VERSION-py3-none-any.whl diff --git a/build/pkgs/execnet/checksums.ini b/build/pkgs/execnet/checksums.ini index ee938e17c8b..5e6df579af0 100644 --- a/build/pkgs/execnet/checksums.ini +++ b/build/pkgs/execnet/checksums.ini @@ -1,4 +1,4 @@ tarball=execnet-VERSION-py3-none-any.whl sha1=3a3b88b478a03a9c9933a7bdaea3224a118cc121 sha256=26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc -upstream_url=https://pypi.io/packages/py3/e/execnet/execnet-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/e/execnet/execnet-VERSION-py3-none-any.whl diff --git a/build/pkgs/executing/checksums.ini b/build/pkgs/executing/checksums.ini index c316d78954d..9f519f28788 100644 --- a/build/pkgs/executing/checksums.ini +++ b/build/pkgs/executing/checksums.ini @@ -1,4 +1,4 @@ tarball=executing-VERSION-py2.py3-none-any.whl sha1=c32699ff6868bf3613d56795016880fdadde4fc6 sha256=eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc -upstream_url=https://pypi.io/packages/py2.py3/e/executing/executing-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/e/executing/executing-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/fastjsonschema/checksums.ini b/build/pkgs/fastjsonschema/checksums.ini index ae58c4c8577..7d5c2bc7709 100644 --- a/build/pkgs/fastjsonschema/checksums.ini +++ b/build/pkgs/fastjsonschema/checksums.ini @@ -1,4 +1,4 @@ tarball=fastjsonschema-VERSION.tar.gz sha1=eab76262783dd81303e2b1da0914a1d5a7f388aa sha256=e820349dd16f806e4bd1467a138dced9def4bc7d6213a34295272a6cac95b5bd -upstream_url=https://pypi.io/packages/source/f/fastjsonschema/fastjsonschema-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/f/fastjsonschema/fastjsonschema-VERSION.tar.gz diff --git a/build/pkgs/filelock/checksums.ini b/build/pkgs/filelock/checksums.ini index e6fc5ecc6f5..57883a7087d 100644 --- a/build/pkgs/filelock/checksums.ini +++ b/build/pkgs/filelock/checksums.ini @@ -1,4 +1,4 @@ tarball=filelock-VERSION-py3-none-any.whl sha1=475b56870663924527abcf2f91b7d8dd7a7ab0ee sha256=43339835842f110ca7ae60f1e1c160714c5a6afd15a2873419ab185334975c0f -upstream_url=https://pypi.io/packages/py3/f/filelock/filelock-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/f/filelock/filelock-VERSION-py3-none-any.whl diff --git a/build/pkgs/flit_core/checksums.ini b/build/pkgs/flit_core/checksums.ini index 0a40b9891b2..ca7a757151c 100644 --- a/build/pkgs/flit_core/checksums.ini +++ b/build/pkgs/flit_core/checksums.ini @@ -1,4 +1,4 @@ tarball=flit_core-VERSION-py3-none-any.whl sha1=cf044db53e986d0735ad708cce9eba0b71684168 sha256=7aada352fb0c7f5538c4fafeddf314d3a6a92ee8e2b1de70482329e42de70301 -upstream_url=https://pypi.io/packages/py3/f/flit_core/flit_core-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/f/flit_core/flit_core-VERSION-py3-none-any.whl diff --git a/build/pkgs/fonttools/checksums.ini b/build/pkgs/fonttools/checksums.ini index 7cb3b54ce86..f1da656f164 100644 --- a/build/pkgs/fonttools/checksums.ini +++ b/build/pkgs/fonttools/checksums.ini @@ -1,4 +1,4 @@ tarball=fonttools-VERSION.tar.gz sha1=5432f0273040b044e8d6465947e3a4c00097bdbf sha256=c391cd5af88aacaf41dd7cfb96eeedfad297b5899a39e12f4c2c3706d0a3329d -upstream_url=https://pypi.io/packages/source/f/fonttools/fonttools-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/f/fonttools/fonttools-VERSION.tar.gz diff --git a/build/pkgs/fpylll/checksums.ini b/build/pkgs/fpylll/checksums.ini index 5f258e7518e..188e768b787 100644 --- a/build/pkgs/fpylll/checksums.ini +++ b/build/pkgs/fpylll/checksums.ini @@ -1,4 +1,4 @@ tarball=fpylll-VERSION.tar.gz sha1=c0bcf8c5583ebf614da9b26710a2c835d498bf34 sha256=dfd9529a26c50993a2a716177debd7994312219070574cad31b35b4f0c040a19 -upstream_url=https://pypi.io/packages/source/f/fpylll/fpylll-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/f/fpylll/fpylll-VERSION.tar.gz diff --git a/build/pkgs/fqdn/checksums.ini b/build/pkgs/fqdn/checksums.ini index 2e3cdea93c6..e12be04eb2c 100644 --- a/build/pkgs/fqdn/checksums.ini +++ b/build/pkgs/fqdn/checksums.ini @@ -1,4 +1,4 @@ tarball=fqdn-VERSION-py3-none-any.whl sha1=85a7ac7d7f45d2e0b64c4b7653ab277ceec91ecf sha256=3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014 -upstream_url=https://pypi.io/packages/py3/f/fqdn/fqdn-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/f/fqdn/fqdn-VERSION-py3-none-any.whl diff --git a/build/pkgs/furo/checksums.ini b/build/pkgs/furo/checksums.ini index eaeef993c08..492fede82ba 100644 --- a/build/pkgs/furo/checksums.ini +++ b/build/pkgs/furo/checksums.ini @@ -1,4 +1,4 @@ tarball=furo-VERSION-py3-none-any.whl sha1=de4aa7aff48696580d62abed717bf1c309af10f5 sha256=b192c7c1f59805494c8ed606d9375fdac6e6ba8178e747e72bc116745fb7e13f -upstream_url=https://pypi.io/packages/py3/f/furo/furo-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/f/furo/furo-VERSION-py3-none-any.whl diff --git a/build/pkgs/gast/checksums.ini b/build/pkgs/gast/checksums.ini index 6035bc7c22d..83cdc0ef554 100644 --- a/build/pkgs/gast/checksums.ini +++ b/build/pkgs/gast/checksums.ini @@ -1,4 +1,4 @@ tarball=gast-VERSION.tar.gz sha1=6c113cf8d33cc654d33210335103485ab41d3dbb sha256=9c270fe5f4b130969b54174de7db4e764b09b4f7f67ccfc32480e29f78348d97 -upstream_url=https://pypi.io/packages/source/g/gast/gast-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/g/gast/gast-VERSION.tar.gz diff --git a/build/pkgs/gmpy2/checksums.ini b/build/pkgs/gmpy2/checksums.ini index 34824279321..17b85732d44 100644 --- a/build/pkgs/gmpy2/checksums.ini +++ b/build/pkgs/gmpy2/checksums.ini @@ -1,4 +1,4 @@ tarball=gmpy2-VERSION.tar.gz sha1=700ef438964acd286d52e973a833cd57ae9a7ad7 sha256=3b8acc939a40411a8ad5541ed178ff866dd1759e667ee26fe34c9291b6b350c3 -upstream_url=https://pypi.io/packages/source/g/gmpy2/gmpy2-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/g/gmpy2/gmpy2-VERSION.tar.gz diff --git a/build/pkgs/gnumake_tokenpool/checksums.ini b/build/pkgs/gnumake_tokenpool/checksums.ini index 889f64341f2..92f70df3c3f 100644 --- a/build/pkgs/gnumake_tokenpool/checksums.ini +++ b/build/pkgs/gnumake_tokenpool/checksums.ini @@ -1,4 +1,4 @@ tarball=gnumake_tokenpool-VERSION-py3-none-any.whl sha1=882c694dc3c0a935275a8d2acd9e766399719754 sha256=0c49578df1a76b6ff7724b99053d96f1583bd3e52fe9547587cfb6ffdb0d1fcd -upstream_url=https://pypi.io/packages/py3/g/gnumake_tokenpool/gnumake_tokenpool-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/g/gnumake_tokenpool/gnumake_tokenpool-VERSION-py3-none-any.whl diff --git a/build/pkgs/h11/checksums.ini b/build/pkgs/h11/checksums.ini index 8e1952d648a..9cf02f6021d 100644 --- a/build/pkgs/h11/checksums.ini +++ b/build/pkgs/h11/checksums.ini @@ -1,4 +1,4 @@ tarball=h11-VERSION-py3-none-any.whl sha1=c502d56dc3288212142a398704a5109749331dd8 sha256=e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761 -upstream_url=https://pypi.io/packages/py3/h/h11/h11-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/h/h11/h11-VERSION-py3-none-any.whl diff --git a/build/pkgs/hatchling/checksums.ini b/build/pkgs/hatchling/checksums.ini index 1d456db2d53..4c75e2006b2 100644 --- a/build/pkgs/hatchling/checksums.ini +++ b/build/pkgs/hatchling/checksums.ini @@ -1,4 +1,4 @@ tarball=hatchling-VERSION-py3-none-any.whl sha1=cae79d374a238c7674687fb4fff0b15cf1af9be4 sha256=b47948e45d4d973034584dd4cb39c14b6a70227cf287ab7ec0ad7983408a882c -upstream_url=https://pypi.io/packages/py3/h/hatchling/hatchling-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/h/hatchling/hatchling-VERSION-py3-none-any.whl diff --git a/build/pkgs/httpcore/checksums.ini b/build/pkgs/httpcore/checksums.ini index 21cb43c4bf6..e489278fdac 100644 --- a/build/pkgs/httpcore/checksums.ini +++ b/build/pkgs/httpcore/checksums.ini @@ -1,4 +1,4 @@ tarball=httpcore-VERSION-py3-none-any.whl sha1=52c8337dcf474d63f5b053e0f65cf79714ae69fe sha256=421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5 -upstream_url=https://pypi.io/packages/py3/h/httpcore/httpcore-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/h/httpcore/httpcore-VERSION-py3-none-any.whl diff --git a/build/pkgs/httpx/checksums.ini b/build/pkgs/httpx/checksums.ini index adc2d9ae791..e1f0fe5fd9a 100644 --- a/build/pkgs/httpx/checksums.ini +++ b/build/pkgs/httpx/checksums.ini @@ -1,4 +1,4 @@ tarball=httpx-VERSION-py3-none-any.whl sha1=01f2a657e43842cb7c8dda30d38860fa741acb7e sha256=71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5 -upstream_url=https://pypi.io/packages/py3/h/httpx/httpx-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/h/httpx/httpx-VERSION-py3-none-any.whl diff --git a/build/pkgs/idna/checksums.ini b/build/pkgs/idna/checksums.ini index b3a22afe657..ad7a4b77355 100644 --- a/build/pkgs/idna/checksums.ini +++ b/build/pkgs/idna/checksums.ini @@ -1,4 +1,4 @@ tarball=idna-VERSION-py3-none-any.whl sha1=ccb2491074ec1b6ffda6e6c11c1c668f885ed20a sha256=82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0 -upstream_url=https://pypi.io/packages/py3/i/idna/idna-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/i/idna/idna-VERSION-py3-none-any.whl diff --git a/build/pkgs/imagesize/checksums.ini b/build/pkgs/imagesize/checksums.ini index 75413be5c69..8eb70146ee6 100644 --- a/build/pkgs/imagesize/checksums.ini +++ b/build/pkgs/imagesize/checksums.ini @@ -1,4 +1,4 @@ tarball=imagesize-VERSION-py2.py3-none-any.whl sha1=6054e528ed40a9979df9952437a20c3e5773d972 sha256=0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b -upstream_url=https://pypi.io/packages/py2.py3/i/imagesize/imagesize-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/i/imagesize/imagesize-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/importlib_metadata/checksums.ini b/build/pkgs/importlib_metadata/checksums.ini index d21661c6dbc..28ed6e985bc 100644 --- a/build/pkgs/importlib_metadata/checksums.ini +++ b/build/pkgs/importlib_metadata/checksums.ini @@ -1,4 +1,4 @@ tarball=importlib_metadata-VERSION-py3-none-any.whl sha1=82c9e2e6cfbb2d5a14558085efa65e75a95bd12f sha256=4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e -upstream_url=https://pypi.io/packages/py3/i/importlib_metadata/importlib_metadata-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/i/importlib_metadata/importlib_metadata-VERSION-py3-none-any.whl diff --git a/build/pkgs/importlib_resources/checksums.ini b/build/pkgs/importlib_resources/checksums.ini index c4025635c2f..da8792a31ec 100644 --- a/build/pkgs/importlib_resources/checksums.ini +++ b/build/pkgs/importlib_resources/checksums.ini @@ -1,4 +1,4 @@ tarball=importlib_resources-VERSION-py3-none-any.whl sha1=5caa4e8a9ee93123a5c3badb6edbc009b5d8494a sha256=e8bf90d8213b486f428c9c39714b920041cb02c184686a3dee24905aaa8105d6 -upstream_url=https://pypi.io/packages/py3/i/importlib_resources/importlib_resources-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/i/importlib_resources/importlib_resources-VERSION-py3-none-any.whl diff --git a/build/pkgs/iniconfig/checksums.ini b/build/pkgs/iniconfig/checksums.ini index 4067da0dcc5..d85d4d0accb 100644 --- a/build/pkgs/iniconfig/checksums.ini +++ b/build/pkgs/iniconfig/checksums.ini @@ -1,4 +1,4 @@ tarball=iniconfig-VERSION-py3-none-any.whl sha1=ec7addd8337eee38e86554d2f0f114f8a1c74b20 sha256=b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 -upstream_url=https://pypi.io/packages/py3/i/iniconfig/iniconfig-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/i/iniconfig/iniconfig-VERSION-py3-none-any.whl diff --git a/build/pkgs/ipykernel/checksums.ini b/build/pkgs/ipykernel/checksums.ini index ccb54046f0a..31a3bf15856 100644 --- a/build/pkgs/ipykernel/checksums.ini +++ b/build/pkgs/ipykernel/checksums.ini @@ -1,4 +1,4 @@ tarball=ipykernel-VERSION.tar.gz sha1=3465b4aa523705e930f295b5c549924e376a02e2 sha256=7d5d594b6690654b4d299edba5e872dc17bb7396a8d0609c97cb7b8a1c605de6 -upstream_url=https://pypi.io/packages/source/i/ipykernel/ipykernel-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/i/ipykernel/ipykernel-VERSION.tar.gz diff --git a/build/pkgs/ipympl/checksums.ini b/build/pkgs/ipympl/checksums.ini index ec23f194f50..45891ffb95d 100644 --- a/build/pkgs/ipympl/checksums.ini +++ b/build/pkgs/ipympl/checksums.ini @@ -1,4 +1,4 @@ tarball=ipympl-VERSION-py2.py3-none-any.whl sha1=9848409026669d9edd83074730d7e2456ae8a187 sha256=d113cd55891bafe9b27ef99b6dd111a87beb6bb2ae550c404292272103be8013 -upstream_url=https://pypi.io/packages/py2.py3/i/ipympl/ipympl-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/i/ipympl/ipympl-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/ipython/checksums.ini b/build/pkgs/ipython/checksums.ini index 0f7cc9c7d51..b22fa04d1e1 100644 --- a/build/pkgs/ipython/checksums.ini +++ b/build/pkgs/ipython/checksums.ini @@ -1,4 +1,4 @@ tarball=ipython-VERSION.tar.gz sha1=4b5ab06a1b5e1a3285ac91d7dac9a22d18898a31 sha256=ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27 -upstream_url=https://pypi.io/packages/source/i/ipython/ipython-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/i/ipython/ipython-VERSION.tar.gz diff --git a/build/pkgs/ipywidgets/checksums.ini b/build/pkgs/ipywidgets/checksums.ini index ad3dca0b6d8..33f8b3193dc 100644 --- a/build/pkgs/ipywidgets/checksums.ini +++ b/build/pkgs/ipywidgets/checksums.ini @@ -1,4 +1,4 @@ tarball=ipywidgets-VERSION.tar.gz sha1=95f7ec13e8ce75e2da40c1789b4af291946a6d99 sha256=40211efb556adec6fa450ccc2a77d59ca44a060f4f9f136833df59c9f538e6e8 -upstream_url=https://pypi.io/packages/source/i/ipywidgets/ipywidgets-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/i/ipywidgets/ipywidgets-VERSION.tar.gz diff --git a/build/pkgs/isoduration/checksums.ini b/build/pkgs/isoduration/checksums.ini index d3e080d1982..5b4c48333b5 100644 --- a/build/pkgs/isoduration/checksums.ini +++ b/build/pkgs/isoduration/checksums.ini @@ -1,4 +1,4 @@ tarball=isoduration-VERSION-py3-none-any.whl sha1=a113878d368fee6881efcfd12421b12f8e6ae11c sha256=b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042 -upstream_url=https://pypi.io/packages/py3/i/isoduration/isoduration-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/i/isoduration/isoduration-VERSION-py3-none-any.whl diff --git a/build/pkgs/jedi/checksums.ini b/build/pkgs/jedi/checksums.ini index bbfe9535f75..f7e115e80ec 100644 --- a/build/pkgs/jedi/checksums.ini +++ b/build/pkgs/jedi/checksums.ini @@ -1,4 +1,4 @@ tarball=jedi-VERSION.tar.gz sha1=07d1e04c24cecf1b7f38f8905ce81c006f76cc20 sha256=cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd -upstream_url=https://pypi.io/packages/source/j/jedi/jedi-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/j/jedi/jedi-VERSION.tar.gz diff --git a/build/pkgs/jinja2/checksums.ini b/build/pkgs/jinja2/checksums.ini index 8f1cd2ceb6a..b68ec8b0fe0 100644 --- a/build/pkgs/jinja2/checksums.ini +++ b/build/pkgs/jinja2/checksums.ini @@ -1,4 +1,4 @@ tarball=jinja2-VERSION-py3-none-any.whl sha1=57760ed83d9ad15fcdf63ad1ffa14941333ef655 sha256=bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d -upstream_url=https://pypi.io/packages/py3/j/jinja2/jinja2-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/j/jinja2/jinja2-VERSION-py3-none-any.whl diff --git a/build/pkgs/json5/checksums.ini b/build/pkgs/json5/checksums.ini index d95e497ddc7..af94454a5b0 100644 --- a/build/pkgs/json5/checksums.ini +++ b/build/pkgs/json5/checksums.ini @@ -1,4 +1,4 @@ tarball=json5-VERSION-py2.py3-none-any.whl sha1=54bf91b9c2812e82ccd212cefca5bc5607a538b4 sha256=740c7f1b9e584a468dbb2939d8d458db3427f2c93ae2139d05f47e453eae964f -upstream_url=https://pypi.io/packages/py2.py3/j/json5/json5-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/j/json5/json5-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/jsonpointer/checksums.ini b/build/pkgs/jsonpointer/checksums.ini index df24503fc54..a0718fcd7d0 100644 --- a/build/pkgs/jsonpointer/checksums.ini +++ b/build/pkgs/jsonpointer/checksums.ini @@ -1,4 +1,4 @@ tarball=jsonpointer-VERSION-py2.py3-none-any.whl sha1=de1b07c2d014f5b8e672cf0fb1225b2232d0b414 sha256=15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a -upstream_url=https://pypi.io/packages/py2.py3/j/jsonpointer/jsonpointer-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/j/jsonpointer/jsonpointer-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/jsonschema/checksums.ini b/build/pkgs/jsonschema/checksums.ini index e709e36e5d3..61c920e4de7 100644 --- a/build/pkgs/jsonschema/checksums.ini +++ b/build/pkgs/jsonschema/checksums.ini @@ -1,4 +1,4 @@ tarball=jsonschema-VERSION-py3-none-any.whl sha1=189537b18c91e60be991a3dba704577d19f8e48d sha256=a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6 -upstream_url=https://pypi.io/packages/py3/j/jsonschema/jsonschema-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/j/jsonschema/jsonschema-VERSION-py3-none-any.whl diff --git a/build/pkgs/jsonschema_specifications/checksums.ini b/build/pkgs/jsonschema_specifications/checksums.ini index df5d6944abd..05fe820f3de 100644 --- a/build/pkgs/jsonschema_specifications/checksums.ini +++ b/build/pkgs/jsonschema_specifications/checksums.ini @@ -1,4 +1,4 @@ tarball=jsonschema_specifications-VERSION-py3-none-any.whl sha1=4132bed31478bc96960099e58ae4c083c514c551 sha256=764a2b9325c225208121948b15f2b2d16fddbe223fdfc096b45c70c1f7f7b8c1 -upstream_url=https://pypi.io/packages/py3/j/jsonschema_specifications/jsonschema_specifications-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/j/jsonschema_specifications/jsonschema_specifications-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_client/checksums.ini b/build/pkgs/jupyter_client/checksums.ini index af7a000f71d..39c8aff188b 100644 --- a/build/pkgs/jupyter_client/checksums.ini +++ b/build/pkgs/jupyter_client/checksums.ini @@ -1,4 +1,4 @@ tarball=jupyter_client-VERSION-py3-none-any.whl sha1=341f822626b55b53f03a21a44d78dc203472406b sha256=5eb9f55eb0650e81de6b7e34308d8b92d04fe4ec41cd8193a913979e33d8e1a5 -upstream_url=https://pypi.io/packages/py3/j/jupyter_client/jupyter_client-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/j/jupyter_client/jupyter_client-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_core/checksums.ini b/build/pkgs/jupyter_core/checksums.ini index 672c7f93bcc..919c1e88af7 100644 --- a/build/pkgs/jupyter_core/checksums.ini +++ b/build/pkgs/jupyter_core/checksums.ini @@ -1,4 +1,4 @@ tarball=jupyter_core-VERSION.tar.gz sha1=0fe33e3247e595cdb83e2220f02c566ea9397e6a sha256=0c28db6cbe2c37b5b398e1a1a5b22f84fd64cd10afc1f6c05b02fb09481ba45f -upstream_url=https://pypi.io/packages/source/j/jupyter_core/jupyter_core-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/j/jupyter_core/jupyter_core-VERSION.tar.gz diff --git a/build/pkgs/jupyter_events/checksums.ini b/build/pkgs/jupyter_events/checksums.ini index d7fc20e35ba..aaf19ecdbf5 100644 --- a/build/pkgs/jupyter_events/checksums.ini +++ b/build/pkgs/jupyter_events/checksums.ini @@ -1,4 +1,4 @@ tarball=jupyter_events-VERSION-py3-none-any.whl sha1=1b3fd8c003ea9e51b0f2d38daa89fded161767f7 sha256=57a2749f87ba387cd1bfd9b22a0875b889237dbf2edc2121ebb22bde47036c17 -upstream_url=https://pypi.io/packages/py3/j/jupyter_events/jupyter_events-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/j/jupyter_events/jupyter_events-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_jsmol/checksums.ini b/build/pkgs/jupyter_jsmol/checksums.ini index 533f2b689d3..11e1c873b56 100644 --- a/build/pkgs/jupyter_jsmol/checksums.ini +++ b/build/pkgs/jupyter_jsmol/checksums.ini @@ -1,4 +1,4 @@ tarball=jupyter_jsmol-VERSION-py2.py3-none-any.whl sha1=b00f1ca76aaa906c7c0a43e36baf608183f3d552 sha256=dca3a232f98aa92739de8b7905765d22f325a2ba5d7a3a2f5b2374e88cc80471 -upstream_url=https://pypi.io/packages/py2.py3/j/jupyter_jsmol/jupyter_jsmol-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/j/jupyter_jsmol/jupyter_jsmol-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/jupyter_lsp/checksums.ini b/build/pkgs/jupyter_lsp/checksums.ini index b925e4da051..7f9c60b089c 100644 --- a/build/pkgs/jupyter_lsp/checksums.ini +++ b/build/pkgs/jupyter_lsp/checksums.ini @@ -1,4 +1,4 @@ tarball=jupyter_lsp-VERSION-py3-none-any.whl sha1=0f7a63d99c5cf624315583099f00eafc4b996b59 sha256=9e06b8b4f7dd50300b70dd1a78c0c3b0c3d8fa68e0f2d8a5d1fbab62072aca3f -upstream_url=https://pypi.io/packages/py3/j/jupyter_lsp/jupyter_lsp-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/j/jupyter_lsp/jupyter_lsp-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_server/checksums.ini b/build/pkgs/jupyter_server/checksums.ini index 9519eaa2ae6..2f9a79e28d7 100644 --- a/build/pkgs/jupyter_server/checksums.ini +++ b/build/pkgs/jupyter_server/checksums.ini @@ -1,4 +1,4 @@ tarball=jupyter_server-VERSION-py3-none-any.whl sha1=a54aa7f6f1657a55cae9ecc4a6654b6e3ca5fb73 sha256=8e4b90380b59d7a1e31086c4692231f2a2ea4cb269f5516e60aba72ce8317fc9 -upstream_url=https://pypi.io/packages/py3/j/jupyter_server/jupyter_server-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/j/jupyter_server/jupyter_server-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_server_terminals/checksums.ini b/build/pkgs/jupyter_server_terminals/checksums.ini index be5ba3efe9b..bb48dce3bae 100644 --- a/build/pkgs/jupyter_server_terminals/checksums.ini +++ b/build/pkgs/jupyter_server_terminals/checksums.ini @@ -1,4 +1,4 @@ tarball=jupyter_server_terminals-VERSION-py3-none-any.whl sha1=fd1201e9f0064b2a5a05ed7346dfe52546f13b0b sha256=75779164661cec02a8758a5311e18bb8eb70c4e86c6b699403100f1585a12a36 -upstream_url=https://pypi.io/packages/py3/j/jupyter_server_terminals/jupyter_server_terminals-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/j/jupyter_server_terminals/jupyter_server_terminals-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyter_sphinx/checksums.ini b/build/pkgs/jupyter_sphinx/checksums.ini index fc843987136..a11301f5fe3 100644 --- a/build/pkgs/jupyter_sphinx/checksums.ini +++ b/build/pkgs/jupyter_sphinx/checksums.ini @@ -1,4 +1,4 @@ tarball=jupyter_sphinx-VERSION.tar.gz sha1=85e6e1665488fac3131da2e3ab9648037c0d1da9 sha256=2e23699a3a1cf5db31b10981da5aa32606ee730f6b73a844d1e76d800756af56 -upstream_url=https://pypi.io/packages/source/j/jupyter_sphinx/jupyter_sphinx-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/j/jupyter_sphinx/jupyter_sphinx-VERSION.tar.gz diff --git a/build/pkgs/jupyterlab/checksums.ini b/build/pkgs/jupyterlab/checksums.ini index eea8e9d4191..0d3e3a75bf0 100644 --- a/build/pkgs/jupyterlab/checksums.ini +++ b/build/pkgs/jupyterlab/checksums.ini @@ -1,4 +1,4 @@ tarball=jupyterlab-VERSION-py3-none-any.whl sha1=4efdd879660e719fd49be6ec169272f32a16593e sha256=67dbec7057c6ad46f08a3667a80bdb890df9453822c93b5ddfd5e8313a718ef9 -upstream_url=https://pypi.io/packages/py3/j/jupyterlab/jupyterlab-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/j/jupyterlab/jupyterlab-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyterlab_mathjax2/checksums.ini b/build/pkgs/jupyterlab_mathjax2/checksums.ini index 3ff851f18bb..942770adea0 100644 --- a/build/pkgs/jupyterlab_mathjax2/checksums.ini +++ b/build/pkgs/jupyterlab_mathjax2/checksums.ini @@ -1,4 +1,4 @@ tarball=jupyterlab_mathjax2-VERSION-py3-none-any.whl sha1=4e2bb182594a6c4f5d4edfb4f6e33597f09de402 sha256=c65c401ee5638e7cbf1223ba95aceed8b26a2a3e48fd1d585a10dd95b9327a8f -upstream_url=https://pypi.io/packages/py3/j/jupyterlab_mathjax2/jupyterlab_mathjax2-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/j/jupyterlab_mathjax2/jupyterlab_mathjax2-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyterlab_pygments/checksums.ini b/build/pkgs/jupyterlab_pygments/checksums.ini index 7cbeda65aab..78b7c052f08 100644 --- a/build/pkgs/jupyterlab_pygments/checksums.ini +++ b/build/pkgs/jupyterlab_pygments/checksums.ini @@ -1,4 +1,4 @@ tarball=jupyterlab_pygments-VERSION-py2.py3-none-any.whl sha1=601f547767fa867494ff0764891807904b8ebbd2 sha256=2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f -upstream_url=https://pypi.io/packages/py2.py3/j/jupyterlab_pygments/jupyterlab_pygments-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/j/jupyterlab_pygments/jupyterlab_pygments-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/jupyterlab_server/checksums.ini b/build/pkgs/jupyterlab_server/checksums.ini index 84eeb7a8b8d..18765921193 100644 --- a/build/pkgs/jupyterlab_server/checksums.ini +++ b/build/pkgs/jupyterlab_server/checksums.ini @@ -1,4 +1,4 @@ tarball=jupyterlab_server-VERSION-py3-none-any.whl sha1=1fff8c8bc4c81b006cb83d4524dc8a6f3364e57c sha256=5f077e142bb8dc9b843d960f940c513581bceca3793a0d80f9c67d9522c4e876 -upstream_url=https://pypi.io/packages/py3/j/jupyterlab_server/jupyterlab_server-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/j/jupyterlab_server/jupyterlab_server-VERSION-py3-none-any.whl diff --git a/build/pkgs/jupyterlab_widgets/checksums.ini b/build/pkgs/jupyterlab_widgets/checksums.ini index f7a3c9bbeb8..175c8761871 100644 --- a/build/pkgs/jupyterlab_widgets/checksums.ini +++ b/build/pkgs/jupyterlab_widgets/checksums.ini @@ -1,4 +1,4 @@ tarball=jupyterlab_widgets-VERSION-py3-none-any.whl sha1=b10775bb3966af627bb44fbda4efb553b24a5b93 sha256=3cf5bdf5b897bf3bccf1c11873aa4afd776d7430200f765e0686bd352487b58d -upstream_url=https://pypi.io/packages/py3/j/jupyterlab_widgets/jupyterlab_widgets-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/j/jupyterlab_widgets/jupyterlab_widgets-VERSION-py3-none-any.whl diff --git a/build/pkgs/lrcalc_python/checksums.ini b/build/pkgs/lrcalc_python/checksums.ini index 99e136d82bb..e86d6c9f9bb 100644 --- a/build/pkgs/lrcalc_python/checksums.ini +++ b/build/pkgs/lrcalc_python/checksums.ini @@ -1,4 +1,4 @@ tarball=lrcalc-VERSION.tar.gz sha1=3e9366d9e8b8beccec70b07d174b8f6683c01574 sha256=e3a0509aeda487b412b391a52e817ca36b5c063a8305e09fd54d53259dd6aaa9 -upstream_url=https://pypi.io/packages/source/l/lrcalc/lrcalc-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/l/lrcalc/lrcalc-VERSION.tar.gz diff --git a/build/pkgs/markupsafe/checksums.ini b/build/pkgs/markupsafe/checksums.ini index 8b2cb02af26..e5cf079ef2d 100644 --- a/build/pkgs/markupsafe/checksums.ini +++ b/build/pkgs/markupsafe/checksums.ini @@ -1,4 +1,4 @@ tarball=MarkupSafe-VERSION.tar.gz sha1=08593f9490b9be070aa2337e7311a392d33944dd sha256=d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b -upstream_url=https://pypi.io/packages/source/m/markupsafe/MarkupSafe-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/m/markupsafe/MarkupSafe-VERSION.tar.gz diff --git a/build/pkgs/matplotlib/checksums.ini b/build/pkgs/matplotlib/checksums.ini index 317be590bcf..bf2fc1fad14 100644 --- a/build/pkgs/matplotlib/checksums.ini +++ b/build/pkgs/matplotlib/checksums.ini @@ -1,4 +1,4 @@ tarball=matplotlib-VERSION.tar.gz sha1=b3391b48ab0bf91778064ce5b2226ff2a2658d7c sha256=df8505e1c19d5c2c26aff3497a7cbd3ccfc2e97043d1e4db3e76afa399164b69 -upstream_url=https://pypi.io/packages/source/m/matplotlib/matplotlib-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/m/matplotlib/matplotlib-VERSION.tar.gz diff --git a/build/pkgs/matplotlib_inline/checksums.ini b/build/pkgs/matplotlib_inline/checksums.ini index 294cf1a777a..455e0e93785 100644 --- a/build/pkgs/matplotlib_inline/checksums.ini +++ b/build/pkgs/matplotlib_inline/checksums.ini @@ -1,4 +1,4 @@ tarball=matplotlib-inline-VERSION.tar.gz sha1=a09347e3f2eaa6f9453c773132bf4bd9d38e2163 sha256=f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304 -upstream_url=https://pypi.io/packages/source/m/matplotlib_inline/matplotlib-inline-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/m/matplotlib_inline/matplotlib-inline-VERSION.tar.gz diff --git a/build/pkgs/matroid_database/checksums.ini b/build/pkgs/matroid_database/checksums.ini index c5415da0919..5a87bc3e746 100644 --- a/build/pkgs/matroid_database/checksums.ini +++ b/build/pkgs/matroid_database/checksums.ini @@ -1,4 +1,4 @@ tarball=matroid_database-VERSION-py3-none-any.whl sha1=f6539d37c9a03e14a8b100555525d3b54feb602b sha256=85d0304575784ceb4797014fb5a761443d2a0bbf01aafc38ef293d2c64a1b5ce -upstream_url=https://pypi.io/packages/py3/m/matroid_database/matroid_database-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/m/matroid_database/matroid_database-VERSION-py3-none-any.whl diff --git a/build/pkgs/memory_allocator/checksums.ini b/build/pkgs/memory_allocator/checksums.ini index 9aaa169c6dd..fb1ba9b6c90 100644 --- a/build/pkgs/memory_allocator/checksums.ini +++ b/build/pkgs/memory_allocator/checksums.ini @@ -1,4 +1,4 @@ tarball=memory_allocator-VERSION.tar.gz sha1=21661580dd3f41aac0f2090033d8804e6ff495d9 sha256=d609216b03031967e2b45a804b12ff9029578f4ec019fde42cf6aed6ca09efe4 -upstream_url=https://pypi.io/packages/source/m/memory_allocator/memory_allocator-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/m/memory_allocator/memory_allocator-VERSION.tar.gz diff --git a/build/pkgs/meson/checksums.ini b/build/pkgs/meson/checksums.ini index 00cf028db1e..23230d96040 100644 --- a/build/pkgs/meson/checksums.ini +++ b/build/pkgs/meson/checksums.ini @@ -1,4 +1,4 @@ tarball=meson-VERSION-py3-none-any.whl sha1=baf5b9bc9ca97f18c7dc87cfaf0e1dc4d617a4cf sha256=d5223ecca9564d735d36daaba2571abc6c032c8c3a7ffa0674e803ef0c7e0219 -upstream_url=https://pypi.io/packages/py3/m/meson/meson-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/m/meson/meson-VERSION-py3-none-any.whl diff --git a/build/pkgs/meson_python/checksums.ini b/build/pkgs/meson_python/checksums.ini index 7aa199d18fb..d754ae46233 100644 --- a/build/pkgs/meson_python/checksums.ini +++ b/build/pkgs/meson_python/checksums.ini @@ -1,4 +1,4 @@ tarball=meson_python-VERSION.tar.gz sha1=71bf382c2f2e76aada2f511a84bd59a99a6b1238 sha256=fddb73eecd49e89c1c41c87937cd89c2d0b65a1c63ba28238681d4bd9484d26f -upstream_url=https://pypi.io/packages/source/m/meson_python/meson_python-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/m/meson_python/meson_python-VERSION.tar.gz diff --git a/build/pkgs/mistune/checksums.ini b/build/pkgs/mistune/checksums.ini index 93397f7ab48..8c77e16a54e 100644 --- a/build/pkgs/mistune/checksums.ini +++ b/build/pkgs/mistune/checksums.ini @@ -1,4 +1,4 @@ tarball=mistune-VERSION.tar.gz sha1=c15d02c98d04a3e615c3c1932d1b9a3b1759067a sha256=9ee0a66053e2267aba772c71e06891fa8f1af6d4b01d5e84e267b4570d4d9808 -upstream_url=https://pypi.io/packages/source/m/mistune/mistune-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/m/mistune/mistune-VERSION.tar.gz diff --git a/build/pkgs/nbclient/checksums.ini b/build/pkgs/nbclient/checksums.ini index 6290bb30c93..79d4e17cc53 100644 --- a/build/pkgs/nbclient/checksums.ini +++ b/build/pkgs/nbclient/checksums.ini @@ -1,4 +1,4 @@ tarball=nbclient-VERSION-py3-none-any.whl sha1=fcb4ad9b3ea1bea4d305076c0a7640a483bd11f3 sha256=25e861299e5303a0477568557c4045eccc7a34c17fc08e7959558707b9ebe548 -upstream_url=https://pypi.io/packages/py3/n/nbclient/nbclient-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/n/nbclient/nbclient-VERSION-py3-none-any.whl diff --git a/build/pkgs/nbconvert/checksums.ini b/build/pkgs/nbconvert/checksums.ini index 56a861567e4..dc985a9eabc 100644 --- a/build/pkgs/nbconvert/checksums.ini +++ b/build/pkgs/nbconvert/checksums.ini @@ -1,4 +1,4 @@ tarball=nbconvert-VERSION-py3-none-any.whl sha1=5317fa68bbd7f66fc3fcc5b0e6b0d6e2df967ba0 sha256=39fe4b8bdd1b0104fdd86fc8a43a9077ba64c720bda4c6132690d917a0a154ee -upstream_url=https://pypi.io/packages/py3/n/nbconvert/nbconvert-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/n/nbconvert/nbconvert-VERSION-py3-none-any.whl diff --git a/build/pkgs/nbformat/checksums.ini b/build/pkgs/nbformat/checksums.ini index e7a225cadfe..253277f0059 100644 --- a/build/pkgs/nbformat/checksums.ini +++ b/build/pkgs/nbformat/checksums.ini @@ -1,4 +1,4 @@ tarball=nbformat-VERSION-py3-none-any.whl sha1=e38af74817e9d81101583363d9ffe349f0038eb9 sha256=1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9 -upstream_url=https://pypi.io/packages/py3/n/nbformat/nbformat-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/n/nbformat/nbformat-VERSION-py3-none-any.whl diff --git a/build/pkgs/nest_asyncio/checksums.ini b/build/pkgs/nest_asyncio/checksums.ini index 48626a85ae1..8c842535040 100644 --- a/build/pkgs/nest_asyncio/checksums.ini +++ b/build/pkgs/nest_asyncio/checksums.ini @@ -1,4 +1,4 @@ tarball=nest_asyncio-VERSION-py3-none-any.whl sha1=675b145491553e6a725884081244860a635552cd sha256=87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c -upstream_url=https://pypi.io/packages/py3/n/nest_asyncio/nest_asyncio-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/n/nest_asyncio/nest_asyncio-VERSION-py3-none-any.whl diff --git a/build/pkgs/networkx/checksums.ini b/build/pkgs/networkx/checksums.ini index 7e02c083c6d..e550b84168b 100644 --- a/build/pkgs/networkx/checksums.ini +++ b/build/pkgs/networkx/checksums.ini @@ -1,4 +1,4 @@ tarball=networkx-VERSION.tar.gz sha1=b12cf95ed8bc3fe568e3c8e023473a3767c43f8d sha256=9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6 -upstream_url=https://pypi.io/packages/source/n/networkx/networkx-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/n/networkx/networkx-VERSION.tar.gz diff --git a/build/pkgs/notebook/checksums.ini b/build/pkgs/notebook/checksums.ini index 2c1fd65675e..597fdff1881 100644 --- a/build/pkgs/notebook/checksums.ini +++ b/build/pkgs/notebook/checksums.ini @@ -1,4 +1,4 @@ tarball=notebook-VERSION-py3-none-any.whl sha1=90ec65091058ac541a55cc2417de83c1bcb24985 sha256=197d8e0595acabf4005851c8716e952a81b405f7aefb648067a761fbde267ce7 -upstream_url=https://pypi.io/packages/py3/n/notebook/notebook-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/n/notebook/notebook-VERSION-py3-none-any.whl diff --git a/build/pkgs/notebook_shim/checksums.ini b/build/pkgs/notebook_shim/checksums.ini index 001afb43e00..d01ed7810ee 100644 --- a/build/pkgs/notebook_shim/checksums.ini +++ b/build/pkgs/notebook_shim/checksums.ini @@ -1,4 +1,4 @@ tarball=notebook_shim-VERSION-py3-none-any.whl sha1=9bb3dce360ce69aec99f873d8e80c1e9fdf92fde sha256=a83496a43341c1674b093bfcebf0fe8e74cbe7eda5fd2bbc56f8e39e1486c0c7 -upstream_url=https://pypi.io/packages/py3/n/notebook_shim/notebook_shim-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/n/notebook_shim/notebook_shim-VERSION-py3-none-any.whl diff --git a/build/pkgs/numpy/checksums.ini b/build/pkgs/numpy/checksums.ini index fde72f78b6d..6814f0f5c10 100644 --- a/build/pkgs/numpy/checksums.ini +++ b/build/pkgs/numpy/checksums.ini @@ -1,4 +1,4 @@ tarball=numpy-VERSION.tar.gz sha1=915414f1efabd7c183583154cf1a709bd2745828 sha256=697df43e2b6310ecc9d95f05d5ef20eacc09c7c4ecc9da3f235d39e71b7da1e4 -upstream_url=https://pypi.io/packages/source/n/numpy/numpy-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/n/numpy/numpy-VERSION.tar.gz diff --git a/build/pkgs/osqp_python/checksums.ini b/build/pkgs/osqp_python/checksums.ini index d8e1ae4b81b..9fd80df4d5a 100644 --- a/build/pkgs/osqp_python/checksums.ini +++ b/build/pkgs/osqp_python/checksums.ini @@ -1,4 +1,4 @@ tarball=osqp-VERSION.tar.gz sha1=3358e48aa6d81496665a8b0ee157465ce6cd329a sha256=03e460e683ec2ce0f839353ddfa3c4c8ffa509ab8cf6a2b2afbb586fa453e180 -upstream_url=https://pypi.io/packages/source/o/osqp/osqp-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/o/osqp/osqp-VERSION.tar.gz diff --git a/build/pkgs/overrides/checksums.ini b/build/pkgs/overrides/checksums.ini index 2812a196d90..fde4eba9a05 100644 --- a/build/pkgs/overrides/checksums.ini +++ b/build/pkgs/overrides/checksums.ini @@ -1,4 +1,4 @@ tarball=overrides-VERSION-py3-none-any.whl sha1=740e9e607a9e4f78dea7a1b82bcb27f285bc5f48 sha256=3ad24583f86d6d7a49049695efe9933e67ba62f0c7625d53c59fa832ce4b8b7d -upstream_url=https://pypi.io/packages/py3/o/overrides/overrides-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/o/overrides/overrides-VERSION-py3-none-any.whl diff --git a/build/pkgs/packaging/checksums.ini b/build/pkgs/packaging/checksums.ini index 560bd2a20a4..eae534e3487 100644 --- a/build/pkgs/packaging/checksums.ini +++ b/build/pkgs/packaging/checksums.ini @@ -1,4 +1,4 @@ tarball=packaging-VERSION-py3-none-any.whl sha1=a050029d1e0c1b95b3ddcd566be4ad352cd42666 sha256=5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124 -upstream_url=https://pypi.io/packages/py3/p/packaging/packaging-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/packaging/packaging-VERSION-py3-none-any.whl diff --git a/build/pkgs/pandocfilters/checksums.ini b/build/pkgs/pandocfilters/checksums.ini index d85750a17f7..5e6e659ef46 100644 --- a/build/pkgs/pandocfilters/checksums.ini +++ b/build/pkgs/pandocfilters/checksums.ini @@ -1,4 +1,4 @@ tarball=pandocfilters-VERSION.tar.gz sha1=bdee4f81063c02168b421640f3e18917011153df sha256=0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38 -upstream_url=https://pypi.io/packages/source/p/pandocfilters/pandocfilters-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pandocfilters/pandocfilters-VERSION.tar.gz diff --git a/build/pkgs/pari_jupyter/checksums.ini b/build/pkgs/pari_jupyter/checksums.ini index bdd7d5278be..c1fe2ec687f 100644 --- a/build/pkgs/pari_jupyter/checksums.ini +++ b/build/pkgs/pari_jupyter/checksums.ini @@ -1,4 +1,4 @@ tarball=pari-jupyter-VERSION.tar.gz sha1=b410ee0352cd58f5f140246540b71b5ff83ddf73 sha256=7cd9291d05b92b8303c6ae8cf25622e5ecbab1ac2bcf13911f900ea987471b9d -upstream_url=https://pypi.io/packages/source/p/pari_jupyter/pari-jupyter-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pari_jupyter/pari-jupyter-VERSION.tar.gz diff --git a/build/pkgs/parso/checksums.ini b/build/pkgs/parso/checksums.ini index d15402d82de..a45225c3a6d 100644 --- a/build/pkgs/parso/checksums.ini +++ b/build/pkgs/parso/checksums.ini @@ -1,4 +1,4 @@ tarball=parso-VERSION-py2.py3-none-any.whl sha1=091d37e09a601d854e18f4d42aeb478392bb7e63 sha256=a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18 -upstream_url=https://pypi.io/packages/py2.py3/p/parso/parso-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/p/parso/parso-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/pathspec/checksums.ini b/build/pkgs/pathspec/checksums.ini index 62d6d08775e..a3af9942abc 100644 --- a/build/pkgs/pathspec/checksums.ini +++ b/build/pkgs/pathspec/checksums.ini @@ -1,4 +1,4 @@ tarball=pathspec-VERSION-py3-none-any.whl sha1=e31b7b2b1a59ab192eb2e92ac283211a11039769 sha256=a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08 -upstream_url=https://pypi.io/packages/py3/p/pathspec/pathspec-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pathspec/pathspec-VERSION-py3-none-any.whl diff --git a/build/pkgs/pexpect/checksums.ini b/build/pkgs/pexpect/checksums.ini index 413053e79a1..dadcb1e66e1 100644 --- a/build/pkgs/pexpect/checksums.ini +++ b/build/pkgs/pexpect/checksums.ini @@ -1,4 +1,4 @@ tarball=pexpect-VERSION.tar.gz sha1=5bff9230c419eecbf701059f104e74a3f3a1b208 sha256=ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f -upstream_url=https://pypi.io/packages/source/p/pexpect/pexpect-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pexpect/pexpect-VERSION.tar.gz diff --git a/build/pkgs/pillow/checksums.ini b/build/pkgs/pillow/checksums.ini index 7e64940e75b..5467334d4b7 100644 --- a/build/pkgs/pillow/checksums.ini +++ b/build/pkgs/pillow/checksums.ini @@ -1,4 +1,4 @@ tarball=Pillow-VERSION.tar.gz sha1=be2dc6aeee145894f3ccbc2358a37f7849e710aa sha256=e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38 -upstream_url=https://pypi.io/packages/source/p/pillow/Pillow-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pillow/Pillow-VERSION.tar.gz diff --git a/build/pkgs/pip/checksums.ini b/build/pkgs/pip/checksums.ini index 0afec1866ed..43918d193ee 100644 --- a/build/pkgs/pip/checksums.ini +++ b/build/pkgs/pip/checksums.ini @@ -1,4 +1,4 @@ tarball=pip-VERSION-py3-none-any.whl sha1=044a04440eef697c8ec9e03544117345c57aa683 sha256=2cd581cf58ab7fcfca4ce8efa6dcacd0de5bf8d0a3eb9ec927e07405f4d9e2a2 -upstream_url=https://pypi.io/packages/py3/p/pip/pip-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pip/pip-VERSION-py3-none-any.whl diff --git a/build/pkgs/pkgconfig/checksums.ini b/build/pkgs/pkgconfig/checksums.ini index 4ecbe8c0096..dbf6ebdd342 100644 --- a/build/pkgs/pkgconfig/checksums.ini +++ b/build/pkgs/pkgconfig/checksums.ini @@ -1,4 +1,4 @@ tarball=pkgconfig-VERSION-py3-none-any.whl sha1=bca14b2806a8e8afb0bd04f8e3675550b286dda8 sha256=d20023bbeb42ee6d428a0fac6e0904631f545985a10cdd71a20aa58bc47a4209 -upstream_url=https://pypi.io/packages/py3/p/pkgconfig/pkgconfig-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pkgconfig/pkgconfig-VERSION-py3-none-any.whl diff --git a/build/pkgs/platformdirs/checksums.ini b/build/pkgs/platformdirs/checksums.ini index 201a01de014..8263d7baf15 100644 --- a/build/pkgs/platformdirs/checksums.ini +++ b/build/pkgs/platformdirs/checksums.ini @@ -1,4 +1,4 @@ tarball=platformdirs-VERSION-py3-none-any.whl sha1=81890edbdf2f709f83001cb5bcfd71c3978225ce sha256=2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee -upstream_url=https://pypi.io/packages/py3/p/platformdirs/platformdirs-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/platformdirs/platformdirs-VERSION-py3-none-any.whl diff --git a/build/pkgs/pluggy/checksums.ini b/build/pkgs/pluggy/checksums.ini index 3b6e7041f14..27359819ce2 100644 --- a/build/pkgs/pluggy/checksums.ini +++ b/build/pkgs/pluggy/checksums.ini @@ -1,4 +1,4 @@ tarball=pluggy-VERSION-py3-none-any.whl sha1=ccb7a74c114522f26e2c3b1884468343f54098d3 sha256=44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 -upstream_url=https://pypi.io/packages/py3/p/pluggy/pluggy-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pluggy/pluggy-VERSION-py3-none-any.whl diff --git a/build/pkgs/ply/checksums.ini b/build/pkgs/ply/checksums.ini index f1003c4c4a0..ffce85083d4 100644 --- a/build/pkgs/ply/checksums.ini +++ b/build/pkgs/ply/checksums.ini @@ -1,4 +1,4 @@ tarball=ply-VERSION.tar.gz sha1=10a555a32095991fbc7f7ed10c677a14e21fad1d sha256=00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3 -upstream_url=https://pypi.io/packages/source/p/ply/ply-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/ply/ply-VERSION.tar.gz diff --git a/build/pkgs/pplpy/checksums.ini b/build/pkgs/pplpy/checksums.ini index 76268f169e2..b864f9fcd26 100644 --- a/build/pkgs/pplpy/checksums.ini +++ b/build/pkgs/pplpy/checksums.ini @@ -1,4 +1,4 @@ tarball=pplpy-VERSION.tar.gz sha1=dc9e8a7a867ee1c066bdbecf22b6a59dc2052711 sha256=db7a3b571d6ef053f75137975e947c3a1c1e45a30bab90eaf215b4e5cc15797e -upstream_url=https://pypi.io/packages/source/p/pplpy/pplpy-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pplpy/pplpy-VERSION.tar.gz diff --git a/build/pkgs/primecountpy/checksums.ini b/build/pkgs/primecountpy/checksums.ini index 57cae477764..dd8445635a3 100644 --- a/build/pkgs/primecountpy/checksums.ini +++ b/build/pkgs/primecountpy/checksums.ini @@ -1,4 +1,4 @@ tarball=primecountpy-VERSION.tar.gz sha1=3526784adad04d67a15f05fb1367d12ec50a59dc sha256=78fe7cc32115f0669a45d7c90faaf39f7ce3939e39e2e7e5f14c17fe4bff0676 -upstream_url=https://pypi.io/packages/source/p/primecountpy/primecountpy-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/primecountpy/primecountpy-VERSION.tar.gz diff --git a/build/pkgs/prometheus_client/checksums.ini b/build/pkgs/prometheus_client/checksums.ini index 9f4fa1845da..7e0ea2a4f0c 100644 --- a/build/pkgs/prometheus_client/checksums.ini +++ b/build/pkgs/prometheus_client/checksums.ini @@ -1,4 +1,4 @@ tarball=prometheus_client-VERSION.tar.gz sha1=dabd66e652ea8275b4980e337cefcea68cc0b560 sha256=5459c427624961076277fdc6dc50540e2bacb98eebde99886e59ec55ed92093a -upstream_url=https://pypi.io/packages/source/p/prometheus-client/prometheus_client-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/prometheus-client/prometheus_client-VERSION.tar.gz diff --git a/build/pkgs/prompt_toolkit/checksums.ini b/build/pkgs/prompt_toolkit/checksums.ini index 3f4bd25570c..e63fb8d4a10 100644 --- a/build/pkgs/prompt_toolkit/checksums.ini +++ b/build/pkgs/prompt_toolkit/checksums.ini @@ -1,4 +1,4 @@ tarball=prompt_toolkit-VERSION.tar.gz sha1=b5ada8cb45c11f9184c990bd33a98d3d690e6edc sha256=3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d -upstream_url=https://pypi.io/packages/source/p/prompt_toolkit/prompt_toolkit-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/prompt_toolkit/prompt_toolkit-VERSION.tar.gz diff --git a/build/pkgs/psutil/checksums.ini b/build/pkgs/psutil/checksums.ini index 417c2210384..53c177f96f5 100644 --- a/build/pkgs/psutil/checksums.ini +++ b/build/pkgs/psutil/checksums.ini @@ -1,4 +1,4 @@ tarball=psutil-VERSION.tar.gz sha1=24c493ef33d4df44e76a1801e480b4185bd911c5 sha256=e4b92ddcd7dd4cdd3f900180ea1e104932c7bce234fb88976e2a3b296441225a -upstream_url=https://pypi.io/packages/source/p/psutil/psutil-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/psutil/psutil-VERSION.tar.gz diff --git a/build/pkgs/ptyprocess/checksums.ini b/build/pkgs/ptyprocess/checksums.ini index 36a12e0f438..3382e090c02 100644 --- a/build/pkgs/ptyprocess/checksums.ini +++ b/build/pkgs/ptyprocess/checksums.ini @@ -1,4 +1,4 @@ tarball=ptyprocess-VERSION.tar.gz sha1=2d8830d1025c8e33149c7723c2f283122f9488c1 sha256=5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220 -upstream_url=https://pypi.io/packages/source/p/ptyprocess/ptyprocess-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/ptyprocess/ptyprocess-VERSION.tar.gz diff --git a/build/pkgs/pure_eval/checksums.ini b/build/pkgs/pure_eval/checksums.ini index 1cdf6f8d2a4..b753dbf3804 100644 --- a/build/pkgs/pure_eval/checksums.ini +++ b/build/pkgs/pure_eval/checksums.ini @@ -1,4 +1,4 @@ tarball=pure_eval-VERSION-py3-none-any.whl sha1=dbd5eaa9eb5a4910cff5ccd42b570f866f581da4 sha256=01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350 -upstream_url=https://pypi.io/packages/py3/p/pure_eval/pure_eval-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pure_eval/pure_eval-VERSION-py3-none-any.whl diff --git a/build/pkgs/py/checksums.ini b/build/pkgs/py/checksums.ini index a10022af08f..48e330dae0a 100644 --- a/build/pkgs/py/checksums.ini +++ b/build/pkgs/py/checksums.ini @@ -1,4 +1,4 @@ tarball=py-VERSION-py2.py3-none-any.whl sha1=44002baec8d2184d218bd2fa6049967cd9b4dbb5 sha256=607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378 -upstream_url=https://pypi.io/packages/py2.py3/p/py/py-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/p/py/py-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/pybind11/checksums.ini b/build/pkgs/pybind11/checksums.ini index c3112e54327..66a54f106b5 100644 --- a/build/pkgs/pybind11/checksums.ini +++ b/build/pkgs/pybind11/checksums.ini @@ -1,4 +1,4 @@ tarball=pybind11-VERSION.tar.gz sha1=3c75333a9056f0be18eb612803cd46a2bb0c87fc sha256=00cd59116a6e8155aecd9174f37ba299d1d397ed4a6b86ac1dfe01b3e40f2cc4 -upstream_url=https://pypi.io/packages/source/p/pybind11/pybind11-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pybind11/pybind11-VERSION.tar.gz diff --git a/build/pkgs/pycparser/checksums.ini b/build/pkgs/pycparser/checksums.ini index 4d250e61a00..c5928f41542 100644 --- a/build/pkgs/pycparser/checksums.ini +++ b/build/pkgs/pycparser/checksums.ini @@ -1,4 +1,4 @@ tarball=pycparser-VERSION-py3-none-any.whl sha1=34702512290f3bfd4850bcc95dfaf1ae972a8929 sha256=c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc -upstream_url=https://pypi.io/packages/py3/p/pycparser/pycparser-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pycparser/pycparser-VERSION-py3-none-any.whl diff --git a/build/pkgs/pygments/checksums.ini b/build/pkgs/pygments/checksums.ini index 5a54fdd0b9a..9a712f15b35 100644 --- a/build/pkgs/pygments/checksums.ini +++ b/build/pkgs/pygments/checksums.ini @@ -1,4 +1,4 @@ tarball=pygments-VERSION-py3-none-any.whl sha1=edb9fdfbc4cf53d356a02beee8822dd8e9529f35 sha256=b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a -upstream_url=https://pypi.io/packages/py3/p/pygments/pygments-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pygments/pygments-VERSION-py3-none-any.whl diff --git a/build/pkgs/pynormaliz/checksums.ini b/build/pkgs/pynormaliz/checksums.ini index caac1894126..70f40fc73c8 100644 --- a/build/pkgs/pynormaliz/checksums.ini +++ b/build/pkgs/pynormaliz/checksums.ini @@ -1,4 +1,4 @@ tarball=pynormaliz-VERSION.tar.gz sha1=4ce4fef4db61a0408bc84747294922fc49afc090 sha256=95d29fff9380ea2948166fd2b4c730985e0881043fa41f3e44ff9f402b97f0b4 -upstream_url=https://pypi.io/packages/source/p/pynormaliz/pynormaliz-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pynormaliz/pynormaliz-VERSION.tar.gz diff --git a/build/pkgs/pyparsing/checksums.ini b/build/pkgs/pyparsing/checksums.ini index 931d057f6b8..997792b6c82 100644 --- a/build/pkgs/pyparsing/checksums.ini +++ b/build/pkgs/pyparsing/checksums.ini @@ -1,4 +1,4 @@ tarball=pyparsing-VERSION-py3-none-any.whl sha1=bf1ab91fb997ccee2793e1e7f22a56a25f5e3a93 sha256=f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742 -upstream_url=https://pypi.io/packages/py3/p/pyparsing/pyparsing-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pyparsing/pyparsing-VERSION-py3-none-any.whl diff --git a/build/pkgs/pyproject_api/checksums.ini b/build/pkgs/pyproject_api/checksums.ini index dc2899fad91..fb4bd700824 100644 --- a/build/pkgs/pyproject_api/checksums.ini +++ b/build/pkgs/pyproject_api/checksums.ini @@ -1,4 +1,4 @@ tarball=pyproject_api-VERSION-py3-none-any.whl sha1=3723eb52bd6844f30f30f6f5b3723ce0f57a3cbf sha256=2dc1654062c2b27733d8fd4cdda672b22fe8741ef1dde8e3a998a9547b071eeb -upstream_url=https://pypi.io/packages/py3/p/pyproject_api/pyproject_api-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pyproject_api/pyproject_api-VERSION-py3-none-any.whl diff --git a/build/pkgs/pyproject_hooks/checksums.ini b/build/pkgs/pyproject_hooks/checksums.ini index fbb1f71394e..590aec528d6 100644 --- a/build/pkgs/pyproject_hooks/checksums.ini +++ b/build/pkgs/pyproject_hooks/checksums.ini @@ -1,4 +1,4 @@ tarball=pyproject_hooks-VERSION-py3-none-any.whl sha1=f8c16752e1deea6a3e9a261c6725c1af408d04e7 sha256=7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2 -upstream_url=https://pypi.io/packages/py3/p/pyproject_hooks/pyproject_hooks-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pyproject_hooks/pyproject_hooks-VERSION-py3-none-any.whl diff --git a/build/pkgs/pyproject_metadata/checksums.ini b/build/pkgs/pyproject_metadata/checksums.ini index 91d3eb258c8..6dc2957b57f 100644 --- a/build/pkgs/pyproject_metadata/checksums.ini +++ b/build/pkgs/pyproject_metadata/checksums.ini @@ -1,4 +1,4 @@ tarball=pyproject_metadata-VERSION-py3-none-any.whl sha1=59998bbcd31cc63f3e95f3ad8120ff71326595a0 sha256=ad858d448e1d3a1fb408ac5bac9ea7743e7a8bbb472f2693aaa334d2db42f526 -upstream_url=https://pypi.io/packages/py3/p/pyproject_metadata/pyproject_metadata-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pyproject_metadata/pyproject_metadata-VERSION-py3-none-any.whl diff --git a/build/pkgs/pyrsistent/checksums.ini b/build/pkgs/pyrsistent/checksums.ini index b7a30f5a171..24a4d3c62ff 100644 --- a/build/pkgs/pyrsistent/checksums.ini +++ b/build/pkgs/pyrsistent/checksums.ini @@ -1,4 +1,4 @@ tarball=pyrsistent-VERSION.tar.gz sha1=79980873658f7634ae25758b9710088b62e0612a sha256=1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440 -upstream_url=https://pypi.io/packages/source/p/pyrsistent/pyrsistent-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pyrsistent/pyrsistent-VERSION.tar.gz diff --git a/build/pkgs/pyscipopt/checksums.ini b/build/pkgs/pyscipopt/checksums.ini index a88c5cf04d8..b41ec57e3f7 100644 --- a/build/pkgs/pyscipopt/checksums.ini +++ b/build/pkgs/pyscipopt/checksums.ini @@ -1,4 +1,4 @@ tarball=PySCIPOpt-VERSION.tar.gz sha1=713e32cc0ff112500c4f43487614094ece4a8bbf sha256=f9c36c941e1373406b00c030f2511578c3fb02a95a2cf5559772deb846a0af47 -upstream_url=https://pypi.io/packages/source/p/pyscipopt/PySCIPOpt-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pyscipopt/PySCIPOpt-VERSION.tar.gz diff --git a/build/pkgs/pysingular/checksums.ini b/build/pkgs/pysingular/checksums.ini index 9f26a37fc9b..0a5e4f3f176 100644 --- a/build/pkgs/pysingular/checksums.ini +++ b/build/pkgs/pysingular/checksums.ini @@ -1,4 +1,4 @@ tarball=PySingular-VERSION.tar.gz sha1=c8d4bbe4552490aac37afe6d87a2cd3a7b445a7e sha256=ca03d1d7538fc61f4350acff42708c6c443e0232712a2dc42ce72140831ef60c -upstream_url=https://pypi.io/packages/source/p/pysingular/PySingular-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pysingular/PySingular-VERSION.tar.gz diff --git a/build/pkgs/pytest/checksums.ini b/build/pkgs/pytest/checksums.ini index 3b273f6dc6a..78106ab01b5 100644 --- a/build/pkgs/pytest/checksums.ini +++ b/build/pkgs/pytest/checksums.ini @@ -1,4 +1,4 @@ tarball=pytest-VERSION-py3-none-any.whl sha1=985b136db51e6729983433c6632564dc557f5fb6 sha256=4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5 -upstream_url=https://pypi.io/packages/py3/p/pytest/pytest-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pytest/pytest-VERSION-py3-none-any.whl diff --git a/build/pkgs/pytest_mock/checksums.ini b/build/pkgs/pytest_mock/checksums.ini index 181cfb34ea0..46f252da1c6 100644 --- a/build/pkgs/pytest_mock/checksums.ini +++ b/build/pkgs/pytest_mock/checksums.ini @@ -1,4 +1,4 @@ tarball=pytest_mock-VERSION-py3-none-any.whl sha1=7fcd316f0d08a7c961bec3ca0d756429ccb6b840 sha256=0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f -upstream_url=https://pypi.io/packages/py3/p/pytest_mock/pytest_mock-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pytest_mock/pytest_mock-VERSION-py3-none-any.whl diff --git a/build/pkgs/pytest_xdist/checksums.ini b/build/pkgs/pytest_xdist/checksums.ini index 97486be4a3a..80547c2d005 100644 --- a/build/pkgs/pytest_xdist/checksums.ini +++ b/build/pkgs/pytest_xdist/checksums.ini @@ -1,4 +1,4 @@ tarball=pytest_xdist-VERSION-py3-none-any.whl sha1=de5b68f355cb51478ba9d5104da67a6359dee9e0 sha256=9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7 -upstream_url=https://pypi.io/packages/py3/p/pytest_xdist/pytest_xdist-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/pytest_xdist/pytest_xdist-VERSION-py3-none-any.whl diff --git a/build/pkgs/python_build/checksums.ini b/build/pkgs/python_build/checksums.ini index c2bafe9d49d..31a63bf6f56 100644 --- a/build/pkgs/python_build/checksums.ini +++ b/build/pkgs/python_build/checksums.ini @@ -1,4 +1,4 @@ tarball=build-VERSION-py3-none-any.whl sha1=950bf228726af5041adbe2bb04a7ca74e27bce60 sha256=75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4 -upstream_url=https://pypi.io/packages/py3/b/build/build-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/b/build/build-VERSION-py3-none-any.whl diff --git a/build/pkgs/python_flint/checksums.ini b/build/pkgs/python_flint/checksums.ini index 19d40c1c7b1..2ed12a73b03 100644 --- a/build/pkgs/python_flint/checksums.ini +++ b/build/pkgs/python_flint/checksums.ini @@ -1,4 +1,4 @@ tarball=python-flint-VERSION.tar.gz sha1=c7d5b3b8db47c903eea9e752bd7732e34d6c5945 sha256=f829e00774534891b38de41bc511cf6c7d6d216544a6a84b92d9e1f159de0878 -upstream_url=https://pypi.io/packages/source/p/python_flint/python-flint-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/python_flint/python-flint-VERSION.tar.gz diff --git a/build/pkgs/python_igraph/checksums.ini b/build/pkgs/python_igraph/checksums.ini index d7247b21a30..f7e3d8bff22 100644 --- a/build/pkgs/python_igraph/checksums.ini +++ b/build/pkgs/python_igraph/checksums.ini @@ -1,4 +1,4 @@ tarball=python-igraph-VERSION.tar.gz sha1=da963213ab22c60938d4e77ffab811875ee43a8a sha256=2d71d645a4c3344c5910543fabbae10d3163f46a3e824ba7753c14b9036b8233 -upstream_url=https://pypi.io/packages/source/i/igraph/igraph-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/i/igraph/igraph-VERSION.tar.gz diff --git a/build/pkgs/python_json_logger/checksums.ini b/build/pkgs/python_json_logger/checksums.ini index 2856b66a14f..7b737ad2ad7 100644 --- a/build/pkgs/python_json_logger/checksums.ini +++ b/build/pkgs/python_json_logger/checksums.ini @@ -1,4 +1,4 @@ tarball=python_json_logger-VERSION-py3-none-any.whl sha1=c1176f521d95b5452b6169943b2b9b259e024b39 sha256=f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd -upstream_url=https://pypi.io/packages/py3/p/python_json_logger/python_json_logger-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/p/python_json_logger/python_json_logger-VERSION-py3-none-any.whl diff --git a/build/pkgs/pythran/checksums.ini b/build/pkgs/pythran/checksums.ini index 03d21286397..b9626c89359 100644 --- a/build/pkgs/pythran/checksums.ini +++ b/build/pkgs/pythran/checksums.ini @@ -1,4 +1,4 @@ tarball=pythran-VERSION.tar.gz sha1=dc8a6035c0c46d36630085003160a3aba4444add sha256=f9bc61bcb96df2cd4b578abc5a62dfb3fbb0b0ef02c264513dfb615c5f87871c -upstream_url=https://pypi.io/packages/source/p/pythran/pythran-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pythran/pythran-VERSION.tar.gz diff --git a/build/pkgs/pytz/checksums.ini b/build/pkgs/pytz/checksums.ini index 8ff6396f13e..223d3179179 100644 --- a/build/pkgs/pytz/checksums.ini +++ b/build/pkgs/pytz/checksums.ini @@ -1,4 +1,4 @@ tarball=pytz-VERSION.tar.gz sha1=be3f14bc0d6b89b8c579d8ae4e0fcb4478ff92e6 sha256=7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b -upstream_url=https://pypi.io/packages/source/p/pytz/pytz-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pytz/pytz-VERSION.tar.gz diff --git a/build/pkgs/pytz_deprecation_shim/checksums.ini b/build/pkgs/pytz_deprecation_shim/checksums.ini index 199685f084c..fd07bf986b3 100644 --- a/build/pkgs/pytz_deprecation_shim/checksums.ini +++ b/build/pkgs/pytz_deprecation_shim/checksums.ini @@ -1,4 +1,4 @@ tarball=pytz_deprecation_shim-VERSION.tar.gz sha1=d7900c309c26d48f6499fbda955eb80bd0b437dd sha256=af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d -upstream_url=https://pypi.io/packages/source/p/pytz_deprecation_shim/pytz_deprecation_shim-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pytz_deprecation_shim/pytz_deprecation_shim-VERSION.tar.gz diff --git a/build/pkgs/pyyaml/checksums.ini b/build/pkgs/pyyaml/checksums.ini index 1e9b9f74722..0823c82b2f8 100644 --- a/build/pkgs/pyyaml/checksums.ini +++ b/build/pkgs/pyyaml/checksums.ini @@ -1,4 +1,4 @@ tarball=PyYAML-VERSION.tar.gz sha1=a80d802ad8f693bed34c8fb5ee168a1872663c9a sha256=bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 -upstream_url=https://pypi.io/packages/source/p/pyyaml/PyYAML-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pyyaml/PyYAML-VERSION.tar.gz diff --git a/build/pkgs/pyzmq/checksums.ini b/build/pkgs/pyzmq/checksums.ini index b4b99817bdc..e04ccdd1c15 100644 --- a/build/pkgs/pyzmq/checksums.ini +++ b/build/pkgs/pyzmq/checksums.ini @@ -1,4 +1,4 @@ tarball=pyzmq-VERSION.tar.gz sha1=f750e59a3d5fcca64d0a1a6723c1bc72173e976f sha256=259c22485b71abacdfa8bf79720cd7bcf4b9d128b30ea554f01ae71fdbfdaa23 -upstream_url=https://pypi.io/packages/source/p/pyzmq/pyzmq-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/p/pyzmq/pyzmq-VERSION.tar.gz diff --git a/build/pkgs/qdldl_python/checksums.ini b/build/pkgs/qdldl_python/checksums.ini index a444f898ae6..0b59f50a58b 100644 --- a/build/pkgs/qdldl_python/checksums.ini +++ b/build/pkgs/qdldl_python/checksums.ini @@ -1,4 +1,4 @@ tarball=qdldl-VERSION.tar.gz sha1=af76c57ca1787f5e44e42f6c9f916b84ae599f1f sha256=69c092f6e1fc23fb779a80a62e6fcdfe2eba05c925860248c4d6754f4736938f -upstream_url=https://pypi.io/packages/source/q/qdldl/qdldl-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/q/qdldl/qdldl-VERSION.tar.gz diff --git a/build/pkgs/referencing/checksums.ini b/build/pkgs/referencing/checksums.ini index 293629ca16d..ace04d9b28c 100644 --- a/build/pkgs/referencing/checksums.ini +++ b/build/pkgs/referencing/checksums.ini @@ -1,4 +1,4 @@ tarball=referencing-VERSION-py3-none-any.whl sha1=9d710ba3a604d24ffded218a3813b5fd1fe2e495 sha256=160f24a7d2411dc82b1efd96dfb083ee9e5cc9bc8e492d323e0dd853989d37b3 -upstream_url=https://pypi.io/packages/py3/r/referencing/referencing-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/r/referencing/referencing-VERSION-py3-none-any.whl diff --git a/build/pkgs/requests/checksums.ini b/build/pkgs/requests/checksums.ini index d7a9d3b8c66..025f971aa2b 100644 --- a/build/pkgs/requests/checksums.ini +++ b/build/pkgs/requests/checksums.ini @@ -1,4 +1,4 @@ tarball=requests-VERSION-py3-none-any.whl sha1=e82ece8f17ba4237cc5a4fd641349e45e1d3ddfd sha256=fc06670dd0ed212426dfeb94fc1b983d917c4f9847c863f313c9dfaaffb7c23c -upstream_url=https://pypi.io/packages/py3/r/requests/requests-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/r/requests/requests-VERSION-py3-none-any.whl diff --git a/build/pkgs/rfc3339_validator/checksums.ini b/build/pkgs/rfc3339_validator/checksums.ini index a0766fbec23..babf4ab8107 100644 --- a/build/pkgs/rfc3339_validator/checksums.ini +++ b/build/pkgs/rfc3339_validator/checksums.ini @@ -1,4 +1,4 @@ tarball=rfc3339_validator-VERSION-py2.py3-none-any.whl sha1=daa86cb641dfd6ebfef4ece6dea1be8fd63dec00 sha256=24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa -upstream_url=https://pypi.io/packages/py2.py3/r/rfc3339_validator/rfc3339_validator-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/r/rfc3339_validator/rfc3339_validator-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/rfc3986_validator/checksums.ini b/build/pkgs/rfc3986_validator/checksums.ini index 5d08b72ca0e..e1da79014c9 100644 --- a/build/pkgs/rfc3986_validator/checksums.ini +++ b/build/pkgs/rfc3986_validator/checksums.ini @@ -1,4 +1,4 @@ tarball=rfc3986_validator-VERSION-py2.py3-none-any.whl sha1=c0fabd5c0568cc516f9258f3e5846a04a059dc31 sha256=2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9 -upstream_url=https://pypi.io/packages/py2.py3/r/rfc3986_validator/rfc3986_validator-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/r/rfc3986_validator/rfc3986_validator-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/rpy2/checksums.ini b/build/pkgs/rpy2/checksums.ini index 62224bc62f8..9236ef7b950 100644 --- a/build/pkgs/rpy2/checksums.ini +++ b/build/pkgs/rpy2/checksums.ini @@ -1,4 +1,4 @@ tarball=rpy2-VERSION.tar.gz sha1=7d236c0c6982333b20b6a126f0c17a5481fea64b sha256=5d31a5ea43f5a59f6dec30faca87edb01fc9b8affa0beae96a99be923bd7dab3 -upstream_url=https://pypi.io/packages/source/r/rpy2/rpy2-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/r/rpy2/rpy2-VERSION.tar.gz diff --git a/build/pkgs/rst2ipynb/checksums.ini b/build/pkgs/rst2ipynb/checksums.ini index 2248cc0a54a..9c968023eee 100644 --- a/build/pkgs/rst2ipynb/checksums.ini +++ b/build/pkgs/rst2ipynb/checksums.ini @@ -1,4 +1,4 @@ tarball=rst2ipynb-VERSION.tar.gz sha1=98926df9a8336c8974f446a2a858458495b5aec4 sha256=30d70b0e96f1c37baad9c8dbe904fc2567354eec02c52b94e7c7287b6268eaa3 -upstream_url=https://pypi.io/packages/source/r/rst2ipynb/rst2ipynb-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/r/rst2ipynb/rst2ipynb-VERSION.tar.gz diff --git a/build/pkgs/sage_numerical_backends_coin/checksums.ini b/build/pkgs/sage_numerical_backends_coin/checksums.ini index 427dcedeb0a..84784d5d282 100644 --- a/build/pkgs/sage_numerical_backends_coin/checksums.ini +++ b/build/pkgs/sage_numerical_backends_coin/checksums.ini @@ -1,4 +1,4 @@ tarball=sage_numerical_backends_coin-VERSION.tar.gz sha1=2033e1ba209315366a6dbfe249d5de5f7a1bc1b0 sha256=6e34d48632d070e97dc37b724098c0f050026b166b328af78929b1ea079fa9e7 -upstream_url=https://pypi.io/packages/source/s/sage_numerical_backends_coin/sage_numerical_backends_coin-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/s/sage_numerical_backends_coin/sage_numerical_backends_coin-VERSION.tar.gz diff --git a/build/pkgs/sage_numerical_backends_cplex/checksums.ini b/build/pkgs/sage_numerical_backends_cplex/checksums.ini index 24a6756620a..8f4439b6691 100644 --- a/build/pkgs/sage_numerical_backends_cplex/checksums.ini +++ b/build/pkgs/sage_numerical_backends_cplex/checksums.ini @@ -1,4 +1,4 @@ tarball=sage_numerical_backends_cplex-VERSION.tar.gz sha1=b7085bfdeecb55a43c799493672a228687c30eaf sha256=367480d7a291e0ac4e3df529fbc2a17f78f3770ce7dc2cf78d765f72b7bd938e -upstream_url=https://pypi.io/packages/source/s/sage_numerical_backends_cplex/sage_numerical_backends_cplex-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/s/sage_numerical_backends_cplex/sage_numerical_backends_cplex-VERSION.tar.gz diff --git a/build/pkgs/sage_numerical_backends_gurobi/checksums.ini b/build/pkgs/sage_numerical_backends_gurobi/checksums.ini index 02b722b9bd2..d9dd145cb9c 100644 --- a/build/pkgs/sage_numerical_backends_gurobi/checksums.ini +++ b/build/pkgs/sage_numerical_backends_gurobi/checksums.ini @@ -1,4 +1,4 @@ tarball=sage_numerical_backends_gurobi-VERSION.tar.gz sha1=6891c154bd035932759152dba6a8bd77e8811f22 sha256=3c3b51d6577f651d10cb7f6fc37ca4bb27c6fe2716d6515d1d23eeed1f34e32a -upstream_url=https://pypi.io/packages/source/s/sage_numerical_backends_gurobi/sage_numerical_backends_gurobi-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/s/sage_numerical_backends_gurobi/sage_numerical_backends_gurobi-VERSION.tar.gz diff --git a/build/pkgs/sagetex/checksums.ini b/build/pkgs/sagetex/checksums.ini index 7cfac7e72f3..99442f969cc 100644 --- a/build/pkgs/sagetex/checksums.ini +++ b/build/pkgs/sagetex/checksums.ini @@ -1,4 +1,4 @@ tarball=sagetex-VERSION.tar.gz sha1=821c8a6ab11ee651d0dcc599c5582fefb6706775 sha256=03162ec62cb86da13a747f982241af3e4f4cdd4d29fcba8fbb6c6982a9e906d9 -upstream_url=https://pypi.io/packages/source/s/sagetex/sagetex-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/s/sagetex/sagetex-VERSION.tar.gz diff --git a/build/pkgs/scipy/checksums.ini b/build/pkgs/scipy/checksums.ini index 8871f77250b..d834a3ad1b3 100644 --- a/build/pkgs/scipy/checksums.ini +++ b/build/pkgs/scipy/checksums.ini @@ -1,4 +1,4 @@ tarball=scipy-VERSION.tar.gz sha1=0fd6e14972d8dd9b4a656686a40aed00ad0f1396 sha256=4bf5abab8a36d20193c698b0f1fc282c1d083c94723902c447e5d2f1780936a3 -upstream_url=https://pypi.io/packages/source/s/scipy/scipy-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/s/scipy/scipy-VERSION.tar.gz diff --git a/build/pkgs/scs/checksums.ini b/build/pkgs/scs/checksums.ini index ceaf994ac5f..d78d19fbac9 100644 --- a/build/pkgs/scs/checksums.ini +++ b/build/pkgs/scs/checksums.ini @@ -1,4 +1,4 @@ tarball=scs-VERSION.tar.gz sha1=92e4ff21b450c9659f610064eb79e804de9167b4 sha256=e3bd779e7e977e3ae5a2f2035aa4c2a309e29082d59a722d5d6592edc4bdb4b3 -upstream_url=https://pypi.io/packages/source/s/scs/scs-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/s/scs/scs-VERSION.tar.gz diff --git a/build/pkgs/send2trash/checksums.ini b/build/pkgs/send2trash/checksums.ini index 8617b6b9b6b..bf0c8b27d6b 100644 --- a/build/pkgs/send2trash/checksums.ini +++ b/build/pkgs/send2trash/checksums.ini @@ -1,4 +1,4 @@ tarball=Send2Trash-VERSION-py3-none-any.whl sha1=e24d3494febe78a4a1c8ecbfde78ed52e78cf299 sha256=0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9 -upstream_url=https://pypi.io/packages/py3/s/send2trash/Send2Trash-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/send2trash/Send2Trash-VERSION-py3-none-any.whl diff --git a/build/pkgs/setuptools/checksums.ini b/build/pkgs/setuptools/checksums.ini index 97d83ec2dd7..13bcfce0429 100644 --- a/build/pkgs/setuptools/checksums.ini +++ b/build/pkgs/setuptools/checksums.ini @@ -1,4 +1,4 @@ tarball=setuptools-VERSION-py3-none-any.whl sha1=3756539d45341ca5cec9e2dfe11539faa066f5cd sha256=b208925fcb9f7af924ed2dc04708ea89791e24bde0d3020b27df0e116088b34e -upstream_url=https://pypi.io/packages/py3/s/setuptools/setuptools-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/setuptools/setuptools-VERSION-py3-none-any.whl diff --git a/build/pkgs/setuptools_scm/checksums.ini b/build/pkgs/setuptools_scm/checksums.ini index abae8c0a4f4..553d3df6614 100644 --- a/build/pkgs/setuptools_scm/checksums.ini +++ b/build/pkgs/setuptools_scm/checksums.ini @@ -1,4 +1,4 @@ tarball=setuptools_scm-VERSION-py3-none-any.whl sha1=be606b6acb67714b96e9e1e9a9944feaca504e44 sha256=897a3226a6fd4a6eb2f068745e49733261a21f70b1bb28fce0339feb978d9af3 -upstream_url=https://pypi.io/packages/py3/s/setuptools_scm/setuptools_scm-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/setuptools_scm/setuptools_scm-VERSION-py3-none-any.whl diff --git a/build/pkgs/six/checksums.ini b/build/pkgs/six/checksums.ini index 24f678da7eb..4944f7d54fe 100644 --- a/build/pkgs/six/checksums.ini +++ b/build/pkgs/six/checksums.ini @@ -1,4 +1,4 @@ tarball=six-VERSION-py2.py3-none-any.whl sha1=79e6f2e4f9e24898f1896df379871b9c9922f147 sha256=8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 -upstream_url=https://pypi.io/packages/py2.py3/s/six/six-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/s/six/six-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/sniffio/checksums.ini b/build/pkgs/sniffio/checksums.ini index c3a342052ec..554eef47d86 100644 --- a/build/pkgs/sniffio/checksums.ini +++ b/build/pkgs/sniffio/checksums.ini @@ -1,4 +1,4 @@ tarball=sniffio-VERSION-py3-none-any.whl sha1=bd8d1ec2b285eed542c53ca22232e6e9e468c389 sha256=2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 -upstream_url=https://pypi.io/packages/py3/s/sniffio/sniffio-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/sniffio/sniffio-VERSION-py3-none-any.whl diff --git a/build/pkgs/snowballstemmer/checksums.ini b/build/pkgs/snowballstemmer/checksums.ini index cab5be15660..a013fcb27e2 100644 --- a/build/pkgs/snowballstemmer/checksums.ini +++ b/build/pkgs/snowballstemmer/checksums.ini @@ -1,4 +1,4 @@ tarball=snowballstemmer-VERSION.tar.gz sha1=aaf1b0e3b58d25e2e297ea3dbef59d8534ef8d92 sha256=09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1 -upstream_url=https://pypi.io/packages/source/s/snowballstemmer/snowballstemmer-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/s/snowballstemmer/snowballstemmer-VERSION.tar.gz diff --git a/build/pkgs/soupsieve/checksums.ini b/build/pkgs/soupsieve/checksums.ini index 3e9ef0ba9fc..8d78dcb4d86 100644 --- a/build/pkgs/soupsieve/checksums.ini +++ b/build/pkgs/soupsieve/checksums.ini @@ -1,4 +1,4 @@ tarball=soupsieve-VERSION-py3-none-any.whl sha1=a155a6208211aa90bbc3bcfc9cab194a05000e59 sha256=eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7 -upstream_url=https://pypi.io/packages/py3/s/soupsieve/soupsieve-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/soupsieve/soupsieve-VERSION-py3-none-any.whl diff --git a/build/pkgs/sphinx/checksums.ini b/build/pkgs/sphinx/checksums.ini index 463dfef26f9..1721e0e8521 100644 --- a/build/pkgs/sphinx/checksums.ini +++ b/build/pkgs/sphinx/checksums.ini @@ -1,4 +1,4 @@ tarball=sphinx-VERSION-py3-none-any.whl sha1=f9af5608fbb188f12e38d3c09cdefeef40255365 sha256=c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239 -upstream_url=https://pypi.io/packages/py3/s/sphinx/sphinx-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/sphinx/sphinx-VERSION-py3-none-any.whl diff --git a/build/pkgs/sphinx_basic_ng/checksums.ini b/build/pkgs/sphinx_basic_ng/checksums.ini index 4933de2fa24..6ad0e9c0b5a 100644 --- a/build/pkgs/sphinx_basic_ng/checksums.ini +++ b/build/pkgs/sphinx_basic_ng/checksums.ini @@ -1,4 +1,4 @@ tarball=sphinx_basic_ng-VERSION-py3-none-any.whl sha1=abcd9bda6ae61bb20c52bf46c17fb1bbdfdab4ea sha256=eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b -upstream_url=https://pypi.io/packages/py3/s/sphinx_basic_ng/sphinx_basic_ng-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/sphinx_basic_ng/sphinx_basic_ng-VERSION-py3-none-any.whl diff --git a/build/pkgs/sphinx_copybutton/checksums.ini b/build/pkgs/sphinx_copybutton/checksums.ini index 1c83ae582e0..17531981252 100644 --- a/build/pkgs/sphinx_copybutton/checksums.ini +++ b/build/pkgs/sphinx_copybutton/checksums.ini @@ -1,4 +1,4 @@ tarball=sphinx_copybutton-VERSION-py3-none-any.whl sha1=a15e038b665225b13f7bd3eae6a2a64c8bd4b582 sha256=fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e -upstream_url=https://pypi.io/packages/py3/s/sphinx_copybutton/sphinx_copybutton-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/sphinx_copybutton/sphinx_copybutton-VERSION-py3-none-any.whl diff --git a/build/pkgs/sphinx_inline_tabs/checksums.ini b/build/pkgs/sphinx_inline_tabs/checksums.ini index 93c03352650..423f9c2772a 100644 --- a/build/pkgs/sphinx_inline_tabs/checksums.ini +++ b/build/pkgs/sphinx_inline_tabs/checksums.ini @@ -1,4 +1,4 @@ tarball=sphinx_inline_tabs-VERSION-py3-none-any.whl sha1=1404e320d0533280355e7e1e71cffd9937015027 sha256=06809ac613f7c48ddd6e2fa588413e3fe92cff2397b56e2ccf0b0218f9ef6a78 -upstream_url=https://pypi.io/packages/py3/s/sphinx_inline_tabs/sphinx_inline_tabs-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/sphinx_inline_tabs/sphinx_inline_tabs-VERSION-py3-none-any.whl diff --git a/build/pkgs/sphinxcontrib_applehelp/checksums.ini b/build/pkgs/sphinxcontrib_applehelp/checksums.ini index 25ebbacf69a..55b9e980fb3 100644 --- a/build/pkgs/sphinxcontrib_applehelp/checksums.ini +++ b/build/pkgs/sphinxcontrib_applehelp/checksums.ini @@ -1,4 +1,4 @@ tarball=sphinxcontrib_applehelp-VERSION-py3-none-any.whl sha1=e426527562da2c5c520b27c58210cd1d44a1185b sha256=cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4 -upstream_url=https://pypi.io/packages/py3/s/sphinxcontrib_applehelp/sphinxcontrib_applehelp-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/sphinxcontrib_applehelp/sphinxcontrib_applehelp-VERSION-py3-none-any.whl diff --git a/build/pkgs/sphinxcontrib_devhelp/checksums.ini b/build/pkgs/sphinxcontrib_devhelp/checksums.ini index 03e4c534a7a..2352006b2c9 100644 --- a/build/pkgs/sphinxcontrib_devhelp/checksums.ini +++ b/build/pkgs/sphinxcontrib_devhelp/checksums.ini @@ -1,4 +1,4 @@ tarball=sphinxcontrib_devhelp-VERSION-py3-none-any.whl sha1=c1c774393d267d97eaf07f0e5c740f82af24d628 sha256=6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f -upstream_url=https://pypi.io/packages/py3/s/sphinxcontrib_devhelp/sphinxcontrib_devhelp-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/sphinxcontrib_devhelp/sphinxcontrib_devhelp-VERSION-py3-none-any.whl diff --git a/build/pkgs/sphinxcontrib_htmlhelp/checksums.ini b/build/pkgs/sphinxcontrib_htmlhelp/checksums.ini index 02f3fefa8df..2a7d6ba97bb 100644 --- a/build/pkgs/sphinxcontrib_htmlhelp/checksums.ini +++ b/build/pkgs/sphinxcontrib_htmlhelp/checksums.ini @@ -1,4 +1,4 @@ tarball=sphinxcontrib_htmlhelp-VERSION-py3-none-any.whl sha1=6b60c617a0fe98a663ca146edc03867581da5e07 sha256=393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04 -upstream_url=https://pypi.io/packages/py3/s/sphinxcontrib_htmlhelp/sphinxcontrib_htmlhelp-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/sphinxcontrib_htmlhelp/sphinxcontrib_htmlhelp-VERSION-py3-none-any.whl diff --git a/build/pkgs/sphinxcontrib_jsmath/checksums.ini b/build/pkgs/sphinxcontrib_jsmath/checksums.ini index 5ad932e6f6c..1f2ec07e8ab 100644 --- a/build/pkgs/sphinxcontrib_jsmath/checksums.ini +++ b/build/pkgs/sphinxcontrib_jsmath/checksums.ini @@ -1,4 +1,4 @@ tarball=sphinxcontrib_jsmath-VERSION-py2.py3-none-any.whl sha1=beff4fc35d13a5f2883bc129f28ac031046195c5 sha256=2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 -upstream_url=https://pypi.io/packages/py2.py3/s/sphinxcontrib_jsmath/sphinxcontrib_jsmath-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/s/sphinxcontrib_jsmath/sphinxcontrib_jsmath-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/sphinxcontrib_qthelp/checksums.ini b/build/pkgs/sphinxcontrib_qthelp/checksums.ini index bb35693af5e..d2c313eb1fb 100644 --- a/build/pkgs/sphinxcontrib_qthelp/checksums.ini +++ b/build/pkgs/sphinxcontrib_qthelp/checksums.ini @@ -1,4 +1,4 @@ tarball=sphinxcontrib_qthelp-VERSION-py3-none-any.whl sha1=8f593bd6ca46487ed25ee0fca50f0d88b18e5f9e sha256=e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182 -upstream_url=https://pypi.io/packages/py3/s/sphinxcontrib_qthelp/sphinxcontrib_qthelp-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/sphinxcontrib_qthelp/sphinxcontrib_qthelp-VERSION-py3-none-any.whl diff --git a/build/pkgs/sphinxcontrib_serializinghtml/checksums.ini b/build/pkgs/sphinxcontrib_serializinghtml/checksums.ini index 292f6b2b195..81e105df791 100644 --- a/build/pkgs/sphinxcontrib_serializinghtml/checksums.ini +++ b/build/pkgs/sphinxcontrib_serializinghtml/checksums.ini @@ -1,4 +1,4 @@ tarball=sphinxcontrib_serializinghtml-VERSION-py3-none-any.whl sha1=a5198a72d1668e97fdda39a559586bcf57cb7278 sha256=326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7 -upstream_url=https://pypi.io/packages/py3/s/sphinxcontrib_serializinghtml/sphinxcontrib_serializinghtml-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/sphinxcontrib_serializinghtml/sphinxcontrib_serializinghtml-VERSION-py3-none-any.whl diff --git a/build/pkgs/sphinxcontrib_websupport/checksums.ini b/build/pkgs/sphinxcontrib_websupport/checksums.ini index 9964fd80b13..c51d7ed6b52 100644 --- a/build/pkgs/sphinxcontrib_websupport/checksums.ini +++ b/build/pkgs/sphinxcontrib_websupport/checksums.ini @@ -1,4 +1,4 @@ tarball=sphinxcontrib_websupport-VERSION-py3-none-any.whl sha1=649d1447a4773b665588060efda66344cb9b99a5 sha256=2dc179d7f821ebd54f31f93c894ca52435ebc5364e4e4dfb0da834ac119d51fd -upstream_url=https://pypi.io/packages/py3/s/sphinxcontrib_websupport/sphinxcontrib_websupport-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/sphinxcontrib_websupport/sphinxcontrib_websupport-VERSION-py3-none-any.whl diff --git a/build/pkgs/stack_data/checksums.ini b/build/pkgs/stack_data/checksums.ini index 4f749a287f0..ddcda4ebb4a 100644 --- a/build/pkgs/stack_data/checksums.ini +++ b/build/pkgs/stack_data/checksums.ini @@ -1,4 +1,4 @@ tarball=stack_data-VERSION-py3-none-any.whl sha1=96814b10bdc464e8ef00f4a07c60dd17a3dc9668 sha256=d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695 -upstream_url=https://pypi.io/packages/py3/s/stack_data/stack_data-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/stack_data/stack_data-VERSION-py3-none-any.whl diff --git a/build/pkgs/symengine_py/checksums.ini b/build/pkgs/symengine_py/checksums.ini index b8984f6553c..243b69d4a3e 100644 --- a/build/pkgs/symengine_py/checksums.ini +++ b/build/pkgs/symengine_py/checksums.ini @@ -1,4 +1,4 @@ tarball=symengine.py-VERSION.tar.gz sha1=4a8da0d0a057c8709c5b28543dbb3d26a060f013 sha256=0dd30d29b804ebb7251bddec29c38c3b1fc15ea6953a2c57ee758d5f6fcba458 -upstream_url=https://pypi.io/packages/source/s/symengine/symengine-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/s/symengine/symengine-VERSION.tar.gz diff --git a/build/pkgs/sympy/checksums.ini b/build/pkgs/sympy/checksums.ini index 17e31ea9f3d..a03797698b1 100644 --- a/build/pkgs/sympy/checksums.ini +++ b/build/pkgs/sympy/checksums.ini @@ -1,4 +1,4 @@ tarball=sympy-VERSION-py3-none-any.whl sha1=e34c28a2aa2b677efe2f1b7cefe275e20d2e652c sha256=c51d75517712f1aed280d4ce58506a4a88d635d6b5dd48b39102a7ae1f3fcfe9 -upstream_url=https://pypi.io/packages/py3/s/sympy/sympy-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/s/sympy/sympy-VERSION-py3-none-any.whl diff --git a/build/pkgs/terminado/checksums.ini b/build/pkgs/terminado/checksums.ini index ce9c0407bad..e54d9b51727 100644 --- a/build/pkgs/terminado/checksums.ini +++ b/build/pkgs/terminado/checksums.ini @@ -1,4 +1,4 @@ tarball=terminado-VERSION.tar.gz sha1=608fcc44b845e1fb783e361d59e79fba83126e14 sha256=6ccbbcd3a4f8a25a5ec04991f39a0b8db52dfcd487ea0e578d977e6752380333 -upstream_url=https://pypi.io/packages/source/t/terminado/terminado-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/t/terminado/terminado-VERSION.tar.gz diff --git a/build/pkgs/texttable/checksums.ini b/build/pkgs/texttable/checksums.ini index 3446dba447f..c83680e54a9 100644 --- a/build/pkgs/texttable/checksums.ini +++ b/build/pkgs/texttable/checksums.ini @@ -1,4 +1,4 @@ tarball=texttable-VERSION.tar.gz sha1=0fa175fa6e0fefea31434746641bedc8cbb60248 sha256=2d2068fb55115807d3ac77a4ca68fa48803e84ebb0ee2340f858107a36522638 -upstream_url=https://pypi.io/packages/source/t/texttable/texttable-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/t/texttable/texttable-VERSION.tar.gz diff --git a/build/pkgs/tinycss2/checksums.ini b/build/pkgs/tinycss2/checksums.ini index a6abd957086..b649e4f8b3e 100644 --- a/build/pkgs/tinycss2/checksums.ini +++ b/build/pkgs/tinycss2/checksums.ini @@ -1,4 +1,4 @@ tarball=tinycss2-VERSION.tar.gz sha1=3871ffec30bde346d1a17f80a423dce488bad4f7 sha256=8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627 -upstream_url=https://pypi.io/packages/source/t/tinycss2/tinycss2-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/t/tinycss2/tinycss2-VERSION.tar.gz diff --git a/build/pkgs/tomli/checksums.ini b/build/pkgs/tomli/checksums.ini index 00d70337b2b..0837611ad26 100644 --- a/build/pkgs/tomli/checksums.ini +++ b/build/pkgs/tomli/checksums.ini @@ -1,4 +1,4 @@ tarball=tomli-VERSION-py3-none-any.whl sha1=5bfc83c14bc54e6193a0d50a50c16a88eda0c4fa sha256=939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc -upstream_url=https://pypi.io/packages/py3/t/tomli/tomli-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/t/tomli/tomli-VERSION-py3-none-any.whl diff --git a/build/pkgs/tornado/checksums.ini b/build/pkgs/tornado/checksums.ini index 9cc0e020c01..c11b8fec974 100644 --- a/build/pkgs/tornado/checksums.ini +++ b/build/pkgs/tornado/checksums.ini @@ -1,4 +1,4 @@ tarball=tornado-VERSION.tar.gz sha1=5b4036313660a74034186ac63b10d244ca9444b8 sha256=72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee -upstream_url=https://pypi.io/packages/source/t/tornado/tornado-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/t/tornado/tornado-VERSION.tar.gz diff --git a/build/pkgs/tox/checksums.ini b/build/pkgs/tox/checksums.ini index fa5a87fb673..713b1eb18fe 100644 --- a/build/pkgs/tox/checksums.ini +++ b/build/pkgs/tox/checksums.ini @@ -1,4 +1,4 @@ tarball=tox-VERSION-py3-none-any.whl sha1=d3312285c4988d3307d3b000a8a18cfcb16aea29 sha256=da761b4a57ee2b92b5ce39f48ff723fc42d185bf2af508effb683214efa662ea -upstream_url=https://pypi.io/packages/py3/t/tox/tox-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/t/tox/tox-VERSION-py3-none-any.whl diff --git a/build/pkgs/traitlets/checksums.ini b/build/pkgs/traitlets/checksums.ini index ad86191465c..a56a3cea9e1 100644 --- a/build/pkgs/traitlets/checksums.ini +++ b/build/pkgs/traitlets/checksums.ini @@ -1,4 +1,4 @@ tarball=traitlets-VERSION-py3-none-any.whl sha1=a6c667ce2b3adf2ab3562f144067f02326383c25 sha256=b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f -upstream_url=https://pypi.io/packages/py3/t/traitlets/traitlets-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/t/traitlets/traitlets-VERSION-py3-none-any.whl diff --git a/build/pkgs/trove_classifiers/checksums.ini b/build/pkgs/trove_classifiers/checksums.ini index 42e0ec6eefe..ab2559ee8c7 100644 --- a/build/pkgs/trove_classifiers/checksums.ini +++ b/build/pkgs/trove_classifiers/checksums.ini @@ -1,4 +1,4 @@ tarball=trove_classifiers-VERSION-py3-none-any.whl sha1=8219f839a8223a9dd0912cde22d579cfa75a516e sha256=ccc57a33717644df4daca018e7ec3ef57a835c48e96a1e71fc07eb7edac67af6 -upstream_url=https://pypi.io/packages/py3/t/trove_classifiers/trove_classifiers-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/t/trove_classifiers/trove_classifiers-VERSION-py3-none-any.whl diff --git a/build/pkgs/types_python_dateutil/checksums.ini b/build/pkgs/types_python_dateutil/checksums.ini index 08fb0805291..71ea4d06e2c 100644 --- a/build/pkgs/types_python_dateutil/checksums.ini +++ b/build/pkgs/types_python_dateutil/checksums.ini @@ -1,4 +1,4 @@ tarball=types_python_dateutil-VERSION-py3-none-any.whl sha1=fc0a6cbd54667dd8dadb95c448014efe66c9ae0a sha256=6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b -upstream_url=https://pypi.io/packages/py3/t/types_python_dateutil/types_python_dateutil-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/t/types_python_dateutil/types_python_dateutil-VERSION-py3-none-any.whl diff --git a/build/pkgs/typing_extensions/checksums.ini b/build/pkgs/typing_extensions/checksums.ini index 5d4ca8ca5f2..52a4f6256ea 100644 --- a/build/pkgs/typing_extensions/checksums.ini +++ b/build/pkgs/typing_extensions/checksums.ini @@ -1,4 +1,4 @@ tarball=typing_extensions-VERSION-py3-none-any.whl sha1=0fb5b2732cc421561b1348cac1334eb6a4e0bb7f sha256=04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d -upstream_url=https://pypi.io/packages/py3/t/typing_extensions/typing_extensions-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/t/typing_extensions/typing_extensions-VERSION-py3-none-any.whl diff --git a/build/pkgs/tzdata/checksums.ini b/build/pkgs/tzdata/checksums.ini index 449a195f648..334ff50b979 100644 --- a/build/pkgs/tzdata/checksums.ini +++ b/build/pkgs/tzdata/checksums.ini @@ -1,4 +1,4 @@ tarball=tzdata-VERSION-py2.py3-none-any.whl sha1=4686c7c91a01d5af9075903937c343afa05c141b sha256=7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda -upstream_url=https://pypi.io/packages/py2.py3/t/tzdata/tzdata-VERSION-py2.py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py2.py3/t/tzdata/tzdata-VERSION-py2.py3-none-any.whl diff --git a/build/pkgs/tzlocal/checksums.ini b/build/pkgs/tzlocal/checksums.ini index 5c246c69ced..7618e395db1 100644 --- a/build/pkgs/tzlocal/checksums.ini +++ b/build/pkgs/tzlocal/checksums.ini @@ -1,4 +1,4 @@ tarball=tzlocal-VERSION.tar.gz sha1=1d61e52edddf882c9af4f5f3f1be0db3788dd7b5 sha256=46eb99ad4bdb71f3f72b7d24f4267753e240944ecfc16f25d2719ba89827a803 -upstream_url=https://pypi.io/packages/source/t/tzlocal/tzlocal-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/t/tzlocal/tzlocal-VERSION.tar.gz diff --git a/build/pkgs/uri_template/checksums.ini b/build/pkgs/uri_template/checksums.ini index 601b51db908..1ffd9d33334 100644 --- a/build/pkgs/uri_template/checksums.ini +++ b/build/pkgs/uri_template/checksums.ini @@ -1,4 +1,4 @@ tarball=uri_template-VERSION-py3-none-any.whl sha1=bbc8808bdb7e687f0c099c8120cd901dc90bce69 sha256=a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363 -upstream_url=https://pypi.io/packages/py3/u/uri_template/uri_template-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/u/uri_template/uri_template-VERSION-py3-none-any.whl diff --git a/build/pkgs/urllib3/checksums.ini b/build/pkgs/urllib3/checksums.ini index 1fbf6f0991c..3689a94a382 100644 --- a/build/pkgs/urllib3/checksums.ini +++ b/build/pkgs/urllib3/checksums.ini @@ -1,4 +1,4 @@ tarball=urllib3-VERSION-py3-none-any.whl sha1=1e197082cd0d0f98bc97f2fbfd7d2a597e3ff3e4 sha256=55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3 -upstream_url=https://pypi.io/packages/py3/u/urllib3/urllib3-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/u/urllib3/urllib3-VERSION-py3-none-any.whl diff --git a/build/pkgs/virtualenv/checksums.ini b/build/pkgs/virtualenv/checksums.ini index c83cfa5112d..ebe17fab050 100644 --- a/build/pkgs/virtualenv/checksums.ini +++ b/build/pkgs/virtualenv/checksums.ini @@ -1,4 +1,4 @@ tarball=virtualenv-VERSION-py3-none-any.whl sha1=f18ea5b827ba66a1724769371c6912601ec4d647 sha256=a624db5e94f01ad993d476b9ee5346fdf7b9de43ccaee0e0197012dc838a0e9b -upstream_url=https://pypi.io/packages/py3/v/virtualenv/virtualenv-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/v/virtualenv/virtualenv-VERSION-py3-none-any.whl diff --git a/build/pkgs/wcwidth/checksums.ini b/build/pkgs/wcwidth/checksums.ini index 18801e12105..169913604d5 100644 --- a/build/pkgs/wcwidth/checksums.ini +++ b/build/pkgs/wcwidth/checksums.ini @@ -1,4 +1,4 @@ tarball=wcwidth-VERSION.tar.gz sha1=49bdbcac346f31be8201c663082331b693264382 sha256=f01c104efdf57971bcb756f054dd58ddec5204dd15fa31d6503ea57947d97c02 -upstream_url=https://pypi.io/packages/source/w/wcwidth/wcwidth-VERSION.tar.gz +upstream_url=https://files.pythonhosted.org/packages/source/w/wcwidth/wcwidth-VERSION.tar.gz diff --git a/build/pkgs/webcolors/checksums.ini b/build/pkgs/webcolors/checksums.ini index 2db93e1e869..2b483c8d29b 100644 --- a/build/pkgs/webcolors/checksums.ini +++ b/build/pkgs/webcolors/checksums.ini @@ -1,4 +1,4 @@ tarball=webcolors-VERSION-py3-none-any.whl sha1=e13a9143964b824fc4972b60eddd8115f6839a26 sha256=29bc7e8752c0a1bd4a1f03c14d6e6a72e93d82193738fa860cbff59d0fcc11bf -upstream_url=https://pypi.io/packages/py3/w/webcolors/webcolors-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/w/webcolors/webcolors-VERSION-py3-none-any.whl diff --git a/build/pkgs/websocket_client/checksums.ini b/build/pkgs/websocket_client/checksums.ini index 6cc10d23812..0ccb613fdd6 100644 --- a/build/pkgs/websocket_client/checksums.ini +++ b/build/pkgs/websocket_client/checksums.ini @@ -1,4 +1,4 @@ tarball=websocket_client-VERSION-py3-none-any.whl sha1=eb78bd39f1ae4d531cc965bd21d121ba3d156f84 sha256=084072e0a7f5f347ef2ac3d8698a5e0b4ffbfcab607628cadabc650fc9a83a24 -upstream_url=https://pypi.io/packages/py3/w/websocket_client/websocket_client-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/w/websocket_client/websocket_client-VERSION-py3-none-any.whl diff --git a/build/pkgs/wheel/checksums.ini b/build/pkgs/wheel/checksums.ini index 3157a2efcec..67624baa8b2 100644 --- a/build/pkgs/wheel/checksums.ini +++ b/build/pkgs/wheel/checksums.ini @@ -1,4 +1,4 @@ tarball=wheel-VERSION-py3-none-any.whl sha1=65ec55742da04152c8b06d6586fb36d779d7883e sha256=2376a90c98cc337d18623527a97c31797bd02bad0033d41547043a1cbfbe448f -upstream_url=https://pypi.io/packages/py3/w/wheel/wheel-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/w/wheel/wheel-VERSION-py3-none-any.whl diff --git a/build/pkgs/widgetsnbextension/checksums.ini b/build/pkgs/widgetsnbextension/checksums.ini index 099c0acb09e..3fc58cecc14 100644 --- a/build/pkgs/widgetsnbextension/checksums.ini +++ b/build/pkgs/widgetsnbextension/checksums.ini @@ -1,4 +1,4 @@ tarball=widgetsnbextension-VERSION-py3-none-any.whl sha1=067535b5d1738a4de0abb5f1219581a4a66d243c sha256=91452ca8445beb805792f206e560c1769284267a30ceb1cec9f5bcc887d15175 -upstream_url=https://pypi.io/packages/py3/w/widgetsnbextension/widgetsnbextension-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/w/widgetsnbextension/widgetsnbextension-VERSION-py3-none-any.whl diff --git a/build/pkgs/zipp/checksums.ini b/build/pkgs/zipp/checksums.ini index 1af443d7f19..5fc5129cab4 100644 --- a/build/pkgs/zipp/checksums.ini +++ b/build/pkgs/zipp/checksums.ini @@ -1,4 +1,4 @@ tarball=zipp-VERSION-py3-none-any.whl sha1=22cf149f293964ac7538ad41af8caa9aacf8fe1a sha256=96dc6ad62f1441bcaccef23b274ec471518daf4fbbc580341204936a5a3dddec -upstream_url=https://pypi.io/packages/py3/z/zipp/zipp-VERSION-py3-none-any.whl +upstream_url=https://files.pythonhosted.org/packages/py3/z/zipp/zipp-VERSION-py3-none-any.whl diff --git a/build/sage_bootstrap/app.py b/build/sage_bootstrap/app.py index 2b8b44959b1..c5dac654cc5 100644 --- a/build/sage_bootstrap/app.py +++ b/build/sage_bootstrap/app.py @@ -430,9 +430,9 @@ def create(self, package_name, version=None, tarball=None, pkg_type=None, upstre tarball = pypi_version.tarball.replace(pypi_version.version, 'VERSION') if not version: version = pypi_version.version - # Use a URL from pypi.io instead of the specific URL received from the PyPI query + # Use a URL from files.pythonhosted.org instead of the specific URL received from the PyPI query # because it follows a simple pattern. - upstream_url = 'https://pypi.io/packages/source/{0:1.1}/{0}/{1}'.format(package_name, tarball) + upstream_url = 'https://files.pythonhosted.org/packages/source/{0:1.1}/{0}/{1}'.format(package_name, tarball) elif source == 'wheel': if not tarball: tarball = pypi_version.tarball.replace(pypi_version.version, 'VERSION') @@ -459,7 +459,7 @@ def create(self, package_name, version=None, tarball=None, pkg_type=None, upstre self.create(dep, pkg_type=pkg_type) dep = Package(dep).name dependencies.append(dep) - upstream_url = 'https://pypi.io/packages/{2}/{0:1.1}/{0}/{1}'.format(package_name, tarball, pypi_version.python_version) + upstream_url = 'https://files.pythonhosted.org/packages/{2}/{0:1.1}/{0}/{1}'.format(package_name, tarball, pypi_version.python_version) if not description: description = pypi_version.summary if not license: diff --git a/src/doc/en/developer/packaging.rst b/src/doc/en/developer/packaging.rst index d59e5dc07e9..2b6903ca466 100644 --- a/src/doc/en/developer/packaging.rst +++ b/src/doc/en/developer/packaging.rst @@ -1010,11 +1010,11 @@ to refer to the dot-separated components of a version by ``VERSION_MAJOR``, ``VERSION_MINOR``, and ``VERSION_MICRO``. For Python packages available from PyPI, you should use an -``upstream_url`` from ``pypi.io``, which follows the format +``upstream_url`` from ``files.pythonhosted.org``, which follows the format .. CODE-BLOCK:: bash - upstream_url=https://pypi.io/packages/source/m/matplotlib/matplotlib-VERSION.tar.gz + upstream_url=https://files.pythonhosted.org/packages/source/m/matplotlib/matplotlib-VERSION.tar.gz Developers who wish to test a package update from a PR branch before the archive is available on a Sage mirror. Sage falls back to From 9e68b02fd10bf02423db1909099f9e0c06acaa44 Mon Sep 17 00:00:00 2001 From: Kyle Hofmann Date: Mon, 28 Oct 2024 17:28:18 -0700 Subject: [PATCH 66/82] Apply suggestions from code review Co-authored-by: Vincent Macri --- src/sage/rings/finite_rings/integer_mod_ring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index 4381b17f645..1afb008cb89 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -1947,11 +1947,11 @@ def _roots_univariate_polynomial(self, f, ring=None, multiplicities=True, algori mod_p_roots = fp.roots(multiplicities=False) this_prime_power = [] - prime_power_roots.append(this_prime_power) for root in mod_p_roots: this_prime_power.extend( self._lift_residue_field_root(p, e, fpe, fpe_prime, root) ) + prime_power_roots.append(this_prime_power) # Combine using Chinese Remainder Theorem ppwr_basis = CRT_basis([p**e for p, e in fac]) From 6562754580888e6059650cbc9ccf62cbe038fb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 29 Oct 2024 10:46:05 +0100 Subject: [PATCH 67/82] using Parent in ring extensions --- src/sage/rings/morphism.pyx | 4 ++- src/sage/rings/number_field/order.py | 25 ++++++++++++---- src/sage/rings/ring_extension.pxd | 17 ++++++----- src/sage/rings/ring_extension.pyx | 35 +++++++++++----------- src/sage/rings/ring_extension_element.pxd | 10 +++---- src/sage/rings/ring_extension_element.pyx | 13 ++++---- src/sage/rings/ring_extension_morphism.pyx | 6 ++-- 7 files changed, 64 insertions(+), 46 deletions(-) diff --git a/src/sage/rings/morphism.pyx b/src/sage/rings/morphism.pyx index 594e2ff0a3e..3079bfa3974 100644 --- a/src/sage/rings/morphism.pyx +++ b/src/sage/rings/morphism.pyx @@ -2879,8 +2879,10 @@ cdef class FrobeniusEndomorphism_generic(RingHomomorphism): over Finite Field of size 5 """ from sage.rings.ring import CommutativeRing + from sage.categories.commutative_rings import CommutativeRings from sage.categories.homset import Hom - if not isinstance(domain, CommutativeRing): + if not (domain in CommutativeRings() or + isinstance(domain, CommutativeRing)): # TODO: remove this line raise TypeError("The base ring must be a commutative ring") self._p = domain.characteristic() if not self._p.is_prime(): diff --git a/src/sage/rings/number_field/order.py b/src/sage/rings/number_field/order.py index 55db3bbbcbf..9dee6a8a481 100644 --- a/src/sage/rings/number_field/order.py +++ b/src/sage/rings/number_field/order.py @@ -77,8 +77,9 @@ # https://www.gnu.org/licenses/ # **************************************************************************** +from sage.categories.integral_domains import IntegralDomains from sage.misc.cachefunc import cached_method -from sage.rings.ring import IntegralDomain +from sage.structure.parent import Parent from sage.structure.sequence import Sequence from sage.rings.integer_ring import ZZ import sage.rings.abc @@ -426,7 +427,7 @@ def EquationOrder(f, names, **kwds): return K.order(K.gens()) -class Order(IntegralDomain, sage.rings.abc.Order): +class Order(Parent, sage.rings.abc.Order): r""" An order in a number field. @@ -478,8 +479,8 @@ def __init__(self, K): 0.0535229072603327 + 1.20934552493846*I """ self._K = K - IntegralDomain.__init__(self, ZZ, names=K.variable_names(), - normalize=False) + Parent.__init__(self, base=ZZ, names=K.variable_names(), + normalize=False, category=IntegralDomains()) self._populate_coercion_lists_(embedding=self.number_field()) if self.absolute_degree() == 2: self.is_maximal() # cache @@ -665,7 +666,7 @@ def krull_dimension(self): sage: O2.krull_dimension() 1 """ - return ZZ(1) + return ZZ.one() def integral_closure(self): r""" @@ -733,6 +734,20 @@ def ngens(self): """ return self.absolute_degree() + def gens(self) -> tuple: + """ + Return the generators as a tuple. + + EXAMPLES:: + + sage: x = polygen(ZZ, 'x') + sage: K. = NumberField(x^3 + x^2 - 2*x + 8) + sage: O = K.maximal_order() + sage: O.gens() + (1, 1/2*a^2 + 1/2*a, a^2) + """ + return tuple(self.gen(i) for i in range(self.absolute_degree())) + def basis(self): # this must be defined in derived class r""" Return a basis over `\ZZ` of this order. diff --git a/src/sage/rings/ring_extension.pxd b/src/sage/rings/ring_extension.pxd index 478bd6eef75..68c2dd0e974 100644 --- a/src/sage/rings/ring_extension.pxd +++ b/src/sage/rings/ring_extension.pxd @@ -1,8 +1,8 @@ from sage.categories.map cimport Map -from sage.rings.ring cimport CommutativeRing +from sage.structure.parent cimport Parent -cdef class RingExtension_generic(CommutativeRing): +cdef class RingExtension_generic(Parent): cdef _type cdef _backend cdef _defining_morphism @@ -15,10 +15,10 @@ cdef class RingExtension_generic(CommutativeRing): cdef type _fraction_field_type cpdef is_defined_over(self, base) - cpdef CommutativeRing _check_base(self, CommutativeRing base) - cpdef _degree_over(self, CommutativeRing base) - cpdef _is_finite_over(self, CommutativeRing base) - cpdef _is_free_over(self, CommutativeRing base) + cpdef Parent _check_base(self, Parent base) + cpdef _degree_over(self, Parent base) + cpdef _is_finite_over(self, Parent base) + cpdef _is_free_over(self, Parent base) cdef Map _defining_morphism_fraction_field(self, bint extend_base) @@ -31,10 +31,11 @@ cdef class RingExtensionWithBasis(RingExtension_generic): cdef _basis_names cdef _basis_latex_names - cpdef _basis_over(self, CommutativeRing base) - # cpdef _free_module(self, CommutativeRing base, bint map) + cpdef _basis_over(self, Parent base) + # cpdef _free_module(self, Parent base, bint map) cdef class RingExtensionWithGen(RingExtensionWithBasis): cdef _gen cdef _name + cdef public object _latex_names diff --git a/src/sage/rings/ring_extension.pyx b/src/sage/rings/ring_extension.pyx index 174af6dd415..0b376794b76 100644 --- a/src/sage/rings/ring_extension.pyx +++ b/src/sage/rings/ring_extension.pyx @@ -117,12 +117,12 @@ from sage.cpython.getattr import dir_with_other_class from sage.misc.latex import latex, latex_variable_name from sage.structure.factory import UniqueFactory +from sage.structure.parent cimport Parent from sage.structure.element cimport Element from sage.structure.category_object import normalize_names from sage.categories.map cimport Map from sage.categories.commutative_rings import CommutativeRings from sage.categories.fields import Fields -from sage.rings.ring cimport CommutativeRing from sage.rings.integer_ring import ZZ from sage.rings.infinity import Infinity @@ -497,7 +497,7 @@ RingExtension = RingExtensionFactory("sage.rings.ring_extension.RingExtension") # General extensions #################### -cdef class RingExtension_generic(CommutativeRing): +cdef class RingExtension_generic(Parent): r""" A generic class for all ring extensions. @@ -564,8 +564,8 @@ cdef class RingExtension_generic(CommutativeRing): ... ValueError: exotic defining morphism between two rings in the tower; consider using another variable name """ - cdef CommutativeRing base, ring - cdef CommutativeRing b, backend + cdef Parent base, ring + cdef Parent b, backend cdef Map f base = defining_morphism.domain() @@ -575,7 +575,7 @@ cdef class RingExtension_generic(CommutativeRing): # but CommutativeRings() seems safer, especially when dealing with # morphisms which do not need to preserve the base category = CommutativeRings() - CommutativeRing.__init__(self, ZZ, category=category) + Parent.__init__(self, ZZ, category=category) self._base = base self._backend = ring self._backend_defining_morphism = defining_morphism @@ -1197,14 +1197,14 @@ cdef class RingExtension_generic(CommutativeRing): :meth:`base`, :meth:`bases`, :meth:`absolute_base` """ - cdef CommutativeRing b + cdef Parent b b = self while isinstance(b, RingExtension_generic): if b is base or (b)._backend is base: return True b = (b)._base return b is base - cpdef CommutativeRing _check_base(self, CommutativeRing base): + cpdef Parent _check_base(self, Parent base): r""" Check if ``base`` is one of the successive bases of this extension and, if it is, normalize it. @@ -1243,7 +1243,7 @@ cdef class RingExtension_generic(CommutativeRing): sage: L._check_base(None) is L.base() # needs sage.rings.finite_rings True """ - cdef CommutativeRing b + cdef Parent b if base is None: return self._base b = self @@ -1450,7 +1450,7 @@ cdef class RingExtension_generic(CommutativeRing): base = self._check_base(base) return self._degree_over(base) - cpdef _degree_over(self, CommutativeRing base): + cpdef _degree_over(self, Parent base): r""" Return the degree of this extension over ``base``. @@ -1572,7 +1572,7 @@ cdef class RingExtension_generic(CommutativeRing): sage: L.is_finite_over() # needs sage.rings.finite_rings True """ - cdef CommutativeRing b + cdef Parent b base = self._check_base(base) if base is self: return True @@ -1590,7 +1590,7 @@ cdef class RingExtension_generic(CommutativeRing): b = (b)._base raise NotImplementedError - cpdef _is_finite_over(self, CommutativeRing base): + cpdef _is_finite_over(self, Parent base): r""" Return whether or not this extension is finite over ``base``. @@ -1635,7 +1635,7 @@ cdef class RingExtension_generic(CommutativeRing): sage: L.is_free_over() # needs sage.rings.finite_rings True """ - cdef CommutativeRing b + cdef Parent b base = self._check_base(base) if base is self or base.is_field(): return True @@ -1653,7 +1653,7 @@ cdef class RingExtension_generic(CommutativeRing): b = (b)._base raise NotImplementedError - cpdef _is_free_over(self, CommutativeRing base): + cpdef _is_free_over(self, Parent base): r""" Return whether or not this extension is finite over ``base``. @@ -2191,7 +2191,7 @@ cdef class RingExtensionWithBasis(RingExtension_generic): b = b.base_ring() return base - cpdef _degree_over(self, CommutativeRing base): + cpdef _degree_over(self, Parent base): r""" Return the degree of this extension over ``base``. @@ -2218,7 +2218,7 @@ cdef class RingExtensionWithBasis(RingExtension_generic): else: return len(self._basis) * self._base._degree_over(base) - cpdef _is_finite_over(self, CommutativeRing base): + cpdef _is_finite_over(self, Parent base): r""" Return whether or not this extension is finite over ``base``. @@ -2237,7 +2237,7 @@ cdef class RingExtensionWithBasis(RingExtension_generic): return True return self._base._is_finite_over(base) - cpdef _is_free_over(self, CommutativeRing base): + cpdef _is_free_over(self, Parent base): r""" Return whether or not this extension is free over ``base``. @@ -2298,7 +2298,7 @@ cdef class RingExtensionWithBasis(RingExtension_generic): base = self._check_base(base) return self._basis_over(base) - cpdef _basis_over(self, CommutativeRing base): + cpdef _basis_over(self, Parent base): r""" Return a basis of this extension over ``base``. @@ -2588,7 +2588,6 @@ cdef class RingExtensionWithGen(RingExtensionWithBasis): RingExtensionWithBasis.__init__(self, defining_morphism, basis, basis_names, check, **kwargs) self._gen = self._backend(gen) self._names = (self._name,) - self._latex_names = (latex_variable_name(self._name),) self._basis_latex_names = basis_latex_names def _repr_topring(self, **options): diff --git a/src/sage/rings/ring_extension_element.pxd b/src/sage/rings/ring_extension_element.pxd index 6b62ad58c06..9bd662f3d0f 100644 --- a/src/sage/rings/ring_extension_element.pxd +++ b/src/sage/rings/ring_extension_element.pxd @@ -1,4 +1,4 @@ -from sage.rings.ring cimport CommutativeRing +from sage.structure.parent cimport Parent from sage.structure.element cimport Element from sage.structure.element cimport CommutativeAlgebraElement from sage.rings.ring_extension cimport RingExtension_generic @@ -13,10 +13,10 @@ cdef class RingExtensionFractionFieldElement(RingExtensionElement): pass cdef class RingExtensionWithBasisElement(RingExtensionElement): - cdef _vector(self, CommutativeRing base) - cdef _matrix(self, CommutativeRing base) - cdef _trace(self, CommutativeRing base) - cdef _norm(self, CommutativeRing base) + cdef _vector(self, Parent base) + cdef _matrix(self, Parent base) + cdef _trace(self, Parent base) + cdef _norm(self, Parent base) cpdef minpoly(self, base=*, var=*) diff --git a/src/sage/rings/ring_extension_element.pyx b/src/sage/rings/ring_extension_element.pyx index 67b6aa90879..e3184503d77 100644 --- a/src/sage/rings/ring_extension_element.pyx +++ b/src/sage/rings/ring_extension_element.pyx @@ -24,6 +24,7 @@ from sage.misc.latex import latex from sage.structure.category_object import normalize_names from sage.structure.element cimport CommutativeAlgebraElement +from sage.structure.parent cimport Parent from sage.rings.integer_ring import ZZ from sage.categories.fields import Fields from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -1033,7 +1034,7 @@ cdef class RingExtensionWithBasisElement(RingExtensionElement): base = (self._parent)._check_base(base) return self._vector(base) - cdef _vector(self, CommutativeRing base): + cdef _vector(self, Parent base): r""" Return the vector of coordinates of this element over ``base`` (in the basis output by the method :meth:`basis_over`). @@ -1198,7 +1199,7 @@ cdef class RingExtensionWithBasisElement(RingExtensionElement): raise ValueError("the extension is not finite free") return self._matrix(base) - cdef _matrix(self, CommutativeRing base): + cdef _matrix(self, Parent base): r""" Return the matrix of the multiplication by this element (in the basis output by :meth:`basis_over`). @@ -1286,7 +1287,7 @@ cdef class RingExtensionWithBasisElement(RingExtensionElement): raise ValueError("the extension is not finite free") return self._trace(base) - cdef _trace(self, CommutativeRing base): + cdef _trace(self, Parent base): r""" Return the trace of this element over ``base``. @@ -1314,7 +1315,7 @@ cdef class RingExtensionWithBasisElement(RingExtensionElement): ....: assert((x+y).trace(base) == x.trace(base) + y.trace(base)) """ cdef RingExtensionWithBasis parent = self._parent - cdef CommutativeRing b + cdef Parent b if base is parent: return self b = parent._base @@ -1379,7 +1380,7 @@ cdef class RingExtensionWithBasisElement(RingExtensionElement): raise ValueError("the extension is not finite free") return self._norm(base) - cdef _norm(self, CommutativeRing base): + cdef _norm(self, Parent base): r""" Return the norm of this element over ``base``. @@ -1407,7 +1408,7 @@ cdef class RingExtensionWithBasisElement(RingExtensionElement): ....: assert((x*y).norm(base) == x.norm(base) * y.norm(base)) """ cdef RingExtensionWithBasis parent = self._parent - cdef CommutativeRing b + cdef Parent b if base is parent: return self b = parent._base diff --git a/src/sage/rings/ring_extension_morphism.pyx b/src/sage/rings/ring_extension_morphism.pyx index 2768bdac81c..d4aad7f8253 100644 --- a/src/sage/rings/ring_extension_morphism.pyx +++ b/src/sage/rings/ring_extension_morphism.pyx @@ -21,7 +21,7 @@ from sage.structure.richcmp import op_EQ, op_NE from sage.structure.element cimport Element from sage.categories.map import Map -from sage.rings.ring cimport CommutativeRing +from sage.structure.parent cimport Parent from sage.rings.morphism cimport RingMap from sage.rings.ring_extension cimport RingExtension_generic, RingExtensionWithBasis from sage.rings.ring_extension_element cimport RingExtensionElement @@ -57,7 +57,7 @@ cdef are_equal_morphisms(f, g): sage: H(f^2) == H(g^2) # indirect doctest True """ - cdef CommutativeRing b + cdef Parent b cdef tuple gens if f is None and g is None: return True @@ -821,7 +821,7 @@ cdef class MapRelativeRingToFreeModule(Map): From: Field in z6 with defining polynomial x^2 + (10*z3^2 + z3 + 6)*x + z3 over its base To: Vector space of dimension 2 over Finite Field in z3 of size 11^3 """ - cdef CommutativeRing L, base + cdef Parent L, base self._degree = (E)._degree_over(K) self._basis = [ (x)._backend for x in E.basis_over(K) ] From 0314517a41323a405f7332947a47c31215de3251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 29 Oct 2024 11:31:51 +0100 Subject: [PATCH 68/82] minor detail fixed --- src/sage/rings/ring_extension.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/ring_extension.pyx b/src/sage/rings/ring_extension.pyx index 0b376794b76..86ac9756351 100644 --- a/src/sage/rings/ring_extension.pyx +++ b/src/sage/rings/ring_extension.pyx @@ -575,7 +575,7 @@ cdef class RingExtension_generic(Parent): # but CommutativeRings() seems safer, especially when dealing with # morphisms which do not need to preserve the base category = CommutativeRings() - Parent.__init__(self, ZZ, category=category) + Parent.__init__(self, base=ZZ, category=category) self._base = base self._backend = ring self._backend_defining_morphism = defining_morphism From f331f7f5fd6f9281b6979ab61b7da88382b79425 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 29 Oct 2024 06:41:50 -0400 Subject: [PATCH 69/82] src/sage: revert "touch libgap consumers" This reverts commit 34817df8, whose only purpose was to change the mtime on several gap files, thereby triggering a rebuild on upgrade. --- src/sage/groups/perm_gps/permgroup_element.pyx | 2 -- src/sage/libs/gap/element.pyx | 3 --- src/sage/libs/gap/libgap.pyx | 2 -- src/sage/libs/gap/util.pyx | 2 -- 4 files changed, 9 deletions(-) diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx index b0150295f1f..86b3ced83ea 100644 --- a/src/sage/groups/perm_gps/permgroup_element.pyx +++ b/src/sage/groups/perm_gps/permgroup_element.pyx @@ -96,8 +96,6 @@ Check that :issue:`13569` is fixed:: (1,2), (1,3), (1,3), (2,3), (1,2), (1,2), (1,3), (2,3)] """ -# hi - # **************************************************************************** # Copyright (C) 2006 William Stein # Copyright (C) 2006 David Joyner diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index 6345c898c66..c24408f401a 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -5,9 +5,6 @@ This document describes the individual wrappers for various GAP elements. For general information about GAP, you should read the :mod:`~sage.libs.gap.libgap` module documentation. """ - -# hi - # **************************************************************************** # Copyright (C) 2012 Volker Braun # diff --git a/src/sage/libs/gap/libgap.pyx b/src/sage/libs/gap/libgap.pyx index 8218d51a5cd..f5b58a929f3 100644 --- a/src/sage/libs/gap/libgap.pyx +++ b/src/sage/libs/gap/libgap.pyx @@ -176,8 +176,6 @@ AUTHORS: libgap API """ -# hi - ############################################################################### # Copyright (C) 2009, William Stein # Copyright (C) 2012, Volker Braun diff --git a/src/sage/libs/gap/util.pyx b/src/sage/libs/gap/util.pyx index 8509ae35e55..29fa347ff30 100644 --- a/src/sage/libs/gap/util.pyx +++ b/src/sage/libs/gap/util.pyx @@ -2,8 +2,6 @@ Utility functions for GAP """ -# hi - #***************************************************************************** # Copyright (C) 2012 Volker Braun # From df30ad581d6d82c88d154441705eb19f2b3ec5a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 29 Oct 2024 13:54:21 +0100 Subject: [PATCH 70/82] move is_subring to category --- src/sage/categories/rings.py | 48 ++++++++++++++++++++++++++++++++++++ src/sage/rings/ring.pyx | 48 ------------------------------------ 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 781f1a1462b..1a798783d09 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -457,6 +457,54 @@ def is_zero(self) -> bool: """ return self.one() == self.zero() + def is_subring(self, other): + """ + Return ``True`` if the canonical map from ``self`` to ``other`` is + injective. + + This raises a :exc:`NotImplementedError` if not known. + + EXAMPLES:: + + sage: ZZ.is_subring(QQ) + True + sage: ZZ.is_subring(GF(19)) + False + + TESTS:: + + sage: QQ.is_subring(QQ['x']) + True + sage: QQ.is_subring(GF(7)) + False + sage: QQ.is_subring(CyclotomicField(7)) # needs sage.rings.number_field + True + sage: QQ.is_subring(ZZ) + False + + Every ring is a subring of itself, :issue:`17287`:: + + sage: QQbar.is_subring(QQbar) # needs sage.rings.number_field + True + sage: RR.is_subring(RR) + True + sage: CC.is_subring(CC) # needs sage.rings.real_mpfr + True + sage: x = polygen(ZZ, 'x') + sage: K. = NumberField(x^3 - x + 1/10) # needs sage.rings.number_field + sage: K.is_subring(K) # needs sage.rings.number_field + True + sage: R. = RR[] + sage: R.is_subring(R) + True + """ + if self is other: + return True + try: + return self.Hom(other).natural_map().is_injective() + except (TypeError, AttributeError): + return False + def bracket(self, x, y): """ Return the Lie bracket `[x, y] = x y - y x` of `x` and `y`. diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index 17d0150357d..5a5d7ab2b0f 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -652,54 +652,6 @@ cdef class Ring(ParentWithGens): """ return True - def is_subring(self, other): - """ - Return ``True`` if the canonical map from ``self`` to ``other`` is - injective. - - Raises a :exc:`NotImplementedError` if not known. - - EXAMPLES:: - - sage: ZZ.is_subring(QQ) - True - sage: ZZ.is_subring(GF(19)) - False - - TESTS:: - - sage: QQ.is_subring(QQ['x']) - True - sage: QQ.is_subring(GF(7)) - False - sage: QQ.is_subring(CyclotomicField(7)) # needs sage.rings.number_field - True - sage: QQ.is_subring(ZZ) - False - - Every ring is a subring of itself, :issue:`17287`:: - - sage: QQbar.is_subring(QQbar) # needs sage.rings.number_field - True - sage: RR.is_subring(RR) - True - sage: CC.is_subring(CC) # needs sage.rings.real_mpfr - True - sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^3 - x + 1/10) # needs sage.rings.number_field - sage: K.is_subring(K) # needs sage.rings.number_field - True - sage: R. = RR[] - sage: R.is_subring(R) - True - """ - if self is other: - return True - try: - return self.Hom(other).natural_map().is_injective() - except (TypeError, AttributeError): - return False - def is_prime_field(self): r""" Return ``True`` if this ring is one of the prime fields `\QQ` or From 445a95ce96c6243a0d1cb92806d1e365defde5e8 Mon Sep 17 00:00:00 2001 From: Vincent Macri Date: Tue, 29 Oct 2024 08:59:25 -0600 Subject: [PATCH 71/82] Suggestion from code review --- src/sage/rings/function_field/function_field_polymod.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/function_field/function_field_polymod.py b/src/sage/rings/function_field/function_field_polymod.py index 7edf21e0cf8..0fe4c84fafb 100644 --- a/src/sage/rings/function_field/function_field_polymod.py +++ b/src/sage/rings/function_field/function_field_polymod.py @@ -571,8 +571,7 @@ def _repr_(self): sage: L._repr_() 'Function field in y defined by y^5 - 2*x*y + (-x^4 - 1)/x' """ - return (f"Function field in {self.variable_name()} defined by " - f"{self._polynomial}") + return f"Function field in {self.variable_name()} defined by {self._polynomial}" def _latex_(self): r""" From 17b14745933271808a9530f0dbf430ad580a1274 Mon Sep 17 00:00:00 2001 From: Kyle Hofmann Date: Tue, 29 Oct 2024 18:14:13 -0700 Subject: [PATCH 72/82] Apply suggestions from code review Co-authored-by: Vincent Macri --- src/sage/rings/finite_rings/integer_mod_ring.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index 1afb008cb89..8e50282178d 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -1824,6 +1824,13 @@ def _roots_univariate_polynomial(self, f, ring=None, multiplicities=True, algori sage: (3*x).roots(multiplicities=False) [0, 4, 2] + Test polynomial with many roots: + + sage: R. = Zmod(6)[] + sage: f = x * (x - 1) * (x - 2) * (x - 3) * (x - 4) * (x - 5) + sage: len(f.roots(multiplicities=False)) + 6 + Test finding roots over large prime powers: sage: R. = Zmod(2**16)[] From 60ca4d3c208349f75f70f8bbd6f1ab516a728b85 Mon Sep 17 00:00:00 2001 From: Kyle Hofmann Date: Tue, 29 Oct 2024 18:18:26 -0700 Subject: [PATCH 73/82] Format docstring --- src/sage/rings/finite_rings/integer_mod_ring.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index 8e50282178d..893fde4e929 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -1826,10 +1826,10 @@ def _roots_univariate_polynomial(self, f, ring=None, multiplicities=True, algori Test polynomial with many roots: - sage: R. = Zmod(6)[] - sage: f = x * (x - 1) * (x - 2) * (x - 3) * (x - 4) * (x - 5) - sage: len(f.roots(multiplicities=False)) - 6 + sage: R. = Zmod(6)[] + sage: f = x * (x - 1) * (x - 2) * (x - 3) * (x - 4) * (x - 5) + sage: len(f.roots(multiplicities=False)) + 6 Test finding roots over large prime powers: From 22c6d395c792d7b9eeb27a35b2fdf2e6b30ecb59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 30 Oct 2024 08:46:10 +0100 Subject: [PATCH 74/82] fix one failing doctest --- src/doc/en/thematic_tutorials/coercion_and_categories.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index ad5a01ea1a6..0895efab774 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -135,7 +135,6 @@ This base class provides a lot more methods than a general parent:: 'is_field', 'is_integrally_closed', 'is_prime_field', - 'is_subring', 'krull_dimension', 'localization', 'ngens', From 440ffdb621292100238cded882373b6f89a9f645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 30 Oct 2024 11:09:34 +0100 Subject: [PATCH 75/82] moving "is_prime_field" to the category of rings --- .../coercion_and_categories.rst | 1 - src/sage/categories/rings.py | 24 +++++++++++++++++++ src/sage/rings/ring.pyx | 22 ----------------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index 0895efab774..63258f05700 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -134,7 +134,6 @@ This base class provides a lot more methods than a general parent:: 'is_commutative', 'is_field', 'is_integrally_closed', - 'is_prime_field', 'krull_dimension', 'localization', 'ngens', diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 1a798783d09..6ea5c51afef 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -434,6 +434,30 @@ def is_noetherian(self): """ return False + def is_prime_field(self): + r""" + Return ``True`` if this ring is one of the prime fields `\QQ` or + `\GF{p}`. + + EXAMPLES:: + + sage: QQ.is_prime_field() + True + sage: GF(3).is_prime_field() + True + sage: GF(9, 'a').is_prime_field() # needs sage.rings.finite_rings + False + sage: ZZ.is_prime_field() + False + sage: QQ['x'].is_prime_field() + False + sage: Qp(19).is_prime_field() # needs sage.rings.padics + False + """ + # the case of QQ is handled by QQ itself + from sage.categories.finite_fields import FiniteFields + return self in FiniteFields() and self.degree() == 1 + def is_zero(self) -> bool: """ Return ``True`` if this is the zero ring. diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx index 5a5d7ab2b0f..e57e20f98d2 100644 --- a/src/sage/rings/ring.pyx +++ b/src/sage/rings/ring.pyx @@ -652,28 +652,6 @@ cdef class Ring(ParentWithGens): """ return True - def is_prime_field(self): - r""" - Return ``True`` if this ring is one of the prime fields `\QQ` or - `\GF{p}`. - - EXAMPLES:: - - sage: QQ.is_prime_field() - True - sage: GF(3).is_prime_field() - True - sage: GF(9, 'a').is_prime_field() # needs sage.rings.finite_rings - False - sage: ZZ.is_prime_field() - False - sage: QQ['x'].is_prime_field() - False - sage: Qp(19).is_prime_field() # needs sage.rings.padics - False - """ - return False - def order(self): """ The number of elements of ``self``. From 05d89d70c9e93c142095dbed81dc5f8c08dda6fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Janek?= <106813190+janekj2727@users.noreply.github.com> Date: Thu, 31 Oct 2024 09:20:14 +0100 Subject: [PATCH 76/82] Fix codestyle W291 trailing whitespace Trailing space removed to pass code style check by pycodestyle-minimal. --- src/sage/functions/trig.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/functions/trig.py b/src/sage/functions/trig.py index c60aada0243..8f390205cae 100644 --- a/src/sage/functions/trig.py +++ b/src/sage/functions/trig.py @@ -261,7 +261,7 @@ def __init__(self): sage: tan(2+I).imag().n() # needs sage.symbolic 1.16673625724092 """ - GinacFunction.__init__(self, 'tan', latex_name=r"\tan", + GinacFunction.__init__(self, 'tan', latex_name=r"\tan", conversions=dict(maxima='tan', mathematica='Tan', giac='tan', fricas='tan', sympy='tan')) @@ -351,7 +351,7 @@ def __init__(self): sage: cot(1.+I) # needs sage.symbolic 0.217621561854403 - 0.868014142895925*I """ - GinacFunction.__init__(self, 'cot', latex_name=r"\cot", + GinacFunction.__init__(self, 'cot', latex_name=r"\cot", conversions=dict(maxima='cot', mathematica='Cot', giac='cot', fricas='cot', sympy='cot')) @@ -425,7 +425,7 @@ def __init__(self): sage: sec(complex(1,1)) # rel tol 1e-15 # needs sage.rings.complex_double (0.49833703055518686+0.5910838417210451j) """ - GinacFunction.__init__(self, 'sec', latex_name=r"\sec", + GinacFunction.__init__(self, 'sec', latex_name=r"\sec", conversions=dict(maxima='sec', mathematica='Sec', giac='sec', fricas='sec', sympy='sec')) @@ -499,7 +499,7 @@ def __init__(self): sage: csc(complex(1,1)) # rel tol 1e-15 # needs sage.rings.complex_double (0.6215180171704284-0.30393100162842646j) """ - GinacFunction.__init__(self, 'csc', latex_name=r"\csc", + GinacFunction.__init__(self, 'csc', latex_name=r"\csc", conversions=dict(maxima='csc', mathematica='Csc', giac='csc', fricas='csc', sympy='csc')) From 7bddcb981293b5dcc947f02de72d691df169a687 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Thu, 31 Oct 2024 09:22:33 +0100 Subject: [PATCH 77/82] be explicit about messages --- src/sage/interfaces/fricas.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index 5982c225439..47cd5570355 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -227,8 +227,26 @@ # between ' and ". FRICAS_INIT_CODE = ( ")set functions compile on", - ")set message autoload off", - ")set message type off", + ")set message any on", + ")set message autoload off", + ")set message bottomup off", + ")set message dropmap off", + ")set message expose off", + ")set message file off", + ")set message frame off", + ")set message highlighting off", + ")set message instant off", + ")set message insteach off", + ")set message interponly off", + ")set message prompt step", + ")set message selection off", + ")set message set off", + ")set message startup on", + ")set message storage off", + ")set message testing off", + ")set message time off", + ")set message type off", + ")set message void off", ")set output length " + str(FRICAS_LINE_LENGTH), ")lisp (setf |$ioHook|" " (lambda (x &optional args)" From 5dce127bc5ef24176f9520905db24f994ec49370 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 6 Sep 2024 16:27:42 -0700 Subject: [PATCH 78/82] build/pkgs/pari: Update to 2.15.5 --- build/pkgs/pari/checksums.ini | 4 ++-- build/pkgs/pari/package-version.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/pkgs/pari/checksums.ini b/build/pkgs/pari/checksums.ini index 12c05141bf1..98446c5f8d9 100644 --- a/build/pkgs/pari/checksums.ini +++ b/build/pkgs/pari/checksums.ini @@ -1,4 +1,4 @@ tarball=pari-VERSION.tar.gz -sha1=ae962671b5bf86849d2021113dfb5b2f59331a10 -sha256=c3545bfee0c6dfb40b77fb4bbabaf999d82e60069b9f6d28bcb6cf004c8c5c0f +sha1=377593dfe72df13578ea0a517fcb0f81cc9758d4 +sha256=0efdda7515d9d954f63324c34b34c560e60f73a81c3924a71260a2cc91d5f981 upstream_url=https://pari.math.u-bordeaux.fr/pub/pari/unix/pari-VERSION.tar.gz diff --git a/build/pkgs/pari/package-version.txt b/build/pkgs/pari/package-version.txt index 86fbeafcc20..7a561821071 100644 --- a/build/pkgs/pari/package-version.txt +++ b/build/pkgs/pari/package-version.txt @@ -1 +1 @@ -2.15.4 +2.15.5 From c7802a4435bf70b040726fab383157271ad00878 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 31 Oct 2024 12:46:00 -0700 Subject: [PATCH 79/82] build/pkgs/pari/checksums.ini: Update upstream_url (2.15 is already OLD) --- build/pkgs/pari/checksums.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/pari/checksums.ini b/build/pkgs/pari/checksums.ini index 98446c5f8d9..d56c437a2ee 100644 --- a/build/pkgs/pari/checksums.ini +++ b/build/pkgs/pari/checksums.ini @@ -1,4 +1,4 @@ tarball=pari-VERSION.tar.gz sha1=377593dfe72df13578ea0a517fcb0f81cc9758d4 sha256=0efdda7515d9d954f63324c34b34c560e60f73a81c3924a71260a2cc91d5f981 -upstream_url=https://pari.math.u-bordeaux.fr/pub/pari/unix/pari-VERSION.tar.gz +upstream_url=https://pari.math.u-bordeaux.fr/pub/pari/OLD/${VERSION_MAJOR}.${VERSION_MINOR}/pari-VERSION.tar.gz From 27343d9adb849ae3ee990eda73ce90dd94972e78 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Fri, 1 Nov 2024 02:49:18 +0100 Subject: [PATCH 80/82] add "# long time" to slow-ish composite isogeny doctest --- src/sage/schemes/elliptic_curves/hom_composite.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/hom_composite.py b/src/sage/schemes/elliptic_curves/hom_composite.py index 6952f2a0e11..0ebfe6261fa 100755 --- a/src/sage/schemes/elliptic_curves/hom_composite.py +++ b/src/sage/schemes/elliptic_curves/hom_composite.py @@ -190,7 +190,7 @@ def _compute_factored_isogeny_prime_power(P, l, n, split=.8, velu_sqrt_bound=Non sage: P, = E.gens() sage: (l,n), = P.order().factor() sage: phis = hom_composite._compute_factored_isogeny_prime_power(P,l,n) - sage: phis == hom_composite._compute_factored_isogeny_prime_power(P,l,n, split=0) + sage: phis == hom_composite._compute_factored_isogeny_prime_power(P,l,n, split=0) # long time -- about 10s True sage: phis == hom_composite._compute_factored_isogeny_prime_power(P,l,n, split=0.1) True From c97a63962198c2e87552350ce51e15997fc1ae8d Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Fri, 1 Nov 2024 09:04:06 +0700 Subject: [PATCH 81/82] Apply suggestions from code review Co-authored-by: Travis Scrimshaw --- src/sage/modules/vector_modn_dense.pyx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/modules/vector_modn_dense.pyx b/src/sage/modules/vector_modn_dense.pyx index e21360964ba..f129632bd03 100644 --- a/src/sage/modules/vector_modn_dense.pyx +++ b/src/sage/modules/vector_modn_dense.pyx @@ -171,13 +171,15 @@ cdef class Vector_modn_dense(free_module_element.FreeModuleElement): """ Create an element. + TESTS: + Note that ``coerce=False`` is dangerous:: sage: V = VectorSpace(GF(7), 3) sage: v = V([2, 9, -5], coerce=False) sage: v[0] == v[1] False - sage: v[0]+1 == v[1]+1 + sage: v[0] + 1 == v[1] + 1 True sage: v[0] == v[2] False From 209ae4c3a438d27f552bde829cbe91edde488578 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Mon, 4 Nov 2024 00:00:35 +0100 Subject: [PATCH 82/82] Updated SageMath version to 10.5.beta9 --- CITATION.cff | 4 ++-- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 4 ++-- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sage_conf/version_requirements.txt | 2 +- build/pkgs/sage_docbuild/version_requirements.txt | 2 +- build/pkgs/sage_setup/version_requirements.txt | 2 +- build/pkgs/sage_sws2rst/version_requirements.txt | 2 +- build/pkgs/sagelib/version_requirements.txt | 2 +- build/pkgs/sagemath_bliss/version_requirements.txt | 2 +- build/pkgs/sagemath_categories/version_requirements.txt | 2 +- build/pkgs/sagemath_coxeter3/version_requirements.txt | 2 +- build/pkgs/sagemath_environment/version_requirements.txt | 2 +- build/pkgs/sagemath_mcqd/version_requirements.txt | 2 +- build/pkgs/sagemath_meataxe/version_requirements.txt | 2 +- build/pkgs/sagemath_objects/version_requirements.txt | 2 +- build/pkgs/sagemath_repl/version_requirements.txt | 2 +- build/pkgs/sagemath_sirocco/version_requirements.txt | 2 +- build/pkgs/sagemath_tdlib/version_requirements.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_conda/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-bliss/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-coxeter3/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-mcqd/VERSION.txt | 2 +- pkgs/sagemath-meataxe/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- pkgs/sagemath-sirocco/VERSION.txt | 2 +- pkgs/sagemath-tdlib/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 38 files changed, 44 insertions(+), 44 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index a3fbfd7caed..27b5af6ac84 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,8 +4,8 @@ title: SageMath abstract: SageMath is a free open-source mathematics software system. authors: - name: "The SageMath Developers" -version: 10.5.beta8 +version: 10.5.beta9 doi: 10.5281/zenodo.8042260 -date-released: 2024-10-26 +date-released: 2024-11-03 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index 5f39e0b41df..01ace814c72 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.5.beta8, Release Date: 2024-10-26 +SageMath version 10.5.beta9, Release Date: 2024-11-03 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index d99b31dddd0..4d5e7295f5b 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,3 +1,3 @@ tarball=configure-VERSION.tar.gz -sha1=8101aa562d9750cf67c652f74d2b6ac448a32844 -sha256=732c3145400765648d198b3271f17b40be094d766d4018b0c30410b5b3246499 +sha1=490f6d988c1c4c0786a0c8b36e708db56e17bfa6 +sha256=2e2b6821c9abd7d2b910edb1237f3622e985a2321cf1eedb2161b714494c6643 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 9a79bf0dc7a..95d7fe86650 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -e360734ab2c895feff77a1076828bfcbadb6a9a6 +93661cbe00c3e83691d6ed8c64586163cfdae62f diff --git a/build/pkgs/sage_conf/version_requirements.txt b/build/pkgs/sage_conf/version_requirements.txt index 570eca0f747..7b7d288febd 100644 --- a/build/pkgs/sage_conf/version_requirements.txt +++ b/build/pkgs/sage_conf/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 10.5b8 +sage-conf ~= 10.5b9 diff --git a/build/pkgs/sage_docbuild/version_requirements.txt b/build/pkgs/sage_docbuild/version_requirements.txt index 253a03aa504..20be798e7f9 100644 --- a/build/pkgs/sage_docbuild/version_requirements.txt +++ b/build/pkgs/sage_docbuild/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 10.5b8 +sage-docbuild ~= 10.5b9 diff --git a/build/pkgs/sage_setup/version_requirements.txt b/build/pkgs/sage_setup/version_requirements.txt index cdca5c8c377..83c89067e18 100644 --- a/build/pkgs/sage_setup/version_requirements.txt +++ b/build/pkgs/sage_setup/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 10.5b8 +sage-setup ~= 10.5b9 diff --git a/build/pkgs/sage_sws2rst/version_requirements.txt b/build/pkgs/sage_sws2rst/version_requirements.txt index dd89096c7e5..ddd53c64619 100644 --- a/build/pkgs/sage_sws2rst/version_requirements.txt +++ b/build/pkgs/sage_sws2rst/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 10.5b8 +sage-sws2rst ~= 10.5b9 diff --git a/build/pkgs/sagelib/version_requirements.txt b/build/pkgs/sagelib/version_requirements.txt index 82fcd9b2e70..d831508e352 100644 --- a/build/pkgs/sagelib/version_requirements.txt +++ b/build/pkgs/sagelib/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-standard ~= 10.5b8 +sagemath-standard ~= 10.5b9 diff --git a/build/pkgs/sagemath_bliss/version_requirements.txt b/build/pkgs/sagemath_bliss/version_requirements.txt index d7a5d2904e6..045266674e4 100644 --- a/build/pkgs/sagemath_bliss/version_requirements.txt +++ b/build/pkgs/sagemath_bliss/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-bliss ~= 10.5b8 +sagemath-bliss ~= 10.5b9 diff --git a/build/pkgs/sagemath_categories/version_requirements.txt b/build/pkgs/sagemath_categories/version_requirements.txt index efc07d283b2..811a813dea6 100644 --- a/build/pkgs/sagemath_categories/version_requirements.txt +++ b/build/pkgs/sagemath_categories/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 10.5b8 +sagemath-categories ~= 10.5b9 diff --git a/build/pkgs/sagemath_coxeter3/version_requirements.txt b/build/pkgs/sagemath_coxeter3/version_requirements.txt index cfc2259b00b..79c22b51001 100644 --- a/build/pkgs/sagemath_coxeter3/version_requirements.txt +++ b/build/pkgs/sagemath_coxeter3/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-coxeter3 ~= 10.5b8 +sagemath-coxeter3 ~= 10.5b9 diff --git a/build/pkgs/sagemath_environment/version_requirements.txt b/build/pkgs/sagemath_environment/version_requirements.txt index fc2b0a5c400..825be89f4b7 100644 --- a/build/pkgs/sagemath_environment/version_requirements.txt +++ b/build/pkgs/sagemath_environment/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 10.5b8 +sagemath-environment ~= 10.5b9 diff --git a/build/pkgs/sagemath_mcqd/version_requirements.txt b/build/pkgs/sagemath_mcqd/version_requirements.txt index a37506596f3..e2f53c39eda 100644 --- a/build/pkgs/sagemath_mcqd/version_requirements.txt +++ b/build/pkgs/sagemath_mcqd/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-mcqd ~= 10.5b8 +sagemath-mcqd ~= 10.5b9 diff --git a/build/pkgs/sagemath_meataxe/version_requirements.txt b/build/pkgs/sagemath_meataxe/version_requirements.txt index 87631b79435..511fc349e39 100644 --- a/build/pkgs/sagemath_meataxe/version_requirements.txt +++ b/build/pkgs/sagemath_meataxe/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-meataxe ~= 10.5b8 +sagemath-meataxe ~= 10.5b9 diff --git a/build/pkgs/sagemath_objects/version_requirements.txt b/build/pkgs/sagemath_objects/version_requirements.txt index 637d04fa986..e76dace4ebf 100644 --- a/build/pkgs/sagemath_objects/version_requirements.txt +++ b/build/pkgs/sagemath_objects/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 10.5b8 +sagemath-objects ~= 10.5b9 diff --git a/build/pkgs/sagemath_repl/version_requirements.txt b/build/pkgs/sagemath_repl/version_requirements.txt index e721b5a1d1f..ddb705e31f7 100644 --- a/build/pkgs/sagemath_repl/version_requirements.txt +++ b/build/pkgs/sagemath_repl/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 10.5b8 +sagemath-repl ~= 10.5b9 diff --git a/build/pkgs/sagemath_sirocco/version_requirements.txt b/build/pkgs/sagemath_sirocco/version_requirements.txt index 3412b468da9..05b07a6349c 100644 --- a/build/pkgs/sagemath_sirocco/version_requirements.txt +++ b/build/pkgs/sagemath_sirocco/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-sirocco ~= 10.5b8 +sagemath-sirocco ~= 10.5b9 diff --git a/build/pkgs/sagemath_tdlib/version_requirements.txt b/build/pkgs/sagemath_tdlib/version_requirements.txt index b78e9037e85..fa143114867 100644 --- a/build/pkgs/sagemath_tdlib/version_requirements.txt +++ b/build/pkgs/sagemath_tdlib/version_requirements.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-tdlib ~= 10.5b8 +sagemath-tdlib ~= 10.5b9 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sage-conf_conda/VERSION.txt b/pkgs/sage-conf_conda/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sage-conf_conda/VERSION.txt +++ b/pkgs/sage-conf_conda/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sagemath-bliss/VERSION.txt b/pkgs/sagemath-bliss/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sagemath-bliss/VERSION.txt +++ b/pkgs/sagemath-bliss/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sagemath-coxeter3/VERSION.txt b/pkgs/sagemath-coxeter3/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sagemath-coxeter3/VERSION.txt +++ b/pkgs/sagemath-coxeter3/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sagemath-mcqd/VERSION.txt b/pkgs/sagemath-mcqd/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sagemath-mcqd/VERSION.txt +++ b/pkgs/sagemath-mcqd/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sagemath-meataxe/VERSION.txt b/pkgs/sagemath-meataxe/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sagemath-meataxe/VERSION.txt +++ b/pkgs/sagemath-meataxe/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sagemath-sirocco/VERSION.txt b/pkgs/sagemath-sirocco/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sagemath-sirocco/VERSION.txt +++ b/pkgs/sagemath-sirocco/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/pkgs/sagemath-tdlib/VERSION.txt b/pkgs/sagemath-tdlib/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/pkgs/sagemath-tdlib/VERSION.txt +++ b/pkgs/sagemath-tdlib/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/src/VERSION.txt b/src/VERSION.txt index 8d89e93406d..99613807a73 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.5.beta8 +10.5.beta9 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 16a381b0b24..e420ab80e2f 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -4,6 +4,6 @@ # which stops "setup.py develop" from rewriting it as a Python file. : # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='10.5.beta8' -SAGE_RELEASE_DATE='2024-10-26' -SAGE_VERSION_BANNER='SageMath version 10.5.beta8, Release Date: 2024-10-26' +SAGE_VERSION='10.5.beta9' +SAGE_RELEASE_DATE='2024-11-03' +SAGE_VERSION_BANNER='SageMath version 10.5.beta9, Release Date: 2024-11-03' diff --git a/src/sage/version.py b/src/sage/version.py index 12f1c856da0..12c31b89416 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '10.5.beta8' -date = '2024-10-26' -banner = 'SageMath version 10.5.beta8, Release Date: 2024-10-26' +version = '10.5.beta9' +date = '2024-11-03' +banner = 'SageMath version 10.5.beta9, Release Date: 2024-11-03'