From 28687752f6d593b5968020b2e061c6cd08c21c6a Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Fri, 25 Nov 2022 12:42:29 +0000 Subject: [PATCH 01/56] trac 34790: added function for finding correct multiple --- src/sage/schemes/elliptic_curves/padics.py | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/sage/schemes/elliptic_curves/padics.py b/src/sage/schemes/elliptic_curves/padics.py index 8dc75a35a43..245bded7155 100644 --- a/src/sage/schemes/elliptic_curves/padics.py +++ b/src/sage/schemes/elliptic_curves/padics.py @@ -584,6 +584,62 @@ def _multiply_point(E, R, P, m): return theta, omega, psi_m * d +def _multiple_to_make_good_reduction(E): + """ + Return the integer n2 such that for all points P in E(Q) + n2*P has good reduction at all primes. + If the model is globally minimal the lcm of the + Tamagawa numbers will do, otherwise we have to take into + account the change of the model. + + INPUT: + + - an elliptic curve ``E`` + + OUTPUT: + + - a positive integer ``n2`` + + EXAMPLE:: + + sage: from sage.schemes.elliptic_curves.padics import _multiple_to_make_good_reduction + sage: E = EllipticCurve([-1728,-100656]) + sage: _multiple_to_make_good_reduction(E) + 30 + + The number ``n2`` is not always optimal but it is in this example. + The first multiple of the generator `P` with good reduction in this + non-minimal model is `30 P`. + + """ + if not E.is_integral(): + st = ("This only implemented for integral models. " + "Please change the model first.") + raise NotImplementedError(st) + if E.is_minimal(): + n2 = arith.LCM(E.tamagawa_numbers()) + else: + # generalising to number fields one can get the u from local_data + Emin = E.global_minimal_model() + iota = E.isomorphism_to(Emin) + u = Integer(iota.u) + ps = u.prime_divisors() + li = [] + for p in ps: + np = u.valuation(p) + if Emin.discriminant() %p != 0: + li.append(Emin.Np(p) * p**(np-1)) + elif Emin.has_additive_reduction(p): + li.append(E.tamagawa_number(p) * p**np) + elif E.has_split_multiplicative_reduction(p): + li.append(E.tamagawa_number(p) * (p-1) * p**(np-1)) + else: # non split + li.append(E.tamagawa_number(p) * (p+1) * p**(np-1)) + otherbad = Integer(Emin.discriminant()).prime_divisors() + otherbad = [p for p in otherbad if u%p != 0 ] + li += [E.tamagawa_number(p) for p in otherbad] + n2 = arith.LCM(li) + return n2 def padic_height(self, p, prec=20, sigma=None, check_hypotheses=True): r""" From 1ff4524c410f5cfbba174964651cec173014ccc5 Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Fri, 25 Nov 2022 14:34:41 +0000 Subject: [PATCH 02/56] trac 34790: integrate it --- src/sage/schemes/elliptic_curves/padic_lseries.py | 5 ++++- src/sage/schemes/elliptic_curves/padics.py | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/padic_lseries.py b/src/sage/schemes/elliptic_curves/padic_lseries.py index 74581cd2479..8b0bf4344ce 100644 --- a/src/sage/schemes/elliptic_curves/padic_lseries.py +++ b/src/sage/schemes/elliptic_curves/padic_lseries.py @@ -89,6 +89,7 @@ from sage.structure.sage_object import SageObject + @richcmp_method class pAdicLseries(SageObject): r""" @@ -1670,7 +1671,9 @@ def Dp_valued_height(self,prec=20): elog = Ehat.log(prec + Integer(3)) # we will have to do it properly with David Harvey's _multiply_point() - n = LCM(E.tamagawa_numbers()) + # import here to avoid circular import + from sage.schemes.elliptic_curves.padics import _multiple_to_make_good_reduction + n = _multiple_to_make_good_reduction(E) n = LCM(n, E.Np(p)) # allowed here because E has good reduction at p def height(P,check=True): diff --git a/src/sage/schemes/elliptic_curves/padics.py b/src/sage/schemes/elliptic_curves/padics.py index 245bded7155..7f9e929a4f1 100644 --- a/src/sage/schemes/elliptic_curves/padics.py +++ b/src/sage/schemes/elliptic_curves/padics.py @@ -794,7 +794,7 @@ def padic_height(self, p, prec=20, sigma=None, check_hypotheses=True): # p-adic Heights", David Harvey (unpublished) n1 = self.change_ring(rings.GF(p)).cardinality() - n2 = arith.LCM(self.tamagawa_numbers()) + n2 = _multiple_to_make_good_reduction(self) n = arith.LCM(n1, n2) m = int(n / n2) @@ -939,7 +939,7 @@ def padic_height_via_multiply(self, p, prec=20, E2=None, check_hypotheses=True): # multiplication'' (David Harvey, still in draft form) n1 = self.change_ring(rings.GF(p)).cardinality() - n2 = arith.LCM(self.tamagawa_numbers()) + n2 = _multiple_to_make_good_reduction(self) n = arith.LCM(n1, n2) m = int(n / n2) From 3612d72fb23f06ef59bafc7545a218a0706ea143 Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Fri, 25 Nov 2022 18:58:35 +0000 Subject: [PATCH 03/56] trac 34790: docstrings --- src/doc/en/reference/references/index.rst | 27 ++++-- .../schemes/elliptic_curves/hom_velusqrt.py | 74 +++++++-------- src/sage/schemes/elliptic_curves/padics.py | 92 ++++++++----------- 3 files changed, 94 insertions(+), 99 deletions(-) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index d19d4616a61..48ea0b34f4e 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -1888,9 +1888,9 @@ REFERENCES: .. [CW2005] \J. E. Cremona and M. Watkins. Computing isogenies of elliptic curves. preprint, 2005. -.. [CHW2015] Shawn X.; Hong, Seung-Moon; Wang, Zhenghan Universal quantum computation +.. [CHW2015] Shawn X.; Hong, Seung-Moon; Wang, Zhenghan Universal quantum computation with weakly integral anyons. Quantum Inf. Process. 14 (2015), - no. 8, 2687-2727. + no. 8, 2687-2727. .. [CW2015] Cui, S. X. and Wang, Z. (2015). Universal quantum computation with metaplectic anyons. Journal of Mathematical Physics, 56(3), 032202. @@ -2275,7 +2275,7 @@ REFERENCES: .. [Dy1993] \M. J. Dyer. *Hecke algebras and shellings of Bruhat intervals*. Compositio Mathematica, 1993, 89(1): 91-115. -.. [Dy1994] \M. J. Dyer. *Bruhat intervals, polyhedral cones and +.. [Dy1994] \M. J. Dyer. *Bruhat intervals, polyhedral cones and Kazhdan-Lusztig-Stanley polynomials*. Math.Z., 215(2):223-236, 1994. .. _ref-E: @@ -3013,6 +3013,9 @@ REFERENCES: .. [Har1994] Frank Harary. *Graph Theory*. Reading, MA: Addison-Wesley, 1994. +.. [Har2009] Harvey, David. *Efficient computation of p-adic heights*. + LMS J. Comput. Math. **11** (2008), 40–59. + .. [Harako2020] Shuichi Harako. *The second homology group of the commutative case of Kontsevich's symplectic derivation Lie algebra*. Preprint, 2020, :arxiv:`2006.06064`. @@ -3506,7 +3509,7 @@ REFERENCES: :doi:`10.1016/j.bbr.2011.03.031`, :arxiv:`0909.2442`. .. [JS2021] \D. Jahn, C. Stump. - *Bruhat intervals, subword complexes and brick polyhedra for + *Bruhat intervals, subword complexes and brick polyhedra for finite Coxeter groups*, 2021, :arxiv:`2103.03715`. .. [JV2000] \J. Justin, L. Vuillon, *Return words in Sturmian and @@ -4708,17 +4711,21 @@ REFERENCES: sharpening of the Parikh mapping*. Theoret. Informatics Appl. 35 (2001) 551-564. +.. [MST2006] Barry Mazur, William Stein, John Tate. + *Computation of p-adic heights and log convergence*. + Doc. Math. 2006, Extra Vol., 577-614. + .. [MSZ2013] Michael Maschler, Solan Eilon, and Zamir Shmuel. *Game Theory*. Cambridge: Cambridge University Press, (2013). ISBN 9781107005488. -.. [MT1991] Mazur, B., & Tate, J. (1991). The `p`-adic sigma - function. Duke Mathematical Journal, 62(3), 663-688. +.. [MT1991] Mazur, B., & Tate, J. (1991). *The `p`-adic sigma + function*. Duke Mathematical Journal, **62** (3), 663-688. -.. [MTT1986] \B. Mazur, J. Tate, and J. Teitelbaum, On `p`-adic - analogues of the conjectures of Birch and - Swinnerton-Dyer, Inventiones Mathematicae 84, (1986), - 1-48. +.. [MTT1986] \B. Mazur, J. Tate, and J. Teitelbaum, + *On `p`-adic analogues of the conjectures of Birch and + Swinnerton-Dyer*, + Inventiones Mathematicae **84**, (1986), 1-48. .. [Mu1997] Murty, M. Ram. *Congruences between modular forms*. In "Analytic Number Theory" (ed. Y. Motohashi), London Math. Soc. Lecture Notes diff --git a/src/sage/schemes/elliptic_curves/hom_velusqrt.py b/src/sage/schemes/elliptic_curves/hom_velusqrt.py index 15863173c4f..221d5a1eb4f 100644 --- a/src/sage/schemes/elliptic_curves/hom_velusqrt.py +++ b/src/sage/schemes/elliptic_curves/hom_velusqrt.py @@ -1,7 +1,7 @@ r""" -√élu algorithm for elliptic-curve isogenies +Vélu algorithm for elliptic-curve isogenies -The √élu algorithm computes isogenies of elliptic curves in time `\tilde +The Vélu algorithm computes isogenies of elliptic curves in time `\tilde O(\sqrt\ell)` rather than naïvely `O(\ell)`, where `\ell` is the degree. The core idea is to reindex the points in the kernel subgroup in a @@ -26,7 +26,7 @@ 10009 sage: phi = EllipticCurveHom_velusqrt(E, K) sage: phi - Elliptic-curve isogeny (using √élu) of degree 10009: + Elliptic-curve isogeny (using Vélu) of degree 10009: From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 6666679 To: Elliptic Curve defined by y^2 = x^3 + 227975*x + 3596133 over Finite Field of size 6666679 sage: phi.codomain() @@ -56,7 +56,7 @@ sage: K = E(9091, 517864) sage: phi = EllipticCurveHom_velusqrt(E, K, model='montgomery') sage: phi - Elliptic-curve isogeny (using √élu) of degree 2999: + Elliptic-curve isogeny (using Vélu) of degree 2999: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 6666679 To: Elliptic Curve defined by y^2 = x^3 + 1559358*x^2 + x over Finite Field of size 6666679 @@ -68,7 +68,7 @@ sage: K.order() 37 sage: EllipticCurveHom_velusqrt(E, K) - Elliptic-curve isogeny (using √élu) of degree 37: + Elliptic-curve isogeny (using Vélu) of degree 37: From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Finite Field of size 101 To: Elliptic Curve defined by y^2 = x^3 + 66*x + 86 over Finite Field of size 101 @@ -88,7 +88,7 @@ Furthermore, the implementation is restricted to finite fields, since this appears to be the most relevant application for the -√élu algorithm:: +Vélu algorithm:: sage: E = EllipticCurve('26b1') sage: P = E(1,0) @@ -534,7 +534,7 @@ def _point_outside_subgroup(P): Frobenius). Thus, once `\pi-1` can be represented in Sage, we may just return that in :meth:`~sage.schemes.elliptic_curves.ell_field.EllipticCurve_field.isogeny` - rather than insisting on using √élu. + rather than insisting on using Vélu. """ E = P.curve() n = P.order() @@ -555,7 +555,7 @@ def _point_outside_subgroup(P): class EllipticCurveHom_velusqrt(EllipticCurveHom): r""" This class implements separable odd-degree isogenies of elliptic - curves over finite fields using the √élu algorithm. + curves over finite fields using the Vélu algorithm. The complexity is `\tilde O(\sqrt{\ell})` base-field operations, where `\ell` is the degree. @@ -578,7 +578,7 @@ class EllipticCurveHom_velusqrt(EllipticCurveHom): sage: E = EllipticCurve(F, [t,t]) sage: K = E(2154*t^2 + 5711*t + 2899, 7340*t^2 + 4653*t + 6935) sage: phi = EllipticCurveHom_velusqrt(E, K); phi - Elliptic-curve isogeny (using √élu) of degree 601: + Elliptic-curve isogeny (using Vélu) of degree 601: From: Elliptic Curve defined by y^2 = x^3 + t*x + t over Finite Field in t of size 10009^3 To: Elliptic Curve defined by y^2 = x^3 + (263*t^2+3173*t+4759)*x + (3898*t^2+6111*t+9443) over Finite Field in t of size 10009^3 sage: phi(K) @@ -644,7 +644,7 @@ class EllipticCurveHom_velusqrt(EllipticCurveHom): """ def __init__(self, E, P, *, codomain=None, model=None, Q=None): r""" - Initialize this √élu isogeny from a kernel point of odd order. + Initialize this Vélu isogeny from a kernel point of odd order. EXAMPLES:: @@ -652,7 +652,7 @@ def __init__(self, E, P, *, codomain=None, model=None, Q=None): sage: E = EllipticCurve(GF(71), [5,5]) sage: P = E(-2, 22) sage: EllipticCurveHom_velusqrt(E, P) - Elliptic-curve isogeny (using √élu) of degree 19: + Elliptic-curve isogeny (using Vélu) of degree 19: From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 71 To: Elliptic Curve defined by y^2 = x^3 + 13*x + 11 over Finite Field of size 71 @@ -661,16 +661,16 @@ def __init__(self, E, P, *, codomain=None, model=None, Q=None): sage: E.

= EllipticCurve(GF(419), [1,0]) sage: K = 4*P sage: EllipticCurveHom_velusqrt(E, K) - Elliptic-curve isogeny (using √élu) of degree 105: + Elliptic-curve isogeny (using Vélu) of degree 105: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419 To: Elliptic Curve defined by y^2 = x^3 + 301*x + 86 over Finite Field of size 419 sage: E2 = EllipticCurve(GF(419), [0,6,0,385,42]) sage: EllipticCurveHom_velusqrt(E, K, codomain=E2) - Elliptic-curve isogeny (using √élu) of degree 105: + Elliptic-curve isogeny (using Vélu) of degree 105: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419 To: Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 385*x + 42 over Finite Field of size 419 sage: EllipticCurveHom_velusqrt(E, K, model="montgomery") - Elliptic-curve isogeny (using √élu) of degree 105: + Elliptic-curve isogeny (using Vélu) of degree 105: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419 To: Elliptic Curve defined by y^2 = x^3 + 6*x^2 + x over Finite Field of size 419 @@ -739,7 +739,7 @@ def __init__(self, E, P, *, codomain=None, model=None, Q=None): def _raw_eval(self, x, y=None): r""" - Evaluate the "inner" √élu isogeny (i.e., without applying + Evaluate the "inner" Vélu isogeny (i.e., without applying pre- and post-isomorphism) at either just an `x`-coordinate or a pair `(x,y)` of coordinates. @@ -812,7 +812,7 @@ def _raw_eval(self, x, y=None): def _compute_codomain(self, model=None): r""" - Helper method to compute the codomain of this √élu isogeny + Helper method to compute the codomain of this Vélu isogeny once the data for :meth:`_raw_eval` has been initialized. Called by the constructor. @@ -839,7 +839,7 @@ def _compute_codomain(self, model=None): sage: phi._compute_codomain('montgomery') sage: phi - Elliptic-curve isogeny (using √élu) of degree 19: + Elliptic-curve isogeny (using Vélu) of degree 19: From: Elliptic Curve defined by y^2 = x^3 + 5*x^2 + x over Finite Field of size 71 To: Elliptic Curve defined by y^2 = x^3 + 40*x^2 + x over Finite Field of size 71 @@ -849,7 +849,7 @@ def _compute_codomain(self, model=None): sage: E = EllipticCurve([3*t, 2*t+4, 3*t+2, t+4, 3*t]) sage: K = E(3*t, 2) sage: EllipticCurveHom_velusqrt(E, K) # indirect doctest - Elliptic-curve isogeny (using √élu) of degree 19: + Elliptic-curve isogeny (using Vélu) of degree 19: From: Elliptic Curve defined by y^2 + 3*t*x*y + (3*t+2)*y = x^3 + (2*t+4)*x^2 + (t+4)*x + 3*t over Finite Field in t of size 5^2 To: Elliptic Curve defined by y^2 = x^3 + (4*t+3)*x + 2 over Finite Field in t of size 5^2 """ @@ -883,7 +883,7 @@ def _compute_codomain(self, model=None): def _eval(self, P): r""" - Evaluate this √élu isogeny at a point. + Evaluate this Vélu isogeny at a point. INPUT: @@ -896,7 +896,7 @@ def _eval(self, P): sage: K = E(4, 19) sage: phi = EllipticCurveHom_velusqrt(E, K, model='montgomery') sage: phi - Elliptic-curve isogeny (using √élu) of degree 19: + Elliptic-curve isogeny (using Vélu) of degree 19: From: Elliptic Curve defined by y^2 = x^3 + 5*x^2 + x over Finite Field of size 71 To: Elliptic Curve defined by y^2 = x^3 + 40*x^2 + x over Finite Field of size 71 sage: phi(K) @@ -955,7 +955,7 @@ def _eval(self, P): def _repr_(self): r""" - Return basic information about this √élu isogeny as a string. + Return basic information about this Vélu isogeny as a string. EXAMPLES:: @@ -963,18 +963,18 @@ def _repr_(self): sage: E.

= EllipticCurve(GF(71), [5,5]) sage: phi = EllipticCurveHom_velusqrt(E, P) sage: phi # indirect doctest - Elliptic-curve isogeny (using √élu) of degree 57: + Elliptic-curve isogeny (using Vélu) of degree 57: From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 71 To: Elliptic Curve defined by y^2 = x^3 + 19*x + 45 over Finite Field of size 71 """ - return f'Elliptic-curve isogeny (using √élu) of degree {self._degree}:' \ + return f'Elliptic-curve isogeny (using Vélu) of degree {self._degree}:' \ f'\n From: {self._domain}' \ f'\n To: {self._codomain}' @staticmethod def _comparison_impl(left, right, op): r""" - Compare a √élu isogeny to another elliptic-curve morphism. + Compare a Vélu isogeny to another elliptic-curve morphism. Called by :meth:`EllipticCurveHom._richcmp_`. @@ -991,11 +991,11 @@ def _comparison_impl(left, right, op): sage: from sage.schemes.elliptic_curves.hom_velusqrt import EllipticCurveHom_velusqrt sage: E = EllipticCurve(GF(101), [5,5,5,5,5]) sage: phi = EllipticCurveHom_velusqrt(E, E.lift_x(11)); phi - Elliptic-curve isogeny (using √élu) of degree 59: + Elliptic-curve isogeny (using Vélu) of degree 59: From: Elliptic Curve defined by y^2 + 5*x*y + 5*y = x^3 + 5*x^2 + 5*x + 5 over Finite Field of size 101 To: Elliptic Curve defined by y^2 = x^3 + 15*x + 25 over Finite Field of size 101 sage: psi = EllipticCurveHom_velusqrt(E, E.lift_x(-1)); psi - Elliptic-curve isogeny (using √élu) of degree 59: + Elliptic-curve isogeny (using Vélu) of degree 59: From: Elliptic Curve defined by y^2 + 5*x*y + 5*y = x^3 + 5*x^2 + 5*x + 5 over Finite Field of size 101 To: Elliptic Curve defined by y^2 = x^3 + 15*x + 25 over Finite Field of size 101 sage: phi == psi @@ -1008,7 +1008,7 @@ def _comparison_impl(left, right, op): @cached_method def kernel_polynomial(self): r""" - Return the kernel polynomial of this √élu isogeny. + Return the kernel polynomial of this Vélu isogeny. .. NOTE:: @@ -1039,19 +1039,19 @@ def kernel_polynomial(self): @cached_method def dual(self): r""" - Return the dual of this √élu isogeny as an :class:`EllipticCurveHom`. + Return the dual of this Vélu isogeny as an :class:`EllipticCurveHom`. .. NOTE:: The dual is computed by :class:`EllipticCurveIsogeny`, - hence it does not benefit from the √élu speedup. + hence it does not benefit from the Vélu speedup. EXAMPLES:: sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) sage: K = E.cardinality() // 11 * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt'); phi - Elliptic-curve isogeny (using √élu) of degree 11: + Elliptic-curve isogeny (using Vélu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 sage: phi.dual() @@ -1072,7 +1072,7 @@ def dual(self): @cached_method def rational_maps(self): r""" - Return the pair of explicit rational maps of this √élu isogeny + Return the pair of explicit rational maps of this Vélu isogeny as fractions of bivariate polynomials in `x` and `y`. .. NOTE:: @@ -1084,7 +1084,7 @@ def rational_maps(self): sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) sage: K = (E.cardinality() // 11) * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt'); phi - Elliptic-curve isogeny (using √élu) of degree 11: + Elliptic-curve isogeny (using Vélu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 sage: phi.rational_maps() @@ -1109,7 +1109,7 @@ def rational_maps(self): @cached_method def x_rational_map(self): r""" - Return the `x`-coordinate rational map of this √élu isogeny + Return the `x`-coordinate rational map of this Vélu isogeny as a univariate rational function in `x`. .. NOTE:: @@ -1121,7 +1121,7 @@ def x_rational_map(self): sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) sage: K = (E.cardinality() // 11) * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt'); phi - Elliptic-curve isogeny (using √élu) of degree 11: + Elliptic-curve isogeny (using Vélu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 sage: phi.x_rational_map() @@ -1145,7 +1145,7 @@ def x_rational_map(self): def scaling_factor(self): r""" Return the Weierstrass scaling factor associated to this - √élu isogeny. + Vélu isogeny. The scaling factor is the constant `u` (in the base field) such that `\varphi^* \omega_2 = u \omega_1`, where @@ -1158,7 +1158,7 @@ def scaling_factor(self): sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) sage: K = (E.cardinality() // 11) * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt', model='montgomery'); phi - Elliptic-curve isogeny (using √élu) of degree 11: + Elliptic-curve isogeny (using Vélu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 To: Elliptic Curve defined by y^2 = x^3 + 61*x^2 + x over Finite Field in z2 of size 101^2 sage: phi.scaling_factor() @@ -1187,7 +1187,7 @@ def is_separable(self): def _random_example_for_testing(): r""" - Function to generate somewhat random valid √élu inputs + Function to generate somewhat random valid Vélu inputs for testing purposes. EXAMPLES:: diff --git a/src/sage/schemes/elliptic_curves/padics.py b/src/sage/schemes/elliptic_curves/padics.py index 7f9e929a4f1..9ad02529be4 100644 --- a/src/sage/schemes/elliptic_curves/padics.py +++ b/src/sage/schemes/elliptic_curves/padics.py @@ -232,6 +232,8 @@ def padic_lseries(self, p, normalize=None, implementation='eclib', def padic_regulator(self, p, prec=20, height=None, check_hypotheses=True): r""" Compute the cyclotomic `p`-adic regulator of this curve. + The model of the curve needs to be integral and minimal at `p`. + Moreover the reduction at `p` should not be additive. INPUT: @@ -246,16 +248,11 @@ def padic_regulator(self, p, prec=20, height=None, check_hypotheses=True): - ``check_hypotheses`` -- boolean, whether to check that this is a curve for which the p-adic height makes sense - OUTPUT: The p-adic cyclotomic regulator of this curve, to the + OUTPUT: The `p`-adic cyclotomic regulator of this curve, to the requested precision. If the rank is 0, we output 1. - .. TODO:: - - Remove restriction that curve must be in minimal - Weierstrass form. This is currently required for E.gens(). - AUTHORS: - Liang Xiao: original implementation at the 2006 MSRI @@ -308,7 +305,7 @@ def padic_regulator(self, p, prec=20, height=None, check_hypotheses=True): sage: E.padic_regulator(7) == Em.padic_regulator(7) True - Allow a Python int as input:: + Allow a python int as input:: sage: E = EllipticCurve('37a') sage: E.padic_regulator(int(5)) @@ -343,9 +340,10 @@ def padic_regulator(self, p, prec=20, height=None, check_hypotheses=True): def padic_height_pairing_matrix(self, p, prec=20, height=None, check_hypotheses=True): r""" Computes the cyclotomic `p`-adic height pairing matrix of - this curve with respect to the basis self.gens() for the - Mordell-Weil group for a given odd prime p of good ordinary + this curve with respect to the basis ``self.gens()`` for the + Mordell-Weil group for a given odd prime `p` of good ordinary reduction. + The model needs to be integral and minimal at `p`. INPUT: @@ -360,14 +358,9 @@ def padic_height_pairing_matrix(self, p, prec=20, height=None, check_hypotheses= - ``check_hypotheses`` -- boolean, whether to check that this is a curve for which the p-adic height makes sense - OUTPUT: The p-adic cyclotomic height pairing matrix of this curve + OUTPUT: The `p`-adic cyclotomic height pairing matrix of this curve to the given precision. - .. TODO:: - - remove restriction that curve must be in minimal - Weierstrass form. This is currently required for E.gens(). - AUTHORS: - David Harvey, Liang Xiao, Robert Bradshaw, Jennifer @@ -428,14 +421,14 @@ def padic_height_pairing_matrix(self, p, prec=20, height=None, check_hypotheses= def _multiply_point(E, R, P, m): r""" - Computes coordinates of a multiple of P with entries in a ring. + Computes coordinates of a multiple of `P` with entries in a ring. INPUT: - - ``E`` -- elliptic curve over Q with integer + - ``E`` -- elliptic curve over `\QQ` with integer coefficients - - ``P`` -- a rational point on P that reduces to a + - ``P`` -- a rational point on `P` that reduces to a non-singular point at all primes - ``R`` -- a ring in which 2 is invertible (typically @@ -455,8 +448,7 @@ def _multiply_point(E, R, P, m): that the sign for `b'` will match the sign for `d'`. - ALGORITHM: Proposition 9 of "Efficient Computation of p-adic - Heights" (David Harvey, to appear in LMS JCM). + ALGORITHM: Proposition 9 in [Har2009]_. Complexity is soft-`O(\log L \log m + \log^2 m)`. @@ -586,28 +578,28 @@ def _multiply_point(E, R, P, m): def _multiple_to_make_good_reduction(E): """ - Return the integer n2 such that for all points P in E(Q) - n2*P has good reduction at all primes. + Return the integer `n_2` such that for all points `P` in `E(\QQ)` + `n_2*P` has good reduction at all primes. If the model is globally minimal the lcm of the Tamagawa numbers will do, otherwise we have to take into account the change of the model. INPUT: - - an elliptic curve ``E`` + - ``E`` -- an elliptic curve over `\QQ` OUTPUT: - a positive integer ``n2`` - EXAMPLE:: + EXAMPLE (:trac:`34790`):: sage: from sage.schemes.elliptic_curves.padics import _multiple_to_make_good_reduction sage: E = EllipticCurve([-1728,-100656]) sage: _multiple_to_make_good_reduction(E) 30 - The number ``n2`` is not always optimal but it is in this example. + The number ``n_2`` is not always optimal but it is in this example. The first multiple of the generator `P` with good reduction in this non-minimal model is `30 P`. @@ -643,9 +635,9 @@ def _multiple_to_make_good_reduction(E): def padic_height(self, p, prec=20, sigma=None, check_hypotheses=True): r""" - Compute the cyclotomic p-adic height. + Compute the cyclotomic `p`-adic height. - The equation of the curve must be minimal at `p`. + The equation of the curve must be integral and minimal at `p`. INPUT: @@ -662,7 +654,7 @@ def padic_height(self, p, prec=20, sigma=None, check_hypotheses=True): OUTPUT: A function that accepts two parameters: - - a Q-rational point on the curve whose height should be computed + - a `\QQ`-rational point on the curve whose height should be computed - optional boolean flag 'check': if False, it skips some input checking, and returns the p-adic height of that point to the @@ -670,8 +662,8 @@ def padic_height(self, p, prec=20, sigma=None, check_hypotheses=True): - The normalization (sign and a factor 1/2 with respect to some other normalizations that appear in the literature) is chosen in such a way - as to make the p-adic Birch Swinnerton-Dyer conjecture hold as stated - in [Mazur-Tate-Teitelbaum]. + as to make the `p`-adic Birch Swinnerton-Dyer conjecture hold as stated + in [MTT1986]_. AUTHORS: @@ -790,8 +782,7 @@ def padic_height(self, p, prec=20, sigma=None, check_hypotheses=True): # else good ordinary case - # For notation and definitions, see "Efficient Computation of - # p-adic Heights", David Harvey (unpublished) + # For notation and definitions, see [Har2009]_. n1 = self.change_ring(rings.GF(p)).cardinality() n2 = _multiple_to_make_good_reduction(self) @@ -848,7 +839,7 @@ def height(P, check=True): def padic_height_via_multiply(self, p, prec=20, E2=None, check_hypotheses=True): r""" - Computes the cyclotomic p-adic height. + Computes the cyclotomic `p`-adic height. The equation of the curve must be minimal at `p`. @@ -861,7 +852,7 @@ def padic_height_via_multiply(self, p, prec=20, E2=None, check_hypotheses=True): - ``E2`` -- precomputed value of E2. If not supplied, this function will call padic_E2 to compute it. The value supplied - must be correct mod `p^(prec-2)` (or slightly higher in the + must be correct mod `p^{prec-2}` (or slightly higher in the anomalous case; see the code for details). - ``check_hypotheses`` -- boolean, whether to check @@ -869,22 +860,21 @@ def padic_height_via_multiply(self, p, prec=20, E2=None, check_hypotheses=True): OUTPUT: A function that accepts two parameters: - - a Q-rational point on the curve whose height should be computed + - a `\QQ`-rational point on the curve whose height should be computed - optional boolean flag 'check': if False, it skips some input - checking, and returns the p-adic height of that point to the + checking, and returns the `p`-adic height of that point to the desired precision. - The normalization (sign and a factor 1/2 with respect to some other normalizations that appear in the literature) is chosen in such a way as to make the p-adic Birch Swinnerton-Dyer conjecture hold as stated - in [Mazur-Tate-Teitelbaum]. + in [MTT1986]_. AUTHORS: - David Harvey (2008-01): based on the padic_height() function, - using the algorithm of"Computing p-adic heights via - point multiplication" + using the algorithm of [Har2009]_. EXAMPLES:: @@ -935,8 +925,7 @@ def padic_height_via_multiply(self, p, prec=20, E2=None, check_hypotheses=True): if prec < 1: raise ValueError("prec (=%s) must be at least 1" % prec) - # For notation and definitions, see ``Computing p-adic heights via point - # multiplication'' (David Harvey, still in draft form) + # For notation and definitions, [Har2009]_ n1 = self.change_ring(rings.GF(p)).cardinality() n2 = _multiple_to_make_good_reduction(self) @@ -994,9 +983,9 @@ def height(P, check=True): def padic_sigma(self, p, N=20, E2=None, check=False, check_hypotheses=True): r""" - Computes the p-adic sigma function with respect to the standard + Computes the `p`-adic sigma function with respect to the standard invariant differential `dx/(2y + a_1 x + a_3)`, as - defined by Mazur and Tate, as a power series in the usual + defined by Mazur and Tate in [MT1991]_, as a power series in the usual uniformiser `t` at the origin. The equation of the curve must be minimal at `p`. @@ -1019,7 +1008,7 @@ def padic_sigma(self, p, N=20, E2=None, check=False, check_hypotheses=True): - ``differential equation`` -- note that this does NOT guarantee correctness of all the returned digits, but it comes - pretty close :-)) + pretty close. - ``check_hypotheses`` -- boolean, whether to check that this is a curve for which the p-adic sigma function makes @@ -1040,9 +1029,9 @@ def padic_sigma(self, p, N=20, E2=None, check=False, check_hypotheses=True): `p`-adic digits). ALGORITHM: Described in "Efficient Computation of p-adic Heights" - (David Harvey), which is basically an optimised version of the + (David Harvey) [Har2009]_ which is basically an optimised version of the algorithm from "p-adic Heights and Log Convergence" (Mazur, Stein, - Tate). + Tate) [MST2006]_. Running time is soft-`O(N^2 \log p)`, plus whatever time is necessary to compute `E_2`. @@ -1215,7 +1204,7 @@ def padic_sigma_truncated(self, p, N=20, lamb=0, E2=None, check_hypotheses=True) r""" Compute the p-adic sigma function with respect to the standard invariant differential `dx/(2y + a_1 x + a_3)`, as - defined by Mazur and Tate, as a power series in the usual + defined by Mazur and Tate in [MT1991]_, as a power series in the usual uniformiser `t` at the origin. The equation of the curve must be minimal at `p`. @@ -1249,10 +1238,9 @@ def padic_sigma_truncated(self, p, N=20, lamb=0, E2=None, check_hypotheses=True) correct to precision `O(p^{N - 2 + (3 - j)(lamb + 1)})`. ALGORITHM: Described in "Efficient Computation of p-adic Heights" - (David Harvey, to appear in LMS JCM), which is basically an + [Har2009]_, which is basically an optimised version of the algorithm from "p-adic Heights and Log - Convergence" (Mazur, Stein, Tate), and "Computing p-adic heights - via point multiplication" (David Harvey, still draft form). + Convergence" (Mazur, Stein, Tate) [MST2006]_. Running time is soft-`O(N^2 \lambda^{-1} \log p)`, plus whatever time is necessary to compute `E_2`. @@ -1434,7 +1422,7 @@ def padic_E2(self, p, prec=20, check=False, check_hypotheses=True, algorithm="au trick. EXAMPLES: Here is the example discussed in the paper "Computation - of p-adic Heights and Log Convergence" (Mazur, Stein, Tate):: + of p-adic Heights and Log Convergence" (Mazur, Stein, Tate) [MST2006]_:: sage: EllipticCurve([-1, 1/4]).padic_E2(5) 2 + 4*5 + 2*5^3 + 5^4 + 3*5^5 + 2*5^6 + 5^8 + 3*5^9 + 4*5^10 + 2*5^11 + 2*5^12 + 2*5^14 + 3*5^15 + 3*5^16 + 3*5^17 + 4*5^18 + 2*5^19 + O(5^20) @@ -1729,7 +1717,7 @@ def _brent(F, p, N): some log-log factors. For more information, and a proof of the precision guarantees, see - Lemma 4 in "Efficient Computation of p-adic Heights" (David Harvey). + Lemma 4 in [Har2009]_. AUTHORS: From caa0c9d5210e9a3ed0ca17eecf37c747b134de4c Mon Sep 17 00:00:00 2001 From: Chris Wuthrich Date: Fri, 5 May 2023 15:01:36 +0100 Subject: [PATCH 04/56] trac 34790: docstring fixing --- src/sage/schemes/elliptic_curves/constructor.py | 6 +++--- src/sage/schemes/elliptic_curves/hom.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/constructor.py b/src/sage/schemes/elliptic_curves/constructor.py index 15bdb273259..6f41ebecb9e 100644 --- a/src/sage/schemes/elliptic_curves/constructor.py +++ b/src/sage/schemes/elliptic_curves/constructor.py @@ -329,7 +329,7 @@ def create_key_and_extra_args(self, x=None, y=None, j=None, minimal_twist=True, sage: EllipticCurve.create_key_and_extra_args(j=8000) ((Rational Field, (0, 1, 0, -3, 1)), {}) - When constructing a curve over `\\QQ` from a Cremona or LMFDB + When constructing a curve over `\QQ` from a Cremona or LMFDB label, the invariants from the database are returned as ``extra_args``:: @@ -466,7 +466,7 @@ def create_object(self, version, key, **kwds): .. NOTE:: Keyword arguments are currently only passed to the - constructor for elliptic curves over `\\QQ`; elliptic + constructor for elliptic curves over `\QQ`; elliptic curves over other fields do not support them. """ R, x = key @@ -680,7 +680,7 @@ def coefficients_from_j(j, minimal_twist=True): sage: coefficients_from_j(1) [1, 0, 0, 36, 3455] - The ``minimal_twist`` parameter (ignored except over `\\QQ` and + The ``minimal_twist`` parameter (ignored except over `\QQ` and True by default) controls whether or not a minimal twist is computed:: diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index e1c5ed25c84..87dbc6fd226 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -56,7 +56,7 @@ def __init__(self, *args, **kwds): From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field in z2 of size 257^2 To: Elliptic Curve defined by y^2 = x^3 + 151*x + 22 over Finite Field in z2 of size 257^2 sage: E.isogeny(P, algorithm='velusqrt') # indirect doctest - Elliptic-curve isogeny (using √élu) of degree 127: + Elliptic-curve isogeny (using Vélu) of degree 127: From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field in z2 of size 257^2 To: Elliptic Curve defined by y^2 = x^3 + 119*x + 231 over Finite Field in z2 of size 257^2 sage: E.montgomery_model(morphism=True) # indirect doctest From de075659aa57c3783faaea8bfd1da353b3c93cc0 Mon Sep 17 00:00:00 2001 From: Chris Wuthrich Date: Fri, 5 May 2023 18:29:34 +0100 Subject: [PATCH 05/56] trac 34790: Q to QQ in dostrings --- src/sage/schemes/elliptic_curves/constructor.py | 2 +- src/sage/schemes/elliptic_curves/ell_torsion.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/constructor.py b/src/sage/schemes/elliptic_curves/constructor.py index 6f41ebecb9e..3e114acc56e 100644 --- a/src/sage/schemes/elliptic_curves/constructor.py +++ b/src/sage/schemes/elliptic_curves/constructor.py @@ -1409,7 +1409,7 @@ def are_projectively_equivalent(P, Q, base_ring): def EllipticCurves_with_good_reduction_outside_S(S=[], proof=None, verbose=False): r""" - Return a sorted list of all elliptic curves defined over `Q` + Return a sorted list of all elliptic curves defined over `\QQ` with good reduction outside the set `S` of primes. INPUT: diff --git a/src/sage/schemes/elliptic_curves/ell_torsion.py b/src/sage/schemes/elliptic_curves/ell_torsion.py index 6a84cb8a5e6..eb4cc38a43c 100644 --- a/src/sage/schemes/elliptic_curves/ell_torsion.py +++ b/src/sage/schemes/elliptic_curves/ell_torsion.py @@ -139,7 +139,7 @@ def __init__(self, E): INPUT: - - ``E`` -- An elliptic curve defined over a number field (including `\Q`) + - ``E`` -- An elliptic curve defined over a number field (including `\QQ`) EXAMPLES:: From 6aabc7421e49f6b254b8bba7b536aaa473055183 Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Sat, 6 May 2023 12:58:19 +0100 Subject: [PATCH 06/56] trac 34790: raw strings --- .../schemes/elliptic_curves/constructor.py | 20 ++--- .../elliptic_curves/ell_rational_field.py | 80 +++++++++---------- .../schemes/elliptic_curves/ell_torsion.py | 6 +- src/sage/schemes/elliptic_curves/hom.py | 12 +-- .../schemes/elliptic_curves/padic_lseries.py | 2 +- src/sage/schemes/elliptic_curves/padics.py | 4 +- 6 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/constructor.py b/src/sage/schemes/elliptic_curves/constructor.py index 3e114acc56e..8160393c57d 100644 --- a/src/sage/schemes/elliptic_curves/constructor.py +++ b/src/sage/schemes/elliptic_curves/constructor.py @@ -308,7 +308,7 @@ class EllipticCurveFactory(UniqueFactory): TypeError: invalid input to EllipticCurve constructor """ def create_key_and_extra_args(self, x=None, y=None, j=None, minimal_twist=True, **kwds): - """ + r""" Return a ``UniqueFactory`` key and possibly extra parameters. INPUT: See the documentation for :class:`EllipticCurveFactory`. @@ -454,7 +454,7 @@ def create_key_and_extra_args(self, x=None, y=None, j=None, minimal_twist=True, return (R, tuple(R(a) for a in x)), kwds def create_object(self, version, key, **kwds): - """ + r""" Create an object from a ``UniqueFactory`` key. EXAMPLES:: @@ -494,7 +494,7 @@ def create_object(self, version, key, **kwds): def EllipticCurve_from_Weierstrass_polynomial(f): - """ + r""" Return the elliptic curve defined by a cubic in (long) Weierstrass form. @@ -534,7 +534,7 @@ def EllipticCurve_from_Weierstrass_polynomial(f): return EllipticCurve(coefficients_from_Weierstrass_polynomial(f)) def coefficients_from_Weierstrass_polynomial(f): - """ + r""" Return the coefficients `[a_1, a_2, a_3, a_4, a_6]` of a cubic in Weierstrass form. @@ -582,7 +582,7 @@ def coefficients_from_Weierstrass_polynomial(f): def EllipticCurve_from_c4c6(c4, c6): - """ + r""" Return an elliptic curve with given `c_4` and `c_6` invariants. @@ -664,7 +664,7 @@ def EllipticCurve_from_j(j, minimal_twist=True): def coefficients_from_j(j, minimal_twist=True): - """ + r""" Return Weierstrass coefficients `(a_1, a_2, a_3, a_4, a_6)` for an elliptic curve with given `j`-invariant. @@ -1238,7 +1238,7 @@ def EllipticCurve_from_cubic(F, P=None, morphism=True): def tangent_at_smooth_point(C,P): - """Return the tangent at the smooth point `P` of projective curve `C`. + r"""Return the tangent at the smooth point `P` of projective curve `C`. INPUT: @@ -1278,7 +1278,7 @@ def tangent_at_smooth_point(C,P): return C.tangents(P,factor=False)[0] def chord_and_tangent(F, P): - """Return the third point of intersection of a cubic with the tangent at one point. + r"""Return the third point of intersection of a cubic with the tangent at one point. INPUT: @@ -1352,7 +1352,7 @@ def chord_and_tangent(F, P): def projective_point(p): - """ + r""" Return equivalent point with denominators removed INPUT: @@ -1384,7 +1384,7 @@ def projective_point(p): def are_projectively_equivalent(P, Q, base_ring): - """ + r""" Test whether ``P`` and ``Q`` are projectively equivalent. INPUT: diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 420a6c7cc77..5983109708e 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -""" +r""" Elliptic curves over the rational numbers AUTHORS: @@ -200,7 +200,7 @@ def __init__(self, ainvs, **kwds): self._set_torsion_order(kwds['torsion_order']) def _set_rank(self, r): - """ + r""" Internal function to set the cached rank of this elliptic curve to ``r``. @@ -221,7 +221,7 @@ def _set_rank(self, r): self.__rank = (Integer(r), True) def _set_torsion_order(self, t): - """ + r""" Internal function to set the cached torsion order of this elliptic curve to ``t``. @@ -242,7 +242,7 @@ def _set_torsion_order(self, t): self.__torsion_order = Integer(t) def _set_cremona_label(self, L): - """ + r""" Internal function to set the cached label of this elliptic curve to ``L``. @@ -267,7 +267,7 @@ def _set_cremona_label(self, L): self.__cremona_label = L def _set_conductor(self, N): - """ + r""" Internal function to set the cached conductor of this elliptic curve to ``N.`` @@ -288,7 +288,7 @@ def _set_conductor(self, N): self.__conductor_pari = Integer(N) def _set_modular_degree(self, deg): - """ + r""" Internal function to set the cached modular degree of this elliptic curve to ``deg``. @@ -309,7 +309,7 @@ def _set_modular_degree(self, deg): self.__modular_degree = Integer(deg) def _set_gens(self, gens): - """ + r""" Internal function to set the cached generators of this elliptic curve to ``gens``. @@ -382,7 +382,7 @@ def is_p_integral(self, p): return bool(misc.mul([x.valuation(p) >= 0 for x in self.ainvs()])) def is_integral(self): - """ + r""" Return ``True`` if this elliptic curve has integral coefficients (in Z). @@ -476,7 +476,7 @@ def mwrank(self, options=''): return mwrank(list(self.a_invariants())) def conductor(self, algorithm="pari"): - """ + r""" Return the conductor of the elliptic curve. INPUT: @@ -576,7 +576,7 @@ def conductor(self, algorithm="pari"): #################################################################### def pari_curve(self): - """ + r""" Return the PARI curve corresponding to this elliptic curve. EXAMPLES:: @@ -629,7 +629,7 @@ def pari_curve(self): return self._pari_curve def pari_mincurve(self): - """ + r""" Return the PARI curve corresponding to a minimal model for this elliptic curve. @@ -653,7 +653,7 @@ def pari_mincurve(self): @cached_method def database_attributes(self): - """ + r""" Return a dictionary containing information about ``self`` in the elliptic curve database. @@ -688,7 +688,7 @@ def database_attributes(self): raise LookupError("Cremona database does not contain entry for " + repr(self)) def database_curve(self): - """ + r""" Return the curve in the elliptic curve database isomorphic to this curve, if possible. Otherwise raise a ``LookupError`` exception. @@ -760,7 +760,7 @@ def Np(self, p): # Access to mwrank #################################################################### def mwrank_curve(self, verbose=False): - """ + r""" Construct an mwrank_EllipticCurve from this elliptic curve The resulting mwrank_EllipticCurve has available methods from John @@ -792,7 +792,7 @@ def two_descent(self, verbose=True, second_limit=8, n_aux=-1, second_descent=1): - """ + r""" Compute 2-descent data for this curve. INPUT: @@ -1362,7 +1362,7 @@ def f(r): return f def pollack_stevens_modular_symbol(self, sign=0, implementation='eclib'): - """ + r""" Create the modular symbol attached to the elliptic curve, suitable for overconvergent calculations. @@ -1979,7 +1979,7 @@ def rank(self, use_database=True, verbose=False, only_use_mwrank=True, algorithm='mwrank_lib', proof=None): - """ + r""" Return the rank of this elliptic curve, assuming no conjectures. If we fail to provably compute the rank, raises a RuntimeError @@ -2398,7 +2398,7 @@ def _compute_gens(self, proof, return G, proved def gens_certain(self): - """ + r""" Return ``True`` if the generators have been proven correct. EXAMPLES:: @@ -2948,7 +2948,7 @@ def an(self, n): return Integer(self.pari_mincurve().ellak(n)) def ap(self, p): - """ + r""" The ``p``-th Fourier coefficient of the modular form corresponding to this elliptic curve, where ``p`` is prime. @@ -3009,7 +3009,7 @@ def is_minimal(self): return self.ainvs() == self.minimal_model().ainvs() def is_p_minimal(self, p): - """ + r""" Tests if curve is ``p``-minimal at a given prime ``p``. INPUT: @@ -3188,7 +3188,7 @@ def tamagawa_exponent(self, p): return 4 def tamagawa_product(self): - """ + r""" Return the product of the Tamagawa numbers. EXAMPLES:: @@ -3204,7 +3204,7 @@ def tamagawa_product(self): return self.__tamagawa_product def real_components(self): - """ + r""" Return the number of real components. EXAMPLES:: @@ -3361,7 +3361,7 @@ def elliptic_exponential(self, z, embedding=None): return self.period_lattice().elliptic_exponential(z) def lseries(self): - """ + r""" Return the L-series of this elliptic curve. Further documentation is available for the functions which apply to @@ -3911,7 +3911,7 @@ def congruence_number(self, M=1): return self._generalized_congmod_numbers(M)["congnum"] def cremona_label(self, space=False): - """ + r""" Return the Cremona label associated to (the minimal model) of this curve, if it is known. If not, raise a ``LookupError`` exception. @@ -4003,7 +4003,7 @@ def reduction(self,p): return self.change_ring(rings.GF(p)) def torsion_order(self): - """ + r""" Return the order of the torsion subgroup. EXAMPLES:: @@ -4107,7 +4107,7 @@ def torsion_subgroup(self): return self.__torsion_subgroup def torsion_points(self): - """ + r""" Return the torsion points of this elliptic curve as a sorted list. @@ -4375,7 +4375,7 @@ def has_rational_cm(self, field=None): raise ValueError("Error in has_rational_cm: %s is not an extension field of QQ" % field) def quadratic_twist(self, D): - """ + r""" Return the global minimal model of the quadratic twist of this curve by ``D``. @@ -4746,7 +4746,7 @@ def isogenies_prime_degree(self, l=None): return isogs def is_isogenous(self, other, proof=True, maxp=200): - """ + r""" Return whether or not self is isogenous to other. INPUT: @@ -4824,7 +4824,7 @@ def is_isogenous(self, other, proof=True, maxp=200): return E2 in E1.isogeny_class().curves def isogeny_degree(self, other): - """ + r""" Return the minimal degree of an isogeny between ``self`` and ``other``. @@ -4949,7 +4949,7 @@ def isogeny_degree(self, other): # """ def optimal_curve(self): - """ + r""" Given an elliptic curve that is in the installed Cremona database, return the optimal curve isogenous to it. @@ -5289,7 +5289,7 @@ def is_ordinary(self, p, ell=None): return self.ap(ell) % p != 0 def is_good(self, p, check=True): - """ + r""" Return ``True`` if ``p`` is a prime of good reduction for `E`. INPUT: @@ -5314,7 +5314,7 @@ def is_good(self, p, check=True): return self.conductor() % p != 0 def is_supersingular(self, p, ell=None): - """ + r""" Return ``True`` precisely when p is a prime of good reduction and the mod-``p`` representation attached to this elliptic curve is supersingular at ell. @@ -5344,7 +5344,7 @@ def is_supersingular(self, p, ell=None): return self.is_good(p) and not self.is_ordinary(p, ell) def supersingular_primes(self, B): - """ + r""" Return a list of all supersingular primes for this elliptic curve up to and possibly including B. @@ -5379,7 +5379,7 @@ def supersingular_primes(self, B): [P[i] for i in range(2,len(v)) if v[i] == 0 and N%P[i] != 0] def ordinary_primes(self, B): - """ + r""" Return a list of all ordinary primes for this elliptic curve up to and possibly including B. @@ -5463,7 +5463,7 @@ def eval_modular_form(self, points, order): ######################################################################## def sha(self): - """ + r""" Return an object of class 'sage.schemes.elliptic_curves.sha_tate.Sha' attached to this elliptic curve. @@ -5528,7 +5528,7 @@ def sha(self): matrix_of_frobenius = padics.matrix_of_frobenius def mod5family(self): - """ + r""" Return the family of all elliptic curves with the same mod-5 representation as ``self``. @@ -5836,7 +5836,7 @@ def integral_x_coords_in_interval(self,xmin,xmax): prove_BSD = BSD.prove_BSD def integral_points(self, mw_base='auto', both_signs=False, verbose=False): - """ + r""" Compute all integral points (up to sign) on this elliptic curve. INPUT: @@ -6232,7 +6232,7 @@ def point_preprocessing(free,tor): return int_points def S_integral_points(self, S, mw_base='auto', both_signs=False, verbose=False, proof=None): - """ + r""" Compute all S-integral points (up to sign) on this elliptic curve. INPUT: @@ -6887,7 +6887,7 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): def cremona_curves(conductors): - """ + r""" Return iterator over all known curves (in database) with conductor in the list of conductors. @@ -6920,7 +6920,7 @@ def cremona_curves(conductors): return sage.databases.cremona.CremonaDatabase().iter(conductors) def cremona_optimal_curves(conductors): - """ + r""" Return iterator over all known optimal curves (in database) with conductor in the list of conductors. diff --git a/src/sage/schemes/elliptic_curves/ell_torsion.py b/src/sage/schemes/elliptic_curves/ell_torsion.py index eb4cc38a43c..fce06899b38 100644 --- a/src/sage/schemes/elliptic_curves/ell_torsion.py +++ b/src/sage/schemes/elliptic_curves/ell_torsion.py @@ -210,7 +210,7 @@ def __init__(self, E): [T1, T2], structure) def _repr_(self): - """ + r""" String representation of an instance of the EllipticCurveTorsionSubgroup class. EXAMPLES:: @@ -239,7 +239,7 @@ def __richcmp__(self, other, op): return richcmp(self.__E, other.__E, op) def curve(self): - """ + r""" Return the curve of this torsion subgroup. EXAMPLES:: @@ -255,7 +255,7 @@ def curve(self): @cached_method def points(self): - """ + r""" Return a list of all the points in this torsion subgroup. The list is cached. diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 87dbc6fd226..34d92d0ae40 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -75,7 +75,7 @@ def __init__(self, *args, **kwds): self._domain._fetch_cached_order(self._codomain) def _repr_type(self): - """ + r""" Return a textual representation of what kind of morphism this is. Used by :meth:`Morphism._repr_`. @@ -89,7 +89,7 @@ def _repr_type(self): @staticmethod def _composition_impl(left, right): - """ + r""" Called by :meth:`_composition_`. TESTS:: @@ -101,7 +101,7 @@ def _composition_impl(left, right): return NotImplemented def _composition_(self, other, homset): - """ + r""" Return the composition of this elliptic-curve morphism with another elliptic-curve morphism. @@ -133,7 +133,7 @@ def _composition_(self, other, homset): @staticmethod def _comparison_impl(left, right, op): - """ + r""" Called by :meth:`_richcmp_`. TESTS:: @@ -626,7 +626,7 @@ def is_injective(self): return self.degree() == 1 def is_zero(self): - """ + r""" Check whether this elliptic-curve morphism is the zero map. .. NOTE:: @@ -664,7 +664,7 @@ def __neg__(self): @cached_method def __hash__(self): - """ + r""" Return a hash value for this elliptic-curve morphism. ALGORITHM: diff --git a/src/sage/schemes/elliptic_curves/padic_lseries.py b/src/sage/schemes/elliptic_curves/padic_lseries.py index 8b0bf4344ce..895b5bb7971 100644 --- a/src/sage/schemes/elliptic_curves/padic_lseries.py +++ b/src/sage/schemes/elliptic_curves/padic_lseries.py @@ -1376,7 +1376,7 @@ def _prec_bounds(self, n, prec): return [infinity] + [2 * e[j] - c0 for j in range(1, len(e))] def _poly(self, a): - """ + r""" Given an element a in Qp[alpha] this returns the list containing the two coordinates in Qp. diff --git a/src/sage/schemes/elliptic_curves/padics.py b/src/sage/schemes/elliptic_curves/padics.py index 9ad02529be4..ed53a1e4c80 100644 --- a/src/sage/schemes/elliptic_curves/padics.py +++ b/src/sage/schemes/elliptic_curves/padics.py @@ -2,7 +2,7 @@ # # All these methods are imported in EllipticCurve_rational_field, # so there is no reason to add this module to the documentation. -""" +r""" Miscellaneous `p`-adic methods """ @@ -577,7 +577,7 @@ def _multiply_point(E, R, P, m): return theta, omega, psi_m * d def _multiple_to_make_good_reduction(E): - """ + r""" Return the integer `n_2` such that for all points `P` in `E(\QQ)` `n_2*P` has good reduction at all primes. If the model is globally minimal the lcm of the From 253491e97dbe6471299384441e7c2e1c6059a2b6 Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Tue, 9 May 2023 20:18:19 +0100 Subject: [PATCH 07/56] add missing doctests in padics.py --- src/sage/schemes/elliptic_curves/padics.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/sage/schemes/elliptic_curves/padics.py b/src/sage/schemes/elliptic_curves/padics.py index ed53a1e4c80..0ec8191213d 100644 --- a/src/sage/schemes/elliptic_curves/padics.py +++ b/src/sage/schemes/elliptic_curves/padics.py @@ -603,6 +603,27 @@ def _multiple_to_make_good_reduction(E): The first multiple of the generator `P` with good reduction in this non-minimal model is `30 P`. + TESTS:: + + sage: from sage.schemes.elliptic_curves.padics import _multiple_to_make_good_reduction + sage: E = EllipticCurve([1/2,1/3]) + sage: _multiple_to_make_good_reduction(E) + Traceback (most recent call last): + ... + NotImplementedError: This only implemented for integral models. Please change the model first. + sage: E = EllipticCurve([0,3]) + sage: _multiple_to_make_good_reduction(E) + 1 + sage: E = EllipticCurve([0,5^7]) # min eq is additive + sage: _multiple_to_make_good_reduction(E) + 5 + sage: E = EllipticCurve([7,0,0,0,7^7]) # min eq is split mult + sage: _multiple_to_make_good_reduction(E) + 6 + sage: E = EllipticCurve([0,-3^2,0,0,3^7]) # min eq is non-split mult + sage: _multiple_to_make_good_reduction(E) + 4 + """ if not E.is_integral(): st = ("This only implemented for integral models. " From bb53db8d20d5b21df9905e8a10babeedde588ce8 Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Tue, 9 May 2023 21:52:15 +0100 Subject: [PATCH 08/56] revert velu to square-root velu --- src/sage/schemes/elliptic_curves/hom.py | 2 +- .../schemes/elliptic_curves/hom_velusqrt.py | 81 ++++++++++--------- 2 files changed, 44 insertions(+), 39 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 34d92d0ae40..be36fdcd162 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -56,7 +56,7 @@ def __init__(self, *args, **kwds): From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field in z2 of size 257^2 To: Elliptic Curve defined by y^2 = x^3 + 151*x + 22 over Finite Field in z2 of size 257^2 sage: E.isogeny(P, algorithm='velusqrt') # indirect doctest - Elliptic-curve isogeny (using Vélu) of degree 127: + Elliptic-curve isogeny (using square-root Vélu) of degree 127: From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field in z2 of size 257^2 To: Elliptic Curve defined by y^2 = x^3 + 119*x + 231 over Finite Field in z2 of size 257^2 sage: E.montgomery_model(morphism=True) # indirect doctest diff --git a/src/sage/schemes/elliptic_curves/hom_velusqrt.py b/src/sage/schemes/elliptic_curves/hom_velusqrt.py index 221d5a1eb4f..0a3c327cef1 100644 --- a/src/sage/schemes/elliptic_curves/hom_velusqrt.py +++ b/src/sage/schemes/elliptic_curves/hom_velusqrt.py @@ -1,7 +1,8 @@ r""" -Vélu algorithm for elliptic-curve isogenies +Square‑root Vélu algorithm for elliptic-curve isogenies -The Vélu algorithm computes isogenies of elliptic curves in time `\tilde +The square-root Vélu algorithm, also called the √élu algorithm, +computes isogenies of elliptic curves in time `\tilde O(\sqrt\ell)` rather than naïvely `O(\ell)`, where `\ell` is the degree. The core idea is to reindex the points in the kernel subgroup in a @@ -26,7 +27,7 @@ 10009 sage: phi = EllipticCurveHom_velusqrt(E, K) sage: phi - Elliptic-curve isogeny (using Vélu) of degree 10009: + Elliptic-curve isogeny (using square-root Vélu) of degree 10009: From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 6666679 To: Elliptic Curve defined by y^2 = x^3 + 227975*x + 3596133 over Finite Field of size 6666679 sage: phi.codomain() @@ -56,7 +57,7 @@ sage: K = E(9091, 517864) sage: phi = EllipticCurveHom_velusqrt(E, K, model='montgomery') sage: phi - Elliptic-curve isogeny (using Vélu) of degree 2999: + Elliptic-curve isogeny (using square-root Vélu) of degree 2999: From: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 6666679 To: Elliptic Curve defined by y^2 = x^3 + 1559358*x^2 + x over Finite Field of size 6666679 @@ -68,7 +69,7 @@ sage: K.order() 37 sage: EllipticCurveHom_velusqrt(E, K) - Elliptic-curve isogeny (using Vélu) of degree 37: + Elliptic-curve isogeny (using square-root Vélu) of degree 37: From: Elliptic Curve defined by y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 over Finite Field of size 101 To: Elliptic Curve defined by y^2 = x^3 + 66*x + 86 over Finite Field of size 101 @@ -88,7 +89,7 @@ Furthermore, the implementation is restricted to finite fields, since this appears to be the most relevant application for the -Vélu algorithm:: +square-root Vélu algorithm:: sage: E = EllipticCurve('26b1') sage: P = E(1,0) @@ -534,7 +535,7 @@ def _point_outside_subgroup(P): Frobenius). Thus, once `\pi-1` can be represented in Sage, we may just return that in :meth:`~sage.schemes.elliptic_curves.ell_field.EllipticCurve_field.isogeny` - rather than insisting on using Vélu. + rather than insisting on using square-root Vélu. """ E = P.curve() n = P.order() @@ -555,7 +556,7 @@ def _point_outside_subgroup(P): class EllipticCurveHom_velusqrt(EllipticCurveHom): r""" This class implements separable odd-degree isogenies of elliptic - curves over finite fields using the Vélu algorithm. + curves over finite fields using the square-root Vélu algorithm. The complexity is `\tilde O(\sqrt{\ell})` base-field operations, where `\ell` is the degree. @@ -578,7 +579,7 @@ class EllipticCurveHom_velusqrt(EllipticCurveHom): sage: E = EllipticCurve(F, [t,t]) sage: K = E(2154*t^2 + 5711*t + 2899, 7340*t^2 + 4653*t + 6935) sage: phi = EllipticCurveHom_velusqrt(E, K); phi - Elliptic-curve isogeny (using Vélu) of degree 601: + Elliptic-curve isogeny (using square-root Vélu) of degree 601: From: Elliptic Curve defined by y^2 = x^3 + t*x + t over Finite Field in t of size 10009^3 To: Elliptic Curve defined by y^2 = x^3 + (263*t^2+3173*t+4759)*x + (3898*t^2+6111*t+9443) over Finite Field in t of size 10009^3 sage: phi(K) @@ -644,7 +645,7 @@ class EllipticCurveHom_velusqrt(EllipticCurveHom): """ def __init__(self, E, P, *, codomain=None, model=None, Q=None): r""" - Initialize this Vélu isogeny from a kernel point of odd order. + Initialize this square-root Vélu isogeny from a kernel point of odd order. EXAMPLES:: @@ -652,7 +653,7 @@ def __init__(self, E, P, *, codomain=None, model=None, Q=None): sage: E = EllipticCurve(GF(71), [5,5]) sage: P = E(-2, 22) sage: EllipticCurveHom_velusqrt(E, P) - Elliptic-curve isogeny (using Vélu) of degree 19: + Elliptic-curve isogeny (using square-root Vélu) of degree 19: From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 71 To: Elliptic Curve defined by y^2 = x^3 + 13*x + 11 over Finite Field of size 71 @@ -661,16 +662,16 @@ def __init__(self, E, P, *, codomain=None, model=None, Q=None): sage: E.

= EllipticCurve(GF(419), [1,0]) sage: K = 4*P sage: EllipticCurveHom_velusqrt(E, K) - Elliptic-curve isogeny (using Vélu) of degree 105: + Elliptic-curve isogeny (using square-root Vélu) of degree 105: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419 To: Elliptic Curve defined by y^2 = x^3 + 301*x + 86 over Finite Field of size 419 sage: E2 = EllipticCurve(GF(419), [0,6,0,385,42]) sage: EllipticCurveHom_velusqrt(E, K, codomain=E2) - Elliptic-curve isogeny (using Vélu) of degree 105: + Elliptic-curve isogeny (using square-root Vélu) of degree 105: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419 To: Elliptic Curve defined by y^2 = x^3 + 6*x^2 + 385*x + 42 over Finite Field of size 419 sage: EllipticCurveHom_velusqrt(E, K, model="montgomery") - Elliptic-curve isogeny (using Vélu) of degree 105: + Elliptic-curve isogeny (using square-root Vélu) of degree 105: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 419 To: Elliptic Curve defined by y^2 = x^3 + 6*x^2 + x over Finite Field of size 419 @@ -739,9 +740,10 @@ def __init__(self, E, P, *, codomain=None, model=None, Q=None): def _raw_eval(self, x, y=None): r""" - Evaluate the "inner" Vélu isogeny (i.e., without applying - pre- and post-isomorphism) at either just an `x`-coordinate - or a pair `(x,y)` of coordinates. + Evaluate the "inner" square-root Vélu isogeny + (i.e., without applying pre- and post-isomorphism) + at either just an `x`-coordinate or a pair + `(x,y)` of coordinates. If the given point lies in the kernel, the empty tuple ``()`` is returned. @@ -812,7 +814,8 @@ def _raw_eval(self, x, y=None): def _compute_codomain(self, model=None): r""" - Helper method to compute the codomain of this Vélu isogeny + Helper method to compute the codomain of this + square-root Vélu isogeny once the data for :meth:`_raw_eval` has been initialized. Called by the constructor. @@ -839,7 +842,7 @@ def _compute_codomain(self, model=None): sage: phi._compute_codomain('montgomery') sage: phi - Elliptic-curve isogeny (using Vélu) of degree 19: + Elliptic-curve isogeny (using square-root Vélu) of degree 19: From: Elliptic Curve defined by y^2 = x^3 + 5*x^2 + x over Finite Field of size 71 To: Elliptic Curve defined by y^2 = x^3 + 40*x^2 + x over Finite Field of size 71 @@ -849,7 +852,7 @@ def _compute_codomain(self, model=None): sage: E = EllipticCurve([3*t, 2*t+4, 3*t+2, t+4, 3*t]) sage: K = E(3*t, 2) sage: EllipticCurveHom_velusqrt(E, K) # indirect doctest - Elliptic-curve isogeny (using Vélu) of degree 19: + Elliptic-curve isogeny (using square-root Vélu) of degree 19: From: Elliptic Curve defined by y^2 + 3*t*x*y + (3*t+2)*y = x^3 + (2*t+4)*x^2 + (t+4)*x + 3*t over Finite Field in t of size 5^2 To: Elliptic Curve defined by y^2 = x^3 + (4*t+3)*x + 2 over Finite Field in t of size 5^2 """ @@ -883,7 +886,7 @@ def _compute_codomain(self, model=None): def _eval(self, P): r""" - Evaluate this Vélu isogeny at a point. + Evaluate this square-root Vélu isogeny at a point. INPUT: @@ -896,7 +899,7 @@ def _eval(self, P): sage: K = E(4, 19) sage: phi = EllipticCurveHom_velusqrt(E, K, model='montgomery') sage: phi - Elliptic-curve isogeny (using Vélu) of degree 19: + Elliptic-curve isogeny (using square-root Vélu) of degree 19: From: Elliptic Curve defined by y^2 = x^3 + 5*x^2 + x over Finite Field of size 71 To: Elliptic Curve defined by y^2 = x^3 + 40*x^2 + x over Finite Field of size 71 sage: phi(K) @@ -955,7 +958,7 @@ def _eval(self, P): def _repr_(self): r""" - Return basic information about this Vélu isogeny as a string. + Return basic information about this square-root Vélu isogeny as a string. EXAMPLES:: @@ -963,18 +966,18 @@ def _repr_(self): sage: E.

= EllipticCurve(GF(71), [5,5]) sage: phi = EllipticCurveHom_velusqrt(E, P) sage: phi # indirect doctest - Elliptic-curve isogeny (using Vélu) of degree 57: + Elliptic-curve isogeny (using square-root Vélu) of degree 57: From: Elliptic Curve defined by y^2 = x^3 + 5*x + 5 over Finite Field of size 71 To: Elliptic Curve defined by y^2 = x^3 + 19*x + 45 over Finite Field of size 71 """ - return f'Elliptic-curve isogeny (using Vélu) of degree {self._degree}:' \ + return f'Elliptic-curve isogeny (using square-root Vélu) of degree {self._degree}:' \ f'\n From: {self._domain}' \ f'\n To: {self._codomain}' @staticmethod def _comparison_impl(left, right, op): r""" - Compare a Vélu isogeny to another elliptic-curve morphism. + Compare a square-root Vélu isogeny to another elliptic-curve morphism. Called by :meth:`EllipticCurveHom._richcmp_`. @@ -991,11 +994,11 @@ def _comparison_impl(left, right, op): sage: from sage.schemes.elliptic_curves.hom_velusqrt import EllipticCurveHom_velusqrt sage: E = EllipticCurve(GF(101), [5,5,5,5,5]) sage: phi = EllipticCurveHom_velusqrt(E, E.lift_x(11)); phi - Elliptic-curve isogeny (using Vélu) of degree 59: + Elliptic-curve isogeny (using square-root Vélu) of degree 59: From: Elliptic Curve defined by y^2 + 5*x*y + 5*y = x^3 + 5*x^2 + 5*x + 5 over Finite Field of size 101 To: Elliptic Curve defined by y^2 = x^3 + 15*x + 25 over Finite Field of size 101 sage: psi = EllipticCurveHom_velusqrt(E, E.lift_x(-1)); psi - Elliptic-curve isogeny (using Vélu) of degree 59: + Elliptic-curve isogeny (using square-root Vélu) of degree 59: From: Elliptic Curve defined by y^2 + 5*x*y + 5*y = x^3 + 5*x^2 + 5*x + 5 over Finite Field of size 101 To: Elliptic Curve defined by y^2 = x^3 + 15*x + 25 over Finite Field of size 101 sage: phi == psi @@ -1008,7 +1011,7 @@ def _comparison_impl(left, right, op): @cached_method def kernel_polynomial(self): r""" - Return the kernel polynomial of this Vélu isogeny. + Return the kernel polynomial of this square-root Vélu isogeny. .. NOTE:: @@ -1039,19 +1042,20 @@ def kernel_polynomial(self): @cached_method def dual(self): r""" - Return the dual of this Vélu isogeny as an :class:`EllipticCurveHom`. + Return the dual of this square-root Vélu + isogeny as an :class:`EllipticCurveHom`. .. NOTE:: The dual is computed by :class:`EllipticCurveIsogeny`, - hence it does not benefit from the Vélu speedup. + hence it does not benefit from the square-root Vélu speedup. EXAMPLES:: sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) sage: K = E.cardinality() // 11 * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt'); phi - Elliptic-curve isogeny (using Vélu) of degree 11: + Elliptic-curve isogeny (using square-root Vélu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 sage: phi.dual() @@ -1072,7 +1076,7 @@ def dual(self): @cached_method def rational_maps(self): r""" - Return the pair of explicit rational maps of this Vélu isogeny + Return the pair of explicit rational maps of this square-root Vélu isogeny as fractions of bivariate polynomials in `x` and `y`. .. NOTE:: @@ -1084,7 +1088,7 @@ def rational_maps(self): sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) sage: K = (E.cardinality() // 11) * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt'); phi - Elliptic-curve isogeny (using Vélu) of degree 11: + Elliptic-curve isogeny (using square-root Vélu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 sage: phi.rational_maps() @@ -1109,7 +1113,8 @@ def rational_maps(self): @cached_method def x_rational_map(self): r""" - Return the `x`-coordinate rational map of this Vélu isogeny + Return the `x`-coordinate rational map of + this square-root Vélu isogeny as a univariate rational function in `x`. .. NOTE:: @@ -1121,7 +1126,7 @@ def x_rational_map(self): sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) sage: K = (E.cardinality() // 11) * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt'); phi - Elliptic-curve isogeny (using Vélu) of degree 11: + Elliptic-curve isogeny (using square-root Vélu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 To: Elliptic Curve defined by y^2 = x^3 + 39*x + 40 over Finite Field in z2 of size 101^2 sage: phi.x_rational_map() @@ -1145,7 +1150,7 @@ def x_rational_map(self): def scaling_factor(self): r""" Return the Weierstrass scaling factor associated to this - Vélu isogeny. + square-root Vélu isogeny. The scaling factor is the constant `u` (in the base field) such that `\varphi^* \omega_2 = u \omega_1`, where @@ -1158,7 +1163,7 @@ def scaling_factor(self): sage: E = EllipticCurve(GF(101^2), [1, 1, 1, 1, 1]) sage: K = (E.cardinality() // 11) * E.gens()[0] sage: phi = E.isogeny(K, algorithm='velusqrt', model='montgomery'); phi - Elliptic-curve isogeny (using Vélu) of degree 11: + Elliptic-curve isogeny (using square-root Vélu) of degree 11: From: Elliptic Curve defined by y^2 + x*y + y = x^3 + x^2 + x + 1 over Finite Field in z2 of size 101^2 To: Elliptic Curve defined by y^2 = x^3 + 61*x^2 + x over Finite Field in z2 of size 101^2 sage: phi.scaling_factor() From abd04ae3e2fa5d1e4a9f67b07bd524cfeb9a3d4b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 22 May 2023 17:45:13 -0700 Subject: [PATCH 09/56] build/pkgs/networkx: Update to 3.1 --- build/pkgs/networkx/checksums.ini | 6 +++--- build/pkgs/networkx/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/networkx/checksums.ini b/build/pkgs/networkx/checksums.ini index 00b6f1fa335..dd792a15a2e 100644 --- a/build/pkgs/networkx/checksums.ini +++ b/build/pkgs/networkx/checksums.ini @@ -1,5 +1,5 @@ tarball=networkx-VERSION.tar.gz -sha1=40e981041664856ba473c9079006367ed0d0e71b -md5=22139ab5a47818fa00cbaa91eb126381 -cksum=4201985987 +sha1=d4b1d6117b7c54db61f6cbec8f0ccfb0f7d47293 +md5=1a9baa93b7fd4470c80e29a7a6d93ccf +cksum=1675580484 upstream_url=https://pypi.io/packages/source/n/networkx/networkx-VERSION.tar.gz diff --git a/build/pkgs/networkx/package-version.txt b/build/pkgs/networkx/package-version.txt index 80803faf1b9..8c50098d8ae 100644 --- a/build/pkgs/networkx/package-version.txt +++ b/build/pkgs/networkx/package-version.txt @@ -1 +1 @@ -2.8.8 +3.1 From 843528536597b41064f3bc0db2a7631d0c52d02a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 22 May 2023 17:47:06 -0700 Subject: [PATCH 10/56] build/pkgs/igraph: Update to 0.10.4 --- build/pkgs/igraph/checksums.ini | 6 +++--- build/pkgs/igraph/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/igraph/checksums.ini b/build/pkgs/igraph/checksums.ini index f7d3336bda8..279cba457a9 100644 --- a/build/pkgs/igraph/checksums.ini +++ b/build/pkgs/igraph/checksums.ini @@ -1,5 +1,5 @@ tarball=igraph-VERSION.tar.gz -sha1=20587332f0f36d6d7eb3cca248e2dab76e1e58ad -md5=af41eb9c614946c4a92a51834e9cab4a -cksum=4011381306 +sha1=fc3c6627f889b13581b2b468e1b16aceff453cfc +md5=10a3f325425970c75a7ba8359376e208 +cksum=3103730646 upstream_url=https://github.com/igraph/igraph/releases/download/VERSION/igraph-VERSION.tar.gz diff --git a/build/pkgs/igraph/package-version.txt b/build/pkgs/igraph/package-version.txt index 5eef0f10e8c..9b40aa6c214 100644 --- a/build/pkgs/igraph/package-version.txt +++ b/build/pkgs/igraph/package-version.txt @@ -1 +1 @@ -0.10.2 +0.10.4 From 0b4ac7088ba47daa0be09ec249ea0e0576a618f1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 22 May 2023 18:31:44 -0700 Subject: [PATCH 11/56] build/pkgs/networkx/install-requires.txt: Update --- build/pkgs/networkx/install-requires.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build/pkgs/networkx/install-requires.txt b/build/pkgs/networkx/install-requires.txt index 9b1205be0a8..ea173da7538 100644 --- a/build/pkgs/networkx/install-requires.txt +++ b/build/pkgs/networkx/install-requires.txt @@ -1,2 +1 @@ -# features removed in 3.0 listed in https://networkx.org/documentation/stable/developer/deprecations.html#version-3-0 -networkx >=2.4, <3.0 +networkx >=2.4, <3.2 From 5b2ca01c269561894fde54f7a185c4d55827185e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 22 May 2023 18:37:08 -0700 Subject: [PATCH 12/56] build/pkgs/python_igraph: Upgrade to 0.10.4 --- build/pkgs/python_igraph/checksums.ini | 6 +++--- build/pkgs/python_igraph/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/python_igraph/checksums.ini b/build/pkgs/python_igraph/checksums.ini index 5f8bc59a4de..7247680193c 100644 --- a/build/pkgs/python_igraph/checksums.ini +++ b/build/pkgs/python_igraph/checksums.ini @@ -1,5 +1,5 @@ tarball=python-igraph-VERSION.tar.gz -sha1=6a6bca77737ff501e97f808aa18a9045e86b3e3e -md5=6951cc2e803118b74209ae21d54de38a -cksum=650236223 +sha1=807a95ad4080d8eb500e7797325d6f11a5c46892 +md5=2ac3561dda7e7321789041261a29aba4 +cksum=754615899 upstream_url=https://pypi.io/packages/source/i/igraph/igraph-VERSION.tar.gz diff --git a/build/pkgs/python_igraph/package-version.txt b/build/pkgs/python_igraph/package-version.txt index 5eef0f10e8c..9b40aa6c214 100644 --- a/build/pkgs/python_igraph/package-version.txt +++ b/build/pkgs/python_igraph/package-version.txt @@ -1 +1 @@ -0.10.2 +0.10.4 From 71238491a5b72a5b0d93ec18d249389727fa06eb Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Thu, 13 Apr 2023 13:32:37 +0800 Subject: [PATCH 13/56] avoid computation of Conway polynomials when comparing elliptic-curve morphisms --- src/sage/schemes/elliptic_curves/hom.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index e1c5ed25c84..c7575277cb8 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -899,7 +899,7 @@ def compare_via_evaluation(left, right): 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)) + EE = E.base_extend(F.extension(e,'U')) Ps = EE.gens() return all(left._eval(P) == right._eval(P) for P in Ps) elif isinstance(F, number_field_base.NumberField): @@ -981,7 +981,7 @@ def find_post_isomorphism(phi, psi): if len(isos) <= 1: break else: - E = E.base_extend(E.base_field().extension(2)) + E = E.base_extend(E.base_field().extension(2,'U')) elif isinstance(F, number_field_base.NumberField): for _ in range(100): From 6afbfb4016c9ef537c10421665fbc18deb3c8130 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 May 2023 01:28:03 +0000 Subject: [PATCH 14/56] :arrow_up: Bump myrotvorets/set-commit-status-action from 1.1.6 to 1.1.7 Bumps [myrotvorets/set-commit-status-action](https://github.com/myrotvorets/set-commit-status-action) from 1.1.6 to 1.1.7. - [Release notes](https://github.com/myrotvorets/set-commit-status-action/releases) - [Commits](https://github.com/myrotvorets/set-commit-status-action/compare/1.1.6...v1.1.7) --- updated-dependencies: - dependency-name: myrotvorets/set-commit-status-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/doc-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc-publish.yml b/.github/workflows/doc-publish.yml index 351b3277f92..538e77322fc 100644 --- a/.github/workflows/doc-publish.yml +++ b/.github/workflows/doc-publish.yml @@ -75,7 +75,7 @@ jobs: [Documentation preview for this PR](${{ steps.deploy-netlify.outputs.NETLIFY_URL }}) (built with commit ${{ steps.source-run-info.outputs.sourceHeadSha }}) is ready! :tada: - name: Update deployment status PR check - uses: myrotvorets/set-commit-status-action@1.1.6 + uses: myrotvorets/set-commit-status-action@v1.1.7 if: ${{ always() }} env: DEPLOY_SUCCESS: Successfully deployed preview. From 2d9b3a292e5771583ae84db20af75a582705900b Mon Sep 17 00:00:00 2001 From: Chris Wuthrich Date: Thu, 1 Jun 2023 12:22:29 +0100 Subject: [PATCH 15/56] delete one extra empty line --- src/sage/schemes/elliptic_curves/padic_lseries.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/padic_lseries.py b/src/sage/schemes/elliptic_curves/padic_lseries.py index 895b5bb7971..4cd3cc11b42 100644 --- a/src/sage/schemes/elliptic_curves/padic_lseries.py +++ b/src/sage/schemes/elliptic_curves/padic_lseries.py @@ -89,7 +89,6 @@ from sage.structure.sage_object import SageObject - @richcmp_method class pAdicLseries(SageObject): r""" From 138b9cf37f2d612466d58ba707da1a95f373bbe4 Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Sat, 6 May 2023 17:21:45 +0100 Subject: [PATCH 16/56] integrate ellrank for elliptic curves over QQ --- .../elliptic_curves/ell_rational_field.py | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 5983109708e..25b0b16e5bf 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -1999,6 +1999,8 @@ def rank(self, use_database=True, verbose=False, - ``'mwrank_lib'`` -- call mwrank c library + - ``'pari'`` -- call ellrank in pari + - ``only_use_mwrank`` -- (default: ``True``) if ``False`` try using analytic rank methods first @@ -2024,7 +2026,7 @@ def rank(self, use_database=True, verbose=False, 4 sage: EllipticCurve([0, 0, 1, -79, 342]).rank(proof=False) 5 - sage: EllipticCurve([0, 0, 1, -79, 342]).simon_two_descent()[0] # long time (7s on sage.math, 2012) + sage: EllipticCurve([0, 0, 1, -79, 342]).rank(algorithm="pari") 5 Examples with denominators in defining equations:: @@ -2168,6 +2170,21 @@ def rank(self, use_database=True, verbose=False, self.__rank = (rank, proof) return rank + if algorithm == 'pari': + ep = self.pari_curve() + lower, upper, s, pts = ep.ellrank() + if lower == upper: + verbose_verbose(f"rank {lower} unconditionally determined by pari") + rank = Integer(lower) + self.__rank = (rank, True) + ge = sorted([self.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) + self._known_points = ge + self.__gens = (ge, True) + return rank + else: + verbose_verbose(f"Warning -- rank could not be determined by pari; ellrank returned {lower=}, {upper=}, {s=}, {pts=}", level=1) + raise RuntimeError(f"rank not provably correct (lower bound: {lower}, upper bound:{upper}") + raise ValueError("unknown algorithm {!r}".format(algorithm)) def gens(self, proof=None, **kwds): @@ -2194,6 +2211,8 @@ def gens(self, proof=None, **kwds): - ``'mwrank_lib'`` -- call mwrank C library + - ``'pari'`` -- use ellrank in pari + - ``only_use_mwrank`` -- bool (default True) if False, first attempts to use more naive, natively implemented methods @@ -2218,7 +2237,7 @@ def gens(self, proof=None, **kwds): :meth:`~gens_certain` method to find out afterwards whether the generators were proved. - IMPLEMENTATION: Uses Cremona's mwrank C library. + IMPLEMENTATION: Uses Cremona's mwrank C library or ellrank in pari. EXAMPLES:: @@ -2333,7 +2352,21 @@ def _compute_gens(self, proof, except RuntimeError: pass # end if (not_use_mwrank) - if algorithm == "mwrank_lib": + if algorithm == "pari": + ep = self.pari_curve() + lower, upper, s, pts = ep.ellrank() + if lower == upper: + verbose_verbose(f"rank {lower} unconditionally determined by pari") + rank = Integer(lower) + self.__rank = (rank, True) + ge = sorted([self.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) + self.__gens = (ge, True) + self._known_points = ge + return ge, True + else: + verbose_verbose(f"Warning -- rank could not be determined by pari; ellrank returned {lower=}, {upper=}, {s=}, {pts=}", level=1) + raise RuntimeError(f"rank not provably correct (lower bound: {lower}, upper bound:{upper}") + elif algorithm == "mwrank_lib": verbose_verbose("Calling mwrank C++ library.") if not self.is_integral(): xterm = 1 From c75835b67b489bb054ae135b307fd77f9889192c Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Sun, 7 May 2023 14:15:45 +0100 Subject: [PATCH 17/56] issue 35621: deprecate simon_two_descent over QQ --- .../elliptic_curves/ell_rational_field.py | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 25b0b16e5bf..aa8d6c1bf23 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -1777,6 +1777,13 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=3, Return lower and upper bounds on the rank of the Mordell-Weil group `E(\QQ)` and a list of points of infinite order. + .. WARNING:: + + This function is deprecated as the functionality of + Simon's script for elliptic curves over the rationals + has been ported over to pari. + Use :meth:`.rank` with the keyword ``algorithm='pari;`` instead. + INPUT: - ``verbose`` -- 0, 1, 2, or 3 (default: 0), the verbosity level @@ -1829,6 +1836,10 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=3, sage: E = EllipticCurve('11a1') sage: E.simon_two_descent() + doctest:warning + ... + DeprecationWarning: Use E.rank(algorithm="pari") instead, as this script has been ported over to pari. + See https://github.com/sagemath/sage/issues/35621 for details. (0, 0, []) sage: E = EllipticCurve('37a1') sage: E.simon_two_descent() @@ -1909,6 +1920,9 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=3, sage: E.selmer_rank() # uses mwrank 1 """ + from sage.misc.superseded import deprecation + deprecation(35621, 'Use E.rank(algorithm="pari") instead, as this script has been ported over to pari.') + t = EllipticCurve_number_field.simon_two_descent(self, verbose=verbose, lim1=lim1, lim3=lim3, limtriv=limtriv, maxprob=maxprob, limbigprime=limbigprime, @@ -2070,6 +2084,12 @@ def rank(self, use_database=True, verbose=False, 0 sage: E._EllipticCurve_rational_field__rank (0, True) + + sage: E =EllipticCurve([-113^2,0]) + sage: E.rank(use_database=False, verbose=False, algorithm="pari") + Traceback (most recent call last): + ... + RuntimeError: rank not provably correct (lower bound: 0, upper bound:2) """ if proof is None: from sage.structure.proof.proof import get_flag @@ -2183,7 +2203,7 @@ def rank(self, use_database=True, verbose=False, return rank else: verbose_verbose(f"Warning -- rank could not be determined by pari; ellrank returned {lower=}, {upper=}, {s=}, {pts=}", level=1) - raise RuntimeError(f"rank not provably correct (lower bound: {lower}, upper bound:{upper}") + raise RuntimeError(f"rank not provably correct (lower bound: {lower}, upper bound:{upper})") raise ValueError("unknown algorithm {!r}".format(algorithm)) @@ -2244,6 +2264,8 @@ def gens(self, proof=None, **kwds): sage: E = EllipticCurve('389a') sage: E.gens() # random output [(-1 : 1 : 1), (0 : 0 : 1)] + sage: E.gens(algorithm="pari") # random output + [(5/4 : 5/8 : 1), (0 : 0 : 1)] A non-integral example:: @@ -2259,6 +2281,9 @@ def gens(self, proof=None, **kwds): over Rational Field sage: E1.gens() # random (if database not used) [(-400 : 8000 : 1), (0 : -8000 : 1)] + sage: E1.gens(algorithm="pari") + [(-400 : 8000 : 1), (0 : 0 : 1)] + """ if proof is None: from sage.structure.proof.proof import get_flag @@ -2365,7 +2390,7 @@ def _compute_gens(self, proof, return ge, True else: verbose_verbose(f"Warning -- rank could not be determined by pari; ellrank returned {lower=}, {upper=}, {s=}, {pts=}", level=1) - raise RuntimeError(f"rank not provably correct (lower bound: {lower}, upper bound:{upper}") + raise RuntimeError(f"rank not provably correct (lower bound: {lower}, upper bound:{upper})") elif algorithm == "mwrank_lib": verbose_verbose("Calling mwrank C++ library.") if not self.is_integral(): From 2ff83fb02a5ce288c27094f16a947331cae2f0f9 Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Mon, 8 May 2023 03:06:30 +0100 Subject: [PATCH 18/56] issue 35621: change prove_bsd --- src/sage/schemes/elliptic_curves/BSD.py | 72 ++++++++++++++- .../elliptic_curves/ell_rational_field.py | 88 ++++++++++++++----- 2 files changed, 133 insertions(+), 27 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/BSD.py b/src/sage/schemes/elliptic_curves/BSD.py index f5522de2e00..aff5bd302fc 100644 --- a/src/sage/schemes/elliptic_curves/BSD.py +++ b/src/sage/schemes/elliptic_curves/BSD.py @@ -3,6 +3,7 @@ from sage.arith.misc import prime_divisors from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ from sage.rings.infinity import Infinity from sage.rings.number_field.number_field import QuadraticField from sage.functions.other import ceil @@ -89,11 +90,17 @@ def simon_two_descent_work(E, two_tor_rk): sage: from sage.schemes.elliptic_curves.BSD import simon_two_descent_work sage: E = EllipticCurve('14a') sage: simon_two_descent_work(E, E.two_torsion_rank()) + doctest:warning + ... + DeprecationWarning: Use E.rank(algorithm="pari") instead, as this script has been ported over to pari. + See https://github.com/sagemath/sage/issues/35621 for details. (0, 0, 0, 0, []) sage: E = EllipticCurve('37a') sage: simon_two_descent_work(E, E.two_torsion_rank()) (1, 1, 0, 0, [(0 : 0 : 1)]) """ + from sage.misc.superseded import deprecation + deprecation(35621, 'Use the two-descent in pari instead, as this script has been ported over to pari.') rank_lower_bd, two_sel_rk, gens = E.simon_two_descent() rank_upper_bd = two_sel_rk - two_tor_rk gens = [P for P in gens if P.additive_order() == Infinity] @@ -140,6 +147,54 @@ def mwrank_two_descent_work(E, two_tor_rk): sha2_upper_bd = MWRC.selmer_rank() - two_tor_rk - rank_lower_bd return rank_lower_bd, rank_upper_bd, sha2_lower_bd, sha2_upper_bd, gens +def pari_two_descent_work(E): + r""" + Prepare the output from pari by two-isogeny. + + INPUT: + + - ``E`` -- an elliptic curve + + OUTPUT: + + - a lower bound on the rank + + - an upper bound on the rank + + - a lower bound on the rank of Sha[2] + + - an upper bound on the rank of Sha[2] + + - a list of the generators found + + EXAMPLES:: + + sage: from sage.schemes.elliptic_curves.BSD import pari_two_descent_work + sage: E = EllipticCurve('14a') + sage: pari_two_descent_work(E) + (0, 0, 0, 0, []) + sage: E = EllipticCurve('37a') + sage: pari_two_descent_work(E) + (1, 1, 0, 0, [(-1 : 0 : 1)]) + sage: E = EllipticCurve('210e7') + sage: pari_two_descent_work(E) + (0, 2, 0, 2, []) + sage: E = EllipticCurve('66b3') + sage: pari_two_descent_work(E) + (0, 0, 2, 2, []) + + """ + ep = E.pari_curve() + lower, rank_upper_bd, s, pts = ep.ellrank() + gens = sorted([E.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) + # this is explained in the pari-gp documentation: + # s is the dimension of Sha[2]/2Sha[4], + # which is a lower bound for dim Sha[2] + # dim Sha[2] = dim Sel2 - rank E(Q) - dim tors + # rank_upper_bd = dim Sel_2 - dim tors - s + sha_upper_bd = rank_upper_bd - len(gens) + s + return len(gens), rank_upper_bd, s, sha_upper_bd, gens + def native_two_isogeny_descent_work(E, two_tor_rk): """ @@ -254,7 +309,7 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, - 2: print information about remaining primes - ``two_desc`` -- string (default ``'mwrank'``), what to use for the - two-descent. Options are ``'mwrank', 'simon', 'sage'`` + two-descent. Options are ``'mwrank', 'pari', 'sage'`` - ``proof`` -- bool or None (default: None, see proof.elliptic_curve or sage.structure.proof). If False, this @@ -317,7 +372,7 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, True for p = 3 by Kolyvagin bound True for p = 5 by Kolyvagin bound [] - sage: E.prove_BSD(two_desc='simon') + sage: E.prove_BSD(two_desc='pari') [] A rank two curve:: @@ -433,6 +488,15 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, p = 2: True by 2-descent True for p not in {2} by Kolyvagin. [] + + :: + + sage: E = EllipticCurve('66b3') + sage: E.prove_BSD(two_desc="pari",verbosity=1) + p = 2: True by 2-descent + True for p not in {2} by Kolyvagin. + [] + """ if proof is None: from sage.structure.proof.proof import get_flag @@ -461,8 +525,8 @@ def prove_BSD(E, verbosity=0, two_desc='mwrank', proof=None, secs_hi=5, if two_desc == 'mwrank': M = mwrank_two_descent_work(BSD.curve, BSD.two_tor_rk) - elif two_desc == 'simon': - M = simon_two_descent_work(BSD.curve, BSD.two_tor_rk) + elif two_desc == 'pari': + M = pari_two_descent_work(BSD.curve) elif two_desc == 'sage': M = native_two_isogeny_descent_work(BSD.curve, BSD.two_tor_rk) else: diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index aa8d6c1bf23..7a6fd78d357 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -1992,7 +1992,8 @@ def three_selmer_rank(self, algorithm='UseSUnits'): def rank(self, use_database=True, verbose=False, only_use_mwrank=True, algorithm='mwrank_lib', - proof=None): + proof=None, + pari_effort=0): r""" Return the rank of this elliptic curve, assuming no conjectures. @@ -2022,9 +2023,15 @@ def rank(self, use_database=True, verbose=False, ``proof.elliptic_curve`` or ``sage.structure.proof``); note that results obtained from databases are considered ``proof=True`` + - ``pari_effort`` -- (default: 0) parameter used in when + the algorithm ``pari`` is chosen. It measure of the effort + done to find rational points. Values up to 10 can be chosen; + the running times increase roughly like the cube of the + effort value. + OUTPUT: the rank of the elliptic curve as :class:`Integer` - IMPLEMENTATION: Uses L-functions, mwrank, and databases. + IMPLEMENTATION: Uses L-functions, mwrank, pari, and databases. EXAMPLES:: @@ -2089,7 +2096,7 @@ def rank(self, use_database=True, verbose=False, sage: E.rank(use_database=False, verbose=False, algorithm="pari") Traceback (most recent call last): ... - RuntimeError: rank not provably correct (lower bound: 0, upper bound:2) + RuntimeError: rank not provably correct (lower bound: 0, upper bound:2). Hint: increase pari_effort. """ if proof is None: from sage.structure.proof.proof import get_flag @@ -2192,19 +2199,21 @@ def rank(self, use_database=True, verbose=False, if algorithm == 'pari': ep = self.pari_curve() - lower, upper, s, pts = ep.ellrank() - if lower == upper: - verbose_verbose(f"rank {lower} unconditionally determined by pari") - rank = Integer(lower) + # if we know already some points in _known_points + # we can give them to pari to speed it up + kpts = [ [x[0],x[1]] for x in self._known_points ] + lower, upper, s, pts = ep.ellrank(pari_effort, kpts) + ge = sorted([self.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) + self._known_points = ge + if len(ge) == upper: + verbose_verbose(f"rank {upper} unconditionally determined by pari") + rank = Integer(upper) self.__rank = (rank, True) - ge = sorted([self.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) - self._known_points = ge self.__gens = (ge, True) return rank else: verbose_verbose(f"Warning -- rank could not be determined by pari; ellrank returned {lower=}, {upper=}, {s=}, {pts=}", level=1) - raise RuntimeError(f"rank not provably correct (lower bound: {lower}, upper bound:{upper})") - + raise RuntimeError(f"rank not provably correct (lower bound: {len(ge)}, upper bound:{upper}). Hint: increase pari_effort.") raise ValueError("unknown algorithm {!r}".format(algorithm)) def gens(self, proof=None, **kwds): @@ -2246,6 +2255,12 @@ def gens(self, proof=None, **kwds): points found by two-descent in the Mordell-Weil group is greater than this, a warning message will be displayed. + - ``pari_effort`` -- (default: 0) parameter used in when + the algorithm ``pari`` is chosen. It measure of the effort + done to find rational points. Values up to 10 can be chosen, + the running times increase roughly like the cube of the + effort value. + OUTPUT: - ``generators`` -- list of generators for the Mordell-Weil @@ -2266,6 +2281,9 @@ def gens(self, proof=None, **kwds): [(-1 : 1 : 1), (0 : 0 : 1)] sage: E.gens(algorithm="pari") # random output [(5/4 : 5/8 : 1), (0 : 0 : 1)] + sage: E = EllipticCurve([0,2429469980725060,0,275130703388172136833647756388,0]) + sage: len(E.gens(algorithm="pari")) + 14 A non-integral example:: @@ -2310,7 +2328,8 @@ def _compute_gens(self, proof, only_use_mwrank=True, use_database=True, descent_second_limit=12, - sat_bound=1000): + sat_bound=1000, + pari_effort=0): r""" Return generators for the Mordell-Weil group `E(Q)` *modulo* torsion. @@ -2333,6 +2352,25 @@ def _compute_gens(self, proof, sage: gens, proved = E._compute_gens(proof=False) sage: proved True + + TESTS:: + + sage: E = EllipticCurve([-127^2,0]) + sage: E.gens(use_database=False, algorithm="pari") + Traceback (most recent call last): + ... + RuntimeError: generators could not be determined. So far we found []. Hint: increase pari_effort. + sage: E.gens(use_database=False, algorithm="pari",pari_effort=4) + [(611429153205013185025/9492121848205441 : 15118836457596902442737698070880/924793900700594415341761 : 1)] + + sage: E = EllipticCurve([-157^2,0]) + sage: E.gens(use_database=False, algorithm="pari") + Traceback (most recent call last): + ... + RuntimeError: generators could not be determined. So far we found []. Hint: increase pari_effort. + sage: E.gens(use_database=False, algorithm="pari",pari_effort=10) + [(-166136231668185267540804/2825630694251145858025 : 167661624456834335404812111469782006/150201095200135518108761470235125 : 1)] + """ # If the optional extended database is installed and an # isomorphic curve is in the database then its gens will be @@ -2379,18 +2417,22 @@ def _compute_gens(self, proof, # end if (not_use_mwrank) if algorithm == "pari": ep = self.pari_curve() - lower, upper, s, pts = ep.ellrank() - if lower == upper: - verbose_verbose(f"rank {lower} unconditionally determined by pari") - rank = Integer(lower) + # if we know already some points in _known_points + # we can give them to pari to speed it up + kpts = [ [x[0],x[1]] for x in self._known_points ] + lower, upper, s, pts = ep.ellrank(pari_effort, kpts) + ge = sorted([self.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) + self._known_points = ge + if len(ge) == upper: + verbose_verbose(f"rank {upper} unconditionally determined by pari") + rank = Integer(upper) self.__rank = (rank, True) - ge = sorted([self.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) - self.__gens = (ge, True) - self._known_points = ge - return ge, True - else: - verbose_verbose(f"Warning -- rank could not be determined by pari; ellrank returned {lower=}, {upper=}, {s=}, {pts=}", level=1) - raise RuntimeError(f"rank not provably correct (lower bound: {lower}, upper bound:{upper})") + if len(ge) == rank: + self.__gens = (ge, True) + return ge, True + # cases when we did not find all points + verbose_verbose(f"Warning -- generators could not be determined by pari; ellrank returned {lower=}, {upper=}, {s=}, {pts=}", level=1) + raise RuntimeError(f"generators could not be determined. So far we found {ge}. Hint: increase pari_effort.") elif algorithm == "mwrank_lib": verbose_verbose("Calling mwrank C++ library.") if not self.is_integral(): From b5d59cdc5b5c097f842e8dd3acb42af43c5e8e0a Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Mon, 8 May 2023 13:38:45 +0100 Subject: [PATCH 19/56] issue 35621: saturation for points from pari --- src/sage/schemes/elliptic_curves/BSD.py | 5 +++-- .../elliptic_curves/ell_rational_field.py | 22 ++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/BSD.py b/src/sage/schemes/elliptic_curves/BSD.py index aff5bd302fc..3221f453103 100644 --- a/src/sage/schemes/elliptic_curves/BSD.py +++ b/src/sage/schemes/elliptic_curves/BSD.py @@ -174,8 +174,8 @@ def pari_two_descent_work(E): sage: pari_two_descent_work(E) (0, 0, 0, 0, []) sage: E = EllipticCurve('37a') - sage: pari_two_descent_work(E) - (1, 1, 0, 0, [(-1 : 0 : 1)]) + sage: pari_two_descent_work(E) # random, up to sign + (1, 1, 0, 0, [(0 : -1 : 1)]) sage: E = EllipticCurve('210e7') sage: pari_two_descent_work(E) (0, 2, 0, 2, []) @@ -187,6 +187,7 @@ def pari_two_descent_work(E): ep = E.pari_curve() lower, rank_upper_bd, s, pts = ep.ellrank() gens = sorted([E.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) + gens = E.saturation(gens)[0] # this is explained in the pari-gp documentation: # s is the dimension of Sha[2]/2Sha[4], # which is a lower bound for dim Sha[2] diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 7a6fd78d357..96f791bc2a7 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -2061,7 +2061,7 @@ def rank(self, use_database=True, verbose=False, sage: E.minimal_model().rank() 1 - A large example where mwrank doesn't determine the result with certainty:: + A large example where mwrank doesn't determine the result with certainty, but pari does:: sage: EllipticCurve([1,0,0,0,37455]).rank(proof=False) 0 @@ -2069,6 +2069,8 @@ def rank(self, use_database=True, verbose=False, Traceback (most recent call last): ... RuntimeError: rank not provably correct (lower bound: 0) + sage: EllipticCurve([1,0,0,0,37455]).rank(algorithm="pari") + 0 TESTS:: @@ -2077,6 +2079,14 @@ def rank(self, use_database=True, verbose=False, ... ValueError: unknown algorithm 'garbage' + An example to check if the points are saturated:: + + sage: E = EllipticCurve([0,0, 1, -7, 6]) + sage: E.gens(use_database=False, algorithm="pari") # random + [(2 : 0 : 1), (-1 : 3 : 1), (11 : 35 : 1)] + sage: E.saturation(_)[1] + 1 + Since :trac:`23962`, the default is to use the Cremona database. We also check that the result is cached correctly:: @@ -2204,6 +2214,7 @@ def rank(self, use_database=True, verbose=False, kpts = [ [x[0],x[1]] for x in self._known_points ] lower, upper, s, pts = ep.ellrank(pari_effort, kpts) ge = sorted([self.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) + ge = self.saturation(ge)[0] self._known_points = ge if len(ge) == upper: verbose_verbose(f"rank {upper} unconditionally determined by pari") @@ -2256,10 +2267,10 @@ def gens(self, proof=None, **kwds): greater than this, a warning message will be displayed. - ``pari_effort`` -- (default: 0) parameter used in when - the algorithm ``pari`` is chosen. It measure of the effort - done to find rational points. Values up to 10 can be chosen, - the running times increase roughly like the cube of the - effort value. + the algorithm ``pari`` is chosen. It measure of the effort + done to find rational points. Values up to 10 can be chosen, + the running times increase roughly like the cube of the + effort value. OUTPUT: @@ -2422,6 +2433,7 @@ def _compute_gens(self, proof, kpts = [ [x[0],x[1]] for x in self._known_points ] lower, upper, s, pts = ep.ellrank(pari_effort, kpts) ge = sorted([self.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) + ge = self.saturation(ge)[0] self._known_points = ge if len(ge) == upper: verbose_verbose(f"rank {upper} unconditionally determined by pari") From b4f0de644f42cad6976ba80ca1d4842bc5e03b56 Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Mon, 8 May 2023 23:30:25 +0100 Subject: [PATCH 20/56] adjust rank_bound and selmer_rank --- .../elliptic_curves/ell_rational_field.py | 127 +++++++++++------- 1 file changed, 80 insertions(+), 47 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 96f791bc2a7..9528a30475d 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -2310,8 +2310,8 @@ def gens(self, proof=None, **kwds): over Rational Field sage: E1.gens() # random (if database not used) [(-400 : 8000 : 1), (0 : -8000 : 1)] - sage: E1.gens(algorithm="pari") - [(-400 : 8000 : 1), (0 : 0 : 1)] + sage: E1.gens(algorithm="pari") #random + [(-400 : 8000 : 1), (0 : -8000 : 1)] """ if proof is None: @@ -2965,86 +2965,119 @@ def point_search(self, height_limit, verbose=False, rank_bound=None): points = self.saturation(points, verbose=verbose)[0] return points - def selmer_rank(self): + def selmer_rank(self, algorithm="pari"): r""" - The rank of the 2-Selmer group of the curve. + Return the rank of the 2-Selmer group of the curve. - EXAMPLES: The following is the curve 960D1, which has rank 0, but - Sha of order 4. + INPUT: - :: + - ``algorithm`` -- (default:``'pari'``) + either ``'pari'`` or ``'mwrank'`` - sage: E = EllipticCurve([0, -1, 0, -900, -10098]) - sage: E.selmer_rank() - 3 - - Here the Selmer rank is equal to the 2-torsion rank (=1) plus - the 2-rank of Sha (=2), and the rank itself is zero:: + EXAMPLES: + This example has rank 1, Sha[2] of order 4 and + a single rational 2-torsion point:: - sage: E.rank() - 0 + sage: E = EllipticCurve([1, 1, 1, 508, -2551]) + sage: E.selmer_rank() + 4 + sage: E.selmer_rank(algorithm="mwrank") + 4 - In contrast, for the curve 571A, also with rank 0 and Sha of - order 4, we get a worse bound:: + The following is the curve 960d1, which has rank 0, but + Sha of order 4:: - sage: E = EllipticCurve([0, -1, 1, -929, -10595]) + sage: E = EllipticCurve([0, -1, 0, -900, -10098]) sage: E.selmer_rank() - 2 - sage: E.rank_bound() - 2 + 3 + sage: E.selmer_rank(algorithm="mwrank") + 3 - To establish that the rank is in fact 0 in this case, we would - need to carry out a higher descent:: + This curve has rank 1, and 4 elements in Sha[2]. + Yet the order of Sha is 16, so that group is the product + of two cyclic groups of order 4:: - sage: E.three_selmer_rank() # optional - magma - 0 + sage: E = EllipticCurve([1, 0, 0, -150752, -22541610]) + sage: E.selmer_rank() + 4 - Or use the L-function to compute the analytic rank:: + Instead in this last example of rank 0, Sha is a product of four cyclic groups of order 2:: - sage: E.rank(only_use_mwrank=False) + sage: E = EllipticCurve([1, 0, 0, -49280, -4214808]) + sage: E.selmer_rank() + 5 + sage: E.rank() 0 """ try: return self.__selmer_rank except AttributeError: - C = self.mwrank_curve() - self.__selmer_rank = C.selmer_rank() - return self.__selmer_rank + if algorithm=="pari": + ep = self.pari_curve() + lower, upper, s, pts = ep.ellrank() + T = self.torsion_subgroup().invariants() + tor = sum(x%2==0 for x in T) + return upper + tor + s + elif algorithm=="mwrank": + C = self.mwrank_curve() + self.__selmer_rank = C.selmer_rank() + return self.__selmer_rank + else: + raise ValueError(f"unknown {algorithm=}") - def rank_bound(self): + def rank_bound(self, algorithm="pari"): r""" - Upper bound on the rank of the curve, computed using - 2-descent. + Return the upper bound on the rank of the curve, + computed using a 2-descent. + + INPUT: + + - ``algorithm`` -- (default:``'pari'``) + either ``'pari'`` or ``'mwrank'`` In many cases, this is the actual rank of the - curve. If the curve has no 2-torsion it is the same as the - 2-selmer rank. + curve. + + EXAMPLES:: - EXAMPLES: The following is the curve 960D1, which has rank 0, but - Sha of order 4. + sage: E = EllipticCurve("389a1") + sage: E.rank_bound() + 2 - :: + The following is the curve 571a1, which has + rank 0, but Sha of order 4, yet pari, using the Cassels + pairing is able to show that the rank is 0. + The 2-descent in mwrank only determines a weaker upper bound:: - sage: E = EllipticCurve([0, -1, 0, -900, -10098]) + sage: E = EllipticCurve([0, -1, 1, -929, -10595]) sage: E.rank_bound() 0 + sage: E.rank_bound(algorithm="mwrank") + 2 - It gives 0 instead of 2, because it knows Sha is nontrivial. In - contrast, for the curve 571A, also with rank 0 and Sha of order 4, - we get a worse bound:: + In the following last example, both algorithm only determine a rank bound larger than the actual rank:: - sage: E = EllipticCurve([0, -1, 1, -929, -10595]) + sage: E = EllipticCurve([1, 1, 1, -896670, -327184905]) sage: E.rank_bound() 2 - sage: E.rank(only_use_mwrank=False) # uses L-function + sage: E.rank_bound(algorithm="mwrank") + 2 + sage: E.rank(only_use_mwrank=False) # uses L-function 0 """ try: return self.__rank_bound except AttributeError: - C = self.mwrank_curve() - self.__rank_bound = C.rank_bound() - return self.__rank_bound + if algorithm=="pari": + ep = self.pari_curve() + lower, upper, s, pts = ep.ellrank() + return upper + elif algorithm=="mwrank": + C = self.mwrank_curve() + self.__rank_bound = C.rank_bound() + return self.__rank_bound + else: + raise ValueError(f"unknown {algorithm=}") def an(self, n): r""" From 3ff268a310f7e6489fbd97177ffc67efc9995274 Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Tue, 9 May 2023 22:50:54 +0100 Subject: [PATCH 21/56] revievers suggested changes --- src/sage/schemes/elliptic_curves/BSD.py | 2 +- .../elliptic_curves/ell_rational_field.py | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/BSD.py b/src/sage/schemes/elliptic_curves/BSD.py index 3221f453103..85130f0a5f9 100644 --- a/src/sage/schemes/elliptic_curves/BSD.py +++ b/src/sage/schemes/elliptic_curves/BSD.py @@ -155,7 +155,7 @@ def pari_two_descent_work(E): - ``E`` -- an elliptic curve - OUTPUT: + OUTPUT: A tuple of 5 elements with the first 4 being integers. - a lower bound on the rank diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 9528a30475d..bf9d4909f5b 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -1782,7 +1782,7 @@ def simon_two_descent(self, verbose=0, lim1=5, lim3=50, limtriv=3, This function is deprecated as the functionality of Simon's script for elliptic curves over the rationals has been ported over to pari. - Use :meth:`.rank` with the keyword ``algorithm='pari;`` instead. + Use :meth:`.rank` with the keyword ``algorithm='pari'`` instead. INPUT: @@ -2102,6 +2102,9 @@ def rank(self, use_database=True, verbose=False, sage: E._EllipticCurve_rational_field__rank (0, True) + This example has Sha = Z/4 x Z/4 and the rank cannot be + determined using pari only:: + sage: E =EllipticCurve([-113^2,0]) sage: E.rank(use_database=False, verbose=False, algorithm="pari") Traceback (most recent call last): @@ -2216,6 +2219,9 @@ def rank(self, use_database=True, verbose=False, ge = sorted([self.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) ge = self.saturation(ge)[0] self._known_points = ge + # note that lower is only a conjectural + # lower bound for the rank, the only + # proven lower bound is #ge. if len(ge) == upper: verbose_verbose(f"rank {upper} unconditionally determined by pari") rank = Integer(upper) @@ -2283,7 +2289,7 @@ def gens(self, proof=None, **kwds): :meth:`~gens_certain` method to find out afterwards whether the generators were proved. - IMPLEMENTATION: Uses Cremona's mwrank C library or ellrank in pari. + IMPLEMENTATION: Uses Cremona's mwrank C++ library or ellrank in pari. EXAMPLES:: @@ -2379,7 +2385,7 @@ def _compute_gens(self, proof, Traceback (most recent call last): ... RuntimeError: generators could not be determined. So far we found []. Hint: increase pari_effort. - sage: E.gens(use_database=False, algorithm="pari",pari_effort=10) + sage: E.gens(use_database=False, algorithm="pari",pari_effort=10) # long time [(-166136231668185267540804/2825630694251145858025 : 167661624456834335404812111469782006/150201095200135518108761470235125 : 1)] """ @@ -2435,6 +2441,9 @@ def _compute_gens(self, proof, ge = sorted([self.point([QQ(x[0]),QQ(x[1])], check=True) for x in pts]) ge = self.saturation(ge)[0] self._known_points = ge + # note that lower is only a conjectural + # lower bound for the rank, the only + # proven lower bound is #ge. if len(ge) == upper: verbose_verbose(f"rank {upper} unconditionally determined by pari") rank = Integer(upper) @@ -3015,8 +3024,7 @@ def selmer_rank(self, algorithm="pari"): if algorithm=="pari": ep = self.pari_curve() lower, upper, s, pts = ep.ellrank() - T = self.torsion_subgroup().invariants() - tor = sum(x%2==0 for x in T) + tor = self.two_torsion_rank() return upper + tor + s elif algorithm=="mwrank": C = self.mwrank_curve() From c2e2fb71d30d42b351a244012687cebf38040235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 3 Jun 2023 08:35:34 +0200 Subject: [PATCH 22/56] fix pep8 E251 in categories, coding, crypto, logic --- src/sage/categories/simplicial_sets.py | 2 +- src/sage/coding/code_constructions.py | 8 ++++---- src/sage/coding/decoder.py | 2 +- src/sage/coding/encoder.py | 2 +- src/sage/coding/extended_code.py | 2 +- src/sage/coding/guruswami_sudan/gs_decoder.py | 20 +++++++++---------- src/sage/coding/information_set_decoder.py | 4 ++-- src/sage/coding/linear_code_no_metric.py | 2 +- src/sage/coding/punctured_code.py | 6 +++--- src/sage/coding/subfield_subcode.py | 2 +- src/sage/crypto/cipher.py | 2 +- src/sage/crypto/classical_cipher.py | 4 ++-- src/sage/crypto/mq/sr.py | 8 ++++---- src/sage/crypto/stream.py | 2 +- src/sage/crypto/stream_cipher.py | 8 ++++---- src/sage/logic/logicparser.py | 6 +++--- 16 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/sage/categories/simplicial_sets.py b/src/sage/categories/simplicial_sets.py index 952053b907d..245868ce900 100644 --- a/src/sage/categories/simplicial_sets.py +++ b/src/sage/categories/simplicial_sets.py @@ -500,7 +500,7 @@ def covering_map(self, character): faces_dict[cell] = grelems cover = SimplicialSet(faces_dict, base_point=cells_dict[(self.base_point(), G.one())]) cover_map_data = {c : s[0] for (s,c) in cells_dict.items()} - return SimplicialSetMorphism(data = cover_map_data, domain = cover, codomain = self) + return SimplicialSetMorphism(data=cover_map_data, domain=cover, codomain=self) def cover(self, character): r""" diff --git a/src/sage/coding/code_constructions.py b/src/sage/coding/code_constructions.py index 812d5d88df9..abe26710355 100644 --- a/src/sage/coding/code_constructions.py +++ b/src/sage/coding/code_constructions.py @@ -367,8 +367,8 @@ def DuadicCodeEvenPair(F,S1,S2): x = P2.gen() gg1 = P2([_lift2smallest_field(c)[0] for c in g1.coefficients(sparse=False)]) gg2 = P2([_lift2smallest_field(c)[0] for c in g2.coefficients(sparse=False)]) - C1 = CyclicCode(length = n, generator_pol = gg1) - C2 = CyclicCode(length = n, generator_pol = gg2) + C1 = CyclicCode(length=n, generator_pol=gg1) + C2 = CyclicCode(length=n, generator_pol=gg2) return C1,C2 def DuadicCodeOddPair(F,S1,S2): @@ -422,8 +422,8 @@ def DuadicCodeOddPair(F,S1,S2): gg2 = P2(coeffs2) gg1 = gcd(gg1, x**n - 1) gg2 = gcd(gg2, x**n - 1) - C1 = CyclicCode(length = n, generator_pol = gg1) - C2 = CyclicCode(length = n, generator_pol = gg2) + C1 = CyclicCode(length=n, generator_pol=gg1) + C2 = CyclicCode(length=n, generator_pol=gg2) return C1,C2 def ExtendedQuadraticResidueCode(n,F): diff --git a/src/sage/coding/decoder.py b/src/sage/coding/decoder.py index 8a8e6496f74..300464c7d28 100644 --- a/src/sage/coding/decoder.py +++ b/src/sage/coding/decoder.py @@ -343,7 +343,7 @@ def input_space(self): else: raise NotImplementedError("Decoder does not have an _input_space parameter") - @abstract_method(optional = True) + @abstract_method(optional=True) def decoding_radius(self, **kwargs): r""" Return the maximal number of errors that ``self`` is able to correct. diff --git a/src/sage/coding/encoder.py b/src/sage/coding/encoder.py index ba1070633fd..69dc8d46edf 100644 --- a/src/sage/coding/encoder.py +++ b/src/sage/coding/encoder.py @@ -356,7 +356,7 @@ def message_space(self): """ return self.code().base_field()**(self.code().dimension()) - @abstract_method(optional = True) + @abstract_method(optional=True) def generator_matrix(self): r""" Returns a generator matrix of the associated code of ``self``. diff --git a/src/sage/coding/extended_code.py b/src/sage/coding/extended_code.py index 6065d4c2c96..3add539a192 100644 --- a/src/sage/coding/extended_code.py +++ b/src/sage/coding/extended_code.py @@ -301,7 +301,7 @@ class ExtendedCodeOriginalCodeDecoder(Decoder): Decoder of Extension of [15, 7, 9] Reed-Solomon Code over GF(16) through Gao decoder for [15, 7, 9] Reed-Solomon Code over GF(16) """ - def __init__(self, code, original_decoder = None, **kwargs): + def __init__(self, code, original_decoder=None, **kwargs): r""" TESTS: diff --git a/src/sage/coding/guruswami_sudan/gs_decoder.py b/src/sage/coding/guruswami_sudan/gs_decoder.py index 830d49238dc..cfbef3fae0f 100644 --- a/src/sage/coding/guruswami_sudan/gs_decoder.py +++ b/src/sage/coding/guruswami_sudan/gs_decoder.py @@ -238,7 +238,7 @@ class GRSGuruswamiSudanDecoder(Decoder): ####################### static methods ############################### @staticmethod - def parameters_given_tau(tau, C = None, n_k = None): + def parameters_given_tau(tau, C=None, n_k=None): r""" Returns the smallest possible multiplicity and list size given the given parameters of the code and decoding radius. @@ -307,7 +307,7 @@ def try_l(l): return (s, l) @staticmethod - def guruswami_sudan_decoding_radius(C = None, n_k = None, l = None, s = None): + def guruswami_sudan_decoding_radius(C=None, n_k=None, l=None, s=None): r""" Returns the maximal decoding radius of the Guruswami-Sudan decoder and the parameter choices needed for this. @@ -364,7 +364,7 @@ def get_tau(s,l): return gilt(n - n/2*(s+1)/(l+1) - (k-1)/2*l/s) if l is None and s is None: tau = gilt(johnson_radius(n, n - k + 1)) - return (tau, GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k))) + return (tau, GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k=(n, k))) if l is not None and s is not None: return (get_tau(s,l), (s,l)) @@ -401,7 +401,7 @@ def find_integral_max(real_max, f): return (tau, (s,l)) @staticmethod - def _suitable_parameters_given_tau(tau, C = None, n_k = None): + def _suitable_parameters_given_tau(tau, C=None, n_k=None): r""" Return quite good multiplicity and list size parameters for the code parameters and the decoding radius. @@ -473,7 +473,7 @@ def _suitable_parameters_given_tau(tau, C = None, n_k = None): return (s, l) @staticmethod - def gs_satisfactory(tau, s, l, C = None, n_k = None): + def gs_satisfactory(tau, s, l, C=None, n_k=None): r""" Returns whether input parameters satisfy the governing equation of Guruswami-Sudan. @@ -535,7 +535,7 @@ def gs_satisfactory(tau, s, l, C = None, n_k = None): return l > 0 and s > 0 and n * s * (s+1) < (l+1) * (2*s*(n-tau) - (k-1) * l) ####################### decoder itself ############################### - def __init__(self, code, tau = None, parameters = None, interpolation_alg = None, root_finder = None): + def __init__(self, code, tau=None, parameters=None, interpolation_alg=None, root_finder=None): r""" TESTS: @@ -585,16 +585,16 @@ def __init__(self, code, tau = None, parameters = None, interpolation_alg = None raise ValueError("code has to be a generalized Reed-Solomon code") n, k = code.length(), code.dimension() if tau and parameters: - if not GRSGuruswamiSudanDecoder.gs_satisfactory(tau, parameters[0], parameters[1], C = code): + if not GRSGuruswamiSudanDecoder.gs_satisfactory(tau, parameters[0], parameters[1], C=code): raise ValueError("Impossible parameters for the Guruswami-Sudan algorithm") self._tau, self._s, self._ell = tau, parameters[0], parameters[1] elif tau: self._tau = tau - self._s, self._ell = GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) + self._s, self._ell = GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k=(n, k)) elif parameters: self._s = parameters[0] self._ell = parameters[1] - (self._tau,_) = GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(C = code, s=self._s, l=self._ell) + (self._tau,_) = GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(C=code, s=self._s, l=self._ell) else: raise ValueError("Specify either tau or parameters") if callable(interpolation_alg): @@ -834,7 +834,7 @@ def decode_to_code(self, r): raise ValueError("The provided interpolation algorithm has a wrong signature. See the documentation of `codes.decoders.GRSGuruswamiSudanDecoder.interpolation_algorithm()` for details") ## EXAMINE THE FACTORS AND CONVERT TO CODEWORDS try: - polynomials = self.rootfinding_algorithm()(Q, maxd = wy) + polynomials = self.rootfinding_algorithm()(Q, maxd=wy) except TypeError: raise ValueError("The provided root-finding algorithm has a wrong signature. See the documentation of `codes.decoders.GRSGuruswamiSudanDecoder.rootfinding_algorithm()` for details") if not polynomials: diff --git a/src/sage/coding/information_set_decoder.py b/src/sage/coding/information_set_decoder.py index fb4612fa69b..c99550aa7dd 100644 --- a/src/sage/coding/information_set_decoder.py +++ b/src/sage/coding/information_set_decoder.py @@ -115,7 +115,7 @@ class InformationSetAlgorithm(SageObject): ISD Algorithm (MinimalISD) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 4 errors """ - def __init__(self, code, decoding_interval, algorithm_name, parameters = None): + def __init__(self, code, decoding_interval, algorithm_name, parameters=None): r""" TESTS:: @@ -394,7 +394,7 @@ class LeeBrickellISDAlgorithm(InformationSetAlgorithm): sage: A = LeeBrickellISDAlgorithm(C, (2,3)); A ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding between 2 and 3 errors """ - def __init__(self, code, decoding_interval, search_size = None): + def __init__(self, code, decoding_interval, search_size=None): r""" TESTS: diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index bb70d6a74c5..5e490c42345 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -406,7 +406,7 @@ def basis(self): """ gens = self.gens() from sage.structure.sequence import Sequence - return Sequence(gens, universe=self.ambient_space(), check = False, immutable=True, cr=True) + return Sequence(gens, universe=self.ambient_space(), check=False, immutable=True, cr=True) @cached_method def parity_check_matrix(self): diff --git a/src/sage/coding/punctured_code.py b/src/sage/coding/punctured_code.py index 0c85dddbd77..6b99d843f3e 100644 --- a/src/sage/coding/punctured_code.py +++ b/src/sage/coding/punctured_code.py @@ -57,7 +57,7 @@ def _puncture(v, points): new_v = [v[i] for i in range(len(v)) if i not in points] return S(new_v) -def _insert_punctured_positions(l, punctured_points, value = None): +def _insert_punctured_positions(l, punctured_points, value=None): r""" Returns ``l`` with ``value`` inserted in the corresponding position from ``punctured_points``. @@ -485,7 +485,7 @@ class PuncturedCodeOriginalCodeDecoder(Decoder): True """ - def __init__(self, code, strategy = None, original_decoder = None, **kwargs): + def __init__(self, code, strategy=None, original_decoder=None, **kwargs): r""" TESTS: @@ -671,7 +671,7 @@ def decode_to_code(self, y): y = A(yl) return _puncture(D.decode_to_code(y), pts) - def decoding_radius(self, number_erasures = None): + def decoding_radius(self, number_erasures=None): r""" Returns maximal number of errors that ``self`` can decode. diff --git a/src/sage/coding/subfield_subcode.py b/src/sage/coding/subfield_subcode.py index b3861707d6b..9f898bfed1d 100644 --- a/src/sage/coding/subfield_subcode.py +++ b/src/sage/coding/subfield_subcode.py @@ -285,7 +285,7 @@ class SubfieldSubcodeOriginalCodeDecoder(Decoder): Decoder of Subfield subcode of [13, 5, 9] Reed-Solomon Code over GF(16) down to GF(4) through Gao decoder for [13, 5, 9] Reed-Solomon Code over GF(16) """ - def __init__(self, code, original_decoder = None, **kwargs): + def __init__(self, code, original_decoder=None, **kwargs): r""" TESTS: diff --git a/src/sage/crypto/cipher.py b/src/sage/crypto/cipher.py index 32c06571483..6d6ed6dd2b3 100644 --- a/src/sage/crypto/cipher.py +++ b/src/sage/crypto/cipher.py @@ -73,7 +73,7 @@ class PublicKeyCipher(Cipher): """ Public key cipher class """ - def __init__(self, parent, key, public = True): + def __init__(self, parent, key, public=True): """ Create a public key cipher diff --git a/src/sage/crypto/classical_cipher.py b/src/sage/crypto/classical_cipher.py index 72ea18a3117..2d5722b04df 100644 --- a/src/sage/crypto/classical_cipher.py +++ b/src/sage/crypto/classical_cipher.py @@ -503,7 +503,7 @@ def __init__(self, parent, key): raise ValueError("key (= %s) must have block length %s" % (key, n)) SymmetricKeyCipher.__init__(self, parent, key) - def __call__(self, M, mode = "ECB"): + def __call__(self, M, mode="ECB"): S = self.domain() # = plaintext_space = ciphertext_space if not isinstance(M, StringMonoidElement) and M.parent() == S: raise TypeError("Argument M (= %s) must be a string in the plaintext space." % M) @@ -555,7 +555,7 @@ def __init__(self, parent, key): """ SymmetricKeyCipher.__init__(self, parent, key) - def __call__(self, M, mode = "ECB"): + def __call__(self, M, mode="ECB"): S = self.domain() # = plaintext_space = ciphertext_space if not isinstance(M, StringMonoidElement) and M.parent() == S: raise TypeError("Argument M (= %s) must be a string in the plaintext space." % M) diff --git a/src/sage/crypto/mq/sr.py b/src/sage/crypto/mq/sr.py index 14385e96878..c826ccd3ba0 100644 --- a/src/sage/crypto/mq/sr.py +++ b/src/sage/crypto/mq/sr.py @@ -1091,7 +1091,7 @@ def random_vector(self, *args, **kwds): """ return self.vector(self.random_state_array(*args, **kwds)) - def random_element(self, elem_type = "vector", *args, **kwds): + def random_element(self, elem_type="vector", *args, **kwds): """ Return a random element for self. Other arguments and keywords are passed to random_* methods. @@ -1569,7 +1569,7 @@ def varstr(self, name, nr, rc, e): format_string = self.varformatstr(name, self.n, self.r*self.c, self.e) return format_string % (nr, rc, e) - def varstrs(self, name, nr, rc = None, e = None): + def varstrs(self, name, nr, rc=None, e=None): """ Return a list of strings representing variables in ``self``. @@ -2284,7 +2284,7 @@ def shift_rows_matrix(self): return shift_rows - def lin_matrix(self, length = None): + def lin_matrix(self, length=None): """ Return the ``Lin`` matrix. @@ -3051,7 +3051,7 @@ def inversion_polynomials_single_sbox(self, x=None, w=None, biaffine_only=None, return l - def _inversion_polynomials_single_sbox(self, x= None, w=None, biaffine_only=None, correct_only=None): + def _inversion_polynomials_single_sbox(self, x=None, w=None, biaffine_only=None, correct_only=None): """ Generate inversion polynomials of a single S-box. diff --git a/src/sage/crypto/stream.py b/src/sage/crypto/stream.py index 8526aca4c44..71d8ffb9a21 100644 --- a/src/sage/crypto/stream.py +++ b/src/sage/crypto/stream.py @@ -28,7 +28,7 @@ class LFSRCryptosystem(SymmetricKeyCryptosystem): """ Linear feedback shift register cryptosystem class """ - def __init__(self, field = None): + def __init__(self, field=None): """ Create a linear feedback shift cryptosystem. diff --git a/src/sage/crypto/stream_cipher.py b/src/sage/crypto/stream_cipher.py index 07a9bf08251..198e93d9216 100644 --- a/src/sage/crypto/stream_cipher.py +++ b/src/sage/crypto/stream_cipher.py @@ -61,9 +61,9 @@ def __init__(self, parent, poly, IS): sage: E == loads(dumps(E)) True """ - SymmetricKeyCipher.__init__(self, parent, key = (poly, IS)) + SymmetricKeyCipher.__init__(self, parent, key=(poly, IS)) - def __call__(self, M, mode = "ECB"): + def __call__(self, M, mode="ECB"): r""" Generate key stream from the binary string ``M``. @@ -179,7 +179,7 @@ def __init__(self, parent, e1, e2): raise TypeError("Argument e1 (= %s) must be a LFSR cipher." % e1) if not isinstance(e2, LFSRCipher): raise TypeError("Argument e2 (= %s) must be a LFSR cipher." % e2) - SymmetricKeyCipher.__init__(self, parent, key = (e1, e2)) + SymmetricKeyCipher.__init__(self, parent, key=(e1, e2)) def keystream_cipher(self): """ @@ -221,7 +221,7 @@ def decimating_cipher(self): """ return self.key()[1] - def __call__(self, M, mode = "ECB"): + def __call__(self, M, mode="ECB"): r""" INPUT: diff --git a/src/sage/logic/logicparser.py b/src/sage/logic/logicparser.py index b854f416127..7c234f2ff7e 100644 --- a/src/sage/logic/logicparser.py +++ b/src/sage/logic/logicparser.py @@ -158,7 +158,7 @@ def polish_parse(s): raise SyntaxError("malformed statement") toks, vars_order = tokenize(s) - tree = tree_parse(toks, polish = True) + tree = tree_parse(toks, polish=True) # special case where the formula s is a single variable if isinstance(tree, str): return vars_order @@ -568,7 +568,7 @@ def tree_parse(toks, polish=False): while tok != '(': tok = stack.pop() lrtoks.insert(0, tok) - branch = parse_ltor(lrtoks[1:-1], polish = polish) + branch = parse_ltor(lrtoks[1:-1], polish=polish) stack.append(branch) return stack[0] @@ -643,7 +643,7 @@ def parse_ltor(toks, n=0, polish=False): toks[j - 1] = args del toks[j] j -= 1 - return parse_ltor(toks, n = n, polish = polish) + return parse_ltor(toks, n=n, polish=polish) else: args = [toks[i - 1], toks[i], toks[i + 1]] toks[i - 1] = [args[1], args[0], args[2]] From bf083fb20614df1f3d3ccb5ceb68a52581f67845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 3 Jun 2023 08:47:57 +0200 Subject: [PATCH 23/56] fix all pep8 E251 in combinat --- .../cluster_algebra_quiver/mutation_type.py | 4 +- .../combinat/crystals/affine_factorization.py | 6 +-- src/sage/combinat/crystals/alcove_path.py | 6 +-- src/sage/combinat/crystals/fast_crystals.py | 4 +- .../fully_commutative_stable_grothendieck.py | 4 +- .../crystals/highest_weight_crystals.py | 4 +- .../combinat/crystals/kirillov_reshetikhin.py | 10 ++--- src/sage/combinat/crystals/littelmann_path.py | 8 ++-- src/sage/combinat/crystals/tensor_product.py | 6 +-- src/sage/combinat/designs/bibd.py | 2 +- src/sage/combinat/designs/database.py | 16 +++---- .../designs/group_divisible_designs.py | 24 +++++----- .../combinat/designs/incidence_structures.py | 4 +- .../combinat/designs/orthogonal_arrays.py | 4 +- src/sage/combinat/designs/resolvable_bibd.py | 44 +++++++++---------- .../designs/steiner_quadruple_systems.py | 20 ++++----- src/sage/combinat/fully_packed_loop.py | 12 ++--- src/sage/combinat/growth.py | 2 +- src/sage/combinat/integer_vector.py | 2 +- src/sage/combinat/integer_vector_weighted.py | 2 +- .../combinat/integer_vectors_mod_permgroup.py | 6 +-- src/sage/combinat/k_tableau.py | 38 ++++++++-------- src/sage/combinat/ncsf_qsym/combinatorics.py | 2 +- .../combinat/ncsf_qsym/generic_basis_code.py | 4 +- src/sage/combinat/ncsf_qsym/ncsf.py | 42 +++++++++--------- src/sage/combinat/ncsf_qsym/qsym.py | 14 +++--- src/sage/combinat/ncsym/ncsym.py | 2 +- src/sage/combinat/partition.py | 4 +- src/sage/combinat/permutation.py | 14 +++--- src/sage/combinat/root_system/cartan_type.py | 14 +++--- .../root_system/extended_affine_weyl_group.py | 12 ++--- .../combinat/root_system/fundamental_group.py | 2 +- .../hecke_algebra_representation.py | 4 +- .../combinat/root_system/pieri_factors.py | 4 +- src/sage/combinat/root_system/plot.py | 6 +-- .../root_system/reflection_group_real.py | 6 +-- .../root_lattice_realization_algebras.py | 4 +- .../root_system/root_lattice_realizations.py | 30 ++++++------- src/sage/combinat/root_system/root_space.py | 10 ++--- src/sage/combinat/root_system/root_system.py | 16 +++---- src/sage/combinat/root_system/type_Q.py | 2 +- src/sage/combinat/root_system/type_affine.py | 6 +-- src/sage/combinat/root_system/type_dual.py | 2 +- src/sage/combinat/root_system/type_relabel.py | 2 +- .../weight_lattice_realizations.py | 6 +-- src/sage/combinat/root_system/weight_space.py | 10 ++--- src/sage/combinat/sidon_sets.py | 2 +- src/sage/combinat/skew_partition.py | 4 +- src/sage/combinat/subsets_pairwise.py | 2 +- src/sage/combinat/vector_partition.py | 4 +- src/sage/combinat/words/word_generators.py | 2 +- 51 files changed, 230 insertions(+), 230 deletions(-) diff --git a/src/sage/combinat/cluster_algebra_quiver/mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/mutation_type.py index da766a9c108..ba4759f56ae 100644 --- a/src/sage/combinat/cluster_algebra_quiver/mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/mutation_type.py @@ -284,7 +284,7 @@ def _check_special_BC_cases(dg, n, check_letter_list, check_twist_list, return 'unknown' # divides into cases depending on whether or not a list 'conn_vert_list' of connecting vertices is given. if conn_vert_list: - mut_type = _connected_mutation_type_AAtildeD( dg, ret_conn_vert = True ) + mut_type = _connected_mutation_type_AAtildeD( dg, ret_conn_vert=True ) # when 'conn_vert_list' is given, the output of _connected_mutation_type_AAtildeD is # either 'unknown' or a pair (mut_type, conn_verts). Then, it is tested if the vertices can be glued together as desired. if not mut_type == 'unknown': @@ -292,7 +292,7 @@ def _check_special_BC_cases(dg, n, check_letter_list, check_twist_list, else: # when conn_vert_list == False, the output of _connected_mutation_type _AAtildeD is simply 'unknown' or the mutation type. # no 'connecting vertices' need to be computed. - mut_type = _connected_mutation_type_AAtildeD( dg, ret_conn_vert = False ) + mut_type = _connected_mutation_type_AAtildeD( dg, ret_conn_vert=False ) conn_verts = [] # when the mutation type is recognized, program now tries more specifically to figure out 'letter' and 'twist' if not mut_type == 'unknown': diff --git a/src/sage/combinat/crystals/affine_factorization.py b/src/sage/combinat/crystals/affine_factorization.py index 9528a3a1f87..eca08c2f3bd 100644 --- a/src/sage/combinat/crystals/affine_factorization.py +++ b/src/sage/combinat/crystals/affine_factorization.py @@ -95,7 +95,7 @@ class AffineFactorizationCrystal(UniqueRepresentation, Parent): ValueError: x cannot be in reduced word of s0*s3*s2 """ @staticmethod - def __classcall_private__(cls, w, n, x = None, k = None): + def __classcall_private__(cls, w, n, x=None, k=None): r""" Classcall to mend the input. @@ -120,7 +120,7 @@ def __classcall_private__(cls, w, n, x = None, k = None): w = w0*(w1.inverse()) return super().__classcall__(cls, w, n, x) - def __init__(self, w, n, x = None): + def __init__(self, w, n, x=None): r""" EXAMPLES:: @@ -146,7 +146,7 @@ def __init__(self, w, n, x = None): sage: B = crystals.AffineFactorization(w,3) sage: TestSuite(B).run() # long time """ - Parent.__init__(self, category = ClassicalCrystals()) + Parent.__init__(self, category=ClassicalCrystals()) self.n = n self.k = w.parent().n-1 self.w = w diff --git a/src/sage/combinat/crystals/alcove_path.py b/src/sage/combinat/crystals/alcove_path.py index 75badb3bde2..ef1ad7a9c75 100644 --- a/src/sage/combinat/crystals/alcove_path.py +++ b/src/sage/combinat/crystals/alcove_path.py @@ -1426,7 +1426,7 @@ class RootsWithHeight(UniqueRepresentation, Parent): """ @staticmethod - def __classcall_private__(cls, starting_weight, cartan_type = None): + def __classcall_private__(cls, starting_weight, cartan_type=None): """ Classcall to mend the input. @@ -1472,7 +1472,7 @@ def __init__(self, weight): sage: R = RootsWithHeight(['A',2],[3,2]) sage: TestSuite(R).run() """ - Parent.__init__(self, category = Sets() ) + Parent.__init__(self, category=Sets() ) cartan_type = weight.parent().cartan_type() self._cartan_type = cartan_type @@ -1959,7 +1959,7 @@ def _test_against_tableaux(R, N, k, clss=CrystalOfAlcovePaths): shapes = Partitions(k).list() for shape in shapes: print("** Shape ", shape) - T = CrystalOfTableaux(R, shape = shape) + T = CrystalOfTableaux(R, shape=shape) ct = len(T.list()) print(" T has ", ct, " nodes.") #T.digraph().show(edge_labels=True) diff --git a/src/sage/combinat/crystals/fast_crystals.py b/src/sage/combinat/crystals/fast_crystals.py index 874f278ee93..d12812f8bce 100644 --- a/src/sage/combinat/crystals/fast_crystals.py +++ b/src/sage/combinat/crystals/fast_crystals.py @@ -100,7 +100,7 @@ class FastCrystal(UniqueRepresentation, Parent): [2, 1, 0]] """ @staticmethod - def __classcall__(cls, cartan_type, shape, format = "string"): + def __classcall__(cls, cartan_type, shape, format="string"): """ Normalize the input arguments to ensure unique representation @@ -126,7 +126,7 @@ def __init__(self, ct, shape, format): The fast crystal for A2 with shape [4,1] sage: TestSuite(C).run() """ - Parent.__init__(self, category = ClassicalCrystals()) + Parent.__init__(self, category=ClassicalCrystals()) # super().__init__(category = FiniteEnumeratedSets()) self._cartan_type = ct if ct[1] != 2: diff --git a/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py b/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py index 5861e84493c..caa2c52fdbc 100644 --- a/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py +++ b/src/sage/combinat/crystals/fully_commutative_stable_grothendieck.py @@ -390,7 +390,7 @@ def __init__(self, w, factors, excess): sage: F = DecreasingHeckeFactorizations(w, 3, 1) sage: TestSuite(F).run() """ - Parent.__init__(self, category = FiniteEnumeratedSets()) + Parent.__init__(self, category=FiniteEnumeratedSets()) self.w = tuple(w.reduced_word()) self.factors = factors self.H = w.parent() @@ -566,7 +566,7 @@ def __init__(self, w, factors, excess): if p.has_pattern([3,2,1]): raise ValueError("w should be fully commutative") - Parent.__init__(self, category = ClassicalCrystals()) + Parent.__init__(self, category=ClassicalCrystals()) self.w = tuple(word) self.factors = factors self.H = w.parent() diff --git a/src/sage/combinat/crystals/highest_weight_crystals.py b/src/sage/combinat/crystals/highest_weight_crystals.py index 35cac6fa5eb..1b1d7f315e8 100644 --- a/src/sage/combinat/crystals/highest_weight_crystals.py +++ b/src/sage/combinat/crystals/highest_weight_crystals.py @@ -288,7 +288,7 @@ def __init__(self, dominant_weight): self._highest_weight = dominant_weight assert dominant_weight.is_dominant() self.rename() - Parent.__init__(self, category = ClassicalCrystals()) + Parent.__init__(self, category=ClassicalCrystals()) self.module_generators = [self.module_generator()] def _repr_(self): @@ -377,7 +377,7 @@ def __init__(self, dominant_weight): 2430 """ B1 = CrystalOfLetters(['E',6]) - B6 = CrystalOfLetters(['E',6], dual = True) + B6 = CrystalOfLetters(['E',6], dual=True) self.column_crystal = {1 : B1, 6 : B6, 4 : TensorProductOfCrystals(B1,B1,B1,generators=[[B1([-3,4]),B1([-1,3]),B1([1])]]), 3 : TensorProductOfCrystals(B1,B1,generators=[[B1([-1,3]),B1([1])]]), diff --git a/src/sage/combinat/crystals/kirillov_reshetikhin.py b/src/sage/combinat/crystals/kirillov_reshetikhin.py index ee7175e8a03..5f79d8e1898 100644 --- a/src/sage/combinat/crystals/kirillov_reshetikhin.py +++ b/src/sage/combinat/crystals/kirillov_reshetikhin.py @@ -1640,7 +1640,7 @@ def classical_decomposition(self): The crystal of tableaux of type ['B', 2] and shape(s) [[], [2], [2, 2]] """ return CrystalOfTableaux(['B', self.cartan_type().rank()-1], - shapes = horizontal_dominoes_removed(self.r(),self.s())) + shapes=horizontal_dominoes_removed(self.r(),self.s())) def ambient_crystal(self): r""" @@ -1920,7 +1920,7 @@ def classical_decomposition(self): The crystal of tableaux of type ['B', 3] and shape(s) [[], [1], [2], [1, 1], [3], [2, 1], [3, 1], [2, 2], [3, 2], [3, 3]] """ return CrystalOfTableaux(self.cartan_type().classical(), - shapes = partitions_in_box(self.r(),self.s())) + shapes=partitions_in_box(self.r(),self.s())) def ambient_crystal(self): r""" @@ -2443,7 +2443,7 @@ def classical_decomposition(self): sage: K.classical_decomposition() The crystal of tableaux of type ['C', 3] and shape(s) [[2, 2, 2]] """ - return CrystalOfTableaux(self.cartan_type().classical(), shape = [self.s()]*self.r() ) + return CrystalOfTableaux(self.cartan_type().classical(), shape=[self.s()]*self.r() ) def from_highest_weight_vector_to_pm_diagram(self, b): r""" @@ -2678,7 +2678,7 @@ def classical_decomposition(self): s = s // 2 else: s = s / 2 - return CrystalOfTableaux(self.cartan_type().classical(), shape = [s]*self.r() ) + return CrystalOfTableaux(self.cartan_type().classical(), shape=[s]*self.r() ) def from_highest_weight_vector_to_pm_diagram(self, b): r""" @@ -3733,7 +3733,7 @@ class PMDiagram(CombinatorialObject): True """ - def __init__(self, pm_diagram, from_shapes = None): + def __init__(self, pm_diagram, from_shapes=None): r""" Initialize ``self``. diff --git a/src/sage/combinat/crystals/littelmann_path.py b/src/sage/combinat/crystals/littelmann_path.py index 7bb0a67ed08..1af0fed2dcb 100644 --- a/src/sage/combinat/crystals/littelmann_path.py +++ b/src/sage/combinat/crystals/littelmann_path.py @@ -121,7 +121,7 @@ class CrystalOfLSPaths(UniqueRepresentation, Parent): """ @staticmethod - def __classcall_private__(cls, starting_weight, cartan_type = None, starting_weight_parent = None): + def __classcall_private__(cls, starting_weight, cartan_type=None, starting_weight_parent=None): """ Classcall to mend the input. @@ -150,7 +150,7 @@ def __classcall_private__(cls, starting_weight, cartan_type = None, starting_wei extended = cartan_type.is_affine() R = RootSystem(cartan_type) - P = R.weight_space(extended = extended) + P = R.weight_space(extended=extended) Lambda = P.basis() offset = R.index_set()[Integer(0)] starting_weight = P.sum(starting_weight[j-offset]*Lambda[j] for j in R.index_set()) @@ -162,7 +162,7 @@ def __classcall_private__(cls, starting_weight, cartan_type = None, starting_wei if starting_weight.parent() != starting_weight_parent: raise ValueError("The passed parent is not equal to parent of the inputted weight!") - return super().__classcall__(cls, starting_weight, starting_weight_parent = starting_weight_parent) + return super().__classcall__(cls, starting_weight, starting_weight_parent=starting_weight_parent) def __init__(self, starting_weight, starting_weight_parent): """ @@ -808,7 +808,7 @@ def weight(x): w = x.weight() return P0.sum(int(c)*P0.basis()[i] for i,c in w if i in P0.index_set()) if group_components: - G = self.digraph(index_set = self.cartan_type().classical().index_set()) + G = self.digraph(index_set=self.cartan_type().classical().index_set()) C = G.connected_components() return sum(q**(c[0].energy_function())*B.sum(B(weight(b)) for b in c) for c in C) return B.sum(q**(b.energy_function())*B(weight(b)) for b in self) diff --git a/src/sage/combinat/crystals/tensor_product.py b/src/sage/combinat/crystals/tensor_product.py index fe90ccc0d9d..0318f6528ae 100644 --- a/src/sage/combinat/crystals/tensor_product.py +++ b/src/sage/combinat/crystals/tensor_product.py @@ -493,7 +493,7 @@ def __init__(self, crystals, generators, cartan_type): assert isinstance(crystals, tuple) assert isinstance(generators, tuple) category = Category.meet([crystal.category() for crystal in crystals]) - Parent.__init__(self, category = category) + Parent.__init__(self, category=category) self.crystals = crystals self._cartan_type = cartan_type self.module_generators = tuple([self(*x) for x in generators]) @@ -891,7 +891,7 @@ class CrystalOfTableaux(CrystalOfWords): """ @staticmethod - def __classcall_private__(cls, cartan_type, shapes = None, shape = None): + def __classcall_private__(cls, cartan_type, shapes=None, shape=None): """ Normalizes the input arguments to ensure unique representation, and to delegate the construction of spin tableaux. @@ -991,7 +991,7 @@ def __init__(self, cartan_type, shapes): sage: TestSuite(T).run() """ # super().__init__(category = FiniteEnumeratedSets()) - Parent.__init__(self, category = ClassicalCrystals()) + Parent.__init__(self, category=ClassicalCrystals()) self.letters = CrystalOfLetters(cartan_type) self.shapes = shapes self.module_generators = tuple(self.module_generator(la) for la in shapes) diff --git a/src/sage/combinat/designs/bibd.py b/src/sage/combinat/designs/bibd.py index 2265e113040..59d9ad6bad3 100644 --- a/src/sage/combinat/designs/bibd.py +++ b/src/sage/combinat/designs/bibd.py @@ -1036,7 +1036,7 @@ def _PBD_4_5_8_9_12_closure(B): BB = [] for X in B: if len(X) not in [4,5,8,9,12]: - PBD = PBD_4_5_8_9_12(len(X), check = False) + PBD = PBD_4_5_8_9_12(len(X), check=False) X = [[X[i] for i in XX] for XX in PBD] BB.extend(X) else: diff --git a/src/sage/combinat/designs/database.py b/src/sage/combinat/designs/database.py index 57060962e69..53fd144746f 100644 --- a/src/sage/combinat/designs/database.py +++ b/src/sage/combinat/designs/database.py @@ -5008,13 +5008,13 @@ def BIBD_56_11_2(): for k in sorted(EDS)) __doc__ = __doc__.format( - LIST_OF_OA_CONSTRUCTIONS = LIST_OF_OA_CONSTRUCTIONS, - LIST_OF_MOLS_CONSTRUCTIONS = LIST_OF_MOLS_CONSTRUCTIONS, - LIST_OF_VMT_VECTORS = LIST_OF_VMT_VECTORS, - LIST_OF_BIBD = LIST_OF_BIBD, - LIST_OF_DF = LIST_OF_DF, - LIST_OF_DM = LIST_OF_DM, - LIST_OF_QDM = LIST_OF_QDM, - LIST_OF_EDS = LIST_OF_EDS) + LIST_OF_OA_CONSTRUCTIONS=LIST_OF_OA_CONSTRUCTIONS, + LIST_OF_MOLS_CONSTRUCTIONS=LIST_OF_MOLS_CONSTRUCTIONS, + LIST_OF_VMT_VECTORS=LIST_OF_VMT_VECTORS, + LIST_OF_BIBD=LIST_OF_BIBD, + LIST_OF_DF=LIST_OF_DF, + LIST_OF_DM=LIST_OF_DM, + LIST_OF_QDM=LIST_OF_QDM, + LIST_OF_EDS=LIST_OF_EDS) del LIST_OF_OA_CONSTRUCTIONS, LIST_OF_MOLS_CONSTRUCTIONS, LIST_OF_VMT_VECTORS,LIST_OF_DF, LIST_OF_DM, LIST_OF_QDM, LIST_OF_EDS, LIST_OF_BIBD del PolynomialRing, ZZ, a, diff --git a/src/sage/combinat/designs/group_divisible_designs.py b/src/sage/combinat/designs/group_divisible_designs.py index 74425c5516f..738cec0222c 100644 --- a/src/sage/combinat/designs/group_divisible_designs.py +++ b/src/sage/combinat/designs/group_divisible_designs.py @@ -122,12 +122,12 @@ def group_divisible_design(v,K,G,existence=False,check=False): if blocks: return GroupDivisibleDesign(v, - groups = groups, - blocks = blocks, - G = G, - K = K, - check = check, - copy = True) + groups=groups, + blocks=blocks, + G=G, + K=K, + check=check, + copy=True) if existence: return Unknown @@ -193,12 +193,12 @@ def GDD_4_2(q,existence=False,check=True): for g in G for j in range(2)] return GroupDivisibleDesign(2*q, - groups = [[i,i+1] for i in range(0,2*q,2)], - blocks = sum(classes,[]), - K = [4], - G = [2], - check = check, - copy = False) + groups=[[i,i+1] for i in range(0,2*q,2)], + blocks=sum(classes,[]), + K=[4], + G=[2], + check=check, + copy=False) class GroupDivisibleDesign(IncidenceStructure): r""" diff --git a/src/sage/combinat/designs/incidence_structures.py b/src/sage/combinat/designs/incidence_structures.py index 1aa6c34d733..c1b0f8c85ec 100644 --- a/src/sage/combinat/designs/incidence_structures.py +++ b/src/sage/combinat/designs/incidence_structures.py @@ -2172,7 +2172,7 @@ def _spring_layout(self): for x in s: g.add_edge((0, s), (1, x)) - _ = g.plot(iterations = 50000,save_pos=True) + _ = g.plot(iterations=50000,save_pos=True) # The values are rounded as TikZ does not like accuracy. return {k[1]: (round(x, 3), round(y, 3)) @@ -2257,7 +2257,7 @@ def _latex_(self): # "center", i.e. the vertex representing the set s cx, cy = pos[Set(s)] s = [pos[_] for _ in s] - s = sorted(s, key = lambda x_y: arctan2(x_y[0] - cx, x_y[1] - cy)) + s = sorted(s, key=lambda x_y: arctan2(x_y[0] - cx, x_y[1] - cy)) for x in s: tex += str(x)+" " diff --git a/src/sage/combinat/designs/orthogonal_arrays.py b/src/sage/combinat/designs/orthogonal_arrays.py index 2fb4d7ecde8..094a8118245 100644 --- a/src/sage/combinat/designs/orthogonal_arrays.py +++ b/src/sage/combinat/designs/orthogonal_arrays.py @@ -360,7 +360,7 @@ def transversal_design(k, n, resolvable=False, check=True, existence=False): return False raise EmptySetError("There exists no TD({},{})!".format(k,n)) - OA = orthogonal_array(k,n, check = False) + OA = orthogonal_array(k,n, check=False) TD = [[i*n+c for i,c in enumerate(l)] for l in OA] else: @@ -1843,7 +1843,7 @@ def OA_from_Vmt(m,t,V): sage: _ = designs.orthogonal_arrays.build(6,46) # indirect doctest """ Fq, M = QDM_from_Vmt(m,t,V) - return OA_from_quasi_difference_matrix(M,Fq,add_col = False) + return OA_from_quasi_difference_matrix(M,Fq,add_col=False) def QDM_from_Vmt(m,t,V): diff --git a/src/sage/combinat/designs/resolvable_bibd.py b/src/sage/combinat/designs/resolvable_bibd.py index e9b90579bc2..623b10be3d2 100644 --- a/src/sage/combinat/designs/resolvable_bibd.py +++ b/src/sage/combinat/designs/resolvable_bibd.py @@ -125,7 +125,7 @@ def resolvable_balanced_incomplete_block_design(v,k,existence=False): B = BalancedIncompleteBlockDesign(v, sum(classes,[]), - k = k, + k=k, check=True, copy=False) B._classes = classes @@ -355,7 +355,7 @@ def kirkman_triple_system(v,existence=False): classs.append([2*i,2*i+1,v-1]) KTS = BalancedIncompleteBlockDesign(v, - blocks = [tr for cl in classes for tr in cl], + blocks=[tr for cl in classes for tr in cl], k=3, lambd=1, check=True, @@ -428,7 +428,7 @@ def v_4_1_rbibd(v,existence=False): for g in G] BIBD = BalancedIncompleteBlockDesign(v, - blocks = sum(classes,[]), + blocks=sum(classes,[]), k=4, check=True, copy=False) @@ -603,8 +603,8 @@ def PBD_4_7(v,check=True, existence=False): S_4_5_7 = [X.intersection(S) for S in AF] S_4_5_7 = [S for S in S_4_5_7 if len(S)>1] S_4_5_7 = PairwiseBalancedDesign(X, - blocks = S_4_5_7, - K = [4,5,7], + blocks=S_4_5_7, + K=[4,5,7], check=False) S_4_5_7.relabel() return PBD_4_7_from_Y(S_4_5_7,check=check) @@ -626,11 +626,11 @@ def PBD_4_7(v,check=True, existence=False): groups = [[x] for x in range(40)] groups.append(list(range(40,40+points_to_add))) GDD = GroupDivisibleDesign(40+points_to_add, - groups = groups, - blocks = GDD, - K = [2,4,5,7], - check = False, - copy = False) + groups=groups, + blocks=GDD, + K=[2,4,5,7], + check=False, + copy=False) return PBD_4_7_from_Y(GDD,check=check) @@ -669,18 +669,18 @@ def PBD_4_7(v,check=True, existence=False): domain = set(range(vv)) GDD = transversal_design(5,g) GDD = GroupDivisibleDesign(vv, - groups = [[x for x in gr if x in domain] for gr in GDD.groups()], - blocks = [[x for x in B if x in domain] for B in GDD], - G = set([g,u]), - K = [4,5], + groups=[[x for x in gr if x in domain] for gr in GDD.groups()], + blocks=[[x for x in B if x in domain] for B in GDD], + G=set([g,u]), + K=[4,5], check=False) return PBD_4_7_from_Y(GDD,check=check) return PairwiseBalancedDesign(v, - blocks = blocks, - K = [4,7], - check = check, - copy = False) + blocks=blocks, + K=[4,7], + check=check, + copy=False) def PBD_4_7_from_Y(gdd,check=True): r""" @@ -771,7 +771,7 @@ def PBD_4_7_from_Y(gdd,check=True): for x in B]) return PairwiseBalancedDesign(3*gdd.num_points()+1, - blocks = PBD, - K = [4,7], - check = check, - copy = False) + blocks=PBD, + K=[4,7], + check=check, + copy=False) diff --git a/src/sage/combinat/designs/steiner_quadruple_systems.py b/src/sage/combinat/designs/steiner_quadruple_systems.py index 0f21f3138bd..8a7ede7af6d 100644 --- a/src/sage/combinat/designs/steiner_quadruple_systems.py +++ b/src/sage/combinat/designs/steiner_quadruple_systems.py @@ -677,7 +677,7 @@ def barP_system(m): return pairs @cached_function -def steiner_quadruple_system(n, check = False): +def steiner_quadruple_system(n, check=False): r""" Return a Steiner Quadruple System on `n` points. @@ -712,29 +712,29 @@ def steiner_quadruple_system(n, check = False): if not ((n%6) in [2, 4]): raise ValueError("n mod 6 must be equal to 2 or 4") elif n == 4: - sqs = IncidenceStructure(4, [[0,1,2,3]], copy = False, check = False) + sqs = IncidenceStructure(4, [[0,1,2,3]], copy=False, check=False) elif n == 14: - sqs = IncidenceStructure(14, _SQS14(), copy = False, check = False) + sqs = IncidenceStructure(14, _SQS14(), copy=False, check=False) elif n == 38: - sqs = IncidenceStructure(38, _SQS38(), copy = False, check = False) + sqs = IncidenceStructure(38, _SQS38(), copy=False, check=False) elif n%12 in [4, 8]: nn = n // 2 - sqs = two_n(steiner_quadruple_system(nn, check = False)) + sqs = two_n(steiner_quadruple_system(nn, check=False)) elif n%18 in [4,10]: nn = (n+2) // 3 - sqs = three_n_minus_two(steiner_quadruple_system(nn, check = False)) + sqs = three_n_minus_two(steiner_quadruple_system(nn, check=False)) elif (n%36) == 34: nn = (n+8) // 3 - sqs = three_n_minus_eight(steiner_quadruple_system(nn, check = False)) + sqs = three_n_minus_eight(steiner_quadruple_system(nn, check=False)) elif (n%36) == 26: nn = (n+4) // 3 - sqs = three_n_minus_four(steiner_quadruple_system(nn, check = False)) + sqs = three_n_minus_four(steiner_quadruple_system(nn, check=False)) elif n%24 in [2, 10]: nn = (n+6) // 4 - sqs = four_n_minus_six(steiner_quadruple_system(nn, check = False)) + sqs = four_n_minus_six(steiner_quadruple_system(nn, check=False)) elif n%72 in [14, 38]: nn = (n+10) // 12 - sqs = twelve_n_minus_ten(steiner_quadruple_system(nn, check = False)) + sqs = twelve_n_minus_ten(steiner_quadruple_system(nn, check=False)) else: raise ValueError("this should never happen") diff --git a/src/sage/combinat/fully_packed_loop.py b/src/sage/combinat/fully_packed_loop.py index 070275077cd..149385ca643 100644 --- a/src/sage/combinat/fully_packed_loop.py +++ b/src/sage/combinat/fully_packed_loop.py @@ -881,9 +881,9 @@ def plot(self, **options): squares = set((i,j) for i in range(n) for j in range(n)) colors = _make_color_list(2*n, - colors = link_options.pop('colors', None), - color_map = link_options.pop('color_map', None), - randomize = link_options.pop('color_randomize', False)) + colors=link_options.pop('colors', None), + color_map=link_options.pop('color_map', None), + randomize=link_options.pop('color_randomize', False)) G = Graphics() for i in range(2*n): @@ -910,9 +910,9 @@ def plot(self, **options): if loop: colors = _make_color_list(len(loops), - colors = loop_options.pop('colors', None), - color_map = loop_options.pop('color_map', None), - randomize = loop_options.pop('color_randomize', False)) + colors=loop_options.pop('colors', None), + color_map=loop_options.pop('color_map', None), + randomize=loop_options.pop('color_randomize', False)) fill = loop_options.pop('fill') diff --git a/src/sage/combinat/growth.py b/src/sage/combinat/growth.py index 763f8f7e482..8a38d0cb9ba 100644 --- a/src/sage/combinat/growth.py +++ b/src/sage/combinat/growth.py @@ -2608,7 +2608,7 @@ def forward_rule(self, y, e, t, f, x, content): # the addable cell with largest content at most e cprime = sorted([c for c in y.to_partition().addable_cells() if c[1]-c[0] <= e], - key = lambda c: -(c[1]-c[0]))[0] + key=lambda c: -(c[1]-c[0]))[0] h = cprime[1] - cprime[0] z = y.affine_symmetric_group_simple_action(h % self.k) diff --git a/src/sage/combinat/integer_vector.py b/src/sage/combinat/integer_vector.py index 9f01bfd787d..e12e6cc27cd 100644 --- a/src/sage/combinat/integer_vector.py +++ b/src/sage/combinat/integer_vector.py @@ -363,7 +363,7 @@ def gale_ryser_theorem(p1, p2, algorithm="gale", from sage.numerical.mip import MixedIntegerLinearProgram k1, k2=len(p1), len(p2) p = MixedIntegerLinearProgram(solver=solver) - b = p.new_variable(binary = True) + b = p.new_variable(binary=True) for (i,c) in enumerate(p1): p.add_constraint(p.sum([b[i,j] for j in range(k2)]) ==c) for (i,c) in enumerate(p2): diff --git a/src/sage/combinat/integer_vector_weighted.py b/src/sage/combinat/integer_vector_weighted.py index 1b110c34140..7fa72fb60fd 100644 --- a/src/sage/combinat/integer_vector_weighted.py +++ b/src/sage/combinat/integer_vector_weighted.py @@ -319,7 +319,7 @@ def __contains__(self, x): and len(x) == len(self._weights) and all(i in ZZ and i >= 0 for i in x)) - def subset(self, size = None): + def subset(self, size=None): """ EXAMPLES:: diff --git a/src/sage/combinat/integer_vectors_mod_permgroup.py b/src/sage/combinat/integer_vectors_mod_permgroup.py index 539fc59b9c0..d3ea07b7d78 100644 --- a/src/sage/combinat/integer_vectors_mod_permgroup.py +++ b/src/sage/combinat/integer_vectors_mod_permgroup.py @@ -278,7 +278,7 @@ def __init__(self, G, sgs=None): Category of infinite enumerated quotients of sets sage: TestSuite(I).run() """ - RecursivelyEnumeratedSet_forest.__init__(self, algorithm = 'breadth', category = InfiniteEnumeratedSets().Quotients()) + RecursivelyEnumeratedSet_forest.__init__(self, algorithm='breadth', category=InfiniteEnumeratedSets().Quotients()) self._permgroup = G self.n = G.degree() @@ -602,7 +602,7 @@ def __init__(self, G, d, max_part, sgs=None): sage: I = IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3,4)]]), 6, max_part=4) """ - RecursivelyEnumeratedSet_forest.__init__(self, algorithm = 'breadth', category = (FiniteEnumeratedSets(), FiniteEnumeratedSets().Quotients())) + RecursivelyEnumeratedSet_forest.__init__(self, algorithm='breadth', category=(FiniteEnumeratedSets(), FiniteEnumeratedSets().Quotients())) self._permgroup = G self.n = G.degree() self._sum = d @@ -757,7 +757,7 @@ def __iter__(self): else: SF = RecursivelyEnumeratedSet_forest((self([0]*(self.n), check=False),), lambda x : [self(y, check=False) for y in canonical_children(self._sgs, x, self._max_part)], - algorithm = 'breadth') + algorithm='breadth') if self._sum is None: return iter(SF) else: diff --git a/src/sage/combinat/k_tableau.py b/src/sage/combinat/k_tableau.py index 5fb1d56b82c..d5dd17d20b2 100644 --- a/src/sage/combinat/k_tableau.py +++ b/src/sage/combinat/k_tableau.py @@ -48,7 +48,7 @@ import copy -def WeakTableau(t, k, inner_shape = [], representation = "core"): +def WeakTableau(t, k, inner_shape=[], representation="core"): r""" This is the dispatcher method for the element class of weak `k`-tableaux. @@ -188,12 +188,12 @@ def WeakTableau(t, k, inner_shape = [], representation = "core"): elif representation == "bounded": return WeakTableau_bounded(t, k) elif representation == "factorized_permutation": - return WeakTableau_factorized_permutation(t, k, inner_shape = inner_shape) + return WeakTableau_factorized_permutation(t, k, inner_shape=inner_shape) else: raise NotImplementedError("The representation option needs to be 'core', 'bounded', or 'factorized_permutation'") -def WeakTableaux(k, shape , weight, representation = "core"): +def WeakTableaux(k, shape , weight, representation="core"): r""" This is the dispatcher method for the parent class of weak `k`-tableaux. @@ -477,7 +477,7 @@ def chi(x): else: return "["+"".join(self[i]._latex_()+',' for i in range(len(self)-1))+self[len(self)-1]._latex_()+"]" - def representation(self, representation = 'core'): + def representation(self, representation='core'): r""" Return the analogue of ``self`` in the specified representation. @@ -605,7 +605,7 @@ def size(self): else: return self._outer_shape.length() - self._inner_shape.length() - def representation(self, representation = 'core'): + def representation(self, representation='core'): r""" Return the analogue of ``self`` in the specified representation. @@ -656,7 +656,7 @@ def representation(self, representation = 'core'): if self._representation == 'bounded' and (representation in ['core', 'factorized_permutation']): outer_shape = outer_shape.to_core(self.k) inner_shape = inner_shape.to_core(self.k) - return WeakTableaux(self.k, [outer_shape, inner_shape], weight, representation = representation) + return WeakTableaux(self.k, [outer_shape, inner_shape], weight, representation=representation) #Weak Tableaux in terms of cores @@ -898,7 +898,7 @@ def to_factorized_permutation_tableau(self): """ shapes = [ Core(p,self.k+1).to_grassmannian() for p in self.intermediate_shapes() ] perms = [ shapes[i]*(shapes[i-1].inverse()) for i in range(len(shapes)-1,0,-1)] - return WeakTableau_factorized_permutation(perms, self.k, inner_shape = self.parent()._inner_shape) + return WeakTableau_factorized_permutation(perms, self.k, inner_shape=self.parent()._inner_shape) def residues_of_entries(self, v): r""" @@ -1033,7 +1033,7 @@ def list_of_standard_cells(self): out.append(standard_cells) return out - def k_charge(self, algorithm = "I"): + def k_charge(self, algorithm="I"): r""" Return the `k`-charge of ``self``. @@ -1289,7 +1289,7 @@ def __init__(self, k, shape, weight): self._shape = (self._outer_shape, self._inner_shape) self._weight = weight self._representation = 'core' - Parent.__init__(self, category = FiniteEnumeratedSets()) + Parent.__init__(self, category=FiniteEnumeratedSets()) def _repr_(self): """ @@ -1653,7 +1653,7 @@ def from_core_tableau(cls, t, k): l = l_new return cls(l, k) - def k_charge(self, algorithm = 'I'): + def k_charge(self, algorithm='I'): r""" Return the `k`-charge of ``self``. @@ -1680,7 +1680,7 @@ def k_charge(self, algorithm = 'I'): sage: t.k_charge() 12 """ - return self.to_core_tableau().k_charge(algorithm = algorithm) + return self.to_core_tableau().k_charge(algorithm=algorithm) class WeakTableaux_bounded(WeakTableaux_abstract): @@ -1755,7 +1755,7 @@ def __init__(self, k, shape, weight): self._shape = (self._outer_shape, self._inner_shape) self._weight = tuple(weight) self._representation = 'bounded' - Parent.__init__(self, category = FiniteEnumeratedSets()) + Parent.__init__(self, category=FiniteEnumeratedSets()) def _repr_(self): """ @@ -1837,7 +1837,7 @@ def straighten_input(t, k): return w_tuple @staticmethod - def __classcall_private__(cls, t, k, inner_shape = []): + def __classcall_private__(cls, t, k, inner_shape=[]): r""" Implements the shortcut ``WeakTableau_factorized_permutation(t, k)`` to ``WeakTableaux_factorized_permutation(k, shape, weight)(t)`` @@ -2085,9 +2085,9 @@ def from_core_tableau(cls, t, k): t = SkewTableau(list(t)) shapes = [ Core(p, k+1).to_grassmannian() for p in intermediate_shapes(t) ] #t.to_chain() ] perms = [ shapes[i]*(shapes[i-1].inverse()) for i in range(len(shapes)-1,0,-1)] - return cls(perms, k, inner_shape = t.inner_shape()) + return cls(perms, k, inner_shape=t.inner_shape()) - def k_charge(self, algorithm = 'I'): + def k_charge(self, algorithm='I'): r""" Return the `k`-charge of ``self``. @@ -2107,7 +2107,7 @@ def k_charge(self, algorithm = 'I'): sage: t.k_charge() 12 """ - return self.to_core_tableau().k_charge(algorithm = algorithm) + return self.to_core_tableau().k_charge(algorithm=algorithm) class WeakTableaux_factorized_permutation(WeakTableaux_abstract): @@ -2178,7 +2178,7 @@ def __init__(self, k, shape, weight): self._shape = (self._outer_shape, self._inner_shape) self._weight = weight self._representation = 'factorized_permutation' - Parent.__init__(self, category = FiniteEnumeratedSets()) + Parent.__init__(self, category=FiniteEnumeratedSets()) def _repr_(self): """ @@ -3945,7 +3945,7 @@ def __init__( self, k, shape, weight ): self._weight = (1,)*(self._outer_shape.length()-self._inner_shape.length()) else: self._weight = weight - Parent.__init__(self, category = FiniteEnumeratedSets()) + Parent.__init__(self, category=FiniteEnumeratedSets()) @staticmethod def __classcall_private__(cls, k, shape, weight=None): @@ -4591,7 +4591,7 @@ def transpositions_to_standard_strong( self, transeq, k, emptyTableau=[] ): out = copy.deepcopy(emptyTableau) for i in range(1,len(transeq)+1): out = StrongTableaux._left_action_list(out, transeq[-i], i, k) - return StrongTableau(out, k, weight = (1,)*len(transeq)) + return StrongTableau(out, k, weight=(1,)*len(transeq)) Element = StrongTableau diff --git a/src/sage/combinat/ncsf_qsym/combinatorics.py b/src/sage/combinat/ncsf_qsym/combinatorics.py index cddfdc1ef2c..cba0de3d45b 100644 --- a/src/sage/combinat/ncsf_qsym/combinatorics.py +++ b/src/sage/combinat/ncsf_qsym/combinatorics.py @@ -255,7 +255,7 @@ def number_of_fCT(content_comp, shape_comp): return 1 else: return 0 - C = Compositions(content_comp.size()-content_comp[-1], outer = list(shape_comp)) + C = Compositions(content_comp.size()-content_comp[-1], outer=list(shape_comp)) s = 0 for x in C: if len(x) >= len(shape_comp)-1: diff --git a/src/sage/combinat/ncsf_qsym/generic_basis_code.py b/src/sage/combinat/ncsf_qsym/generic_basis_code.py index 0f2b819457f..012f8bd7ce1 100644 --- a/src/sage/combinat/ncsf_qsym/generic_basis_code.py +++ b/src/sage/combinat/ncsf_qsym/generic_basis_code.py @@ -234,7 +234,7 @@ def alternating_sum_of_compositions(self, n): return (-ring.one())**(n)*self.sum_of_terms( (compo, ring((-1)**(len(compo)))) for compo in Compositions(n) ) - def alternating_sum_of_finer_compositions(self, composition, conjugate = False): + def alternating_sum_of_finer_compositions(self, composition, conjugate=False): """ Return the alternating sum of finer compositions in a basis of the non-commutative symmetric functions. @@ -996,7 +996,7 @@ class AlgebraMorphism(ModuleMorphismByLinearity): # Find a better name A class for algebra morphism defined on a free algebra from the image of the generators """ - def __init__(self, domain, on_generators, position = 0, codomain = None, category = None, anti = False): + def __init__(self, domain, on_generators, position=0, codomain=None, category=None, anti=False): """ Given a map on the multiplicative basis of a free algebra, this method returns the algebra morphism that is the linear extension of its image diff --git a/src/sage/combinat/ncsf_qsym/ncsf.py b/src/sage/combinat/ncsf_qsym/ncsf.py index a17d14b33d9..f9aafb014aa 100644 --- a/src/sage/combinat/ncsf_qsym/ncsf.py +++ b/src/sage/combinat/ncsf_qsym/ncsf.py @@ -2208,7 +2208,7 @@ def to_symmetric_function(self): h[1, 1, 1, 1] - 3*h[2, 1, 1] + 3*h[3, 1] """ codom = self.to_symmetric_function_on_generators(1).parent() - return self.algebra_morphism(self.to_symmetric_function_on_generators, codomain = codom) + return self.algebra_morphism(self.to_symmetric_function_on_generators, codomain=codom) @lazy_attribute def antipode(self): @@ -2232,7 +2232,7 @@ def antipode(self): Generic endomorphism of Non-Commutative Symmetric Functions over the Rational Field in the Complete basis """ if hasattr(self, "antipode_on_generators"): - return self.algebra_morphism(self.antipode_on_generators, codomain = self, anti = True) + return self.algebra_morphism(self.antipode_on_generators, codomain=self, anti=True) else: return NotImplemented @@ -2256,7 +2256,7 @@ def coproduct(self): """ from sage.categories.tensor import tensor if hasattr(self, "coproduct_on_generators"): - return self.algebra_morphism(self.coproduct_on_generators, codomain = tensor([self, self])) + return self.algebra_morphism(self.coproduct_on_generators, codomain=tensor([self, self])) else: return NotImplemented @@ -4521,15 +4521,15 @@ def __init__(self, NCSF): S = NCSF.complete() Psi = NCSF.Psi() to_S = self.module_morphism( - on_basis = self._to_complete_on_basis, - codomain = S, - category = category) + on_basis=self._to_complete_on_basis, + codomain=S, + category=category) to_S.register_as_coercion() from_psi = Psi.module_morphism( - on_basis = self._from_psi_on_basis, - codomain = self, - category = category) + on_basis=self._from_psi_on_basis, + codomain=self, + category=category) from_psi.register_as_coercion() def _to_complete_on_basis(self, I): @@ -4680,15 +4680,15 @@ def __init__(self, NCSF): category = self.category() S = self.realization_of().complete() to_S = self.module_morphism( - on_basis = self._to_complete_on_basis, - codomain = S, - category = category) + on_basis=self._to_complete_on_basis, + codomain=S, + category=category) to_S.register_as_coercion() from_S = S.module_morphism( - on_basis = self._from_complete_on_basis, - codomain = self, - category = category) + on_basis=self._from_complete_on_basis, + codomain=self, + category=category) from_S.register_as_coercion() def _realization_name(self): @@ -4968,15 +4968,15 @@ def __init__(self, NCSF): category = self.category() self._S = self.realization_of().complete() to_S = self.module_morphism( - on_basis = self._to_complete_on_basis, - codomain = self._S, - category = category) + on_basis=self._to_complete_on_basis, + codomain=self._S, + category=category) to_S.register_as_coercion() from_S = self._S.module_morphism( - on_basis = self._from_complete_on_basis, - codomain = self, - category = category) + on_basis=self._from_complete_on_basis, + codomain=self, + category=category) from_S.register_as_coercion() def _realization_name(self): diff --git a/src/sage/combinat/ncsf_qsym/qsym.py b/src/sage/combinat/ncsf_qsym/qsym.py index 9169e38e1d1..fe4e58277b1 100644 --- a/src/sage/combinat/ncsf_qsym/qsym.py +++ b/src/sage/combinat/ncsf_qsym/qsym.py @@ -561,7 +561,7 @@ def __init__(self, R): self._base = R # Won't be needed once CategoryObject won't override base_ring category = GradedHopfAlgebras(R).Commutative() self._category = category - Parent.__init__(self, category = category.WithRealizations()) + Parent.__init__(self, category=category.WithRealizations()) # Bases Monomial = self.Monomial() @@ -578,11 +578,11 @@ def __init__(self, R): ).register_as_coercion() #This changes dualImmaculate into Monomial dualImmaculate.module_morphism(dualImmaculate._to_Monomial_on_basis, - codomain = Monomial, category = category + codomain=Monomial, category=category ).register_as_coercion() #This changes Monomial into dualImmaculate Monomial.module_morphism(dualImmaculate._from_Monomial_on_basis, - codomain = dualImmaculate, category = category + codomain=dualImmaculate, category=category ).register_as_coercion() #This changes Quasisymmetric Schur into Monomial QS .module_morphism(QS._to_monomial_on_basis, @@ -1922,7 +1922,7 @@ def lambda_of_monomial(self, I, n): QQ_result *= (-1) ** n # QQ_result is now \lambda^n(M_I) over QQ. result = self.sum_of_terms([(J, ZZ(coeff)) for (J, coeff) in QQ_result], - distinct = True) + distinct=True) return result class Element(CombinatorialFreeModule.Element): @@ -2052,7 +2052,7 @@ def on_basis(comp, i): return x[i-1]**comp[-1] * on_basis(comp[:-1], i-1) + \ on_basis(comp, i-1) return M._apply_module_morphism(self, lambda comp: on_basis(comp,n), - codomain = P) + codomain=P) def is_symmetric( self ): r""" @@ -3380,11 +3380,11 @@ def __init_extra__(self): category = self.realization_of()._category # This changes Monomial into Hazewinkel Lambda M.module_morphism(self._from_Monomial_on_basis, - codomain = self, category = category + codomain=self, category=category ).register_as_coercion() # This changes Hazewinkel Lambda into Monomial self.module_morphism(self._to_Monomial_on_basis, - codomain = M, category = category + codomain=M, category=category ).register_as_coercion() # cache for the coordinates of the elements diff --git a/src/sage/combinat/ncsym/ncsym.py b/src/sage/combinat/ncsym/ncsym.py index 551ca834b1d..64772ade2d7 100644 --- a/src/sage/combinat/ncsym/ncsym.py +++ b/src/sage/combinat/ncsym/ncsym.py @@ -297,7 +297,7 @@ def __init__(self, R): assert(R in Fields() or R in Rings()) # side effect of this statement assures MRO exists for R self._base = R # Won't be needed once CategoryObject won't override base_ring category = GradedHopfAlgebras(R) # TODO: .Cocommutative() - Parent.__init__(self, category = category.WithRealizations()) + Parent.__init__(self, category=category.WithRealizations()) def _repr_(self): r""" diff --git a/src/sage/combinat/partition.py b/src/sage/combinat/partition.py index 8e3b777c35e..6b0c3017928 100644 --- a/src/sage/combinat/partition.py +++ b/src/sage/combinat/partition.py @@ -4403,7 +4403,7 @@ def k_boundary(self, k): """ return SkewPartition([self, self.k_interior(k)]) - def add_cell(self, i, j = None): + def add_cell(self, i, j=None): r""" Return a partition corresponding to ``self`` with a cell added in row ``i``. (This does not change ``self``.) @@ -6670,7 +6670,7 @@ def cardinality(self, algorithm='flint'): raise ValueError("unknown algorithm '%s'" % algorithm) - def random_element(self, measure = 'uniform'): + def random_element(self, measure='uniform'): """ Return a random partitions of `n` for the specified measure. diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index 9593055e9ed..cacdf386e47 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -1738,7 +1738,7 @@ def show(self, representation="cycles", orientation="landscape", **args): if representation == "cycles": d.show(**args) else: - d.show(layout = "circular", **args) + d.show(layout="circular", **args) elif representation == "braid": from sage.plot.line import line @@ -1759,7 +1759,7 @@ def show(self, representation="cycles", orientation="landscape", **args): L += line([r(i, 1.0), r(p[i]-1, 0)]) L += text(str(i), r(i, 1.05)) + text(str(i), r(p[i]-1, -.05)) - return L.show(axes = False, **args) + return L.show(axes=False, **args) else: raise ValueError("The value of 'representation' must be equal to "+ @@ -4808,7 +4808,7 @@ def rec(perm): return LBT(None) mn = compare(perm) k = perm.index(mn) - return LBT([rec(perm[:k]), rec(perm[k + 1:])], label = mn) + return LBT([rec(perm[:k]), rec(perm[k + 1:])], label=mn) return rec(self) @combinatorial_map(name="Increasing tree") @@ -4883,7 +4883,7 @@ def binary_search_tree(self, left_to_right=True): res = res.binary_search_insert(i) return res - @combinatorial_map(name = "Binary search tree (left to right)") + @combinatorial_map(name="Binary search tree (left to right)") def binary_search_tree_shape(self, left_to_right=True): r""" Return the shape of the binary search tree of the permutation @@ -5263,7 +5263,7 @@ def hyperoctahedral_double_coset_type(self): # Binary operations # ##################### - def shifted_concatenation(self, other, side = "right"): + def shifted_concatenation(self, other, side="right"): r""" Return the right (or left) shifted concatenation of ``self`` with a permutation ``other``. These operations are also known @@ -7787,7 +7787,7 @@ def from_reduced_word(rw, parent=None): return parent(p) -def bistochastic_as_sum_of_permutations(M, check = True): +def bistochastic_as_sum_of_permutations(M, check=True): r""" Return the positive sum of permutations corresponding to the bistochastic matrix ``M``. @@ -7887,7 +7887,7 @@ def bistochastic_as_sum_of_permutations(M, check = True): if not all(x >= 0 for x in M.list()): raise ValueError("The matrix should have nonnegative entries") - if check and not M.is_bistochastic(normalized = False): + if check and not M.is_bistochastic(normalized=False): raise ValueError("The matrix is not bistochastic") if not RR.has_coerce_map_from(M.base_ring()): diff --git a/src/sage/combinat/root_system/cartan_type.py b/src/sage/combinat/root_system/cartan_type.py index 6c89e131c9d..d8a37f350ce 100644 --- a/src/sage/combinat/root_system/cartan_type.py +++ b/src/sage/combinat/root_system/cartan_type.py @@ -1142,7 +1142,7 @@ def index_set(self): # be used for Coxeter groups etc. (experimental feature) _index_set_coloring = {1:"blue", 2:"red", 3:"green"} - @abstract_method(optional = True) + @abstract_method(optional=True) def coxeter_diagram(self): """ Return the Coxeter diagram for ``self``. @@ -1734,7 +1734,7 @@ def symmetrizer(self): from sage.matrix.constructor import matrix, diagonal_matrix m = self.cartan_matrix() n = m.nrows() - M = matrix(ZZ, n, n*n, sparse = True) + M = matrix(ZZ, n, n*n, sparse=True) for (i,j) in m.nonzero_positions(): M[i, n * i + j] = m[i,j] M[j, n * i + j] -= m[j,i] @@ -2082,7 +2082,7 @@ def basic_untwisted(self): ['D', 4] """ - def row_annihilator(self, m = None): + def row_annihilator(self, m=None): r""" Return the unique minimal non trivial annihilating linear combination of `\alpha_0, \alpha_1, \ldots, \alpha_n` with @@ -2423,7 +2423,7 @@ def other_affinization(self): class CartanType_standard(UniqueRepresentation, SageObject): # Technical methods - def _repr_(self, compact = False): + def _repr_(self, compact=False): """ TESTS:: @@ -2681,7 +2681,7 @@ class CartanType_standard_affine(CartanType_standard, CartanType_affine): A concrete class for affine simple Cartan types. """ - def __init__(self, letter, n, affine = 1): + def __init__(self, letter, n, affine=1): """ EXAMPLES:: @@ -2706,7 +2706,7 @@ def __init__(self, letter, n, affine = 1): self.n = n self.affine = affine - def _repr_(self, compact = False): + def _repr_(self, compact=False): """ TESTS:: @@ -3016,7 +3016,7 @@ def index_set(self): class SuperCartanType_standard(UniqueRepresentation, SageObject): # Technical methods - def _repr_(self, compact = False): + def _repr_(self, compact=False): """ TESTS:: diff --git a/src/sage/combinat/root_system/extended_affine_weyl_group.py b/src/sage/combinat/root_system/extended_affine_weyl_group.py index 87fe3399169..1fcd553da5a 100644 --- a/src/sage/combinat/root_system/extended_affine_weyl_group.py +++ b/src/sage/combinat/root_system/extended_affine_weyl_group.py @@ -574,7 +574,7 @@ def __init__(self, cartan_type, general_linear, **print_options): self._extended = True - Parent.__init__(self, category = Groups().WithRealizations().Infinite()) + Parent.__init__(self, category=Groups().WithRealizations().Infinite()) # create the realizations (they are cached) PW0 = self.PW0() @@ -1974,7 +1974,7 @@ def __init__(self, E): def twist(w,l): return E.exp_lattice()(w.action(l.value)) - GroupSemidirectProduct.__init__(self, E.exp_lattice(), E.classical_weyl(), twist = twist, act_to_right=False, prefix0=E._prefixt, print_tuple = E._print_tuple, category=E.Realizations()) + GroupSemidirectProduct.__init__(self, E.exp_lattice(), E.classical_weyl(), twist=twist, act_to_right=False, prefix0=E._prefixt, print_tuple=E._print_tuple, category=E.Realizations()) self._style = "PW0" def _repr_(self): @@ -2348,7 +2348,7 @@ def __init__(self, E): def twist(g,w): return g.act_on_affine_weyl(w) - GroupSemidirectProduct.__init__(self, E.affine_weyl(), E.fundamental_group(), twist = twist, act_to_right=False, print_tuple = E._print_tuple, category=E.Realizations()) + GroupSemidirectProduct.__init__(self, E.affine_weyl(), E.fundamental_group(), twist=twist, act_to_right=False, print_tuple=E._print_tuple, category=E.Realizations()) self._style = "WF" def _repr_(self): @@ -2506,7 +2506,7 @@ def __init__(self, E): def twist(g,w): return g.act_on_affine_weyl(w) - GroupSemidirectProduct.__init__(self, E.fundamental_group(), E.affine_weyl(), twist = twist, act_to_right=True, print_tuple = E._print_tuple, category=E.Realizations()) + GroupSemidirectProduct.__init__(self, E.fundamental_group(), E.affine_weyl(), twist=twist, act_to_right=True, print_tuple=E._print_tuple, category=E.Realizations()) self._style = "FW" def _repr_(self): @@ -2678,7 +2678,7 @@ def __init__(self, E): def twist(w,l): return E.exp_dual_lattice()(w.action(l.value)) - GroupSemidirectProduct.__init__(self, E.exp_dual_lattice(), E.dual_classical_weyl(), twist = twist, act_to_right=False, prefix0=E._prefixt, print_tuple = E._print_tuple, category=E.Realizations()) + GroupSemidirectProduct.__init__(self, E.exp_dual_lattice(), E.dual_classical_weyl(), twist=twist, act_to_right=False, prefix0=E._prefixt, print_tuple=E._print_tuple, category=E.Realizations()) self._style = "PvW0" def _repr_(self): @@ -2844,7 +2844,7 @@ def __init__(self, E): def twist(w,l): return E.exp_dual_lattice()(w.action(l.value)) - GroupSemidirectProduct.__init__(self, E.dual_classical_weyl(), E.exp_dual_lattice(), twist = twist, act_to_right=True, prefix1=E._prefixt, print_tuple = E._print_tuple, category=E.Realizations()) + GroupSemidirectProduct.__init__(self, E.dual_classical_weyl(), E.exp_dual_lattice(), twist=twist, act_to_right=True, prefix1=E._prefixt, print_tuple=E._print_tuple, category=E.Realizations()) self._style = "W0Pv" def _repr_(self): diff --git a/src/sage/combinat/root_system/fundamental_group.py b/src/sage/combinat/root_system/fundamental_group.py index 87b6e1094e0..f42acd0a44a 100644 --- a/src/sage/combinat/root_system/fundamental_group.py +++ b/src/sage/combinat/root_system/fundamental_group.py @@ -406,7 +406,7 @@ def leading_support(beta): EnumeratedSets())) else: cat = Groups().Commutative().Infinite() - Parent.__init__(self, category = cat) + Parent.__init__(self, category=cat) @cached_method def one(self): diff --git a/src/sage/combinat/root_system/hecke_algebra_representation.py b/src/sage/combinat/root_system/hecke_algebra_representation.py index 8ac99319bec..8de4bce6107 100644 --- a/src/sage/combinat/root_system/hecke_algebra_representation.py +++ b/src/sage/combinat/root_system/hecke_algebra_representation.py @@ -392,7 +392,7 @@ def Tw(self, word, signs=None, scalar=None): """ word = self.straighten_word(word) result = self._domain.module_morphism(functools.partial(self.on_basis, word=word, signs=signs, scalar=scalar), - codomain = self._domain) + codomain=self._domain) # For debugging purpose, make the parameters easily accessible: result.word = word result.signs = signs @@ -802,7 +802,7 @@ class CherednikOperatorsEigenvectors(UniqueRepresentation, SageObject): classical operators `T_1, \ldots, T_n` from `T` and `T_Y` coincide. """ - def __init__(self, T, T_Y = None, normalized = True): + def __init__(self, T, T_Y=None, normalized=True): r""" INPUT: diff --git a/src/sage/combinat/root_system/pieri_factors.py b/src/sage/combinat/root_system/pieri_factors.py index 14d78e3b3f4..e0e3053d8e3 100644 --- a/src/sage/combinat/root_system/pieri_factors.py +++ b/src/sage/combinat/root_system/pieri_factors.py @@ -175,7 +175,7 @@ def __iter__(self): """ return iter(self.elements()) - def generating_series(self, weight = None): + def generating_series(self, weight=None): r""" Return a length generating series for the elements of ``self``. @@ -755,7 +755,7 @@ def cardinality(self): if self._min_length == len(self._min_support) and self._max_length == len(self._max_support) -1: return Integer(2**(len(self._extra_support)) - 1) else: - return self.generating_series(weight = ConstantFunction(1)) + return self.generating_series(weight=ConstantFunction(1)) def generating_series(self, weight=None): r""" diff --git a/src/sage/combinat/root_system/plot.py b/src/sage/combinat/root_system/plot.py index ee23f9fe836..354ae0ca741 100644 --- a/src/sage/combinat/root_system/plot.py +++ b/src/sage/combinat/root_system/plot.py @@ -1404,7 +1404,7 @@ def cone(self, rays=[], lines=[], color="black", thickness=1, alpha=1, wireframe rays = [ ray for ray in rays if ray ] # Polyhedron does not accept yet zero rays # Build the polyhedron - p = Polyhedron(vertices=vertices, rays = rays) + p = Polyhedron(vertices=vertices, rays=rays) if as_polyhedron: return p @@ -1417,7 +1417,7 @@ def cone(self, rays=[], lines=[], color="black", thickness=1, alpha=1, wireframe q = q.translation(-center).dilation(ZZ(95)/ZZ(100)).translation(center) else: options = dict(wireframe=False, line={"thickness":thickness}) - result = q.plot(color = color, alpha=alpha, **options) + result = q.plot(color=color, alpha=alpha, **options) if label is not None: # Put the label on the vertex having largest z, then y, then x coordinate. vertices = sorted([vector(v) for v in q.vertices()], @@ -1489,7 +1489,7 @@ def reflection_hyperplane(self, coroot, as_polyhedron=False): text_label = "H_%s$" % (str(label)) else: text_label = "$H_{%s}$" % (latex(label)) - return self.cone(lines = basis, color = self.color(label), label=text_label, + return self.cone(lines=basis, color=self.color(label), label=text_label, as_polyhedron=as_polyhedron) diff --git a/src/sage/combinat/root_system/reflection_group_real.py b/src/sage/combinat/root_system/reflection_group_real.py index 8b230e27ee6..885e0ee549e 100644 --- a/src/sage/combinat/root_system/reflection_group_real.py +++ b/src/sage/combinat/root_system/reflection_group_real.py @@ -271,9 +271,9 @@ def __init__(self, W_types, index_set=None, hyperplane_index_set=None, reflectio cls = IrreducibleComplexReflectionGroup else: cls = ComplexReflectionGroup - cls.__init__(self, W_types, index_set = index_set, - hyperplane_index_set = hyperplane_index_set, - reflection_index_set = reflection_index_set) + cls.__init__(self, W_types, index_set=index_set, + hyperplane_index_set=hyperplane_index_set, + reflection_index_set=reflection_index_set) def _repr_(self): r""" diff --git a/src/sage/combinat/root_system/root_lattice_realization_algebras.py b/src/sage/combinat/root_system/root_lattice_realization_algebras.py index 3e70a2e8fd9..c795890da5e 100644 --- a/src/sage/combinat/root_system/root_lattice_realization_algebras.py +++ b/src/sage/combinat/root_system/root_lattice_realization_algebras.py @@ -577,7 +577,7 @@ def demazure_lusztig_operators(self, q1, q2, convention="antidominant"): ....: T._test_relations(elements=elements) """ T_on_basis = functools.partial(self.demazure_lusztig_operator_on_basis, - q1 = q1, q2 = q2, convention = convention) + q1=q1, q2=q2, convention=convention) return HeckeAlgebraRepresentation(self, T_on_basis, self.cartan_type(), q1, q2, side="left") def demazure_lusztig_operator_on_classical_on_basis(self, weight, i, q, q1, q2, convention="antidominant"): @@ -1117,7 +1117,7 @@ def twisted_demazure_lusztig_operators(self, q1, q2, convention="antidominant"): T_on_basis, self.cartan_type().classical().dual().affine().dual(), q1, q2, - side = "left") + side="left") class ElementMethods: diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index faadbe3ea21..84a7b847f43 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -195,7 +195,7 @@ def __init_extra__(self): # Build and register the embeddings for domain in domains: domain.module_morphism(self.simple_root, - codomain = self + codomain=self ).register_as_coercion() if self.cartan_type().is_affine(): self._to_classical.register_as_conversion() @@ -693,7 +693,7 @@ def positive_roots(self, index_set=None): structure='graded', enumeration='breadth') @cached_method - def nonparabolic_positive_roots(self, index_set = None): + def nonparabolic_positive_roots(self, index_set=None): r""" Return the positive roots of ``self`` that are not in the parabolic subsystem indicated by ``index_set``. @@ -869,7 +869,7 @@ def positive_imaginary_roots(self): return F @cached_method - def positive_roots_by_height(self, increasing = True): + def positive_roots_by_height(self, increasing=True): r""" Returns a list of positive roots in increasing order by height. @@ -906,7 +906,7 @@ def positive_roots_by_height(self, increasing = True): return [x.element for x in roots] @cached_method - def positive_roots_parabolic(self, index_set = None): + def positive_roots_parabolic(self, index_set=None): r""" Return the set of positive roots for the parabolic subsystem with Dynkin node set ``index_set``. @@ -941,7 +941,7 @@ def parabolic_covers(alpha): structure='graded', enumeration='breadth') @cached_method - def positive_roots_nonparabolic(self, index_set = None): + def positive_roots_nonparabolic(self, index_set=None): r""" Returns the set of positive roots outside the parabolic subsystem with Dynkin node set ``index_set``. @@ -973,7 +973,7 @@ def positive_roots_nonparabolic(self, index_set = None): return [x for x in self.positive_roots() if not x.is_parabolic_root(index_set)] @cached_method - def positive_roots_nonparabolic_sum(self, index_set = None): + def positive_roots_nonparabolic_sum(self, index_set=None): r""" Returns the sum of positive roots outside the parabolic subsystem with Dynkin node set ``index_set``. @@ -1212,7 +1212,7 @@ def coroot_lattice(self): """ return self.root_system.coroot_lattice() - def coroot_space(self, base_ring = QQ): + def coroot_space(self, base_ring=QQ): r""" Return the coroot space over ``base_ring``. @@ -1229,7 +1229,7 @@ def coroot_space(self, base_ring = QQ): Coroot space over the Univariate Polynomial Ring in q over Rational Field of the Root system of type ['A', 2] """ - return self.root_system.coroot_space(base_ring = base_ring) + return self.root_system.coroot_space(base_ring=base_ring) def simple_coroot(self, i): """ @@ -1870,7 +1870,7 @@ def _to_classical(self): sage: L._to_classical(e[2]) (0, 0, 1) """ - return self.module_morphism(self._to_classical_on_basis, codomain = self.classical()) + return self.module_morphism(self._to_classical_on_basis, codomain=self.classical()) def _classical_alpha_0(self): """ @@ -2610,7 +2610,7 @@ def plot_fundamental_chamber(self, style="normal", **options): else: I = cartan_type.index_set() lines = [] - return plot_options.cone(rays = [Lambda[i] for i in I], + return plot_options.cone(rays=[Lambda[i] for i in I], lines=lines, color="lightgrey", alpha=.3) @@ -3562,7 +3562,7 @@ def associated_coroot(self): alphacheck[1] """ - def reflection(self, root, use_coroot = False): + def reflection(self, root, use_coroot=False): r""" Reflects ``self`` across the hyperplane orthogonal to ``root``. @@ -3665,7 +3665,7 @@ def descents(self, index_set=None, positive=False): index_set=self.parent().index_set() return [ i for i in index_set if self.has_descent(i, positive) ] - def to_dominant_chamber(self, index_set = None, positive = True, reduced_word = False): + def to_dominant_chamber(self, index_set=None, positive=True, reduced_word=False): r""" Returns the unique dominant element in the Weyl group orbit of the vector ``self``. @@ -3759,7 +3759,7 @@ def to_dominant_chamber(self, index_set = None, positive = True, reduced_word = direction.append(i) self = self.simple_reflection(i) - def reduced_word(self, index_set = None, positive = True): + def reduced_word(self, index_set=None, positive=True): r""" Returns a reduced word for the inverse of the shortest Weyl group element that sends the vector ``self`` into the dominant chamber. @@ -3778,9 +3778,9 @@ def reduced_word(self, index_set = None, positive = True): [2] """ - return self.to_dominant_chamber(index_set=index_set,positive=positive,reduced_word = True)[1] + return self.to_dominant_chamber(index_set=index_set,positive=positive,reduced_word=True)[1] - def is_dominant(self, index_set = None, positive = True): + def is_dominant(self, index_set=None, positive=True): r""" Returns whether self is dominant. diff --git a/src/sage/combinat/root_system/root_space.py b/src/sage/combinat/root_system/root_space.py index d4e6f8746d2..790b45f9606 100644 --- a/src/sage/combinat/root_system/root_space.py +++ b/src/sage/combinat/root_system/root_space.py @@ -64,9 +64,9 @@ def __init__(self, root_system, base_ring): self.root_system = root_system CombinatorialFreeModule.__init__(self, base_ring, root_system.index_set(), - prefix = "alphacheck" if root_system.dual_side else "alpha", - latex_prefix = "\\alpha^\\vee" if root_system.dual_side else "\\alpha", - category = RootLatticeRealizations(base_ring)) + prefix="alphacheck" if root_system.dual_side else "alpha", + latex_prefix="\\alpha^\\vee" if root_system.dual_side else "\\alpha", + category=RootLatticeRealizations(base_ring)) if base_ring is not ZZ: # Register the partial conversion back from ``self`` to the root lattice # See :meth:`_to_root_lattice` for tests @@ -139,7 +139,7 @@ def to_coroot_space_morphism(self): """ R = self.base_ring() C = self.cartan_type().symmetrizer().map(R) - return self.module_morphism(diagonal = C.__getitem__, + return self.module_morphism(diagonal=C.__getitem__, codomain=self.coroot_space(R)) def _to_root_lattice(self, x): @@ -228,7 +228,7 @@ def to_ambient_space_morphism(self): def basis_value(basis, i): return basis[i] - return self.module_morphism(on_basis = functools.partial(basis_value, basis) , codomain=L) + return self.module_morphism(on_basis=functools.partial(basis_value, basis) , codomain=L) class RootSpaceElement(CombinatorialFreeModule.Element): diff --git a/src/sage/combinat/root_system/root_system.py b/src/sage/combinat/root_system/root_system.py index fc84a35b4c1..82512778857 100644 --- a/src/sage/combinat/root_system/root_system.py +++ b/src/sage/combinat/root_system/root_system.py @@ -531,7 +531,7 @@ def coroot_space(self, base_ring=QQ): return self.dual.root_space(base_ring) @cached_method - def weight_lattice(self, extended = False): + def weight_lattice(self, extended=False): """ Returns the weight lattice associated to self. @@ -549,10 +549,10 @@ def weight_lattice(self, extended = False): sage: RootSystem(['A',3,1]).weight_space(extended = True) Extended weight space over the Rational Field of the Root system of type ['A', 3, 1] """ - return WeightSpace(self, ZZ, extended = extended) + return WeightSpace(self, ZZ, extended=extended) @cached_method - def weight_space(self, base_ring=QQ, extended = False): + def weight_space(self, base_ring=QQ, extended=False): """ Returns the weight space associated to self. @@ -570,9 +570,9 @@ def weight_space(self, base_ring=QQ, extended = False): sage: RootSystem(['A',3,1]).weight_space(extended = True) Extended weight space over the Rational Field of the Root system of type ['A', 3, 1] """ - return WeightSpace(self, base_ring, extended = extended) + return WeightSpace(self, base_ring, extended=extended) - def coweight_lattice(self, extended = False): + def coweight_lattice(self, extended=False): """ Returns the coweight lattice associated to self. @@ -592,9 +592,9 @@ def coweight_lattice(self, extended = False): sage: RootSystem(['A',3,1]).coweight_lattice(extended = True) Extended coweight lattice of the Root system of type ['A', 3, 1] """ - return self.dual.weight_lattice(extended = extended) + return self.dual.weight_lattice(extended=extended) - def coweight_space(self, base_ring=QQ, extended = False): + def coweight_space(self, base_ring=QQ, extended=False): """ Returns the coweight space associated to self. @@ -614,7 +614,7 @@ def coweight_space(self, base_ring=QQ, extended = False): sage: RootSystem(['A',3,1]).coweight_space(extended=True) Extended coweight space over the Rational Field of the Root system of type ['A', 3, 1] """ - return self.dual.weight_space(base_ring, extended = extended) + return self.dual.weight_space(base_ring, extended=extended) def ambient_lattice(self): r""" diff --git a/src/sage/combinat/root_system/type_Q.py b/src/sage/combinat/root_system/type_Q.py index a8884c8905a..e9a0e15d941 100644 --- a/src/sage/combinat/root_system/type_Q.py +++ b/src/sage/combinat/root_system/type_Q.py @@ -49,7 +49,7 @@ def __init__(self, m): assert m >= 2 CartanType_standard_finite.__init__(self, "Q", m-1) - def _repr_(self, compact = False): + def _repr_(self, compact=False): """ TESTS:: diff --git a/src/sage/combinat/root_system/type_affine.py b/src/sage/combinat/root_system/type_affine.py index b24f2d2afa5..db1daad875a 100644 --- a/src/sage/combinat/root_system/type_affine.py +++ b/src/sage/combinat/root_system/type_affine.py @@ -158,10 +158,10 @@ def sortkey(x): return (1 if isinstance(x, str) else 0, x) CombinatorialFreeModule.__init__(self, base_ring, basis_keys, - prefix = "e", - latex_prefix = "e", + prefix="e", + latex_prefix="e", sorting_key=sortkey, - category = WeightLatticeRealizations(base_ring)) + category=WeightLatticeRealizations(base_ring)) self._weight_space = self.root_system.weight_space(base_ring=base_ring,extended=True) self.classical().module_morphism(self.monomial, codomain=self).register_as_coercion() # Duplicated from ambient_space.AmbientSpace diff --git a/src/sage/combinat/root_system/type_dual.py b/src/sage/combinat/root_system/type_dual.py index 8922a4cd9ac..38d39b80b90 100644 --- a/src/sage/combinat/root_system/type_dual.py +++ b/src/sage/combinat/root_system/type_dual.py @@ -163,7 +163,7 @@ def __init__(self, type): _stable_abstract_classes = [ cartan_type.CartanType_simple] - def _repr_(self, compact = False): + def _repr_(self, compact=False): """ EXAMPLES:: diff --git a/src/sage/combinat/root_system/type_relabel.py b/src/sage/combinat/root_system/type_relabel.py index f37c6a724e6..624619db3fc 100644 --- a/src/sage/combinat/root_system/type_relabel.py +++ b/src/sage/combinat/root_system/type_relabel.py @@ -229,7 +229,7 @@ def _repr_(self, compact=False): return 'D4^3' return "['D', 4, 3]" relab = pformat(self._relabelling) - return self._type._repr_(compact = compact) + " relabelled by {}".format(relab) + return self._type._repr_(compact=compact) + " relabelled by {}".format(relab) def _latex_(self): r""" diff --git a/src/sage/combinat/root_system/weight_lattice_realizations.py b/src/sage/combinat/root_system/weight_lattice_realizations.py index a088fd912c8..126a045327a 100644 --- a/src/sage/combinat/root_system/weight_lattice_realizations.py +++ b/src/sage/combinat/root_system/weight_lattice_realizations.py @@ -228,7 +228,7 @@ def __init_extra__(self): # Build and register the embeddings for domain in domains: domain.module_morphism(self.fundamental_weight, - codomain = self + codomain=self ).register_as_coercion() def _test_weight_lattice_realization(self, **options): @@ -813,7 +813,7 @@ def rho_classical(self): Lambda = self.fundamental_weights() return rho - Lambda[0] * rho.level() / Lambda[0].level() - def embed_at_level(self, x, level = 1): + def embed_at_level(self, x, level=1): r""" Embed the classical weight `x` in the level ``level`` hyperplane @@ -1065,7 +1065,7 @@ def symmetric_form(self, la): # assert( t == self.plus(t.scalar(alphac[i]) * Lambda[i] for i in self.index_set() ) ) # t = self.plus( t.scalar(alphac[i]) * c[i] * Lambda[i] for i in self.index_set() ) - def to_weight_space(self, base_ring = None): + def to_weight_space(self, base_ring=None): r""" Map ``self`` to the weight space. diff --git a/src/sage/combinat/root_system/weight_space.py b/src/sage/combinat/root_system/weight_space.py index 808067aef1f..9e700a26f5a 100644 --- a/src/sage/combinat/root_system/weight_space.py +++ b/src/sage/combinat/root_system/weight_space.py @@ -187,17 +187,17 @@ def sortkey(x): self.root_system = root_system CombinatorialFreeModule.__init__(self, base_ring, basis_keys, - prefix = "Lambdacheck" if root_system.dual_side else "Lambda", - latex_prefix = "\\Lambda^\\vee" if root_system.dual_side else "\\Lambda", + prefix="Lambdacheck" if root_system.dual_side else "Lambda", + latex_prefix="\\Lambda^\\vee" if root_system.dual_side else "\\Lambda", sorting_key=sortkey, - category = WeightLatticeRealizations(base_ring)) + category=WeightLatticeRealizations(base_ring)) if root_system.cartan_type().is_affine() and not extended: # For an affine type, register the quotient map from the # extended weight lattice/space to the weight lattice/space domain = root_system.weight_space(base_ring, extended=True) domain.module_morphism(self.fundamental_weight, - codomain = self + codomain=self ).register_as_coercion() def is_extended(self): @@ -451,7 +451,7 @@ def to_ambient_space_morphism(self): def basis_value(basis, i): return basis[i] - return self.module_morphism(on_basis = functools.partial(basis_value, basis), codomain=L) + return self.module_morphism(on_basis=functools.partial(basis_value, basis), codomain=L) class WeightSpaceElement(CombinatorialFreeModule.Element): diff --git a/src/sage/combinat/sidon_sets.py b/src/sage/combinat/sidon_sets.py index ec5038eb2c4..9ba6bdb5c71 100644 --- a/src/sage/combinat/sidon_sets.py +++ b/src/sage/combinat/sidon_sets.py @@ -16,7 +16,7 @@ from sage.rings.integer import Integer -def sidon_sets(N, g = 1): +def sidon_sets(N, g=1): r""" Return the set of all Sidon-`g` sets that have elements less than or equal to `N`. diff --git a/src/sage/combinat/skew_partition.py b/src/sage/combinat/skew_partition.py index dd66961a807..bd65d1ee5ff 100644 --- a/src/sage/combinat/skew_partition.py +++ b/src/sage/combinat/skew_partition.py @@ -1874,7 +1874,7 @@ def cardinality(self): return ZZ.one() if self.overlap > 0: - gg = Compositions(self.n, min_part = max(1, self.overlap)) + gg = Compositions(self.n, min_part=max(1, self.overlap)) else: gg = Compositions(self.n) @@ -1925,7 +1925,7 @@ def __iter__(self): sage: SkewPartitions(3, overlap=4).list() [] """ - for co in Compositions(self.n, min_part = max(1, self.overlap)): + for co in Compositions(self.n, min_part=max(1, self.overlap)): for sp in SkewPartitions(row_lengths=co, overlap=self.overlap): yield self.element_class(self, sp) diff --git a/src/sage/combinat/subsets_pairwise.py b/src/sage/combinat/subsets_pairwise.py index fc64df2e48f..ed5613157f2 100644 --- a/src/sage/combinat/subsets_pairwise.py +++ b/src/sage/combinat/subsets_pairwise.py @@ -105,7 +105,7 @@ def __init__(self, ambient, predicate, maximal=False, element_class=Set_object_e # TODO: use self.element_class for consistency # At this point (2011/03) TestSuite fails if we do so self._element_class = element_class - RecursivelyEnumeratedSet_forest.__init__(self, algorithm = 'depth', category = FiniteEnumeratedSets()) + RecursivelyEnumeratedSet_forest.__init__(self, algorithm='depth', category=FiniteEnumeratedSets()) def __eq__(self, other): """ diff --git a/src/sage/combinat/vector_partition.py b/src/sage/combinat/vector_partition.py index 03a142c8034..b9a6882d207 100644 --- a/src/sage/combinat/vector_partition.py +++ b/src/sage/combinat/vector_partition.py @@ -60,7 +60,7 @@ def find_min(vect): return min -def IntegerVectorsIterator(vect, min = None): +def IntegerVectorsIterator(vect, min=None): """ Return an iterator over the list of integer vectors which are componentwise less than or equal to ``vect``, and lexicographically greater than or equal @@ -161,7 +161,7 @@ def partition_at_vertex(self, i): sage: V.partition_at_vertex(1) [4, 2] """ - return Partition(sorted([vec[i] for vec in self._list], reverse = True)) + return Partition(sorted([vec[i] for vec in self._list], reverse=True)) class VectorPartitions(UniqueRepresentation, Parent): diff --git a/src/sage/combinat/words/word_generators.py b/src/sage/combinat/words/word_generators.py index 9c42e379cd4..2dba020eb34 100644 --- a/src/sage/combinat/words/word_generators.py +++ b/src/sage/combinat/words/word_generators.py @@ -1048,7 +1048,7 @@ def KolakoskiWord(self, alphabet=(1,2)): if a not in ZZ or a <= 0 or b not in ZZ or b <= 0 or a == b: msg = 'the alphabet (=%s) must consist of two distinct positive integers' % (alphabet,) raise ValueError(msg) - return InfiniteWords(alphabet)(self._KolakoskiWord_iterator(a, b), datatype = 'iter') + return InfiniteWords(alphabet)(self._KolakoskiWord_iterator(a, b), datatype='iter') def _KolakoskiWord_iterator(self, a=1, b=2): r""" From 884e7d65ffd5e4c7fbe9e0b1487fa454bc89c66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 3 Jun 2023 09:08:23 +0200 Subject: [PATCH 24/56] fix pep8 E251 in rings/ --- src/sage/rings/complex_interval_field.py | 2 +- .../rings/finite_rings/conway_polynomials.py | 2 +- src/sage/rings/function_field/ideal.py | 2 +- src/sage/rings/function_field/place.py | 2 +- src/sage/rings/homset.py | 8 +-- src/sage/rings/ideal.py | 2 +- src/sage/rings/lazy_series.py | 16 ++--- src/sage/rings/multi_power_series_ring.py | 5 +- .../rings/number_field/number_field_ideal.py | 2 +- .../number_field/number_field_ideal_rel.py | 2 +- .../rings/number_field/number_field_rel.py | 4 +- src/sage/rings/padics/factory.py | 72 +++++++++---------- src/sage/rings/padics/generic_nodes.py | 2 +- src/sage/rings/padics/local_generic.py | 2 +- src/sage/rings/padics/padic_base_leaves.py | 2 +- src/sage/rings/padics/padic_generic.py | 6 +- .../rings/padics/relative_extension_leaves.py | 2 +- .../padics/unramified_extension_generic.py | 4 +- .../laurent_polynomial_ring_base.py | 8 +-- .../polynomial/multi_polynomial_ideal.py | 6 +- .../polynomial/polynomial_element_generic.py | 4 +- .../polynomial/polynomial_quotient_ring.py | 4 +- src/sage/rings/polynomial/polynomial_ring.py | 20 +++--- src/sage/rings/power_series_ring.py | 8 +-- src/sage/rings/qqbar.py | 2 +- src/sage/rings/quotient_ring.py | 2 +- src/sage/rings/rational_field.py | 2 +- 27 files changed, 96 insertions(+), 97 deletions(-) diff --git a/src/sage/rings/complex_interval_field.py b/src/sage/rings/complex_interval_field.py index 81385cc7bfb..7cbf5d60929 100644 --- a/src/sage/rings/complex_interval_field.py +++ b/src/sage/rings/complex_interval_field.py @@ -627,7 +627,7 @@ def random_element(self, *args, **kwds): im = rand(*args, **kwds) return self.element_class(self, re, im) - def is_field(self, proof = True): + def is_field(self, proof=True): """ Return ``True``, since the complex numbers are a field. diff --git a/src/sage/rings/finite_rings/conway_polynomials.py b/src/sage/rings/finite_rings/conway_polynomials.py index d4a08e1fb4d..d947fa25cc8 100644 --- a/src/sage/rings/finite_rings/conway_polynomials.py +++ b/src/sage/rings/finite_rings/conway_polynomials.py @@ -273,7 +273,7 @@ def check_consistency(self, n): sage: PCL.check_consistency(60) # long time """ p = self.p - K = FiniteField(p**n, modulus = self.polynomial(n), names='a') + K = FiniteField(p**n, modulus=self.polynomial(n), names='a') a = K.gen() for m in n.divisors(): assert (a**((p**n-1)//(p**m-1))).minimal_polynomial() == self.polynomial(m) diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index 8d203e9f019..69edbcec2f0 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -1015,7 +1015,7 @@ def __init__(self, R): sage: TestSuite(M).run() # optional - sage.rings.finite_rings """ self.Element = R._ideal_class - Parent.__init__(self, category = Monoids()) + Parent.__init__(self, category=Monoids()) self.__R = R self._populate_coercion_lists_() diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index 685af63a571..0c61671bffa 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -342,7 +342,7 @@ def __init__(self, field): sage: TestSuite(places).run() # optional - sage.rings.finite_rings sage.rings.function_field """ self.Element = field._place_class - Parent.__init__(self, category = Sets().Infinite()) + Parent.__init__(self, category=Sets().Infinite()) self._field = field diff --git a/src/sage/rings/homset.py b/src/sage/rings/homset.py index 77fa3323bc0..b89ba5a1ed7 100644 --- a/src/sage/rings/homset.py +++ b/src/sage/rings/homset.py @@ -36,7 +36,7 @@ def is_RingHomset(H): return isinstance(H, RingHomset_generic) -def RingHomset(R, S, category = None): +def RingHomset(R, S, category=None): """ Construct a space of homomorphisms between the rings ``R`` and ``S``. @@ -51,8 +51,8 @@ def RingHomset(R, S, category = None): if quotient_ring.is_QuotientRing(R): from .polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing if not is_PolynomialQuotientRing(R): # backwards compatibility - return RingHomset_quo_ring(R, S, category = category) - return RingHomset_generic(R, S, category = category) + return RingHomset_quo_ring(R, S, category=category) + return RingHomset_generic(R, S, category=category) class RingHomset_generic(HomsetWithBase): @@ -69,7 +69,7 @@ class RingHomset_generic(HomsetWithBase): Element = morphism.RingHomomorphism - def __init__(self, R, S, category = None): + def __init__(self, R, S, category=None): """ Initialize ``self``. diff --git a/src/sage/rings/ideal.py b/src/sage/rings/ideal.py index bf557adc1a1..c6bcf374d6c 100644 --- a/src/sage/rings/ideal.py +++ b/src/sage/rings/ideal.py @@ -1689,7 +1689,7 @@ def residue_field(self): raise ValueError("The ideal (%s) is not prime"%self) from sage.rings.integer_ring import ZZ if self.ring() is ZZ: - return ZZ.residue_field(self, check = False) + 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): diff --git a/src/sage/rings/lazy_series.py b/src/sage/rings/lazy_series.py index 3403552e9c8..5b12d744a4b 100644 --- a/src/sage/rings/lazy_series.py +++ b/src/sage/rings/lazy_series.py @@ -5084,24 +5084,24 @@ def _format_series(self, formatter, format_strings=False): poly = repr_lincomb([(1, m) for m in mons + bigO], is_latex=True, strip_one=True) elif formatter == ascii_art: if atomic_repr: - poly = ascii_art(*(mons + bigO), sep = " + ") + poly = ascii_art(*(mons + bigO), sep=" + ") else: def parenthesize(m): a = ascii_art(m) h = a.height() return ascii_art(ascii_left_parenthesis.character_art(h), a, ascii_right_parenthesis.character_art(h)) - poly = ascii_art(*([parenthesize(m) for m in mons] + bigO), sep = " + ") + poly = ascii_art(*([parenthesize(m) for m in mons] + bigO), sep=" + ") elif formatter == unicode_art: if atomic_repr: - poly = unicode_art(*(mons + bigO), sep = " + ") + poly = unicode_art(*(mons + bigO), sep=" + ") else: def parenthesize(m): a = unicode_art(m) h = a.height() return unicode_art(unicode_left_parenthesis.character_art(h), a, unicode_right_parenthesis.character_art(h)) - poly = unicode_art(*([parenthesize(m) for m in mons] + bigO), sep = " + ") + poly = unicode_art(*([parenthesize(m) for m in mons] + bigO), sep=" + ") return poly @@ -5398,24 +5398,24 @@ def _format_series(self, formatter, format_strings=False): poly = repr_lincomb([(1, m) for m in mons + bigO], is_latex=True, strip_one=True) elif formatter == ascii_art: if atomic_repr: - poly = ascii_art(*(mons + bigO), sep = " + ") + poly = ascii_art(*(mons + bigO), sep=" + ") else: def parenthesize(m): a = ascii_art(m) h = a.height() return ascii_art(ascii_left_parenthesis.character_art(h), a, ascii_right_parenthesis.character_art(h)) - poly = ascii_art(*([parenthesize(m) for m in mons] + bigO), sep = " + ") + poly = ascii_art(*([parenthesize(m) for m in mons] + bigO), sep=" + ") elif formatter == unicode_art: if atomic_repr: - poly = unicode_art(*(mons + bigO), sep = " + ") + poly = unicode_art(*(mons + bigO), sep=" + ") else: def parenthesize(m): a = unicode_art(m) h = a.height() return unicode_art(unicode_left_parenthesis.character_art(h), a, unicode_right_parenthesis.character_art(h)) - poly = unicode_art(*([parenthesize(m) for m in mons] + bigO), sep = " + ") + poly = unicode_art(*([parenthesize(m) for m in mons] + bigO), sep=" + ") return poly diff --git a/src/sage/rings/multi_power_series_ring.py b/src/sage/rings/multi_power_series_ring.py index 20e3cba3977..dd374ea0f75 100644 --- a/src/sage/rings/multi_power_series_ring.py +++ b/src/sage/rings/multi_power_series_ring.py @@ -365,8 +365,7 @@ def __init__(self, base_ring, num_gens, name_list, # Multivariate power series rings inherit from power series rings. But # apparently we can not call their initialisation. Instead, initialise # CommutativeRing and Nonexact: - CommutativeRing.__init__(self, base_ring, name_list, category = - _IntegralDomains if base_ring in + CommutativeRing.__init__(self, base_ring, name_list, category=_IntegralDomains if base_ring in _IntegralDomains else _CommutativeRings) Nonexact.__init__(self, default_prec) @@ -561,7 +560,7 @@ def change_ring(self, R): sage: S.change_ring(GF(5)) # optional - sage.rings.finite_rings Multivariate Power Series Ring in x, y over Finite Field of size 5 """ - return PowerSeriesRing(R, names = self.variable_names(), default_prec = self.default_prec()) + return PowerSeriesRing(R, names=self.variable_names(), default_prec=self.default_prec()) def remove_var(self, *var): """ diff --git a/src/sage/rings/number_field/number_field_ideal.py b/src/sage/rings/number_field/number_field_ideal.py index ce1e8bce645..7a4b3b2debc 100644 --- a/src/sage/rings/number_field/number_field_ideal.py +++ b/src/sage/rings/number_field/number_field_ideal.py @@ -3196,7 +3196,7 @@ def residue_field(self, names=None): """ if not self.is_prime(): raise ValueError("The ideal must be prime") - return self.number_field().residue_field(self, names = names) + return self.number_field().residue_field(self, names=names) def residue_class_degree(self): r""" diff --git a/src/sage/rings/number_field/number_field_ideal_rel.py b/src/sage/rings/number_field/number_field_ideal_rel.py index c465ecf438a..95c842bc92e 100644 --- a/src/sage/rings/number_field/number_field_ideal_rel.py +++ b/src/sage/rings/number_field/number_field_ideal_rel.py @@ -129,7 +129,7 @@ def pari_rhnf(self): self.__pari_rhnf = rnf.rnfidealabstorel(nfzk * L_hnf) return self.__pari_rhnf - def absolute_ideal(self, names = 'a'): + def absolute_ideal(self, names='a'): r""" If this is an ideal in the extension `L/K`, return the ideal with the same generators in the absolute field `L/\QQ`. diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index 7405a08b4bb..f4ba2b9f412 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -2104,7 +2104,7 @@ def automorphisms(self): abs_base_gens = [self_into_L(_) for _ in self.base_field().gens()] v = sorted([ self.hom([ L_into_self(aa(a)) ]) for aa in aas if all(aa(g) == g for g in abs_base_gens) ]) put_natural_embedding_first(v) - self.__automorphisms = Sequence(v, cr = (v != []), immutable=True, + self.__automorphisms = Sequence(v, cr=(v != []), immutable=True, check=False, universe=self.Hom(self)) return self.__automorphisms @@ -2611,7 +2611,7 @@ def relativize(self, alpha, names): L = K.relativize(beta, names) return K.relativize(beta, names, structure=structure.RelativeFromRelative(L)) - def uniformizer(self, P, others = "positive"): + def uniformizer(self, P, others="positive"): """ Returns an element of ``self`` with valuation 1 at the prime ideal `P`. diff --git a/src/sage/rings/padics/factory.py b/src/sage/rings/padics/factory.py index 25e5c796cc2..d3a701decfe 100644 --- a/src/sage/rings/padics/factory.py +++ b/src/sage/rings/padics/factory.py @@ -723,10 +723,10 @@ class Qp_class(UniqueFactory): sage: K = Qp(15, check=False); a = K(999); a 9 + 6*15 + 4*15^2 + O(15^20) """ - def create_key(self, p, prec = None, type = 'capped-rel', print_mode = None, - names = None, ram_name = None, print_pos = None, - print_sep = None, print_alphabet = None, print_max_terms = None, show_prec = None, check = True, - label = None): # specific to Lattice precision + def create_key(self, p, prec=None, type='capped-rel', print_mode=None, + names=None, ram_name=None, print_pos=None, + print_sep=None, print_alphabet=None, print_max_terms=None, show_prec=None, check=True, + label=None): # specific to Lattice precision r""" Creates a key from input parameters for ``Qp``. @@ -822,10 +822,10 @@ def create_object(self, version, key): # Qq -- unramified extensions ###################################################### -def Qq(q, prec = None, type = 'capped-rel', modulus = None, names=None, - print_mode=None, ram_name = None, res_name = None, print_pos = None, - print_sep = None, print_max_ram_terms = None, - print_max_unram_terms = None, print_max_terse_terms = None, show_prec=None, check = True, implementation = 'FLINT'): +def Qq(q, prec=None, type='capped-rel', modulus=None, names=None, + print_mode=None, ram_name=None, res_name=None, print_pos=None, + print_sep=None, print_max_ram_terms=None, + print_max_unram_terms=None, print_max_terse_terms=None, show_prec=None, check=True, implementation='FLINT'): r""" Given a prime power `q = p^n`, return the unique unramified extension of `\QQ_p` of degree `n`. @@ -1380,7 +1380,7 @@ def Qq(q, prec = None, type = 'capped-rel', modulus = None, names=None, # Short constructor names for different types ###################################################### -def QpCR(p, prec = None, *args, **kwds): +def QpCR(p, prec=None, *args, **kwds): r""" A shortcut function to create capped relative `p`-adic fields. @@ -1394,7 +1394,7 @@ def QpCR(p, prec = None, *args, **kwds): """ return Qp(p, prec, 'capped-rel', *args, **kwds) -def QpFP(p, prec = None, *args, **kwds): +def QpFP(p, prec=None, *args, **kwds): r""" A shortcut function to create floating point `p`-adic fields. @@ -1408,7 +1408,7 @@ def QpFP(p, prec = None, *args, **kwds): """ return Qp(p, prec, 'floating-point', *args, **kwds) -def QqCR(q, prec = None, *args, **kwds): +def QqCR(q, prec=None, *args, **kwds): r""" A shortcut function to create capped relative unramified `p`-adic fields. @@ -1423,7 +1423,7 @@ def QqCR(q, prec = None, *args, **kwds): """ return Qq(q, prec, 'capped-rel', *args, **kwds) -def QqFP(q, prec = None, *args, **kwds): +def QqFP(q, prec=None, *args, **kwds): r""" A shortcut function to create floating point unramified `p`-adic fields. @@ -1439,7 +1439,7 @@ def QqFP(q, prec = None, *args, **kwds): return Qq(q, prec, 'floating-point', *args, **kwds) @experimental(23505) -def QpLC(p, prec = None, *args, **kwds): +def QpLC(p, prec=None, *args, **kwds): r""" A shortcut function to create `p`-adic fields with lattice precision. @@ -1454,7 +1454,7 @@ def QpLC(p, prec = None, *args, **kwds): return Qp(p, prec, 'lattice-cap', *args, **kwds) @experimental(23505) -def QpLF(p, prec = None, *args, **kwds): +def QpLF(p, prec=None, *args, **kwds): r""" A shortcut function to create `p`-adic fields with lattice precision. @@ -1930,10 +1930,10 @@ class Zp_class(UniqueFactory): sage: a + b 1 + 5 + O(5^10) """ - def create_key(self, p, prec = None, type = 'capped-rel', print_mode = None, - names = None, ram_name = None, print_pos = None, print_sep = None, print_alphabet = None, - print_max_terms = None, show_prec = None, check = True, - label = None): + def create_key(self, p, prec=None, type='capped-rel', print_mode=None, + names=None, ram_name=None, print_pos=None, print_sep=None, print_alphabet=None, + print_max_terms=None, show_prec=None, check=True, + label=None): r""" Creates a key from input parameters for ``Zp``. @@ -2034,10 +2034,10 @@ def create_object(self, version, key): # Zq -- unramified extensions ###################################################### -def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, - print_mode=None, ram_name = None, res_name = None, print_pos = None, - print_sep = None, print_max_ram_terms = None, - print_max_unram_terms = None, print_max_terse_terms = None, show_prec = None, check = True, implementation = 'FLINT'): +def Zq(q, prec=None, type='capped-rel', modulus=None, names=None, + print_mode=None, ram_name=None, res_name=None, print_pos=None, + print_sep=None, print_max_ram_terms=None, + print_max_unram_terms=None, print_max_terse_terms=None, show_prec=None, check=True, implementation='FLINT'): r""" Given a prime power `q = p^n`, return the unique unramified extension of `\ZZ_p` of degree `n`. @@ -2599,7 +2599,7 @@ def Zq(q, prec = None, type = 'capped-rel', modulus = None, names=None, # Short constructor names for different types ###################################################### -def ZpCR(p, prec = None, *args, **kwds): +def ZpCR(p, prec=None, *args, **kwds): r""" A shortcut function to create capped relative `p`-adic rings. @@ -2613,7 +2613,7 @@ def ZpCR(p, prec = None, *args, **kwds): """ return Zp(p, prec, 'capped-rel', *args, **kwds) -def ZpCA(p, prec = None, *args, **kwds): +def ZpCA(p, prec=None, *args, **kwds): r""" A shortcut function to create capped absolute `p`-adic rings. @@ -2626,7 +2626,7 @@ def ZpCA(p, prec = None, *args, **kwds): """ return Zp(p, prec, 'capped-abs', *args, **kwds) -def ZpFM(p, prec = None, *args, **kwds): +def ZpFM(p, prec=None, *args, **kwds): r""" A shortcut function to create fixed modulus `p`-adic rings. @@ -2639,7 +2639,7 @@ def ZpFM(p, prec = None, *args, **kwds): """ return Zp(p, prec, 'fixed-mod', *args, **kwds) -def ZpFP(p, prec = None, *args, **kwds): +def ZpFP(p, prec=None, *args, **kwds): r""" A shortcut function to create floating point `p`-adic rings. @@ -2653,7 +2653,7 @@ def ZpFP(p, prec = None, *args, **kwds): """ return Zp(p, prec, 'floating-point', *args, **kwds) -def ZqCR(q, prec = None, *args, **kwds): +def ZqCR(q, prec=None, *args, **kwds): r""" A shortcut function to create capped relative unramified `p`-adic rings. @@ -2667,7 +2667,7 @@ def ZqCR(q, prec = None, *args, **kwds): """ return Zq(q, prec, 'capped-rel', *args, **kwds) -def ZqCA(q, prec = None, *args, **kwds): +def ZqCA(q, prec=None, *args, **kwds): r""" A shortcut function to create capped absolute unramified `p`-adic rings. @@ -2680,7 +2680,7 @@ def ZqCA(q, prec = None, *args, **kwds): """ return Zq(q, prec, 'capped-abs', *args, **kwds) -def ZqFM(q, prec = None, *args, **kwds): +def ZqFM(q, prec=None, *args, **kwds): r""" A shortcut function to create fixed modulus unramified `p`-adic rings. @@ -2693,7 +2693,7 @@ def ZqFM(q, prec = None, *args, **kwds): """ return Zq(q, prec, 'fixed-mod', *args, **kwds) -def ZqFP(q, prec = None, *args, **kwds): +def ZqFP(q, prec=None, *args, **kwds): r""" A shortcut function to create floating point unramified `p`-adic rings. @@ -3235,12 +3235,12 @@ class pAdicExtension_class(UniqueFactory): sage: W.precision_cap() 12 """ - def create_key_and_extra_args(self, base, modulus, prec = None, print_mode = None, - names = None, var_name = None, res_name = None, - unram_name = None, ram_name = None, print_pos = None, - print_sep = None, print_alphabet = None, print_max_ram_terms = None, - print_max_unram_terms = None, print_max_terse_terms = None, - show_prec = None, check = True, unram = False, implementation='FLINT'): + def create_key_and_extra_args(self, base, modulus, prec=None, print_mode=None, + names=None, var_name=None, res_name=None, + unram_name=None, ram_name=None, print_pos=None, + print_sep=None, print_alphabet=None, print_max_ram_terms=None, + print_max_unram_terms=None, print_max_terse_terms=None, + show_prec=None, check=True, unram=False, implementation='FLINT'): r""" Creates a key from input parameters for :class:`pAdicExtension`. diff --git a/src/sage/rings/padics/generic_nodes.py b/src/sage/rings/padics/generic_nodes.py index 062bc28d8f8..c3d9dce2ded 100644 --- a/src/sage/rings/padics/generic_nodes.py +++ b/src/sage/rings/padics/generic_nodes.py @@ -1201,7 +1201,7 @@ def is_pAdicRing(R): class pAdicRingGeneric(pAdicGeneric, sage.rings.abc.pAdicRing): - def is_field(self, proof = True): + def is_field(self, proof=True): """ Return whether this ring is actually a field, ie ``False``. diff --git a/src/sage/rings/padics/local_generic.py b/src/sage/rings/padics/local_generic.py index 83d77282c2a..21f3e458255 100644 --- a/src/sage/rings/padics/local_generic.py +++ b/src/sage/rings/padics/local_generic.py @@ -231,7 +231,7 @@ def _latex_(self): sage: latex(Zq(27,names='a')) #indirect doctest \Bold{Z}_{3^{3}} """ - return self._repr_(do_latex = True) + return self._repr_(do_latex=True) def change(self, **kwds): r""" diff --git a/src/sage/rings/padics/padic_base_leaves.py b/src/sage/rings/padics/padic_base_leaves.py index 99823338bc4..8c4636e2904 100644 --- a/src/sage/rings/padics/padic_base_leaves.py +++ b/src/sage/rings/padics/padic_base_leaves.py @@ -729,7 +729,7 @@ def random_element(self, algorithm='default'): if (algorithm == 'default'): k = ZZ.random_element() a = ZZ.random_element(self.prime()**self.precision_cap()) - return self(self.prime()**k * a, absprec = k + self.precision_cap()) + return self(self.prime()**k * a, absprec=k + self.precision_cap()) else: raise NotImplementedError("Don't know %s algorithm"%algorithm) diff --git a/src/sage/rings/padics/padic_generic.py b/src/sage/rings/padics/padic_generic.py index b7caad54122..a4596240d57 100644 --- a/src/sage/rings/padics/padic_generic.py +++ b/src/sage/rings/padics/padic_generic.py @@ -497,7 +497,7 @@ def integer_ring(self, print_mode=None): deprecation(23227, "Use the change method if you want to change print options in integer_ring()") return self.change(field=False, **print_mode) - def teichmuller(self, x, prec = None): + def teichmuller(self, x, prec=None): r""" Return the Teichmüller representative of ``x``. @@ -614,7 +614,7 @@ def teichmuller_system(self): # """ # raise NotImplementedError - def extension(self, modulus, prec = None, names = None, print_mode = None, implementation='FLINT', **kwds): + def extension(self, modulus, prec=None, names=None, print_mode=None, implementation='FLINT', **kwds): r""" Create an extension of this p-adic ring. @@ -665,7 +665,7 @@ def extension(self, modulus, prec = None, names = None, print_mode = None, imple print_mode[option] = kwds[option] else: print_mode[option] = self._printer.dict()[option] - return ExtensionFactory(base=self, modulus=modulus, prec=prec, names=names, check = True, implementation=implementation, **print_mode) + return ExtensionFactory(base=self, modulus=modulus, prec=prec, names=names, check=True, implementation=implementation, **print_mode) def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): r""" diff --git a/src/sage/rings/padics/relative_extension_leaves.py b/src/sage/rings/padics/relative_extension_leaves.py index 455af0bdd35..a9f20adce21 100644 --- a/src/sage/rings/padics/relative_extension_leaves.py +++ b/src/sage/rings/padics/relative_extension_leaves.py @@ -210,7 +210,7 @@ def __init__(self, exact_modulus, approx_modulus, prec, print_mode, shift_seed, """ self._exact_modulus = exact_modulus unram_prec = (prec + approx_modulus.degree() - 1) // approx_modulus.degree() - KFP = approx_modulus.base_ring().change(prec = unram_prec+1) + KFP = approx_modulus.base_ring().change(prec=unram_prec+1) self.prime_pow = PowComputer_relative_maker(approx_modulus.base_ring().prime(), max(min(unram_prec - 1, 30), 1), unram_prec, prec, False, exact_modulus.change_ring(KFP), shift_seed.change_ring(KFP), 'fixed-mod') self._implementation = 'Polynomial' EisensteinExtensionGeneric.__init__(self, approx_modulus, prec, print_mode, names, RelativeRamifiedFixedModElement) diff --git a/src/sage/rings/padics/unramified_extension_generic.py b/src/sage/rings/padics/unramified_extension_generic.py index 5bc08a7a54f..4887cfcaf06 100644 --- a/src/sage/rings/padics/unramified_extension_generic.py +++ b/src/sage/rings/padics/unramified_extension_generic.py @@ -52,7 +52,7 @@ def __init__(self, poly, prec, print_mode, names, element_class): #else: # self._PQR = pqr.PolynomialQuotientRing_domain(poly.parent(), poly, name = names) pAdicExtensionGeneric.__init__(self, poly, prec, print_mode, names, element_class) - self._res_field = GF(self.prime_pow.pow_Integer_Integer(poly.degree()), name = names[1], modulus = poly.change_ring(poly.base_ring().residue_field())) + self._res_field = GF(self.prime_pow.pow_Integer_Integer(poly.degree()), name=names[1], modulus=poly.change_ring(poly.base_ring().residue_field())) def _extension_type(self): """ @@ -209,7 +209,7 @@ def gen(self, n=0): return self([0,1]) @cached_method - def _frob_gen(self, arithmetic = True): + def _frob_gen(self, arithmetic=True): """ Return frobenius of the generator for this unramified extension diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py index 93d8f9a4fc0..014fa20efaa 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring_base.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring_base.py @@ -433,7 +433,7 @@ def is_finite(self): """ return False - def is_field(self, proof = True): + def is_field(self, proof=True): """ EXAMPLES:: @@ -480,7 +480,7 @@ def krull_dimension(self): """ raise NotImplementedError - def random_element(self, low_degree = -2, high_degree = 2, terms = 5, choose_degree=False,*args, **kwds): + def random_element(self, low_degree=-2, high_degree=2, terms=5, choose_degree=False,*args, **kwds): """ EXAMPLES:: @@ -530,11 +530,11 @@ def change_ring(self, base_ring=None, names=None, sparse=False, order=None): if names is None: names = self.variable_names() if isinstance(self, LaurentPolynomialRing_univariate): - return LaurentPolynomialRing(base_ring, names[0], sparse = sparse) + return LaurentPolynomialRing(base_ring, names[0], sparse=sparse) if order is None: order = self.polynomial_ring().term_order() - return LaurentPolynomialRing(base_ring, self._n, names, order = order) + return LaurentPolynomialRing(base_ring, self._n, names, order=order) def fraction_field(self): """ diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 47f14f96229..c783d0e8753 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -3052,7 +3052,7 @@ def hilbert_series(self, grading=None, algorithm='sage'): @require_field @handle_AA_and_QQbar - def hilbert_numerator(self, grading = None, algorithm = 'sage'): + def hilbert_numerator(self, grading=None, algorithm='sage'): r""" Return the Hilbert numerator of this ideal. @@ -3419,7 +3419,7 @@ def _reduce_using_macaulay2(self, f): return R(k) class NCPolynomialIdeal(MPolynomialIdeal_singular_repr, Ideal_nc): - def __init__(self, ring, gens, coerce=True, side = "left"): + def __init__(self, ring, gens, coerce=True, side="left"): r""" Creates a non-commutative polynomial ideal. @@ -3464,7 +3464,7 @@ def __init__(self, ring, gens, coerce=True, side = "left"): raise ValueError("Only left and two-sided ideals are allowed.") Ideal_nc.__init__(self, ring, gens, coerce=coerce, side=side) - def __call_singular(self, cmd, arg = None): + def __call_singular(self, cmd, arg=None): """ Internal function for calling a Singular function. diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index 2f012daca29..cf4e6344a8c 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -1108,12 +1108,12 @@ class Polynomial_generic_sparse_field(Polynomial_generic_sparse, Polynomial_gene sage: loads(f.dumps()) == f True """ - def __init__(self, parent, x=None, check=True, is_gen = False, construct=False): + def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): Polynomial_generic_sparse.__init__(self, parent, x, check, is_gen) class Polynomial_generic_dense_field(Polynomial_generic_dense, Polynomial_generic_field): - def __init__(self, parent, x=None, check=True, is_gen = False, construct=False): + def __init__(self, parent, x=None, check=True, is_gen=False, construct=False): Polynomial_generic_dense.__init__(self, parent, x, check, is_gen) diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index 057aecded7c..7661d4c24ca 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -1031,7 +1031,7 @@ class of the image of the generator of the polynomial ring. self.__gen = self(self.polynomial_ring().gen()) return self.__gen - def is_field(self, proof = True): + def is_field(self, proof=True): """ Return whether or not this quotient ring is a field. @@ -1077,7 +1077,7 @@ def is_field(self, proof = True): self._refine_category_(Fields()) return ret - def is_integral_domain(self, proof = True): + def is_integral_domain(self, proof=True): """ Return whether or not this quotient ring is an integral domain. diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index ff1d3532124..a56b7c5bdce 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -541,7 +541,7 @@ def _implementation_names_impl(implementation, base_ring, sparse): return [None, "generic"] return NotImplemented - def is_integral_domain(self, proof = True): + def is_integral_domain(self, proof=True): """ EXAMPLES:: @@ -552,7 +552,7 @@ def is_integral_domain(self, proof = True): """ return self.base_ring().is_integral_domain(proof) - def is_unique_factorization_domain(self, proof = True): + def is_unique_factorization_domain(self, proof=True): """ EXAMPLES:: @@ -1065,9 +1065,9 @@ def change_var(self, var): """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing - return PolynomialRing(self.base_ring(), names = var, sparse=self.is_sparse()) + return PolynomialRing(self.base_ring(), names=var, sparse=self.is_sparse()) - def extend_variables(self, added_names, order = 'degrevlex'): + def extend_variables(self, added_names, order='degrevlex'): r""" Return a multivariate polynomial ring with the same base ring but with ``added_names`` as additional variables. @@ -1085,7 +1085,7 @@ def extend_variables(self, added_names, order = 'degrevlex'): if isinstance(added_names, str): added_names = added_names.split(',') - return PolynomialRing(self.base_ring(), names = self.variable_names() + tuple(added_names), order = order) + return PolynomialRing(self.base_ring(), names=self.variable_names() + tuple(added_names), order=order) def variable_names_recursive(self, depth=sage.rings.infinity.infinity): r""" @@ -1246,7 +1246,7 @@ def parameter(self): def is_exact(self): return self.base_ring().is_exact() - def is_field(self, proof = True): + def is_field(self, proof=True): """ Return False, since polynomial rings are never fields. @@ -1553,7 +1553,7 @@ def set_karatsuba_threshold(self, Karatsuba_threshold): """ self._Karatsuba_threshold = int(Karatsuba_threshold) - def polynomials( self, of_degree = None, max_degree = None ): + def polynomials( self, of_degree=None, max_degree=None ): """ Return an iterator over the polynomials of specified degree. @@ -1618,7 +1618,7 @@ def polynomials( self, of_degree = None, max_degree = None ): return self._polys_max( max_degree ) raise ValueError("you should pass exactly one of of_degree and max_degree") - def monics( self, of_degree = None, max_degree = None ): + def monics( self, of_degree=None, max_degree=None ): """ Return an iterator over the monic polynomials of specified degree. @@ -1793,8 +1793,8 @@ def _roots_univariate_polynomial(self, p, ring=None, multiplicities=True, algori if ring is not None and ring is not self: p = p.change_ring(ring) if degree_bound is None: - return p.roots(multiplicities = multiplicities, algorithm = algorithm) - return p.roots(multiplicities = multiplicities, algorithm = algorithm, degree_bound = degree_bound) + return p.roots(multiplicities=multiplicities, algorithm=algorithm) + return p.roots(multiplicities=multiplicities, algorithm=algorithm, degree_bound=degree_bound) roots = p._roots_from_factorization(p.factor(), multiplicities) if degree_bound is not None: diff --git a/src/sage/rings/power_series_ring.py b/src/sage/rings/power_series_ring.py index 65ed3311cd8..e023867b67e 100644 --- a/src/sage/rings/power_series_ring.py +++ b/src/sage/rings/power_series_ring.py @@ -1013,7 +1013,7 @@ def change_ring(self, R): Power Series Ring in T over Number Field in a with defining polynomial x^2 - 3 with a = 1.732050807568878? """ - return PowerSeriesRing(R, name = self.variable_name(), default_prec = self.default_prec()) + return PowerSeriesRing(R, name=self.variable_name(), default_prec=self.default_prec()) def change_var(self, var): """ @@ -1026,7 +1026,7 @@ def change_var(self, var): sage: R.change_var('D') Power Series Ring in D over Rational Field """ - return PowerSeriesRing(self.base_ring(), names = var, sparse=self.is_sparse()) + return PowerSeriesRing(self.base_ring(), names=var, sparse=self.is_sparse()) def is_exact(self): """ @@ -1184,7 +1184,7 @@ def __contains__(self, x): """ return self.has_coerce_map_from(parent(x)) - def is_field(self, proof = True): + def is_field(self, proof=True): """ Return ``False`` since the ring of power series over any ring is never a field. @@ -1351,4 +1351,4 @@ def unpickle_power_series_ring_v0(base_ring, name, default_prec, sparse): sage: loads(dumps(P)) == P # indirect doctest True """ - return PowerSeriesRing(base_ring, name=name, default_prec = default_prec, sparse=sparse) + return PowerSeriesRing(base_ring, name=name, default_prec=default_prec, sparse=sparse) diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index fe71e673da3..e57b7cf7988 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -1012,7 +1012,7 @@ def NF_elem_map(e): trial = Factorization(factorization).value() - return Factorization(factorization, unit = f.lc() / trial.lc()) + return Factorization(factorization, unit=f.lc() / trial.lc()) class AlgebraicRealField(Singleton, AlgebraicField_common, sage.rings.abc.AlgebraicRealField): diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index b683889b79a..11ac5510cf9 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -832,7 +832,7 @@ def defining_ideal(self): return self.__I @cached_method - def is_field(self, proof = True): + def is_field(self, proof=True): r""" Returns ``True`` if the quotient ring is a field. Checks to see if the defining ideal is maximal. diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index a5755f56206..90763e26622 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -318,7 +318,7 @@ def construction(self): from . import integer_ring return FractionField(), integer_ring.ZZ - def completion(self, p, prec, extras = {}): + def completion(self, p, prec, extras={}): r""" Return the completion of `\QQ` at `p`. From 8b14707300a8d4be6e1b636ac8ed72f4bde1ada7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 3 Jun 2023 17:37:01 +0200 Subject: [PATCH 25/56] minimal cleanup for imports in quadratic forms pyx files --- src/sage/quadratic_forms/count_local_2.pyx | 3 --- src/sage/quadratic_forms/ternary.pyx | 4 +--- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/sage/quadratic_forms/count_local_2.pyx b/src/sage/quadratic_forms/count_local_2.pyx index 7ffedf8d8d2..95228c64208 100644 --- a/src/sage/quadratic_forms/count_local_2.pyx +++ b/src/sage/quadratic_forms/count_local_2.pyx @@ -1,13 +1,10 @@ r""" Optimized counting of congruence solutions """ - from sage.arith.misc import is_prime, kronecker as kronecker_symbol, valuation from sage.rings.finite_rings.integer_mod cimport IntegerMod_gmp from sage.rings.finite_rings.integer_mod import Mod from sage.rings.finite_rings.integer_mod_ring import IntegerModRing -from sage.rings.integer_ring import ZZ -from sage.sets.set import Set def count_modp__by_gauss_sum(n, p, m, Qdet): diff --git a/src/sage/quadratic_forms/ternary.pyx b/src/sage/quadratic_forms/ternary.pyx index a0c86f7c7cb..28db34fd5eb 100644 --- a/src/sage/quadratic_forms/ternary.pyx +++ b/src/sage/quadratic_forms/ternary.pyx @@ -9,14 +9,12 @@ Helper code for ternary quadratic forms # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from sage.arith.misc import gcd, inverse_mod, xgcd from sage.matrix.constructor import matrix, identity_matrix, diagonal_matrix from sage.misc.prandom import randint -from sage.modules.free_module_element import vector -from sage.quadratic_forms.extras import extend_to_primitive from sage.rings.finite_rings.integer_mod import mod from sage.rings.integer_ring import ZZ From 29c51b0d7ae6464d2a88676a1885524ade9641a2 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 3 Jun 2023 17:51:58 +0100 Subject: [PATCH 26/56] update symengine(_py) to versions 0.10.0 and 0.10.1 --- build/pkgs/symengine/checksums.ini | 6 +- build/pkgs/symengine/package-version.txt | 2 +- build/pkgs/symengine_py/checksums.ini | 6 +- build/pkgs/symengine_py/package-version.txt | 2 +- ...tring-representation-of-sage-objects.patch | 118 ------------------ 5 files changed, 8 insertions(+), 126 deletions(-) delete mode 100644 build/pkgs/symengine_py/patches/0001-Fix-getting-string-representation-of-sage-objects.patch diff --git a/build/pkgs/symengine/checksums.ini b/build/pkgs/symengine/checksums.ini index 712c4eddb90..1c1813e7eea 100644 --- a/build/pkgs/symengine/checksums.ini +++ b/build/pkgs/symengine/checksums.ini @@ -1,5 +1,5 @@ tarball=symengine-VERSION.tar.gz -sha1=87a0104d8682cb2f192d8b4bf3435a514bdb6f4c -md5=967b913b365eda9fb30ecb3f1ded46f2 -cksum=2359123828 +sha1=11885879ddcd0a9ab69e36a79b93aef836d6c95d +md5=4673c85b423241ce85a9df35a7ed61bb +cksum=1344562381 upstream_url=https://github.com/symengine/symengine/releases/download/vVERSION/symengine-VERSION.tar.gz diff --git a/build/pkgs/symengine/package-version.txt b/build/pkgs/symengine/package-version.txt index 6f4eebdf6f6..571215736a6 100644 --- a/build/pkgs/symengine/package-version.txt +++ b/build/pkgs/symengine/package-version.txt @@ -1 +1 @@ -0.8.1 +0.10.1 diff --git a/build/pkgs/symengine_py/checksums.ini b/build/pkgs/symengine_py/checksums.ini index 3b0db282ffa..0235c5e9cd9 100644 --- a/build/pkgs/symengine_py/checksums.ini +++ b/build/pkgs/symengine_py/checksums.ini @@ -1,5 +1,5 @@ tarball=symengine.py-VERSION.tar.gz -sha1=16da67020baf6ab95cd517f58618fa7af1c8fc5e -md5=1c365dd039f8568b732c39fa4c9a7cf4 -cksum=3244910588 +sha1=fbbf052e66077ec51df319444b71f94114f33d9e +md5=fc5d2d7f571a880aa2e040214aed2ff0 +cksum=2535731241 upstream_url=https://github.com/symengine/symengine.py/archive/vVERSION.tar.gz diff --git a/build/pkgs/symengine_py/package-version.txt b/build/pkgs/symengine_py/package-version.txt index 25329dc9cba..78bc1abd14f 100644 --- a/build/pkgs/symengine_py/package-version.txt +++ b/build/pkgs/symengine_py/package-version.txt @@ -1 +1 @@ -0.8.1.p0 +0.10.0 diff --git a/build/pkgs/symengine_py/patches/0001-Fix-getting-string-representation-of-sage-objects.patch b/build/pkgs/symengine_py/patches/0001-Fix-getting-string-representation-of-sage-objects.patch deleted file mode 100644 index 78c71610b53..00000000000 --- a/build/pkgs/symengine_py/patches/0001-Fix-getting-string-representation-of-sage-objects.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 68c90c14ae3e779b88a513195cc89db599d10efb Mon Sep 17 00:00:00 2001 -From: Isuru Fernando -Date: Fri, 1 Oct 2021 19:25:07 -0700 -Subject: [PATCH] Fix getting string representation of sage objects - ---- - symengine/lib/pywrapper.cpp | 17 ++++++----------- - symengine/lib/symengine_wrapper.pyx | 9 ++++++--- - symengine/tests/test_sage.py | 10 +++------- - symengine/tests/test_sympy_conv.py | 1 + - 4 files changed, 16 insertions(+), 21 deletions(-) - -diff --git a/symengine/lib/pywrapper.cpp b/symengine/lib/pywrapper.cpp -index ca7b7c1..c321ea3 100644 ---- a/symengine/lib/pywrapper.cpp -+++ b/symengine/lib/pywrapper.cpp -@@ -175,17 +175,12 @@ RCP PyNumber::eval(long bits) const { - } - - std::string PyNumber::__str__() const { -- PyObject* temp; -- std::string str; --#if PY_MAJOR_VERSION > 2 -- temp = PyUnicode_AsUTF8String(pyobject_); -- str = std::string(PyBytes_AsString(temp)); --#else -- temp = PyObject_Str(pyobject_); -- str = std::string(PyString_AsString(temp)); --#endif -- Py_XDECREF(temp); -- return str; -+ Py_ssize_t size; -+ PyObject *pystr = PyObject_Str(pyobject_); -+ const char* data = PyUnicode_AsUTF8AndSize(pystr, &size); -+ std::string result = std::string(data, size); -+ Py_XDECREF(pystr); -+ return result; - } - - // PyFunctionClass -diff --git a/symengine/lib/symengine_wrapper.pyx b/symengine/lib/symengine_wrapper.pyx -index d178afe..d18c058 100644 ---- a/symengine/lib/symengine_wrapper.pyx -+++ b/symengine/lib/symengine_wrapper.pyx -@@ -2690,7 +2690,7 @@ class FunctionSymbol(Function): - def _sage_(self): - import sage.all as sage - name = self.get_name() -- return sage.function(name, *self.args_as_sage()) -+ return sage.function(name)(*self.args_as_sage()) - - def func(self, *values): - name = self.get_name() -@@ -2711,7 +2711,7 @@ cdef rcp_const_basic pynumber_to_symengine(PyObject* o1): - - cdef PyObject* symengine_to_sage(rcp_const_basic o1): - import sage.all as sage -- t = sage.SR(c2py(o1)._sage_()) -+ t = c2py(o1)._sage_() - Py_XINCREF(t) - return (t) - -@@ -2765,7 +2765,10 @@ cdef class PyNumber(Number): - - def _sage_(self): - import sage.all as sage -- return sage.SR(self.pyobject()) -+ res = self.pyobject() -+ if hasattr(res, '_sage_'): -+ return res._sage_() -+ return res - - def pyobject(self): - return deref(symengine.rcp_static_cast_PyNumber(self.thisptr)).get_py_object() -diff --git a/symengine/tests/test_sage.py b/symengine/tests/test_sage.py -index 3b994ab..e364bd6 100644 ---- a/symengine/tests/test_sage.py -+++ b/symengine/tests/test_sage.py -@@ -66,9 +66,9 @@ def test_sage_conversions(): - assert cos(x1)._sage_() == sage.cos(x) - assert cos(x1) == sympify(sage.cos(x)) - -- assert function_symbol('f', x1, y1)._sage_() == sage.function('f', x, y) -+ assert function_symbol('f', x1, y1)._sage_() == sage.function('f')(x, y) - assert (function_symbol('f', 2 * x1, x1 + y1).diff(x1)._sage_() == -- sage.function('f', 2 * x, x + y).diff(x)) -+ sage.function('f')(2 * x, x + y).diff(x)) - - assert LambertW(x1) == LambertW(x) - assert LambertW(x1)._sage_() == sage.lambert_w(x) -@@ -142,11 +142,7 @@ def test_sage_conversions(): - b = b + 8 - assert isinstance(b, PyNumber) - assert b._sage_() == a -- -- a = a + x -- b = b + x -- assert isinstance(b, Add) -- assert b._sage_() == a -+ assert str(a) == str(b) - - # Sage Function - e = x1 + wrap_sage_function(sage.log_gamma(x)) -diff --git a/symengine/tests/test_sympy_conv.py b/symengine/tests/test_sympy_conv.py -index 3f8b152..ee070a8 100644 ---- a/symengine/tests/test_sympy_conv.py -+++ b/symengine/tests/test_sympy_conv.py -@@ -760,6 +760,7 @@ def test_pynumber(): - assert isinstance(b, PyNumber) - assert b == a # Check equality via SymEngine - assert a == b # Check equality via SymPy -+ assert str(a) == str(b) - - a = 1 - a - b = 1 - b --- -2.7.4 - From 8a55ca8fdf62a509abd07a6a4f507e997a74bddc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 24 May 2023 22:26:44 -0700 Subject: [PATCH 27/56] sage.graphs: Modularization fixes for imports --- src/sage/graphs/generators/basic.py | 4 ++-- src/sage/graphs/generic_graph.py | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/generators/basic.py b/src/sage/graphs/generators/basic.py index 27578e76e4b..33e04e94b38 100644 --- a/src/sage/graphs/generators/basic.py +++ b/src/sage/graphs/generators/basic.py @@ -20,8 +20,6 @@ # import from Sage library from sage.graphs.graph import Graph from math import sin, cos, pi -from numpy import corrcoef -from sage.matrix.constructor import Matrix def BullGraph(): @@ -418,6 +416,8 @@ def CorrelationGraph(seqs, alpha, include_anticorrelation): [(0, 0, None), (0, 1, None), (0, 2, None), (1, 1, None), (1, 2, None), (2, 2, None)] """ + from numpy import corrcoef + from sage.matrix.constructor import Matrix # compute pairwise correlation coeffecients corrs = corrcoef(seqs) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index cd1be3f851a..d7d06530c93 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -440,15 +440,16 @@ from sage.misc.cachefunc import cached_method from sage.misc.prandom import random from sage.misc.superseded import deprecation -from sage.misc.lazy_import import LazyImport +from sage.misc.lazy_import import lazy_import, LazyImport from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer from sage.rings.rational import Rational -from sage.matrix.constructor import matrix from sage.rings.rational_field import QQ from sage.features.igraph import python_igraph as igraph_feature +lazy_import('sage.matrix.constructor', 'matrix') + to_hex = LazyImport('matplotlib.colors', 'to_hex') From a14c1b9d1de4f08d13df34b1c5be953ac42abc81 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 25 May 2023 17:51:46 -0700 Subject: [PATCH 28/56] sage.graphs: Modularization fixes for imports --- src/sage/graphs/all.py | 4 ++-- src/sage/graphs/graph.py | 8 ++++---- src/sage/graphs/graph_coloring.pyx | 18 +++++++++++++----- src/sage/graphs/hyperbolicity.pyx | 8 ++++++-- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/sage/graphs/all.py b/src/sage/graphs/all.py index edb920f6897..2cbc65d0e23 100644 --- a/src/sage/graphs/all.py +++ b/src/sage/graphs/all.py @@ -4,7 +4,7 @@ lazy_import("sage.graphs.graph_generators", "graphs") lazy_import("sage.graphs.digraph_generators", "digraphs") lazy_import("sage.graphs.hypergraph_generators", "hypergraphs") -from .graph_database import GraphDatabase, GenericGraphQuery, GraphQuery +lazy_import("sage.graphs.graph_database", ["GraphDatabase", "GenericGraphQuery", "GraphQuery"]) from .graph import Graph from .digraph import DiGraph from .bipartite_graph import BipartiteGraph @@ -13,7 +13,7 @@ import sage.graphs.partial_cube from . import graph_list as graphs_list lazy_import("sage.graphs", "graph_coloring") -from .graph_database import graph_db_info +lazy_import("sage.graphs.graph_database", "graph_db_info") lazy_import("sage.graphs.graph_editor", "graph_editor") from sage.graphs.isgci import graph_classes diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index b351b8501c0..a83da34a230 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -424,7 +424,7 @@ from sage.graphs.views import EdgesView from sage.parallel.decorate import parallel -from sage.misc.lazy_import import lazy_import +from sage.misc.lazy_import import lazy_import, LazyImport from sage.features import PythonModule lazy_import('sage.graphs.mcqd', ['mcqd'], feature=PythonModule('sage.graphs.mcqd', spkg='mcqd')) @@ -10022,7 +10022,7 @@ def bipartite_double(self, extended=False): # Aliases to functions defined in other modules from sage.graphs.weakly_chordal import is_long_hole_free, is_long_antihole_free, is_weakly_chordal from sage.graphs.asteroidal_triples import is_asteroidal_triple_free - from sage.graphs.chrompoly import chromatic_polynomial + chromatic_polynomial = LazyImport('sage.graphs.chrompoly', 'chromatic_polynomial', at_startup=True) from sage.graphs.graph_decompositions.rankwidth import rank_decomposition from sage.graphs.graph_decompositions.tree_decomposition import treewidth from sage.graphs.graph_decompositions.vertex_separation import pathwidth @@ -10030,7 +10030,7 @@ def bipartite_double(self, extended=False): from sage.graphs.graph_decompositions.clique_separators import atoms_and_clique_separators from sage.graphs.graph_decompositions.bandwidth import bandwidth from sage.graphs.graph_decompositions.cutwidth import cutwidth - from sage.graphs.matchpoly import matching_polynomial + matching_polynomial = LazyImport('sage.graphs.matchpoly', 'matching_polynomial', at_startup=True) from sage.graphs.cliquer import all_max_clique as cliques_maximum from sage.graphs.cliquer import all_cliques from sage.graphs.spanning_tree import random_spanning_tree @@ -10047,7 +10047,7 @@ def bipartite_double(self, extended=False): from sage.graphs.connectivity import is_triconnected from sage.graphs.comparability import is_comparability from sage.graphs.comparability import is_permutation - from sage.graphs.convexity_properties import geodetic_closure + geodetic_closure = LazyImport('sage.graphs.convexity_properties', 'geodetic_closure', at_startup=True) from sage.graphs.domination import is_dominating from sage.graphs.domination import is_redundant from sage.graphs.domination import private_neighbors diff --git a/src/sage/graphs/graph_coloring.pyx b/src/sage/graphs/graph_coloring.pyx index 844969f8b94..f04f1e382e8 100644 --- a/src/sage/graphs/graph_coloring.pyx +++ b/src/sage/graphs/graph_coloring.pyx @@ -65,13 +65,14 @@ Methods # **************************************************************************** from copy import copy -from sage.combinat.matrices.dlxcpp import DLXCPP from libcpp.vector cimport vector from libcpp.pair cimport pair -from sage.numerical.mip import MixedIntegerLinearProgram -from sage.numerical.mip import MIPSolverException from sage.graphs.independent_sets import IndependentSets +from sage.misc.lazy_import import LazyImport + +DLXCPP = LazyImport('sage.combinat.matrices.dlxcpp', 'DLXCPP') +MixedIntegerLinearProgram = LazyImport('sage.numerical.mip', 'MixedIntegerLinearProgram') def all_graph_colorings(G, n, count_only=False, hex_colors=False, vertex_color_dict=False): @@ -643,6 +644,7 @@ def vertex_coloring(g, k=None, value_only=False, hex_colors=False, solver=None, # it, and it can help. p.add_constraint(color[next(g.vertex_iterator()), 0], max=1, min=1) + from sage.numerical.mip import MIPSolverException try: if value_only: p.solve(objective_only=True, log=verbose) @@ -1038,6 +1040,7 @@ def grundy_coloring(g, k, value_only=True, solver=None, verbose=0, # Trying to use as many colors as possible p.set_objective(p.sum(is_used[i] for i in range(k))) + from sage.numerical.mip import MIPSolverException try: p.solve(log=verbose) except MIPSolverException: @@ -1227,6 +1230,7 @@ def b_coloring(g, k, value_only=True, solver=None, verbose=0, # We want to maximize the number of used colors p.set_objective(p.sum(is_used[i] for i in range(k))) + from sage.numerical.mip import MIPSolverException try: p.solve(log=verbose) except MIPSolverException: @@ -1458,6 +1462,8 @@ def edge_coloring(g, value_only=False, vizing=False, hex_colors=False, solver=No # We color the edges of the vertex of maximum degree for i, v in enumerate(h.neighbor_iterator(X)): p.add_constraint(color[frozenset((v, X)), i] == 1) + + from sage.numerical.mip import MIPSolverException try: p.solve(objective_only=value_only, log=verbose) except MIPSolverException: @@ -1885,6 +1891,7 @@ def linear_arboricity(g, plus_one=None, hex_colors=False, value_only=False, # no cycles p.add_constraint(p.sum(r[i, (u, v)] for v in g.neighbor_iterator(u)), max=MAD) + from sage.numerical.mip import MIPSolverException try: p.solve(objective_only=value_only, log=verbose) if value_only: @@ -2139,6 +2146,7 @@ def acyclic_edge_coloring(g, hex_colors=False, value_only=False, k=0, p.set_objective(None) + from sage.numerical.mip import MIPSolverException try: p.solve(objective_only=value_only, log=verbose) if value_only: @@ -2181,9 +2189,9 @@ def acyclic_edge_coloring(g, hex_colors=False, value_only=False, k=0, cdef class Test: r""" - This class performs randomized testing for all_graph_colorings. + This class performs randomized testing for :func:`all_graph_colorings`. - Since everything else in this file is derived from all_graph_colorings, this + Since everything else in this file is derived from :func:`all_graph_colorings`, this is a pretty good randomized tester for the entire file. Note that for a graph `G`, ``G.chromatic_polynomial()`` uses an entirely different algorithm, so we provide a good, independent test. diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index 05fb3c3da79..ff2d20a4d80 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -146,7 +146,7 @@ Methods # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# https://www.gnu.org/licenses/ +# http://www.gnu.org/licenses/ # **************************************************************************** from libc.string cimport memset @@ -157,7 +157,7 @@ from memory_allocator cimport MemoryAllocator from sage.graphs.distances_all_pairs cimport c_distances_all_pairs from sage.arith.misc import binomial from sage.rings.integer_ring import ZZ -from sage.rings.real_mpfr import RR +from sage.data_structures.bitset import Bitset from sage.graphs.base.static_sparse_graph cimport short_digraph from sage.graphs.base.static_sparse_graph cimport init_short_digraph from sage.graphs.base.static_sparse_graph cimport free_short_digraph @@ -1287,6 +1287,8 @@ def hyperbolicity(G, elif approximation_factor == 1.0: pass elif algorithm in ['CCL', 'CCL+FA', 'BCCM']: + from sage.rings.real_mpfr import RR + if approximation_factor not in RR or approximation_factor < 1.0: raise ValueError("the approximation factor must be >= 1.0") else: @@ -1297,6 +1299,8 @@ def hyperbolicity(G, elif additive_gap == 0.0: pass elif algorithm in ['CCL', 'CCL+FA', 'BCCM']: + from sage.rings.real_mpfr import RR + if additive_gap not in RR or additive_gap < 0.0: raise ValueError("the additive gap must be a real positive number") else: From 42363bf15c05eb8da0ea8cae56bd15f44f4ab21c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 26 May 2023 18:01:39 -0700 Subject: [PATCH 29/56] src/sage/graphs/bipartite_graph.py: Use lazy_import --- src/sage/graphs/bipartite_graph.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/bipartite_graph.py b/src/sage/graphs/bipartite_graph.py index 9b843ca965e..ed96e1f710c 100644 --- a/src/sage/graphs/bipartite_graph.py +++ b/src/sage/graphs/bipartite_graph.py @@ -47,6 +47,9 @@ from sage.rings.integer import Integer from sage.misc.decorators import rename_keyword from sage.misc.cachefunc import cached_method +from sage.misc.lazy_import import lazy_import + +lazy_import('networkx', ['MultiGraph', 'Graph'], as_=['networkx_MultiGraph', 'networkx_Graph']) class BipartiteGraph(Graph): @@ -504,8 +507,7 @@ def __init__(self, data=None, partition=None, check=True, hash_labels=None, *arg if len(left) + len(right) != self.num_verts(): raise ValueError("not all vertices appear in partition") - import networkx - if isinstance(data, (networkx.MultiGraph, networkx.Graph)): + if isinstance(data, (networkx_MultiGraph, networkx_Graph)): if hasattr(data, "node_type"): # Assume the graph is bipartite self.left = set() From 94bca97cfe97c46287b2f5d3264f872fa63fbb63 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 26 May 2023 18:02:40 -0700 Subject: [PATCH 30/56] sage.graphs: Add # optional --- src/sage/graphs/base/boost_graph.pyx | 6 +- src/sage/graphs/base/c_graph.pyx | 28 +- .../graphs/base/static_sparse_backend.pyx | 10 +- src/sage/graphs/bipartite_graph.py | 124 +++---- src/sage/graphs/centrality.pyx | 34 +- src/sage/graphs/comparability.pyx | 12 +- src/sage/graphs/connectivity.pyx | 4 +- src/sage/graphs/digraph.py | 141 ++++---- src/sage/graphs/distances_all_pairs.pyx | 38 +-- src/sage/graphs/dot2tex_utils.py | 6 +- src/sage/graphs/edge_connectivity.pyx | 8 +- src/sage/graphs/generators/basic.py | 20 +- .../graphs/generators/classical_geometries.py | 322 +++++++++--------- src/sage/graphs/generators/degree_sequence.py | 42 ++- .../graphs/generators/distance_regular.pyx | 18 +- src/sage/graphs/generators/families.py | 91 ++--- src/sage/graphs/generators/random.py | 170 ++++----- src/sage/graphs/generic_graph.py | 73 ++-- src/sage/graphs/generic_graph_pyx.pyx | 28 +- .../graphs/graph_decompositions/bandwidth.pyx | 4 +- .../graph_decompositions/graph_products.pyx | 4 +- .../modular_decomposition.py | 7 +- .../vertex_separation.pyx | 36 +- src/sage/graphs/graph_input.py | 34 +- src/sage/graphs/graph_list.py | 4 +- src/sage/graphs/graph_plot_js.py | 16 +- src/sage/graphs/hypergraph_generators.py | 16 +- .../graphs/isoperimetric_inequalities.pyx | 4 +- src/sage/graphs/line_graph.pyx | 38 +-- src/sage/graphs/partial_cube.py | 10 +- src/sage/graphs/spanning_tree.pyx | 21 +- src/sage/graphs/strongly_regular_db.pyx | 25 +- src/sage/graphs/traversals.pyx | 42 +-- src/sage/graphs/views.pyx | 6 +- 34 files changed, 735 insertions(+), 707 deletions(-) diff --git a/src/sage/graphs/base/boost_graph.pyx b/src/sage/graphs/base/boost_graph.pyx index 22a6f4e5ba4..d6508f172f8 100644 --- a/src/sage/graphs/base/boost_graph.pyx +++ b/src/sage/graphs/base/boost_graph.pyx @@ -572,7 +572,7 @@ cpdef bandwidth_heuristics(g, algorithm='cuthill_mckee'): from sage.graphs.base.boost_graph import bandwidth_heuristics sage: bandwidth_heuristics(Graph()) (0, []) - sage: bandwidth_heuristics(graphs.RandomGNM(10,0)) + sage: bandwidth_heuristics(graphs.RandomGNM(10,0)) # optional - networkx (0, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) """ @@ -1964,8 +1964,8 @@ cpdef diameter_DHV(g, weight_function=None, check_weight=True): TESTS:: - sage: G = graphs.RandomBarabasiAlbert(17,6) - sage: diameter_DHV(G) == G.diameter(algorithm = 'Dijkstra_Boost') + sage: G = graphs.RandomBarabasiAlbert(17,6) # optional - networkx + sage: diameter_DHV(G) == G.diameter(algorithm = 'Dijkstra_Boost') # optional - networkx True sage: G = Graph([(0,1,-1)], weighted=True) sage: diameter_DHV(G) diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index 83a01eb4f9b..d6fb119d3cf 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -1577,11 +1577,11 @@ cdef class CGraphBackend(GenericGraphBackend): We check that the bug described in :trac:`8406` is gone:: sage: G = Graph() - sage: R. = GF(3**3) - sage: S. = R[] - sage: G.add_vertex(a**2) - sage: G.add_vertex(x) - sage: G.vertices(sort=True) + sage: R. = GF(3**3) # optional - sage.rings.finite_rings + sage: S. = R[] # optional - sage.rings.finite_rings + sage: G.add_vertex(a**2) # optional - sage.rings.finite_rings + sage: G.add_vertex(x) # optional - sage.rings.finite_rings + sage: G.vertices(sort=True) # optional - sage.rings.finite_rings [a^2, x] And that the bug described in :trac:`9610` is gone:: @@ -2107,9 +2107,9 @@ cdef class CGraphBackend(GenericGraphBackend): Ensure that :trac:`13664` is fixed :: - sage: W = WeylGroup(["A",1]) - sage: G = W.cayley_graph() - sage: Graph(G).degree() + sage: W = WeylGroup(["A",1]) # optional - sage.combinat sage.groups + sage: G = W.cayley_graph() # optional - sage.combinat sage.groups + sage: Graph(G).degree() # optional - sage.combinat sage.groups [1, 1] sage: h = Graph() sage: h.add_edge(1,2,"a") @@ -4406,9 +4406,9 @@ cdef class CGraphBackend(GenericGraphBackend): TESTS:: - sage: P = posets.PentagonPoset() - sage: H = P._hasse_diagram - sage: H._backend.is_connected() + sage: P = posets.PentagonPoset() # optional - sage.modules + sage: H = P._hasse_diagram # optional - sage.modules + sage: H._backend.is_connected() # optional - sage.modules True """ cdef int v_int @@ -4589,9 +4589,9 @@ cdef class CGraphBackend(GenericGraphBackend): TESTS:: - sage: m = Matrix(3,[0, 1, 1, 0, 0, 0, 0, 1, 0]) - sage: g = DiGraph(m) - sage: g.is_directed_acyclic(certificate=True) + sage: m = Matrix(3,[0, 1, 1, 0, 0, 0, 0, 1, 0]) # optional - sage.modules + sage: g = DiGraph(m) # optional - sage.modules + sage: g.is_directed_acyclic(certificate=True) # optional - sage.modules (True, [0, 2, 1]) """ if not self._directed: diff --git a/src/sage/graphs/base/static_sparse_backend.pyx b/src/sage/graphs/base/static_sparse_backend.pyx index c380777c0e7..b8b32405515 100644 --- a/src/sage/graphs/base/static_sparse_backend.pyx +++ b/src/sage/graphs/base/static_sparse_backend.pyx @@ -446,17 +446,17 @@ cdef class StaticSparseBackend(CGraphBackend): :: - sage: g = DiGraph(digraphs.DeBruijn(4, 3), data_structure="static_sparse") - sage: gi = DiGraph(g, data_structure="static_sparse") - sage: gi.edges(sort=True)[0] + sage: g = DiGraph(digraphs.DeBruijn(4, 3), data_structure="static_sparse") # optional - sage.combinat + sage: gi = DiGraph(g, data_structure="static_sparse") # optional - sage.combinat + sage: gi.edges(sort=True)[0] # optional - sage.combinat ('000', '000', '0') - sage: sorted(gi.edges_incident('111')) + sage: sorted(gi.edges_incident('111')) # optional - sage.combinat [('111', '110', '0'), ('111', '111', '1'), ('111', '112', '2'), ('111', '113', '3')] - sage: set(g.edges(sort=False)) == set(gi.edges(sort=False)) + sage: set(g.edges(sort=False)) == set(gi.edges(sort=False)) # optional - sage.combinat True :: diff --git a/src/sage/graphs/bipartite_graph.py b/src/sage/graphs/bipartite_graph.py index ed96e1f710c..c30ed062e50 100644 --- a/src/sage/graphs/bipartite_graph.py +++ b/src/sage/graphs/bipartite_graph.py @@ -198,16 +198,16 @@ class BipartiteGraph(Graph): #. From a reduced adjacency matrix:: - sage: M = Matrix([(1,1,1,0,0,0,0), (1,0,0,1,1,0,0), + sage: M = Matrix([(1,1,1,0,0,0,0), (1,0,0,1,1,0,0), # optional - sage.modules ....: (0,1,0,1,0,1,0), (1,1,0,1,0,0,1)]) - sage: M + sage: M # optional - sage.modules [1 1 1 0 0 0 0] [1 0 0 1 1 0 0] [0 1 0 1 0 1 0] [1 1 0 1 0 0 1] - sage: H = BipartiteGraph(M); H + sage: H = BipartiteGraph(M); H # optional - sage.modules Bipartite graph on 11 vertices - sage: H.edges(sort=True) + sage: H.edges(sort=True) # optional - sage.modules [(0, 7, None), (0, 8, None), (0, 10, None), @@ -224,9 +224,9 @@ class BipartiteGraph(Graph): :: - sage: M = Matrix([(1, 1, 2, 0, 0), (0, 2, 1, 1, 1), (0, 1, 2, 1, 1)]) - sage: B = BipartiteGraph(M, multiedges=True, sparse=True) - sage: B.edges(sort=True) + sage: M = Matrix([(1, 1, 2, 0, 0), (0, 2, 1, 1, 1), (0, 1, 2, 1, 1)]) # optional - sage.modules + sage: B = BipartiteGraph(M, multiedges=True, sparse=True) # optional - sage.modules + sage: B.edges(sort=True) # optional - sage.modules [(0, 5, None), (1, 5, None), (1, 6, None), @@ -244,13 +244,13 @@ class BipartiteGraph(Graph): :: - sage: F. = GF(4) - sage: MS = MatrixSpace(F, 2, 3) - sage: M = MS.matrix([[0, 1, a + 1], [a, 1, 1]]) - sage: B = BipartiteGraph(M, weighted=True, sparse=True) - sage: B.edges(sort=True) + sage: F. = GF(4) # optional - sage.modules sage.rings.finite_rings + sage: MS = MatrixSpace(F, 2, 3) # optional - sage.modules sage.rings.finite_rings + sage: M = MS.matrix([[0, 1, a + 1], [a, 1, 1]]) # optional - sage.modules sage.rings.finite_rings + sage: B = BipartiteGraph(M, weighted=True, sparse=True) # optional - sage.modules sage.rings.finite_rings + sage: B.edges(sort=True) # optional - sage.modules sage.rings.finite_rings [(0, 4, a), (1, 3, 1), (1, 4, 1), (2, 3, a + 1), (2, 4, 1)] - sage: B.weighted() + sage: B.weighted() # optional - sage.modules sage.rings.finite_rings True #. From an alist file:: @@ -264,7 +264,7 @@ class BipartiteGraph(Graph): ....: 1 2 4 7 \n") ....: f.flush() ....: B = BipartiteGraph(f.name) - sage: B.is_isomorphic(H) + sage: B.is_isomorphic(H) # optional - sage.modules True #. From a ``graph6`` string:: @@ -328,15 +328,15 @@ class BipartiteGraph(Graph): Ensure that we can construct a ``BipartiteGraph`` with isolated vertices via the reduced adjacency matrix (:trac:`10356`):: - sage: a = BipartiteGraph(matrix(2, 2, [1, 0, 1, 0])) - sage: a + sage: a = BipartiteGraph(matrix(2, 2, [1, 0, 1, 0])) # optional - sage.modules + sage: a # optional - sage.modules Bipartite graph on 4 vertices - sage: a.vertices(sort=True) + sage: a.vertices(sort=True) # optional - sage.modules [0, 1, 2, 3] - sage: g = BipartiteGraph(matrix(4, 4, [1] * 4 + [0] * 12)) - sage: g.vertices(sort=True) + sage: g = BipartiteGraph(matrix(4, 4, [1] * 4 + [0] * 12)) # optional - sage.modules + sage: g.vertices(sort=True) # optional - sage.modules [0, 1, 2, 3, 4, 5, 6, 7] - sage: sorted(g.left.union(g.right)) + sage: sorted(g.left.union(g.right)) # optional - sage.modules [0, 1, 2, 3, 4, 5, 6, 7] Make sure that loops are not allowed (:trac:`23275`):: @@ -1805,26 +1805,26 @@ def save_afile(self, fname): EXAMPLES:: - sage: M = Matrix([(1,1,1,0,0,0,0), (1,0,0,1,1,0,0), + sage: M = Matrix([(1,1,1,0,0,0,0), (1,0,0,1,1,0,0), # optional - sage.modules ....: (0,1,0,1,0,1,0), (1,1,0,1,0,0,1)]) - sage: M + sage: M # optional - sage.modules [1 1 1 0 0 0 0] [1 0 0 1 1 0 0] [0 1 0 1 0 1 0] [1 1 0 1 0 0 1] - sage: b = BipartiteGraph(M) - sage: import tempfile - sage: with tempfile.NamedTemporaryFile() as f: + sage: b = BipartiteGraph(M) # optional - sage.modules + sage: import tempfile # optional - sage.modules + sage: with tempfile.NamedTemporaryFile() as f: # optional - sage.modules ....: b.save_afile(f.name) ....: b2 = BipartiteGraph(f.name) - sage: b.is_isomorphic(b2) + sage: b.is_isomorphic(b2) # optional - sage.modules True TESTS:: sage: import tempfile sage: f = tempfile.NamedTemporaryFile() - sage: for order in range(3, 13, 3): + sage: for order in range(3, 13, 3): # optional - sage.combinat ....: num_chks = int(order / 3) ....: num_vars = order - num_chks ....: partition = (list(range(num_vars)), list(range(num_vars, num_vars+num_chks))) @@ -1922,78 +1922,78 @@ def reduced_adjacency_matrix(self, sparse=True, *, base_ring=None, **kwds): Bipartite graphs that are not weighted will return a matrix over ZZ, unless a base ring is specified:: - sage: M = Matrix([(1,1,1,0,0,0,0), (1,0,0,1,1,0,0), + sage: M = Matrix([(1,1,1,0,0,0,0), (1,0,0,1,1,0,0), # optional - sage.modules ....: (0,1,0,1,0,1,0), (1,1,0,1,0,0,1)]) - sage: B = BipartiteGraph(M) - sage: N = B.reduced_adjacency_matrix() - sage: N + sage: B = BipartiteGraph(M) # optional - sage.modules + sage: N = B.reduced_adjacency_matrix() # optional - sage.modules + sage: N # optional - sage.modules [1 1 1 0 0 0 0] [1 0 0 1 1 0 0] [0 1 0 1 0 1 0] [1 1 0 1 0 0 1] - sage: N == M + sage: N == M # optional - sage.modules True - sage: N[0,0].parent() + sage: N[0,0].parent() # optional - sage.modules Integer Ring - sage: N2 = B.reduced_adjacency_matrix(base_ring=RDF); N2 + sage: N2 = B.reduced_adjacency_matrix(base_ring=RDF); N2 # optional - sage.modules [1.0 1.0 1.0 0.0 0.0 0.0 0.0] [1.0 0.0 0.0 1.0 1.0 0.0 0.0] [0.0 1.0 0.0 1.0 0.0 1.0 0.0] [1.0 1.0 0.0 1.0 0.0 0.0 1.0] - sage: N2[0, 0].parent() + sage: N2[0, 0].parent() # optional - sage.modules Real Double Field Multi-edge graphs also return a matrix over ZZ, unless a base ring is specified:: - sage: M = Matrix([(1,1,2,0,0), (0,2,1,1,1), (0,1,2,1,1)]) - sage: B = BipartiteGraph(M, multiedges=True, sparse=True) - sage: N = B.reduced_adjacency_matrix() - sage: N == M + sage: M = Matrix([(1,1,2,0,0), (0,2,1,1,1), (0,1,2,1,1)]) # optional - sage.modules + sage: B = BipartiteGraph(M, multiedges=True, sparse=True) # optional - sage.modules + sage: N = B.reduced_adjacency_matrix() # optional - sage.modules + sage: N == M # optional - sage.modules True - sage: N[0,0].parent() + sage: N[0,0].parent() # optional - sage.modules Integer Ring - sage: N2 = B.reduced_adjacency_matrix(base_ring=RDF) - sage: N2[0, 0].parent() + sage: N2 = B.reduced_adjacency_matrix(base_ring=RDF) # optional - sage.modules + sage: N2[0, 0].parent() # optional - sage.modules Real Double Field Weighted graphs will return a matrix over the ring given by their (first) weights, unless a base ring is specified:: - sage: F. = GF(4) - sage: MS = MatrixSpace(F, 2, 3) - sage: M = MS.matrix([[0, 1, a+1], [a, 1, 1]]) - sage: B = BipartiteGraph(M, weighted=True, sparse=True) - sage: N = B.reduced_adjacency_matrix(sparse=False) - sage: N == M + sage: F. = GF(4) # optional - sage.modules sage.rings.finite_rings + sage: MS = MatrixSpace(F, 2, 3) # optional - sage.modules sage.rings.finite_rings + sage: M = MS.matrix([[0, 1, a+1], [a, 1, 1]]) # optional - sage.modules sage.rings.finite_rings + sage: B = BipartiteGraph(M, weighted=True, sparse=True) # optional - sage.modules sage.rings.finite_rings + sage: N = B.reduced_adjacency_matrix(sparse=False) # optional - sage.modules sage.rings.finite_rings + sage: N == M # optional - sage.modules sage.rings.finite_rings True - sage: N[0,0].parent() + sage: N[0,0].parent() # optional - sage.modules sage.rings.finite_rings Finite Field in a of size 2^2 - sage: N2 = B.reduced_adjacency_matrix(base_ring=F) - sage: N2[0, 0].parent() + sage: N2 = B.reduced_adjacency_matrix(base_ring=F) # optional - sage.modules sage.rings.finite_rings + sage: N2[0, 0].parent() # optional - sage.modules sage.rings.finite_rings Finite Field in a of size 2^2 TESTS:: sage: B = BipartiteGraph() - sage: B.reduced_adjacency_matrix() + sage: B.reduced_adjacency_matrix() # optional - sage.modules [] - sage: M = Matrix([[0,0], [0,0]]) - sage: BipartiteGraph(M).reduced_adjacency_matrix() == M + sage: M = Matrix([[0,0], [0,0]]) # optional - sage.modules + sage: BipartiteGraph(M).reduced_adjacency_matrix() == M # optional - sage.modules True - sage: M = Matrix([[10,2/3], [0,0]]) - sage: B = BipartiteGraph(M, weighted=True, sparse=True) - sage: M == B.reduced_adjacency_matrix() + sage: M = Matrix([[10,2/3], [0,0]]) # optional - sage.modules + sage: B = BipartiteGraph(M, weighted=True, sparse=True) # optional - sage.modules + sage: M == B.reduced_adjacency_matrix() # optional - sage.modules True An error is raised if the specified base ring is not compatible with the type of the weights of the bipartite graph:: - sage: F. = GF(4) - sage: MS = MatrixSpace(F, 2, 3) - sage: M = MS.matrix([[0, 1, a+1], [a, 1, 1]]) - sage: B = BipartiteGraph(M, weighted=True, sparse=True) - sage: B.reduced_adjacency_matrix(base_ring=RDF) + sage: F. = GF(4) # optional - sage.modules sage.rings.finite_rings + sage: MS = MatrixSpace(F, 2, 3) # optional - sage.modules sage.rings.finite_rings + sage: M = MS.matrix([[0, 1, a+1], [a, 1, 1]]) # optional - sage.modules sage.rings.finite_rings + sage: B = BipartiteGraph(M, weighted=True, sparse=True) # optional - sage.modules sage.rings.finite_rings + sage: B.reduced_adjacency_matrix(base_ring=RDF) # optional - sage.modules sage.rings.finite_rings Traceback (most recent call last): ... TypeError: float() argument must be a string or a ...number, not 'sage.rings.finite_rings.element_givaro.FiniteField_givaroElement' diff --git a/src/sage/graphs/centrality.pyx b/src/sage/graphs/centrality.pyx index 91f0fc21a52..9de214115f9 100755 --- a/src/sage/graphs/centrality.pyx +++ b/src/sage/graphs/centrality.pyx @@ -99,11 +99,11 @@ def centrality_betweenness(G, bint exact=False, bint normalize=True): Compare with NetworkX:: - sage: import networkx # optional - networkx - sage: g = graphs.RandomGNP(100, .2) # optional - networkx - sage: nw = networkx.betweenness_centrality(g.networkx_graph()) # optional - networkx - sage: sg = centrality_betweenness(g) # optional - networkx - sage: max(abs(nw[x] - sg[x]) for x in g) # abs tol 1e-10 # optional - networkx + sage: import networkx # optional - networkx + sage: g = graphs.RandomGNP(100, .2) # optional - networkx + sage: nw = networkx.betweenness_centrality(g.networkx_graph()) # optional - networkx + sage: sg = centrality_betweenness(g) # optional - networkx + sage: max(abs(nw[x] - sg[x]) for x in g) # abs tol 1e-10 # optional - networkx 0 Stupid cases:: @@ -642,13 +642,13 @@ def centrality_closeness_top_k(G, int k=1, int verbose=0): sage: n = 20 sage: m = random.randint(1, n * (n - 1) / 2) sage: k = random.randint(1, n) - sage: g = graphs.RandomGNM(n, m) - sage: topk = centrality_closeness_top_k(g, k) - sage: centr = g.centrality_closeness(algorithm='BFS') - sage: sorted_centr = sorted(centr.values(), reverse=True) - sage: len(topk) == min(k, len(sorted_centr)) + sage: g = graphs.RandomGNM(n, m) # optional - networkx + sage: topk = centrality_closeness_top_k(g, k) # optional - networkx + sage: centr = g.centrality_closeness(algorithm='BFS') # optional - networkx + sage: sorted_centr = sorted(centr.values(), reverse=True) # optional - networkx + sage: len(topk) == min(k, len(sorted_centr)) # optional - networkx True - sage: all(abs(topk[i][0] - sorted_centr[i]) < 1e-12 for i in range(len(topk))) + sage: all(abs(topk[i][0] - sorted_centr[i]) < 1e-12 for i in range(len(topk))) # optional - networkx True Directed case:: @@ -658,13 +658,13 @@ def centrality_closeness_top_k(G, int k=1, int verbose=0): sage: n = 20 sage: m = random.randint(1, n * (n - 1)) sage: k = random.randint(1, n) - sage: g = digraphs.RandomDirectedGNM(n, m) - sage: topk = centrality_closeness_top_k(g, k) - sage: centr = g.centrality_closeness(algorithm='BFS') - sage: sorted_centr = sorted(centr.values(), reverse=True) - sage: len(topk) == min(k, len(sorted_centr)) + sage: g = digraphs.RandomDirectedGNM(n, m) # optional - networkx + sage: topk = centrality_closeness_top_k(g, k) # optional - networkx + sage: centr = g.centrality_closeness(algorithm='BFS') # optional - networkx + sage: sorted_centr = sorted(centr.values(), reverse=True) # optional - networkx + sage: len(topk) == min(k, len(sorted_centr)) # optional - networkx True - sage: all(abs(topk[i][0] - sorted_centr[i]) < 1e-12 for i in range(len(topk))) + sage: all(abs(topk[i][0] - sorted_centr[i]) < 1e-12 for i in range(len(topk))) # optional - networkx True """ cdef list res diff --git a/src/sage/graphs/comparability.pyx b/src/sage/graphs/comparability.pyx index 0585473a75d..0271f43d9d8 100644 --- a/src/sage/graphs/comparability.pyx +++ b/src/sage/graphs/comparability.pyx @@ -745,15 +745,15 @@ def is_transitive(g, certificate=False): (0, 2) sage: digraphs.RandomDirectedGNP(30,.2).is_transitive() False - sage: D = digraphs.DeBruijn(5, 2) - sage: D.is_transitive() + sage: D = digraphs.DeBruijn(5, 2) # optional - sage.combinat + sage: D.is_transitive() # optional - sage.combinat False - sage: cert = D.is_transitive(certificate=True) - sage: D.has_edge(*cert) + sage: cert = D.is_transitive(certificate=True) # optional - sage.combinat + sage: D.has_edge(*cert) # optional - sage.combinat False - sage: bool(D.shortest_path(*cert)) + sage: bool(D.shortest_path(*cert)) # optional - sage.combinat True - sage: digraphs.RandomDirectedGNP(20,.2).transitive_closure().is_transitive() + sage: digraphs.RandomDirectedGNP(20,.2).transitive_closure().is_transitive() # optional - networkx True """ cdef int n = g.order() diff --git a/src/sage/graphs/connectivity.pyx b/src/sage/graphs/connectivity.pyx index 2837f63201d..0f7b84d66da 100644 --- a/src/sage/graphs/connectivity.pyx +++ b/src/sage/graphs/connectivity.pyx @@ -4246,8 +4246,8 @@ def is_triconnected(G): Comparing different methods on random graphs that are not always triconnected:: - sage: G = graphs.RandomBarabasiAlbert(50, 3) - sage: G.is_triconnected() == G.vertex_connectivity(k=3) + sage: G = graphs.RandomBarabasiAlbert(50, 3) # optional - networkx + sage: G.is_triconnected() == G.vertex_connectivity(k=3) # optional - networkx True .. SEEALSO:: diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index 203a6a4f299..b1d046ee25d 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -357,7 +357,7 @@ class DiGraph(GenericGraph): sage: g = DiGraph([[1..12], lambda i,j: i != j and i.divides(j)]) sage: g.vertices(sort=True) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] - sage: g.adjacency_matrix() + sage: g.adjacency_matrix() # optional - sage.modules [0 1 1 1 1 1 1 1 1 1 1 1] [0 0 0 1 0 1 0 1 0 1 0 1] [0 0 0 0 0 1 0 0 1 0 0 1] @@ -377,34 +377,36 @@ class DiGraph(GenericGraph): - an adjacency matrix:: - sage: M = Matrix([[0, 1, 1, 1, 0],[0, 0, 0, 0, 0],[0, 0, 0, 0, 1],[0, 0, 0, 0, 0],[0, 0, 0, 0, 0]]); M + sage: M = Matrix([[0, 1, 1, 1, 0], [0, 0, 0, 0, 0], # optional - sage.modules + ....: [0, 0, 0, 0, 1], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]); M [0 1 1 1 0] [0 0 0 0 0] [0 0 0 0 1] [0 0 0 0 0] [0 0 0 0 0] - sage: DiGraph(M) + sage: DiGraph(M) # optional - sage.modules Digraph on 5 vertices - sage: M = Matrix([[0,1,-1],[-1,0,-1/2],[1,1/2,0]]); M + sage: M = Matrix([[0,1,-1], [-1,0,-1/2], [1,1/2,0]]); M # optional - sage.modules [ 0 1 -1] [ -1 0 -1/2] [ 1 1/2 0] - sage: G = DiGraph(M,sparse=True,weighted=True); G + sage: G = DiGraph(M, sparse=True, weighted=True); G # optional - sage.modules Digraph on 3 vertices - sage: G.weighted() + sage: G.weighted() # optional - sage.modules True - an incidence matrix:: - sage: M = Matrix(6, [-1,0,0,0,1, 1,-1,0,0,0, 0,1,-1,0,0, 0,0,1,-1,0, 0,0,0,1,-1, 0,0,0,0,0]); M + sage: M = Matrix(6, [-1,0,0,0,1, 1,-1,0,0,0, 0,1,-1,0,0, # optional - sage.modules + ....: 0,0,1,-1,0, 0,0,0,1,-1, 0,0,0,0,0]); M [-1 0 0 0 1] [ 1 -1 0 0 0] [ 0 1 -1 0 0] [ 0 0 1 -1 0] [ 0 0 0 1 -1] [ 0 0 0 0 0] - sage: DiGraph(M) + sage: DiGraph(M) # optional - sage.modules Digraph on 6 vertices #. A ``dig6`` string: Sage automatically recognizes whether a string is in @@ -530,12 +532,12 @@ def __init__(self, data=None, pos=None, loops=None, format=None, sage: loads(dumps(D)) == D True - sage: a = matrix(2,2,[1,2,0,1]) - sage: DiGraph(a,sparse=True).adjacency_matrix() == a + sage: a = matrix(2,2,[1,2,0,1]) # optional - sage.modules + sage: DiGraph(a, sparse=True).adjacency_matrix() == a # optional - sage.modules True - sage: a = matrix(2,2,[3,2,0,1]) - sage: DiGraph(a,sparse=True).adjacency_matrix() == a + sage: a = matrix(2,2,[3,2,0,1]) # optional - sage.modules + sage: DiGraph(a, sparse=True).adjacency_matrix() == a # optional - sage.modules True The positions are copied when the DiGraph is built from another DiGraph @@ -575,11 +577,12 @@ def __init__(self, data=None, pos=None, loops=None, format=None, Problem with weighted adjacency matrix (:trac:`13919`):: - sage: B = {0:{1:2,2:5,3:4},1:{2:2,4:7},2:{3:1,4:4,5:3},3:{5:4},4:{5:1,6:5},5:{4:1,6:7,5:1}} + sage: B = {0:{1:2,2:5,3:4},1:{2:2,4:7},2:{3:1,4:4,5:3}, + ....: 3:{5:4},4:{5:1,6:5},5:{4:1,6:7,5:1}} sage: grafo3 = DiGraph(B, weighted=True) - sage: matad = grafo3.weighted_adjacency_matrix() - sage: grafo4 = DiGraph(matad, format="adjacency_matrix", weighted=True) - sage: grafo4.shortest_path(0, 6, by_weight=True) + sage: matad = grafo3.weighted_adjacency_matrix() # optional - sage.modules + sage: grafo4 = DiGraph(matad, format="adjacency_matrix", weighted=True) # optional - sage.modules + sage: grafo4.shortest_path(0, 6, by_weight=True) # optional - sage.modules [0, 1, 2, 5, 4, 6] Building a DiGraph with ``immutable=False`` returns a mutable graph:: @@ -1454,8 +1457,8 @@ def degree_polynomial(self): EXAMPLES:: - sage: G = posets.PentagonPoset().hasse_diagram() - sage: G.degree_polynomial() + sage: G = posets.PentagonPoset().hasse_diagram() # optional - sage.matrix + sage: G.degree_polynomial() # optional - sage.matrix x^2 + 3*x*y + y^2 sage: G = posets.BooleanLattice(4).hasse_diagram() @@ -2068,9 +2071,10 @@ def reverse_edges(self, edges, inplace=True, multiedges=None): [(0, 5, None), (1, 0, None), (2, 1, None), (3, 2, None), (4, 3, None), (5, 4, None)] - sage: D = digraphs.Kautz(2, 3) - sage: Dr = D.reverse_edges(D.edges(sort=True), inplace=False, multiedges=True) - sage: Dr.edges(sort=True) == D.reverse().edges(sort=True) + sage: D = digraphs.Kautz(2, 3) # optional - sage.combinat + sage: Dr = D.reverse_edges(D.edges(sort=True), inplace=False, # optional - sage.combinat + ....: multiedges=True) + sage: Dr.edges(sort=True) == D.reverse().edges(sort=True) # optional - sage.combinat True """ tempG = self if inplace else copy(self) @@ -2173,37 +2177,37 @@ def eccentricity(self, v=None, by_weight=False, algorithm=None, sage: G.eccentricity(with_labels=True) {0: 0} sage: G = DiGraph([(0,1,2), (1,2,3), (2,0,2)]) - sage: G.eccentricity(algorithm = 'BFS') + sage: G.eccentricity(algorithm='BFS') [2, 2, 2] - sage: G.eccentricity(algorithm = 'Floyd-Warshall-Cython') + sage: G.eccentricity(algorithm='Floyd-Warshall-Cython') [2, 2, 2] - sage: G.eccentricity(by_weight = True, algorithm = 'Dijkstra_NetworkX') + sage: G.eccentricity(by_weight=True, algorithm='Dijkstra_NetworkX') # optional - networkx [5, 5, 4] - sage: G.eccentricity(by_weight = True, algorithm = 'Dijkstra_Boost') + sage: G.eccentricity(by_weight=True, algorithm='Dijkstra_Boost') [5, 5, 4] - sage: G.eccentricity(by_weight = True, algorithm = 'Johnson_Boost') + sage: G.eccentricity(by_weight=True, algorithm='Johnson_Boost') [5, 5, 4] - sage: G.eccentricity(by_weight = True, algorithm = 'Floyd-Warshall-Python') + sage: G.eccentricity(by_weight=True, algorithm='Floyd-Warshall-Python') [5, 5, 4] - sage: G.eccentricity(dist_dict = G.shortest_path_all_pairs(by_weight = True)[0]) + sage: G.eccentricity(dist_dict=G.shortest_path_all_pairs(by_weight=True)[0]) [5, 5, 4] TESTS: A non-implemented algorithm:: - sage: G.eccentricity(algorithm = 'boh') + sage: G.eccentricity(algorithm='boh') Traceback (most recent call last): ... ValueError: unknown algorithm "boh" An algorithm that does not work with edge weights:: - sage: G.eccentricity(by_weight = True, algorithm = 'BFS') + sage: G.eccentricity(by_weight=True, algorithm='BFS') Traceback (most recent call last): ... ValueError: algorithm 'BFS' does not work with weights - sage: G.eccentricity(by_weight = True, algorithm = 'Floyd-Warshall-Cython') + sage: G.eccentricity(by_weight=True, algorithm='Floyd-Warshall-Cython') Traceback (most recent call last): ... ValueError: algorithm 'Floyd-Warshall-Cython' does not work with weights @@ -2211,15 +2215,15 @@ def eccentricity(self, v=None, by_weight=False, algorithm=None, An algorithm that computes the all-pair-shortest-paths when not all vertices are needed:: - sage: G.eccentricity(0, algorithm = 'Floyd-Warshall-Cython') + sage: G.eccentricity(0, algorithm='Floyd-Warshall-Cython') Traceback (most recent call last): ... ValueError: algorithm 'Floyd-Warshall-Cython' works only if all eccentricities are needed - sage: G.eccentricity(0, algorithm = 'Floyd-Warshall-Python') + sage: G.eccentricity(0, algorithm='Floyd-Warshall-Python') Traceback (most recent call last): ... ValueError: algorithm 'Floyd-Warshall-Python' works only if all eccentricities are needed - sage: G.eccentricity(0, algorithm = 'Johnson_Boost') + sage: G.eccentricity(0, algorithm='Johnson_Boost') Traceback (most recent call last): ... ValueError: algorithm 'Johnson_Boost' works only if all eccentricities are needed @@ -2442,11 +2446,11 @@ def diameter(self, by_weight=False, algorithm=None, weight_function=None, EXAMPLES:: - sage: G = digraphs.DeBruijn(5,4) - sage: G.diameter() + sage: G = digraphs.DeBruijn(5,4) # optional - sage.combinat + sage: G.diameter() # optional - sage.combinat 4 - sage: G = digraphs.GeneralizedDeBruijn(9, 3) - sage: G.diameter() + sage: G = digraphs.GeneralizedDeBruijn(9, 3) # optional - sage.combinat + sage: G.diameter() # optional - sage.combinat 2 TESTS:: @@ -3152,9 +3156,10 @@ def topological_sort(self, implementation="default"): Using the NetworkX implementation :: - sage: s = list(D.topological_sort(implementation="NetworkX")); s # random + sage: s = list(D.topological_sort(implementation="NetworkX")); s # random # optional - networkx [0, 4, 1, 3, 2, 5, 6, 9, 7, 8, 10] - sage: all(s.index(u) < s.index(v) for u, v in D.edges(sort=False, labels=False)) + sage: all(s.index(u) < s.index(v) # optional - networkx + ....: for u, v in D.edges(sort=False, labels=False)) True :: @@ -3221,8 +3226,9 @@ def topological_sort_generator(self): sage: D = DiGraph({0: [1, 2], 1: [3], 2: [3, 4]}) sage: D.plot(layout='circular').show() # optional - sage.plot - sage: list(D.topological_sort_generator()) - [[0, 1, 2, 3, 4], [0, 2, 1, 3, 4], [0, 2, 1, 4, 3], [0, 2, 4, 1, 3], [0, 1, 2, 4, 3]] + sage: list(D.topological_sort_generator()) # optional - sage.modules sage.rings.finite_rings + [[0, 1, 2, 3, 4], [0, 2, 1, 3, 4], [0, 2, 1, 4, 3], + [0, 2, 4, 1, 3], [0, 1, 2, 4, 3]] :: @@ -3586,7 +3592,7 @@ def flow_polytope(self, edges=None, ends=None, backend=None): Flow polytopes can also be built through the ``polytopes.`` object:: - sage: polytopes.flow_polytope(digraphs.Path(5)) + sage: polytopes.flow_polytope(digraphs.Path(5)) # optional - sage.geometry.polyhedron A 0-dimensional polyhedron in QQ^4 defined as the convex hull of 1 vertex EXAMPLES: @@ -3594,26 +3600,26 @@ def flow_polytope(self, edges=None, ends=None, backend=None): A commutative square:: sage: G = DiGraph({1: [2, 3], 2: [4], 3: [4]}) - sage: fl = G.flow_polytope(); fl + sage: fl = G.flow_polytope(); fl # optional - sage.geometry.polyhedron A 1-dimensional polyhedron in QQ^4 defined as the convex hull of 2 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 1, 0, 1), A vertex at (1, 0, 1, 0)) Using a different order for the edges of the graph:: - sage: fl = G.flow_polytope(edges=G.edges(key=lambda x: x[0] - x[1])); fl + sage: fl = G.flow_polytope(edges=G.edges(key=lambda x: x[0] - x[1])); fl # optional - sage.geometry.polyhedron A 1-dimensional polyhedron in QQ^4 defined as the convex hull of 2 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 1, 1, 0), A vertex at (1, 0, 0, 1)) A tournament on 4 vertices:: sage: H = digraphs.TransitiveTournament(4) - sage: fl = H.flow_polytope(); fl + sage: fl = H.flow_polytope(); fl # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in QQ^6 defined as the convex hull of 4 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 0, 1, 0, 0, 0), A vertex at (0, 1, 0, 0, 0, 1), A vertex at (1, 0, 0, 0, 1, 0), @@ -3621,41 +3627,40 @@ def flow_polytope(self, edges=None, ends=None, backend=None): Restricting to a subset of the edges:: - sage: fl = H.flow_polytope(edges=[(0, 1, None), (1, 2, None), - ....: (2, 3, None), (0, 3, None)]) - sage: fl + sage: fl = H.flow_polytope(edges=[(0, 1, None), (1, 2, None), # optional - sage.geometry.polyhedron + ....: (2, 3, None), (0, 3, None)]); fl A 1-dimensional polyhedron in QQ^4 defined as the convex hull of 2 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 0, 0, 1), A vertex at (1, 1, 1, 0)) Using a different choice of sources and sinks:: - sage: fl = H.flow_polytope(ends=([1], [3])); fl + sage: fl = H.flow_polytope(ends=([1], [3])); fl # optional - sage.geometry.polyhedron A 1-dimensional polyhedron in QQ^6 defined as the convex hull of 2 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 0, 0, 1, 0, 1), A vertex at (0, 0, 0, 0, 1, 0)) - sage: fl = H.flow_polytope(ends=([0, 1], [3])); fl + sage: fl = H.flow_polytope(ends=([0, 1], [3])); fl # optional - sage.geometry.polyhedron The empty polyhedron in QQ^6 - sage: fl = H.flow_polytope(ends=([3], [0])); fl + sage: fl = H.flow_polytope(ends=([3], [0])); fl # optional - sage.geometry.polyhedron The empty polyhedron in QQ^6 - sage: fl = H.flow_polytope(ends=([0, 1], [2, 3])); fl + sage: fl = H.flow_polytope(ends=([0, 1], [2, 3])); fl # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in QQ^6 defined as the convex hull of 5 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 0, 1, 1, 0, 0), A vertex at (0, 1, 0, 0, 1, 0), A vertex at (1, 0, 0, 2, 0, 1), A vertex at (1, 0, 0, 1, 1, 0), A vertex at (0, 1, 0, 1, 0, 1)) - sage: fl = H.flow_polytope(edges=[(0, 1, None), (1, 2, None), + sage: fl = H.flow_polytope(edges=[(0, 1, None), (1, 2, None), # optional - sage.geometry.polyhedron ....: (2, 3, None), (0, 2, None), ....: (1, 3, None)], ....: ends=([0, 1], [2, 3])); fl A 2-dimensional polyhedron in QQ^5 defined as the convex hull of 4 vertices - sage: fl.vertices() + sage: fl.vertices() # optional - sage.geometry.polyhedron (A vertex at (0, 0, 0, 1, 1), A vertex at (1, 2, 1, 0, 0), A vertex at (1, 1, 0, 0, 1), @@ -3664,27 +3669,25 @@ def flow_polytope(self, edges=None, ends=None, backend=None): A digraph with one source and two sinks:: sage: Y = DiGraph({1: [2], 2: [3, 4]}) - sage: Y.flow_polytope() + sage: Y.flow_polytope() # optional - sage.geometry.polyhedron The empty polyhedron in QQ^3 A digraph with one vertex and no edge:: sage: Z = DiGraph({1: []}) - sage: Z.flow_polytope() + sage: Z.flow_polytope() # optional - sage.geometry.polyhedron A 0-dimensional polyhedron in QQ^0 defined as the convex hull of 1 vertex A digraph with multiple edges (:trac:`28837`):: - sage: G = DiGraph([(0, 1), (0,1)], multiedges=True) - sage: G + sage: G = DiGraph([(0, 1), (0,1)], multiedges=True); G Multi-digraph on 2 vertices - sage: P = G.flow_polytope() - sage: P + sage: P = G.flow_polytope(); P # optional - sage.geometry.polyhedron A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices - sage: P.vertices() + sage: P.vertices() # optional - sage.geometry.polyhedron (A vertex at (1, 0), A vertex at (0, 1)) - sage: P.lines() + sage: P.lines() # optional - sage.geometry.polyhedron () """ from sage.geometry.polyhedron.constructor import Polyhedron diff --git a/src/sage/graphs/distances_all_pairs.pyx b/src/sage/graphs/distances_all_pairs.pyx index 87e83b4f5ce..2451de506fd 100644 --- a/src/sage/graphs/distances_all_pairs.pyx +++ b/src/sage/graphs/distances_all_pairs.pyx @@ -545,7 +545,7 @@ def is_distance_regular(G, parameters=False): sage: graphs.PathGraph(2).is_distance_regular(parameters=True) ([1, None], [None, 1]) - sage: graphs.Tutte12Cage().is_distance_regular(parameters=True) + sage: graphs.Tutte12Cage().is_distance_regular(parameters=True) # optional - networkx ([3, 2, 2, 2, 2, 2, None], [None, 1, 1, 1, 1, 1, 3]) """ @@ -843,8 +843,8 @@ cdef uint32_t * c_eccentricity_DHV(short_digraph sd) except NULL: TESTS: - sage: G = graphs.RandomBarabasiAlbert(50, 2) - sage: eccentricity(G, algorithm='bounds') == eccentricity(G, algorithm='DHV') + sage: G = graphs.RandomBarabasiAlbert(50, 2) # optional - networkx + sage: eccentricity(G, algorithm='bounds') == eccentricity(G, algorithm='DHV') # optional - networkx True """ cdef uint32_t n = sd.n @@ -1777,26 +1777,26 @@ def diameter(G, algorithm=None, source=None): Comparison of exact algorithms for graphs:: - sage: G = graphs.RandomBarabasiAlbert(100, 2) - sage: d1 = diameter(G, algorithm='standard') - sage: d2 = diameter(G, algorithm='iFUB') - sage: d3 = diameter(G, algorithm='iFUB', source=G.random_vertex()) - sage: d4 = diameter(G, algorithm='DHV') - sage: if d1 != d2 or d1 != d3 or d1 != d4: print("Something goes wrong!") + sage: G = graphs.RandomBarabasiAlbert(100, 2) # optional - networkx + sage: d1 = diameter(G, algorithm='standard') # optional - networkx + sage: d2 = diameter(G, algorithm='iFUB') # optional - networkx + sage: d3 = diameter(G, algorithm='iFUB', source=G.random_vertex()) # optional - networkx + sage: d4 = diameter(G, algorithm='DHV') # optional - networkx + sage: if d1 != d2 or d1 != d3 or d1 != d4: print("Something goes wrong!") # optional - networkx Comparison of lower bound algorithms:: - sage: lb2 = diameter(G, algorithm='2sweep') - sage: lbm = diameter(G, algorithm='multi-sweep') - sage: if not (lb2 <= lbm and lbm <= d3): print("Something goes wrong!") + sage: lb2 = diameter(G, algorithm='2sweep') # optional - networkx + sage: lbm = diameter(G, algorithm='multi-sweep') # optional - networkx + sage: if not (lb2 <= lbm and lbm <= d3): print("Something goes wrong!") # optional - networkx Comparison of exact algorithms for digraphs:: - sage: D = DiGraph(graphs.RandomBarabasiAlbert(50, 2)) - sage: d1 = diameter(D, algorithm='standard') - sage: d2 = diameter(D, algorithm='DiFUB') - sage: d3 = diameter(D, algorithm='DiFUB', source=D.random_vertex()) - sage: d1 == d2 and d1 == d3 + sage: D = DiGraph(graphs.RandomBarabasiAlbert(50, 2)) # optional - networkx + sage: d1 = diameter(D, algorithm='standard') # optional - networkx + sage: d2 = diameter(D, algorithm='DiFUB') # optional - networkx + sage: d3 = diameter(D, algorithm='DiFUB', source=D.random_vertex()) # optional - networkx + sage: d1 == d2 and d1 == d3 # optional - networkx True TESTS: @@ -2438,8 +2438,8 @@ def distances_distribution(G): The de Bruijn digraph dB(2,3):: - sage: D = digraphs.DeBruijn(2,3) - sage: D.distances_distribution() + sage: D = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: D.distances_distribution() # optional - sage.combinat {1: 1/4, 2: 11/28, 3: 5/14} """ cdef size_t n = G.order() diff --git a/src/sage/graphs/dot2tex_utils.py b/src/sage/graphs/dot2tex_utils.py index cfa4613fdf9..710f3872b2a 100644 --- a/src/sage/graphs/dot2tex_utils.py +++ b/src/sage/graphs/dot2tex_utils.py @@ -74,7 +74,7 @@ def quoted_latex(x): EXAMPLES:: - sage: sage.graphs.dot2tex_utils.quoted_latex(matrix([[1,1],[0,1],[0,0]])) + sage: sage.graphs.dot2tex_utils.quoted_latex(matrix([[1,1],[0,1],[0,0]])) # optional - sage.modules '\\left(\\begin{array}{rr}1 & 1 \\\\0 & 1 \\\\0 & 0\\end{array}\\right)' """ return re.sub("\"|\r|(%[^\n]*)?\n", "", latex(x)) @@ -89,9 +89,9 @@ def quoted_str(x): EXAMPLES:: - sage: sage.graphs.dot2tex_utils.quoted_str(matrix([[1,1],[0,1],[0,0]])) + sage: sage.graphs.dot2tex_utils.quoted_str(matrix([[1,1],[0,1],[0,0]])) # optional - sage.modules '[1 1]\\n\\\n[0 1]\\n\\\n[0 0]' - sage: print(sage.graphs.dot2tex_utils.quoted_str(matrix([[1,1],[0,1],[0,0]]))) + sage: print(sage.graphs.dot2tex_utils.quoted_str(matrix([[1,1],[0,1],[0,0]]))) # optional - sage.modules [1 1]\n\ [0 1]\n\ [0 0] diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 5263e712db5..2bcfcc9beaf 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -56,17 +56,17 @@ cdef class GabowEdgeConnectivity: A random `d`-regular digraph is `d`-edge-connected:: sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity - sage: D = DiGraph(graphs.RandomRegular(6, 50)) - sage: while not D.is_strongly_connected(): + sage: D = DiGraph(graphs.RandomRegular(6, 50)) # optional - networkx + sage: while not D.is_strongly_connected(): # optional - networkx ....: D = DiGraph(graphs.RandomRegular(6, 50)) - sage: GabowEdgeConnectivity(D).edge_connectivity() + sage: GabowEdgeConnectivity(D).edge_connectivity() # optional - networkx 6 A complete digraph with `n` vertices is `n-1`-edge-connected:: sage: from sage.graphs.edge_connectivity import GabowEdgeConnectivity sage: D = DiGraph(digraphs.Complete(10)) - sage: GabowEdgeConnectivity(D, use_rec = True).edge_connectivity() + sage: GabowEdgeConnectivity(D, use_rec=True).edge_connectivity() 9 Check that we get the same result when with and without the DFS-based diff --git a/src/sage/graphs/generators/basic.py b/src/sage/graphs/generators/basic.py index 33e04e94b38..43e0b683703 100644 --- a/src/sage/graphs/generators/basic.py +++ b/src/sage/graphs/generators/basic.py @@ -404,15 +404,15 @@ def CorrelationGraph(seqs, alpha, include_anticorrelation): EXAMPLES: sage: from sage.graphs.generators.basic import CorrelationGraph - sage: data=[[1,2,3],[4,5,6],[7,8,9999]] - sage: CG1 = CorrelationGraph(data, 0.9, False) - sage: CG2 = CorrelationGraph(data, 0.9, True) - sage: CG3 = CorrelationGraph(data, 0.1, True) - sage: CG1.edges(sort=False) + sage: data = [[1,2,3], [4,5,6], [7,8,9999]] + sage: CG1 = CorrelationGraph(data, 0.9, False) # optional - numpy + sage: CG2 = CorrelationGraph(data, 0.9, True) # optional - numpy + sage: CG3 = CorrelationGraph(data, 0.1, True) # optional - numpy + sage: CG1.edges(sort=False) # optional - numpy [(0, 0, None), (0, 1, None), (1, 1, None), (2, 2, None)] - sage: CG2.edges(sort=False) + sage: CG2.edges(sort=False) # optional - numpy [(0, 0, None), (0, 1, None), (1, 1, None), (2, 2, None)] - sage: CG3.edges(sort=False) + sage: CG3.edges(sort=False) # optional - numpy [(0, 0, None), (0, 1, None), (0, 2, None), (1, 1, None), (1, 2, None), (2, 2, None)] """ @@ -825,11 +825,11 @@ def Toroidal6RegularGrid2dGraph(p, q): sage: g = graphs.Toroidal6RegularGrid2dGraph(5,5) sage: g.is_regular(k=6) True - sage: g.is_vertex_transitive() + sage: g.is_vertex_transitive() # optional - sage.groups True - sage: g.line_graph().is_vertex_transitive() + sage: g.line_graph().is_vertex_transitive() # optional - sage.groups True - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 300 sage: g.is_hamiltonian() True diff --git a/src/sage/graphs/generators/classical_geometries.py b/src/sage/graphs/generators/classical_geometries.py index 059d46d0c7f..680402dc476 100644 --- a/src/sage/graphs/generators/classical_geometries.py +++ b/src/sage/graphs/generators/classical_geometries.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.modules r""" Families of graphs derived from classical geometries over finite fields @@ -39,7 +39,7 @@ def SymplecticPolarGraph(d, q, algorithm=None): - ``d,q`` -- integers; note that only even values of `d` are accepted by the function. - - ``algorithm`` -- string (default: ``None``); if set to 'gap' then the + - ``algorithm`` -- string (default: ``None``); if set to ``'gap'``, then the computation is carried via GAP library interface, computing totally singular subspaces, which is faster for `q>3`. Otherwise it is done directly. @@ -60,17 +60,18 @@ def SymplecticPolarGraph(d, q, algorithm=None): sage: G = graphs.SymplecticPolarGraph(4,3) sage: G.is_strongly_regular(parameters=True) (40, 12, 2, 4) - sage: O=graphs.OrthogonalPolarGraph(5,3) + sage: O = graphs.OrthogonalPolarGraph(5,3) sage: O.is_strongly_regular(parameters=True) (40, 12, 2, 4) sage: O.is_isomorphic(G) False - sage: graphs.SymplecticPolarGraph(6,4,algorithm="gap").is_strongly_regular(parameters=True) # not tested (long time) + sage: S = graphs.SymplecticPolarGraph(6,4,algorithm="gap") # not tested (long time) # optional - sage.libs.gap + sage: S.is_strongly_regular(parameters=True) # not tested (long time) # optional - sage.libs.gap (1365, 340, 83, 85) TESTS:: - sage: graphs.SymplecticPolarGraph(4,4,algorithm="gap").is_strongly_regular(parameters=True) + sage: graphs.SymplecticPolarGraph(4,4,algorithm="gap").is_strongly_regular(parameters=True) # optional - sage.libs.gap (85, 20, 3, 5) sage: graphs.SymplecticPolarGraph(4,4).is_strongly_regular(parameters=True) (85, 20, 3, 5) @@ -223,61 +224,61 @@ def _orthogonal_polar_graph(m, q, sign="+", point_type=[0]): Petersen graph:: sage: from sage.graphs.generators.classical_geometries import _orthogonal_polar_graph - sage: g=_orthogonal_polar_graph(3,5,point_type=[2,3]) - sage: g.is_strongly_regular(parameters=True) + sage: g = _orthogonal_polar_graph(3,5,point_type=[2,3]) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (10, 3, 0, 1) A locally Petersen graph (a.k.a. Doro graph, a.k.a. Hall graph):: - sage: g=_orthogonal_polar_graph(4,5,'-',point_type=[2,3]) - sage: g.is_distance_regular(parameters=True) + sage: g = _orthogonal_polar_graph(4,5,'-',point_type=[2,3]) # optional - sage.libs.gap + sage: g.is_distance_regular(parameters=True) # optional - sage.libs.gap ([10, 6, 4, None], [None, 1, 2, 5]) Various big and slow to build graphs: `NO^+(7,3)`:: - sage: g=_orthogonal_polar_graph(7,3,point_type=[1]) # not tested (long time) - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g = _orthogonal_polar_graph(7,3,point_type=[1]) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) (378, 117, 36, 36) `NO^-(7,3)`:: - sage: g=_orthogonal_polar_graph(7,3,point_type=[-1]) # not tested (long time) - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g = _orthogonal_polar_graph(7,3,point_type=[-1]) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) (351, 126, 45, 45) `NO^+(6,3)`:: - sage: g=_orthogonal_polar_graph(6,3,point_type=[1]) - sage: g.is_strongly_regular(parameters=True) + sage: g = _orthogonal_polar_graph(6,3,point_type=[1]) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (117, 36, 15, 9) `NO^-(6,3)`:: - sage: g=_orthogonal_polar_graph(6,3,'-',point_type=[1]) - sage: g.is_strongly_regular(parameters=True) + sage: g = _orthogonal_polar_graph(6,3,'-',point_type=[1]) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (126, 45, 12, 18) `NO^{-,\perp}(5,5)`:: - sage: g=_orthogonal_polar_graph(5,5,point_type=[2,3]) # long time - sage: g.is_strongly_regular(parameters=True) # long time + sage: g = _orthogonal_polar_graph(5,5,point_type=[2,3]) # long time, optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (300, 65, 10, 15) `NO^{+,\perp}(5,5)`:: - sage: g=_orthogonal_polar_graph(5,5,point_type=[1,-1]) # not tested (long time) - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g = _orthogonal_polar_graph(5,5,point_type=[1,-1]) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) (325, 60, 15, 10) TESTS:: - sage: g=_orthogonal_polar_graph(5,3,point_type=[-1]) - sage: g.is_strongly_regular(parameters=True) + sage: g = _orthogonal_polar_graph(5,3,point_type=[-1]) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (45, 12, 3, 3) - sage: g=_orthogonal_polar_graph(5,3,point_type=[1]) - sage: g.is_strongly_regular(parameters=True) + sage: g = _orthogonal_polar_graph(5,3,point_type=[1]) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (36, 15, 6, 6) """ @@ -341,34 +342,34 @@ def OrthogonalPolarGraph(m, q, sign="+"): EXAMPLES:: - sage: G = graphs.OrthogonalPolarGraph(6,3,"+"); G + sage: G = graphs.OrthogonalPolarGraph(6,3,"+"); G # optional - sage.libs.gap Orthogonal Polar Graph O^+(6, 3): Graph on 130 vertices - sage: G.is_strongly_regular(parameters=True) + sage: G.is_strongly_regular(parameters=True) # optional - sage.libs.gap (130, 48, 20, 16) - sage: G = graphs.OrthogonalPolarGraph(6,3,"-"); G + sage: G = graphs.OrthogonalPolarGraph(6,3,"-"); G # optional - sage.libs.gap Orthogonal Polar Graph O^-(6, 3): Graph on 112 vertices - sage: G.is_strongly_regular(parameters=True) + sage: G.is_strongly_regular(parameters=True) # optional - sage.libs.gap (112, 30, 2, 10) - sage: G = graphs.OrthogonalPolarGraph(5,3); G + sage: G = graphs.OrthogonalPolarGraph(5,3); G # optional - sage.libs.gap Orthogonal Polar Graph O(5, 3): Graph on 40 vertices - sage: G.is_strongly_regular(parameters=True) + sage: G.is_strongly_regular(parameters=True) # optional - sage.libs.gap (40, 12, 2, 4) - sage: G = graphs.OrthogonalPolarGraph(8,2,"+"); G + sage: G = graphs.OrthogonalPolarGraph(8,2,"+"); G # optional - sage.libs.gap Orthogonal Polar Graph O^+(8, 2): Graph on 135 vertices - sage: G.is_strongly_regular(parameters=True) + sage: G.is_strongly_regular(parameters=True) # optional - sage.libs.gap (135, 70, 37, 35) - sage: G = graphs.OrthogonalPolarGraph(8,2,"-"); G + sage: G = graphs.OrthogonalPolarGraph(8,2,"-"); G # optional - sage.libs.gap Orthogonal Polar Graph O^-(8, 2): Graph on 119 vertices - sage: G.is_strongly_regular(parameters=True) + sage: G.is_strongly_regular(parameters=True) # optional - sage.libs.gap (119, 54, 21, 27) TESTS:: - sage: G = graphs.OrthogonalPolarGraph(4,3,"") + sage: G = graphs.OrthogonalPolarGraph(4,3,"") # optional - sage.libs.gap Traceback (most recent call last): ... ValueError: sign must be equal to either '-' or '+' when m is even - sage: G = graphs.OrthogonalPolarGraph(5,3,"-") + sage: G = graphs.OrthogonalPolarGraph(5,3,"-") # optional - sage.libs.gap Traceback (most recent call last): ... ValueError: sign must be equal to either '' or '+' when m is odd @@ -416,71 +417,74 @@ def NonisotropicOrthogonalPolarGraph(m, q, sign="+", perp=None): `NO^-(4,2)` is isomorphic to Petersen graph:: - sage: g=graphs.NonisotropicOrthogonalPolarGraph(4,2,'-'); g + sage: g = graphs.NonisotropicOrthogonalPolarGraph(4,2,'-'); g # optional - sage.libs.gap NO^-(4, 2): Graph on 10 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (10, 3, 0, 1) `NO^-(6,2)` and `NO^+(6,2)`:: - sage: g=graphs.NonisotropicOrthogonalPolarGraph(6,2,'-') - sage: g.is_strongly_regular(parameters=True) + sage: g = graphs.NonisotropicOrthogonalPolarGraph(6,2,'-') # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (36, 15, 6, 6) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(6,2,'+'); g + sage: g = graphs.NonisotropicOrthogonalPolarGraph(6,2,'+'); g # optional - sage.libs.gap NO^+(6, 2): Graph on 28 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (28, 15, 6, 10) `NO^+(8,2)`:: - sage: g=graphs.NonisotropicOrthogonalPolarGraph(8,2,'+') - sage: g.is_strongly_regular(parameters=True) + sage: g = graphs.NonisotropicOrthogonalPolarGraph(8,2,'+') # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (120, 63, 30, 36) Wilbrink's graphs for `q=5`:: - sage: graphs.NonisotropicOrthogonalPolarGraph(5,5,perp=1).is_strongly_regular(parameters=True) # long time + sage: g = graphs.NonisotropicOrthogonalPolarGraph(5,5,perp=1) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (325, 60, 15, 10) - sage: graphs.NonisotropicOrthogonalPolarGraph(5,5,'-',perp=1).is_strongly_regular(parameters=True) # long time + sage: g = graphs.NonisotropicOrthogonalPolarGraph(5,5,'-',perp=1) # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (300, 65, 10, 15) Wilbrink's graphs:: - sage: g=graphs.NonisotropicOrthogonalPolarGraph(5,4,'+') - sage: g.is_strongly_regular(parameters=True) + sage: g = graphs.NonisotropicOrthogonalPolarGraph(5,4,'+') # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (136, 75, 42, 40) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(5,4,'-') - sage: g.is_strongly_regular(parameters=True) + sage: g = graphs.NonisotropicOrthogonalPolarGraph(5,4,'-') # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (120, 51, 18, 24) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(7,4,'+'); g # not tested (long time) + sage: g = graphs.NonisotropicOrthogonalPolarGraph(7,4,'+'); g # not tested (long time) NO^+(7, 4): Graph on 2080 vertices - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) (2080, 1071, 558, 544) TESTS:: - sage: g=graphs.NonisotropicOrthogonalPolarGraph(4,2); g + sage: g = graphs.NonisotropicOrthogonalPolarGraph(4,2); g # optional - sage.libs.gap NO^+(4, 2): Graph on 6 vertices - sage: graphs.NonisotropicOrthogonalPolarGraph(4,3,'-').is_strongly_regular(parameters=True) + sage: g = graphs.NonisotropicOrthogonalPolarGraph(4,3,'-') # optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (15, 6, 1, 3) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(3,5,'-',perp=1); g + sage: g = graphs.NonisotropicOrthogonalPolarGraph(3,5,'-',perp=1); g # optional - sage.libs.gap NO^-,perp(3, 5): Graph on 10 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (10, 3, 0, 1) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(6,3,'+') # long time - sage: g.is_strongly_regular(parameters=True) # long time + sage: g = graphs.NonisotropicOrthogonalPolarGraph(6,3,'+') # long time, optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (117, 36, 15, 9) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(6,3,'-'); g # long time + sage: g = graphs.NonisotropicOrthogonalPolarGraph(6,3,'-'); g # long time, optional - sage.libs.gap NO^-(6, 3): Graph on 126 vertices - sage: g.is_strongly_regular(parameters=True) # long time + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (126, 45, 12, 18) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(5,5,'-') # long time - sage: g.is_strongly_regular(parameters=True) # long time + sage: g = graphs.NonisotropicOrthogonalPolarGraph(5,5,'-') # long time, optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (300, 104, 28, 40) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(5,5,'+') # long time - sage: g.is_strongly_regular(parameters=True) # long time + sage: g = graphs.NonisotropicOrthogonalPolarGraph(5,5,'+') # long time, optional - sage.libs.gap + sage: g.is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (325, 144, 68, 60) - sage: g=graphs.NonisotropicOrthogonalPolarGraph(6,4,'+') + sage: g = graphs.NonisotropicOrthogonalPolarGraph(6,4,'+') # optional - sage.libs.gap Traceback (most recent call last): ... ValueError: for m even q must be 2 or 3 @@ -561,9 +565,9 @@ def _polar_graph(m, q, g, intersection_size=None): TESTS:: sage: from sage.graphs.generators.classical_geometries import _polar_graph - sage: _polar_graph(4, 4, libgap.GeneralUnitaryGroup(4, 2)) + sage: _polar_graph(4, 4, libgap.GeneralUnitaryGroup(4, 2)) # optional - sage.libs.gap Graph on 45 vertices - sage: _polar_graph(4, 4, libgap.GeneralUnitaryGroup(4, 2), intersection_size=1) + sage: _polar_graph(4, 4, libgap.GeneralUnitaryGroup(4, 2), intersection_size=1) # optional - sage.libs.gap Graph on 27 vertices """ from sage.libs.gap.libgap import libgap @@ -605,20 +609,20 @@ def UnitaryPolarGraph(m, q, algorithm="gap"): EXAMPLES:: - sage: G = graphs.UnitaryPolarGraph(4,2); G + sage: G = graphs.UnitaryPolarGraph(4,2); G # optional - sage.libs.gap Unitary Polar Graph U(4, 2); GQ(4, 2): Graph on 45 vertices - sage: G.is_strongly_regular(parameters=True) + sage: G.is_strongly_regular(parameters=True) # optional - sage.libs.gap (45, 12, 3, 3) - sage: graphs.UnitaryPolarGraph(5,2).is_strongly_regular(parameters=True) + sage: graphs.UnitaryPolarGraph(5,2).is_strongly_regular(parameters=True) # optional - sage.libs.gap (165, 36, 3, 9) - sage: graphs.UnitaryPolarGraph(6,2) # not tested (long time) + sage: graphs.UnitaryPolarGraph(6,2) # not tested (long time) # optional - sage.libs.gap Unitary Polar Graph U(6, 2): Graph on 693 vertices TESTS:: - sage: graphs.UnitaryPolarGraph(4,3, algorithm="gap").is_strongly_regular(parameters=True) + sage: graphs.UnitaryPolarGraph(4,3, algorithm="gap").is_strongly_regular(parameters=True) # optional - sage.libs.gap (280, 36, 8, 4) - sage: graphs.UnitaryPolarGraph(4,3).is_strongly_regular(parameters=True) + sage: graphs.UnitaryPolarGraph(4,3).is_strongly_regular(parameters=True) # optional - sage.libs.gap (280, 36, 8, 4) sage: graphs.UnitaryPolarGraph(4,3, algorithm="foo") Traceback (most recent call last): @@ -672,18 +676,18 @@ def NonisotropicUnitaryPolarGraph(m, q): EXAMPLES:: - sage: g=graphs.NonisotropicUnitaryPolarGraph(5,2); g + sage: g = graphs.NonisotropicUnitaryPolarGraph(5,2); g # optional - sage.libs.gap NU(5, 2): Graph on 176 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.libs.gap (176, 135, 102, 108) TESTS:: - sage: graphs.NonisotropicUnitaryPolarGraph(4,2).is_strongly_regular(parameters=True) + sage: graphs.NonisotropicUnitaryPolarGraph(4,2).is_strongly_regular(parameters=True) # optional - sage.libs.gap (40, 27, 18, 18) - sage: graphs.NonisotropicUnitaryPolarGraph(4,3).is_strongly_regular(parameters=True) # long time + sage: graphs.NonisotropicUnitaryPolarGraph(4,3).is_strongly_regular(parameters=True) # long time, optional - sage.libs.gap (540, 224, 88, 96) - sage: graphs.NonisotropicUnitaryPolarGraph(6,6) + sage: graphs.NonisotropicUnitaryPolarGraph(6,6) # optional - sage.libs.gap Traceback (most recent call last): ... ValueError: q must be a prime power @@ -738,16 +742,16 @@ def UnitaryDualPolarGraph(m, q): The point graph of a generalized quadrangle (see :wikipedia:`Generalized_quadrangle`, [PT2009]_) of order (8,4):: - sage: G = graphs.UnitaryDualPolarGraph(5,2); G # long time + sage: G = graphs.UnitaryDualPolarGraph(5,2); G # long time # optional - sage.libs.gap Unitary Dual Polar Graph DU(5, 2); GQ(8, 4): Graph on 297 vertices - sage: G.is_strongly_regular(parameters=True) # long time + sage: G.is_strongly_regular(parameters=True) # long time # optional - sage.libs.gap (297, 40, 7, 5) Another way to get the generalized quadrangle of order (2,4):: - sage: G = graphs.UnitaryDualPolarGraph(4,2); G + sage: G = graphs.UnitaryDualPolarGraph(4,2); G # optional - sage.libs.gap Unitary Dual Polar Graph DU(4, 2); GQ(2, 4): Graph on 27 vertices - sage: G.is_isomorphic(graphs.OrthogonalPolarGraph(6,2,'-')) + sage: G.is_isomorphic(graphs.OrthogonalPolarGraph(6,2,'-')) # optional - sage.libs.gap True A bigger graph:: @@ -759,7 +763,7 @@ def UnitaryDualPolarGraph(m, q): TESTS:: - sage: graphs.UnitaryDualPolarGraph(6,6) + sage: graphs.UnitaryDualPolarGraph(6,6) # optional - sage.libs.gap Traceback (most recent call last): ... GAPError: Error, must be a prime or a finite field @@ -796,11 +800,11 @@ def SymplecticDualPolarGraph(m, q): TESTS:: - sage: G = graphs.SymplecticDualPolarGraph(6,2); G + sage: G = graphs.SymplecticDualPolarGraph(6,2); G # optional - sage.libs.gap Symplectic Dual Polar Graph DSp(6, 2): Graph on 135 vertices - sage: G.is_distance_regular(parameters=True) + sage: G.is_distance_regular(parameters=True) # optional - sage.libs.gap ([14, 12, 8, None], [None, 1, 3, 7]) - sage: graphs.SymplecticDualPolarGraph(6,6) + sage: graphs.SymplecticDualPolarGraph(6,6) # optional - sage.libs.gap Traceback (most recent call last): ... GAPError: Error, must be a prime or a finite field @@ -844,28 +848,28 @@ def TaylorTwographDescendantSRG(q, clique_partition=False): EXAMPLES:: - sage: g=graphs.TaylorTwographDescendantSRG(3); g + sage: g = graphs.TaylorTwographDescendantSRG(3); g # optional - sage.rings.finite_rings Taylor two-graph descendant SRG: Graph on 27 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (27, 10, 1, 5) sage: from sage.combinat.designs.twographs import taylor_twograph - sage: T = taylor_twograph(3) # long time - sage: g.is_isomorphic(T.descendant(T.ground_set()[1])) # long time + sage: T = taylor_twograph(3) # long time, optional - sage.rings.finite_rings + sage: g.is_isomorphic(T.descendant(T.ground_set()[1])) # long time, optional - sage.rings.finite_rings True - sage: g=graphs.TaylorTwographDescendantSRG(5) # not tested (long time) - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g = graphs.TaylorTwographDescendantSRG(5) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) (125, 52, 15, 26) TESTS:: - sage: g,l,_=graphs.TaylorTwographDescendantSRG(3,clique_partition=True) - sage: all(g.is_clique(x) for x in l) + sage: g,l,_ = graphs.TaylorTwographDescendantSRG(3, clique_partition=True) # optional - sage.rings.finite_rings + sage: all(g.is_clique(x) for x in l) # optional - sage.rings.finite_rings True - sage: graphs.TaylorTwographDescendantSRG(4) + sage: graphs.TaylorTwographDescendantSRG(4) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: q must be an odd prime power - sage: graphs.TaylorTwographDescendantSRG(6) + sage: graphs.TaylorTwographDescendantSRG(6) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: q must be an odd prime power @@ -918,9 +922,9 @@ def TaylorTwographSRG(q): EXAMPLES:: - sage: t=graphs.TaylorTwographSRG(3); t + sage: t = graphs.TaylorTwographSRG(3); t # optional - sage.rings.finite_rings Taylor two-graph SRG: Graph on 28 vertices - sage: t.is_strongly_regular(parameters=True) + sage: t.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (28, 15, 6, 10) """ G, l, v0 = TaylorTwographDescendantSRG(q, clique_partition=True) @@ -955,13 +959,13 @@ def AhrensSzekeresGeneralizedQuadrangleGraph(q, dual=False): EXAMPLES:: - sage: g=graphs.AhrensSzekeresGeneralizedQuadrangleGraph(5); g + sage: g = graphs.AhrensSzekeresGeneralizedQuadrangleGraph(5); g # optional - sage.rings.finite_rings AS(5); GQ(4, 6): Graph on 125 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (125, 28, 3, 7) - sage: g=graphs.AhrensSzekeresGeneralizedQuadrangleGraph(5,dual=True); g + sage: g = graphs.AhrensSzekeresGeneralizedQuadrangleGraph(5, dual=True); g # optional - sage.rings.finite_rings AS(5)*; GQ(6, 4): Graph on 175 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (175, 30, 5, 5) """ from sage.combinat.designs.incidence_structures import IncidenceStructure @@ -1025,34 +1029,35 @@ def T2starGeneralizedQuadrangleGraph(q, dual=False, hyperoval=None, field=None, using the built-in construction:: - sage: g=graphs.T2starGeneralizedQuadrangleGraph(4); g + sage: g = graphs.T2starGeneralizedQuadrangleGraph(4); g # optional - sage.rings.finite_rings T2*(O,4); GQ(3, 5): Graph on 64 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (64, 18, 2, 6) - sage: g=graphs.T2starGeneralizedQuadrangleGraph(4,dual=True); g + sage: g = graphs.T2starGeneralizedQuadrangleGraph(4, dual=True); g # optional - sage.rings.finite_rings T2*(O,4)*; GQ(5, 3): Graph on 96 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (96, 20, 4, 4) supplying your own hyperoval:: - sage: F=GF(4,'b') - sage: O=[vector(F,(0,0,0,1)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] - sage: g=graphs.T2starGeneralizedQuadrangleGraph(4, hyperoval=O, field=F); g + sage: F = GF(4,'b') # optional - sage.rings.finite_rings + sage: O = [vector(F,(0,0,0,1)),vector(F,(0,0,1,0))] + [vector(F, (0,1,x^2,x)) # optional - sage.rings.finite_rings + ....: for x in F] + sage: g = graphs.T2starGeneralizedQuadrangleGraph(4, hyperoval=O, field=F); g # optional - sage.rings.finite_rings T2*(O,4); GQ(3, 5): Graph on 64 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (64, 18, 2, 6) TESTS:: - sage: F=GF(4,'b') # repeating a point... - sage: O=[vector(F,(0,1,0,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] - sage: graphs.T2starGeneralizedQuadrangleGraph(4, hyperoval=O, field=F) + sage: F = GF(4,'b') # repeating a point... + sage: O = [vector(F,(0,1,0,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] # optional - sage.rings.finite_rings + sage: graphs.T2starGeneralizedQuadrangleGraph(4, hyperoval=O, field=F) # optional - sage.rings.finite_rings Traceback (most recent call last): ... RuntimeError: incorrect hyperoval size - sage: O=[vector(F,(0,1,1,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] - sage: graphs.T2starGeneralizedQuadrangleGraph(4, hyperoval=O, field=F) + sage: O = [vector(F,(0,1,1,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] # optional - sage.rings.finite_rings + sage: graphs.T2starGeneralizedQuadrangleGraph(4, hyperoval=O, field=F) # optional - sage.rings.finite_rings Traceback (most recent call last): ... RuntimeError: incorrect hyperoval @@ -1144,35 +1149,35 @@ def HaemersGraph(q, hyperoval=None, hyperoval_matching=None, field=None, check_h using the built-in constructions:: - sage: g=graphs.HaemersGraph(4); g + sage: g = graphs.HaemersGraph(4); g # optional - sage.rings.finite_rings Haemers(4): Graph on 96 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (96, 19, 2, 4) supplying your own hyperoval_matching:: - sage: g=graphs.HaemersGraph(4,hyperoval_matching=((0,5),(1,4),(2,3))); g + sage: g = graphs.HaemersGraph(4, hyperoval_matching=((0,5),(1,4),(2,3))); g # optional - sage.rings.finite_rings Haemers(4): Graph on 96 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (96, 19, 2, 4) TESTS:: - sage: F=GF(4,'b') # repeating a point... - sage: O=[vector(F,(0,1,0,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] - sage: graphs.HaemersGraph(4, hyperoval=O, field=F) + sage: F=GF(4,'b') # repeating a point... # optional - sage.rings.finite_rings + sage: O=[vector(F,(0,1,0,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] # optional - sage.rings.finite_rings + sage: graphs.HaemersGraph(4, hyperoval=O, field=F) # optional - sage.rings.finite_rings Traceback (most recent call last): ... RuntimeError: incorrect hyperoval size - sage: O=[vector(F,(0,1,1,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] - sage: graphs.HaemersGraph(4, hyperoval=O, field=F) + sage: O=[vector(F,(0,1,1,0)),vector(F,(0,0,1,0))]+[vector(F, (0,1,x^2,x)) for x in F] # optional - sage.rings.finite_rings + sage: graphs.HaemersGraph(4, hyperoval=O, field=F) # optional - sage.rings.finite_rings Traceback (most recent call last): ... RuntimeError: incorrect hyperoval - sage: g=graphs.HaemersGraph(8); g # not tested (long time) + sage: g = graphs.HaemersGraph(8); g # not tested (long time) # optional - sage.rings.finite_rings Haemers(8): Graph on 640 vertices - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) # optional - sage.rings.finite_rings (640, 71, 6, 8) """ @@ -1259,20 +1264,20 @@ def CossidentePenttilaGraph(q): For `q=3` one gets Sims-Gewirtz graph. :: - sage: G=graphs.CossidentePenttilaGraph(3) # optional - gap_packages (grape) - sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) + sage: g = graphs.CossidentePenttilaGraph(3) # optional - gap_packages (grape) + sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) (56, 10, 0, 2) For `q>3` one gets new graphs. :: - sage: G=graphs.CossidentePenttilaGraph(5) # optional - gap_packages (grape) - sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) + sage: g = graphs.CossidentePenttilaGraph(5) # optional - gap_packages (grape) + sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) (378, 52, 1, 8) TESTS:: - sage: G=graphs.CossidentePenttilaGraph(7) # optional - gap_packages (grape) # long time - sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) # long time + sage: g = graphs.CossidentePenttilaGraph(7) # optional - gap_packages (grape) # long time + sage: G.is_strongly_regular(parameters=True) # optional - gap_packages (grape) # long time (1376, 150, 2, 18) sage: graphs.CossidentePenttilaGraph(2) Traceback (most recent call last): @@ -1367,32 +1372,33 @@ def Nowhere0WordsTwoWeightCodeGraph(q, hyperoval=None, field=None, check_hyperov using the built-in construction:: - sage: g=graphs.Nowhere0WordsTwoWeightCodeGraph(8); g + sage: g = graphs.Nowhere0WordsTwoWeightCodeGraph(8); g # optional - sage.rings.finite_rings Nowhere0WordsTwoWeightCodeGraph(8): Graph on 196 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (196, 60, 14, 20) - sage: g=graphs.Nowhere0WordsTwoWeightCodeGraph(16) # not tested (long time) - sage: g.is_strongly_regular(parameters=True) # not tested (long time) + sage: g = graphs.Nowhere0WordsTwoWeightCodeGraph(16) # not tested (long time) + sage: g.is_strongly_regular(parameters=True) # not tested (long time) (1800, 728, 268, 312) supplying your own hyperoval:: - sage: F=GF(8) - sage: O=[vector(F,(0,0,1)),vector(F,(0,1,0))]+[vector(F, (1,x^2,x)) for x in F] - sage: g=graphs.Nowhere0WordsTwoWeightCodeGraph(8,hyperoval=O,field=F); g + sage: F = GF(8) + sage: O = [vector(F,(0,0,1)),vector(F,(0,1,0))] + [vector(F, (1,x^2,x)) # optional - sage.rings.finite_rings + ....: for x in F] + sage: g = graphs.Nowhere0WordsTwoWeightCodeGraph(8,hyperoval=O,field=F); g # optional - sage.rings.finite_rings Nowhere0WordsTwoWeightCodeGraph(8): Graph on 196 vertices - sage: g.is_strongly_regular(parameters=True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.rings.finite_rings (196, 60, 14, 20) TESTS:: - sage: F=GF(8) # repeating a point... - sage: O=[vector(F,(1,0,0)),vector(F,(0,1,0))]+[vector(F, (1,x^2,x)) for x in F] - sage: graphs.Nowhere0WordsTwoWeightCodeGraph(8,hyperoval=O,field=F) + sage: F = GF(8) # repeating a point... # optional - sage.rings.finite_rings + sage: O = [vector(F,(1,0,0)),vector(F,(0,1,0))]+[vector(F, (1,x^2,x)) for x in F] # optional - sage.rings.finite_rings + sage: graphs.Nowhere0WordsTwoWeightCodeGraph(8,hyperoval=O,field=F) # optional - sage.rings.finite_rings Traceback (most recent call last): ... RuntimeError: incorrect hyperoval size - sage: O=[vector(F,(1,1,0)),vector(F,(0,1,0))]+[vector(F, (1,x^2,x)) for x in F] + sage: O = [vector(F,(1,1,0)),vector(F,(0,1,0))]+[vector(F, (1,x^2,x)) for x in F] # optional - sage.rings.finite_rings sage: graphs.Nowhere0WordsTwoWeightCodeGraph(8,hyperoval=O,field=F) Traceback (most recent call last): ... @@ -1461,13 +1467,13 @@ def OrthogonalDualPolarGraph(e, d, q): EXAMPLES:: - sage: G = graphs.OrthogonalDualPolarGraph(1,3,2) - sage: G.is_distance_regular(True) + sage: G = graphs.OrthogonalDualPolarGraph(1,3,2) # optional - sage.libs.gap + sage: G.is_distance_regular(True) # optional - sage.libs.gap ([7, 6, 4, None], [None, 1, 3, 7]) - sage: G = graphs.OrthogonalDualPolarGraph(0,3,3) # long time - sage: G.is_distance_regular(True) # long time + sage: G = graphs.OrthogonalDualPolarGraph(0,3,3) # long time # optional - sage.libs.gap + sage: G.is_distance_regular(True) # long time # optional - sage.libs.gap ([39, 36, 27, None], [None, 1, 4, 13]) - sage: G.order() # long time + sage: G.order() # long time # optional - sage.libs.gap 1120 REFERENCES: @@ -1476,17 +1482,17 @@ def OrthogonalDualPolarGraph(e, d, q): TESTS:: - sage: G = graphs.OrthogonalDualPolarGraph(0,3,2) - sage: G.is_distance_regular(True) + sage: G = graphs.OrthogonalDualPolarGraph(0,3,2) # optional - sage.libs.gap + sage: G.is_distance_regular(True) # optional - sage.libs.gap ([14, 12, 8, None], [None, 1, 3, 7]) - sage: G = graphs.OrthogonalDualPolarGraph(-1,3,2) # long time - sage: G.is_distance_regular(True) # long time + sage: G = graphs.OrthogonalDualPolarGraph(-1,3,2) # long time # optional - sage.libs.gap + sage: G.is_distance_regular(True) # long time # optional - sage.libs.gap ([28, 24, 16, None], [None, 1, 3, 7]) - sage: G = graphs.OrthogonalDualPolarGraph(1,3,4) - sage: G.is_distance_regular(True) + sage: G = graphs.OrthogonalDualPolarGraph(1,3,4) # optional - sage.libs.gap + sage: G.is_distance_regular(True) # optional - sage.libs.gap ([21, 20, 16, None], [None, 1, 5, 21]) - sage: G = graphs.OrthogonalDualPolarGraph(1,4,2) - sage: G.is_distance_regular(True) + sage: G = graphs.OrthogonalDualPolarGraph(1,4,2) # optional - sage.libs.gap + sage: G.is_distance_regular(True) # optional - sage.libs.gap ([15, 14, 12, 8, None], [None, 1, 3, 7, 15]) """ from sage.libs.gap.libgap import libgap diff --git a/src/sage/graphs/generators/degree_sequence.py b/src/sage/graphs/generators/degree_sequence.py index 606f96fb3fd..52eeb8ac633 100644 --- a/src/sage/graphs/generators/degree_sequence.py +++ b/src/sage/graphs/generators/degree_sequence.py @@ -41,25 +41,25 @@ def DegreeSequence(deg_sequence): EXAMPLES:: - sage: G = graphs.DegreeSequence([3,3,3,3]) - sage: G.edges(sort=True, labels=False) + sage: G = graphs.DegreeSequence([3,3,3,3]) # optional - networkx + sage: G.edges(sort=True, labels=False) # optional - networkx [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)] - sage: G.show() # long time + sage: G.show() # long time # optional - networkx sage.plot :: - sage: G = graphs.DegreeSequence([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]) - sage: G.show() # long time + sage: G = graphs.DegreeSequence([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot :: - sage: G = graphs.DegreeSequence([4,4,4,4,4,4,4,4]) - sage: G.show() # long time + sage: G = graphs.DegreeSequence([4,4,4,4,4,4,4,4]) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot :: - sage: G = graphs.DegreeSequence([1,2,3,4,3,4,3,2,3,2,1]) - sage: G.show() # long time + sage: G = graphs.DegreeSequence([1,2,3,4,3,4,3,2,3,2,1]) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot """ import networkx return Graph(networkx.havel_hakimi_graph([int(i) for i in deg_sequence])) @@ -147,20 +147,20 @@ def DegreeSequenceConfigurationModel(deg_sequence, seed=None): EXAMPLES:: - sage: G = graphs.DegreeSequenceConfigurationModel([1,1]) - sage: G.adjacency_matrix() + sage: G = graphs.DegreeSequenceConfigurationModel([1,1]) # optional - networkx + sage: G.adjacency_matrix() # optional - networkx sage.modules [0 1] [1 0] The output is allowed to contain both loops and multiple edges:: - sage: deg_sequence = [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3] - sage: G = graphs.DegreeSequenceConfigurationModel(deg_sequence) - sage: G.order(), G.size() + sage: deg_sequence = [3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3] # optional - networkx + sage: G = graphs.DegreeSequenceConfigurationModel(deg_sequence) # optional - networkx + sage: G.order(), G.size() # optional - networkx (20, 30) - sage: G.has_loops() or G.has_multiple_edges() # random + sage: G.has_loops() or G.has_multiple_edges() # random # optional - networkx True - sage: G.show() # long time + sage: G.show() # long time # optional - networkx sage.plot REFERENCE: @@ -191,10 +191,9 @@ def DegreeSequenceTree(deg_sequence): EXAMPLES:: - sage: G = graphs.DegreeSequenceTree([3,1,3,3,1,1,1,2,1]) - sage: G + sage: G = graphs.DegreeSequenceTree([3,1,3,3,1,1,1,2,1]); G # optional - networkx Graph on 9 vertices - sage: G.show() # long time + sage: G.show() # long time # optional - networkx sage.plot """ import networkx return Graph(networkx.degree_sequence_tree([int(i) for i in deg_sequence])) @@ -220,10 +219,9 @@ def DegreeSequenceExpected(deg_sequence, seed=None): EXAMPLES:: - sage: G = graphs.DegreeSequenceExpected([1,2,3,2,3]) - sage: G + sage: G = graphs.DegreeSequenceExpected([1,2,3,2,3]); G # optional - networkx Looped graph on 5 vertices - sage: G.show() # long time + sage: G.show() # long time # optional - networkx sage.plot REFERENCE: diff --git a/src/sage/graphs/generators/distance_regular.pyx b/src/sage/graphs/generators/distance_regular.pyx index 0df5f3e66b5..dd809a835af 100644 --- a/src/sage/graphs/generators/distance_regular.pyx +++ b/src/sage/graphs/generators/distance_regular.pyx @@ -35,15 +35,12 @@ AUTHORS: # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.coding import codes_catalog as codes -from sage.graphs.graph import Graph -from sage.libs.gap.libgap import libgap -from sage.modules.free_module import VectorSpace -from sage.modules.free_module_element import vector -from sage.rings.finite_rings.finite_field_constructor import GF -from sage.matrix.constructor import Matrix import itertools + from cysignals.signals cimport sig_check + +from sage.graphs.graph import Graph +from sage.misc.lazy_import import LazyImport from sage.graphs.generators.smallgraphs import (FosterGraph, BiggsSmithGraph, CoxeterGraph, LivingstoneGraph, WellsGraph, GossetGraph, @@ -53,6 +50,13 @@ from sage.graphs.generators.smallgraphs import (FosterGraph, BiggsSmithGraph, from sage.graphs.generators.platonic_solids import DodecahedralGraph from sage.graphs.strongly_regular_db import strongly_regular_graph +codes = LazyImport('sage.coding', 'codes_catalog', as_name='codes') +libgap = LazyImport('sage.libs.gap.libgap', 'libgap') +Matrix = LazyImport('sage.matrix.constructor', 'Matrix') +VectorSpace = LazyImport('sage.modules.free_module', 'VectorSpace') +vector = LazyImport('sage.modules.free_module_element', 'vector') +GF = LazyImport('sage.rings.finite_rings.finite_field_constructor', 'GF') + def cocliques_HoffmannSingleton(): r""" diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index f6c7b89bca7..30396e1ab9e 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -452,7 +452,7 @@ def HammingGraph(n, q, X=None): True sage: g.is_regular() True - sage: g.is_vertex_transitive() + sage: g.is_vertex_transitive() # optional - sage.groups True A Hamming graph with parameters (1,q) is isomorphic to the @@ -526,9 +526,9 @@ def BalancedTree(r, h): A balanced tree whose root node has degree `r = 2`, and of height `h = 1`, has order 3 and size 2:: - sage: G = graphs.BalancedTree(2, 1); G + sage: G = graphs.BalancedTree(2, 1); G # optional - networkx Balanced tree: Graph on 3 vertices - sage: G.order(); G.size() + sage: G.order(); G.size() # optional - networkx 3 2 sage: r = 2; h = 1 @@ -539,21 +539,21 @@ def BalancedTree(r, h): Plot a balanced tree of height 5, whose root node has degree `r = 3`:: - sage: G = graphs.BalancedTree(3, 5) - sage: G.show() # long time + sage: G = graphs.BalancedTree(3, 5) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot A tree is bipartite. If its vertex set is finite, then it is planar. :: sage: r = randint(2, 5); h = randint(1, 7) - sage: T = graphs.BalancedTree(r, h) - sage: T.is_bipartite() + sage: T = graphs.BalancedTree(r, h) # optional - networkx + sage: T.is_bipartite() # optional - networkx True - sage: T.is_planar() + sage: T.is_planar() # optional - networkx True - sage: v = (r^(h + 1) - 1) / (r - 1) - sage: T.order() == v + sage: v = (r^(h + 1) - 1) / (r - 1) # optional - networkx + sage: T.order() == v # optional - networkx True - sage: T.size() == v - 1 + sage: T.size() == v - 1 # optional - networkx True TESTS: @@ -562,13 +562,13 @@ def BalancedTree(r, h): has degree `r \geq 2`, but the construction degenerates gracefully:: - sage: graphs.BalancedTree(1, 10) + sage: graphs.BalancedTree(1, 10) # optional - networkx Balanced tree: Graph on 11 vertices Similarly, we usually want the tree must have height `h \geq 1` but the algorithm also degenerates gracefully here:: - sage: graphs.BalancedTree(3, 0) + sage: graphs.BalancedTree(3, 0) # optional - networkx Balanced tree: Graph on 1 vertex """ import networkx @@ -627,11 +627,11 @@ def BarbellGraph(n1, n2): True sage: K_n1 = graphs.CompleteGraph(n1) sage: P_n2 = graphs.PathGraph(n2) - sage: s_K = g.subgraph_search(K_n1, induced=True) - sage: s_P = g.subgraph_search(P_n2, induced=True) - sage: K_n1.is_isomorphic(s_K) + sage: s_K = g.subgraph_search(K_n1, induced=True) # optional - sage.modules + sage: s_P = g.subgraph_search(P_n2, induced=True) # optional - sage.modules + sage: K_n1.is_isomorphic(s_K) # optional - sage.modules True - sage: P_n2.is_isomorphic(s_P) + sage: P_n2.is_isomorphic(s_P) # optional - sage.modules True TESTS:: @@ -1025,13 +1025,13 @@ def chang_graphs(): Construct the Chang graphs by Seidel switching:: - sage: c3c5=graphs.CycleGraph(3).disjoint_union(graphs.CycleGraph(5)) - sage: c8=graphs.CycleGraph(8) - sage: s=[K8.subgraph_search(c8).edges(sort=False), - ....: [(0,1,None),(2,3,None),(4,5,None),(6,7,None)], - ....: K8.subgraph_search(c3c5).edges(sort=False)] - sage: list(map(lambda x,G: T8.seidel_switching(x, inplace=False).is_isomorphic(G), - ....: s, chang_graphs)) + sage: c3c5 = graphs.CycleGraph(3).disjoint_union(graphs.CycleGraph(5)) + sage: c8 = graphs.CycleGraph(8) + sage: s = [K8.subgraph_search(c8).edges(sort=False), # optional - sage.modules + ....: [(0,1,None),(2,3,None),(4,5,None),(6,7,None)], + ....: K8.subgraph_search(c3c5).edges(sort=False)] + sage: [T8.seidel_switching(x, inplace=False).is_isomorphic(G) # optional - sage.modules + ....: for x, G in zip(s, chang_graphs)] [True, True, True] """ @@ -1353,8 +1353,8 @@ def DorogovtsevGoltsevMendesGraph(n): EXAMPLES:: - sage: G = graphs.DorogovtsevGoltsevMendesGraph(8) - sage: G.size() + sage: G = graphs.DorogovtsevGoltsevMendesGraph(8) # optional - networkx + sage: G.size() # optional - networkx 6561 REFERENCE: @@ -1538,7 +1538,7 @@ def FuzzyBallGraph(partition, q): EXAMPLES:: sage: F = graphs.FuzzyBallGraph([3,1],2) - sage: F.adjacency_matrix(vertices=list(F)) + sage: F.adjacency_matrix(vertices=list(F)) # optional - sage.modules [0 0 1 1 1 0 0 0] [0 0 0 0 0 1 0 0] [1 0 0 1 1 1 1 1] @@ -1553,10 +1553,14 @@ def FuzzyBallGraph(partition, q): `k` parts should be cospectral with respect to the normalized Laplacian:: - sage: m=4; q=2; k=2 - sage: g_list=[graphs.FuzzyBallGraph(p,q) for p in Partitions(m, length=k)] - sage: set([g.laplacian_matrix(normalized=True, vertices=list(g)).charpoly() for g in g_list]) # long time (7s on sage.math, 2011) - {x^8 - 8*x^7 + 4079/150*x^6 - 68689/1350*x^5 + 610783/10800*x^4 - 120877/3240*x^3 + 1351/100*x^2 - 931/450*x} + sage: m = 4; q = 2; k = 2 + sage: g_list = [graphs.FuzzyBallGraph(p,q) # optional - sage.combinat sage.modules + ....: for p in Partitions(m, length=k)] + sage: set(g.laplacian_matrix(normalized=True, # long time (7s on sage.math, 2011), optional - sage.combinat sage.modules + ....: vertices=list(g)).charpoly() + ....: for g in g_list) + {x^8 - 8*x^7 + 4079/150*x^6 - 68689/1350*x^5 + 610783/10800*x^4 + - 120877/3240*x^3 + 1351/100*x^2 - 931/450*x} """ from sage.graphs.generators.basic import CompleteGraph if len(partition) < 1: @@ -2203,30 +2207,31 @@ def LCFGraph(n, shift_list, repeats): EXAMPLES:: - sage: G = graphs.LCFGraph(4, [2,-2], 2) - sage: G.is_isomorphic(graphs.TetrahedralGraph()) + sage: G = graphs.LCFGraph(4, [2,-2], 2) # optional - networkx + sage: G.is_isomorphic(graphs.TetrahedralGraph()) # optional - networkx True :: - sage: G = graphs.LCFGraph(20, [10,7,4,-4,-7,10,-4,7,-7,4], 2) - sage: G.is_isomorphic(graphs.DodecahedralGraph()) + sage: G = graphs.LCFGraph(20, [10,7,4,-4,-7,10,-4,7,-7,4], 2) # optional - networkx + sage: G.is_isomorphic(graphs.DodecahedralGraph()) # optional - networkx True :: - sage: G = graphs.LCFGraph(14, [5,-5], 7) - sage: G.is_isomorphic(graphs.HeawoodGraph()) + sage: G = graphs.LCFGraph(14, [5,-5], 7) # optional - networkx + sage: G.is_isomorphic(graphs.HeawoodGraph()) # optional - networkx True The largest cubic nonplanar graph of diameter three:: - sage: G = graphs.LCFGraph(20, [-10,-7,-5,4,7,-10,-7,-4,5,7,-10,-7,6,-5,7,-10,-7,5,-6,7], 1) - sage: G.degree() + sage: G = graphs.LCFGraph(20, [-10,-7,-5,4,7,-10,-7,-4,5,7, # optional - networkx + ....: -10,-7,6,-5,7,-10,-7,5,-6,7], 1) + sage: G.degree() # optional - networkx [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] - sage: G.diameter() + sage: G.diameter() # optional - networkx 3 - sage: G.show() # long time + sage: G.show() # long time # optional - networkx sage.plot PLOTTING: LCF Graphs are plotted as an n-cycle with edges in the middle, as described above. @@ -2583,9 +2588,9 @@ def PasechnikGraph(n): EXAMPLES:: - sage: graphs.PasechnikGraph(4).is_strongly_regular(parameters=True) + sage: graphs.PasechnikGraph(4).is_strongly_regular(parameters=True) # optional - sage.combinat sage.modules (225, 98, 43, 42) - sage: graphs.PasechnikGraph(5).is_strongly_regular(parameters=True) # long time + sage: graphs.PasechnikGraph(5).is_strongly_regular(parameters=True) # long time, optional - sage.combinat sage.modules (361, 162, 73, 72) sage: graphs.PasechnikGraph(9).is_strongly_regular(parameters=True) # not tested (1225, 578, 273, 272) diff --git a/src/sage/graphs/generators/random.py b/src/sage/graphs/generators/random.py index a947f4488c9..37b8a0d31a7 100644 --- a/src/sage/graphs/generators/random.py +++ b/src/sage/graphs/generators/random.py @@ -97,7 +97,7 @@ def RandomGNP(n, p, seed=None, fast=True, algorithm='Sage'): sage: set_random_seed(0) sage: graphs.RandomGNP(50,.2, algorithm="Sage").size() 243 - sage: graphs.RandomGNP(50,.2, algorithm="networkx").size() + sage: graphs.RandomGNP(50,.2, algorithm="networkx").size() # optional - networkx 279 # 32-bit 209 # 64-bit """ @@ -149,16 +149,16 @@ def RandomBarabasiAlbert(n, m, seed=None): We show the edge list of a random graph on 6 nodes with `m = 2`:: - sage: G = graphs.RandomBarabasiAlbert(6,2) - sage: G.order(), G.size() + sage: G = graphs.RandomBarabasiAlbert(6,2) # optional - networkx + sage: G.order(), G.size() # optional - networkx (6, 8) - sage: G.degree_sequence() # random + sage: G.degree_sequence() # random # optional - networkx [4, 3, 3, 2, 2, 2] We plot a random graph on 12 nodes with `m = 3`:: - sage: ba = graphs.RandomBarabasiAlbert(12,3) - sage: ba.show() # long time + sage: ba = graphs.RandomBarabasiAlbert(12,3) # optional - networkx + sage: ba.show() # long time # optional - networkx sage.plot We view many random graphs using a graphics array:: @@ -206,35 +206,35 @@ def RandomBipartite(n1, n2, p, set_position=False, seed=None): EXAMPLES:: - sage: g = graphs.RandomBipartite(5, 2, 0.5) - sage: g.vertices(sort=True) + sage: g = graphs.RandomBipartite(5, 2, 0.5) # optional - numpy + sage: g.vertices(sort=True) # optional - numpy [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1)] TESTS:: - sage: g = graphs.RandomBipartite(5, -3, 0.5) + sage: g = graphs.RandomBipartite(5, -3, 0.5) # optional - numpy Traceback (most recent call last): ... ValueError: n1 and n2 should be integers strictly greater than 0 - sage: g = graphs.RandomBipartite(5, 3, 1.5) + sage: g = graphs.RandomBipartite(5, 3, 1.5) # optional - numpy Traceback (most recent call last): ... ValueError: parameter p is a probability, and so should be a real value between 0 and 1 :trac:`12155`:: - sage: graphs.RandomBipartite(5, 6, .2).complement() + sage: graphs.RandomBipartite(5, 6, .2).complement() # optional - numpy complement(Random bipartite graph of order 5+6 with edge probability 0.200000000000000): Graph on 11 vertices Test assigned positions:: - sage: graphs.RandomBipartite(1, 2, .1, set_position=True).get_pos() + sage: graphs.RandomBipartite(1, 2, .1, set_position=True).get_pos() # optional - numpy {(0, 0): (1, 1.0), (1, 0): (0, 0), (1, 1): (2.0, 0.0)} - sage: graphs.RandomBipartite(2, 1, .1, set_position=True).get_pos() + sage: graphs.RandomBipartite(2, 1, .1, set_position=True).get_pos() # optional - numpy {(0, 0): (0, 1), (0, 1): (2.0, 1.0), (1, 0): (1, 0.0)} - sage: graphs.RandomBipartite(2, 2, .1, set_position=True).get_pos() + sage: graphs.RandomBipartite(2, 2, .1, set_position=True).get_pos() # optional - numpy {(0, 0): (0, 1), (0, 1): (2.0, 1.0), (1, 0): (0, 0), (1, 1): (2.0, 0.0)} - sage: graphs.RandomBipartite(2, 2, .1, set_position=False).get_pos() + sage: graphs.RandomBipartite(2, 2, .1, set_position=False).get_pos() # optional - numpy """ if not (p >= 0 and p <= 1): @@ -665,12 +665,12 @@ def RandomGNM(n, m, dense=False, seed=None): INPUT: - - ``n`` - number of vertices. + - ``n`` -- number of vertices. - - ``m`` - number of edges. + - ``m`` -- number of edges. - - ``dense`` - whether to use NetworkX's - dense_gnm_random_graph or gnm_random_graph + - ``dense`` -- whether to use NetworkX's + :func:`dense_gnm_random_graph` or :func:`gnm_random_graph` - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random number generator (default: ``None``) @@ -679,28 +679,28 @@ def RandomGNM(n, m, dense=False, seed=None): We show the edge list of a random graph on 5 nodes with 10 edges:: - sage: graphs.RandomGNM(5, 10).edges(sort=True, labels=False) + sage: graphs.RandomGNM(5, 10).edges(sort=True, labels=False) # optional - networkx [(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] We plot a random graph on 12 nodes with m = 12:: - sage: gnm = graphs.RandomGNM(12, 12) - sage: gnm.show() # long time + sage: gnm = graphs.RandomGNM(12, 12) # optional - networkx + sage: gnm.show() # long time # optional - networkx sage.plot We view many random graphs using a graphics array:: sage: g = [] sage: j = [] - sage: for i in range(9): + sage: for i in range(9): # optional - networkx ....: k = graphs.RandomGNM(i+3, i^2-i) ....: g.append(k) - sage: for i in range(3): # optional - sage.plot + sage: for i in range(3): # optional - networkx sage.plot ....: n = [] ....: for m in range(3): ....: n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False)) ....: j.append(n) - sage: G = graphics_array(j) # optional - sage.plot - sage: G.show() # long time # optional - sage.plot + sage: G = graphics_array(j) # optional - networkx sage.plot + sage: G.show() # long time # optional - networkx sage.plot """ if seed is None: seed = int(current_randstate().long_seed() % sys.maxsize) @@ -737,33 +737,33 @@ def RandomNewmanWattsStrogatz(n, k, p, seed=None): We check that the generated graph contains a cycle of order `n`:: - sage: G = graphs.RandomNewmanWattsStrogatz(7, 2, 0.2) - sage: G.order() + sage: G = graphs.RandomNewmanWattsStrogatz(7, 2, 0.2) # optional - networkx + sage: G.order() # optional - networkx 7 - sage: C7 = graphs.CycleGraph(7) - sage: G.subgraph_search(C7) + sage: C7 = graphs.CycleGraph(7) # optional - networkx + sage: G.subgraph_search(C7) # optional - networkx Subgraph of (): Graph on 7 vertices - sage: G.diameter() <= C7.diameter() + sage: G.diameter() <= C7.diameter() # optional - networkx True :: - sage: G = graphs.RandomNewmanWattsStrogatz(12, 2, .3) - sage: G.show() # long time + sage: G = graphs.RandomNewmanWattsStrogatz(12, 2, .3) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot TESTS: We check that when `k = 2` and `p = 0`, the generated graph is a cycle:: - sage: G = graphs.RandomNewmanWattsStrogatz(7, 2, 0) - sage: G.is_cycle() + sage: G = graphs.RandomNewmanWattsStrogatz(7, 2, 0) # optional - networkx + sage: G.is_cycle() # optional - networkx True We check that when `k = 4` and `p = 0`, the generated graph is a circulant graph of parameters ``[1, 2]``:: - sage: G = graphs.RandomNewmanWattsStrogatz(7, 4, 0) - sage: G.is_isomorphic(graphs.CirculantGraph(7, [1, 2])) + sage: G = graphs.RandomNewmanWattsStrogatz(7, 4, 0) # optional - networkx + sage: G.is_isomorphic(graphs.CirculantGraph(7, [1, 2])) # optional - networkx True REFERENCE: @@ -807,8 +807,8 @@ def RandomHolmeKim(n, m, p, seed=None): EXAMPLES:: - sage: G = graphs.RandomHolmeKim(12, 3, .3) - sage: G.show() # long time + sage: G = graphs.RandomHolmeKim(12, 3, .3) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot REFERENCE: @@ -952,8 +952,8 @@ def connecting_nodes(T, l): sage: from sage.graphs.generators.random import connecting_nodes sage: T = graphs.RandomTree(10) - sage: S = connecting_nodes(T, 5) - sage: len(S) + sage: S = connecting_nodes(T, 5) # optional - numpy + sage: len(S) # optional - numpy 10 """ from sage.combinat.permutation import Permutations @@ -1178,8 +1178,8 @@ def RandomChordalGraph(n, algorithm="growing", k=None, l=None, f=None, s=None, s sage: T = RandomChordalGraph(20, algorithm="growing", k=5) sage: T.is_chordal() True - sage: T = RandomChordalGraph(20, algorithm="connecting", l=3) - sage: T.is_chordal() + sage: T = RandomChordalGraph(20, algorithm="connecting", l=3) # optional - numpy + sage: T.is_chordal() # optional - numpy True sage: T = RandomChordalGraph(20, algorithm="pruned", f=1/3, s=.5) sage: T.is_chordal() @@ -1303,13 +1303,13 @@ def RandomLobster(n, p, q, seed=None): We check a random graph with 12 backbone nodes and probabilities `p = 0.7` and `q = 0.3`:: - sage: G = graphs.RandomLobster(12, 0.7, 0.3) - sage: leaves = [v for v in G.vertices(sort=False) if G.degree(v) == 1] - sage: G.delete_vertices(leaves) # caterpillar - sage: leaves = [v for v in G.vertices(sort=False) if G.degree(v) == 1] - sage: G.delete_vertices(leaves) # path - sage: s = G.degree_sequence() - sage: if G: + sage: G = graphs.RandomLobster(12, 0.7, 0.3) # optional - networkx + sage: leaves = [v for v in G.vertices(sort=False) if G.degree(v) == 1] # optional - networkx + sage: G.delete_vertices(leaves) # caterpillar # optional - networkx + sage: leaves = [v for v in G.vertices(sort=False) if G.degree(v) == 1] # optional - networkx + sage: G.delete_vertices(leaves) # path # optional - networkx + sage: s = G.degree_sequence() # optional - networkx + sage: if G: # optional - networkx ....: if G.num_verts() == 1: ....: assert s == [0] ....: else: @@ -1318,8 +1318,8 @@ def RandomLobster(n, p, q, seed=None): :: - sage: G = graphs.RandomLobster(9, .6, .3) - sage: G.show() # long time + sage: G = graphs.RandomLobster(9, .6, .3) # optional - networkx + sage: G.show() # long time # optional - networkx sage.plot """ if seed is None: seed = int(current_randstate().long_seed() % sys.maxsize) @@ -1434,16 +1434,16 @@ def RandomTreePowerlaw(n, gamma=3, tries=1000, seed=None): We check that the generated graph is a tree:: - sage: G = graphs.RandomTreePowerlaw(10, 3) - sage: G.is_tree() + sage: G = graphs.RandomTreePowerlaw(10, 3) # optional - networkx + sage: G.is_tree() # optional - networkx True - sage: G.order(), G.size() + sage: G.order(), G.size() # optional - networkx (10, 9) :: - sage: G = graphs.RandomTreePowerlaw(15, 2) - sage: if G: # random output, long time + sage: G = graphs.RandomTreePowerlaw(15, 2) # optional - networkx + sage: if G: # random output, long time # optional - networkx sage.plot ....: G.show() """ if seed is None: @@ -1474,16 +1474,16 @@ def RandomRegular(d, n, seed=None): We check that a random graph with 8 nodes each of degree 3 is 3-regular:: - sage: G = graphs.RandomRegular(3, 8) - sage: G.is_regular(k=3) + sage: G = graphs.RandomRegular(3, 8) # optional - networkx + sage: G.is_regular(k=3) # optional - networkx True - sage: G.degree_histogram() + sage: G.degree_histogram() # optional - networkx [0, 0, 0, 8] :: - sage: G = graphs.RandomRegular(3, 20) - sage: if G: # random output, long time + sage: G = graphs.RandomRegular(3, 20) # optional - networkx + sage: if G: # random output, long time # optional - networkx sage.plot ....: G.show() REFERENCES: @@ -1524,10 +1524,10 @@ def RandomShell(constructor, seed=None): EXAMPLES:: - sage: G = graphs.RandomShell([(10,20,0.8),(20,40,0.8)]) - sage: G.order(), G.size() + sage: G = graphs.RandomShell([(10,20,0.8),(20,40,0.8)]) # optional - networkx + sage: G.order(), G.size() # optional - networkx (30, 52) - sage: G.show() # long time + sage: G.show() # long time # optional - networkx sage.plot """ if seed is None: seed = int(current_randstate().long_seed() % sys.maxsize) @@ -2005,16 +2005,16 @@ def blossoming_contour(t, shift=0, seed=None): sage: print(blossoming_contour(BinaryTrees(1).an_element())) [('i', 0), ('xb',), ('i', 0), ('xb',), ('i', 0)] - sage: t = BinaryTrees(2).random_element() - sage: print(blossoming_contour(t)) # random + sage: t = BinaryTrees(2).random_element() # optional - sage.combinat + sage: print(blossoming_contour(t)) # random # optional - sage.combinat [('i', 0), ('xb',), ('i', 0), ('n', 2), ('i', 1), ('xb',), ('i', 1), ('xb',), ('i', 1), ('n', 2), ('x',), ('n', 2), ('i', 0)] - sage: w = blossoming_contour(BinaryTrees(3).random_element()); len(w) + sage: w = blossoming_contour(BinaryTrees(3).random_element()); len(w) # optional - sage.combinat 21 - sage: w.count(('xb',)) + sage: w.count(('xb',)) # optional - sage.combinat 4 - sage: w.count(('x',)) + sage: w.count(('x',)) # optional - sage.combinat 2 TESTS:: @@ -2099,16 +2099,16 @@ def RandomBicubicPlanar(n, seed=None): EXAMPLES:: sage: n = randint(200, 300) - sage: G = graphs.RandomBicubicPlanar(n) - sage: G.order() == 2*n + sage: G = graphs.RandomBicubicPlanar(n) # optional - sage.combinat + sage: G.order() == 2*n # optional - sage.combinat True - sage: G.size() == 3*n + sage: G.size() == 3*n # optional - sage.combinat True - sage: G.is_bipartite() and G.is_planar() and G.is_regular(3) + sage: G.is_bipartite() and G.is_planar() and G.is_regular(3) # optional - sage.combinat True - sage: dic = {'red': [v for v in G.vertices(sort=False) if v[0] == 'n'], + sage: dic = {'red': [v for v in G.vertices(sort=False) if v[0] == 'n'], # optional - sage.combinat ....: 'blue': [v for v in G.vertices(sort=False) if v[0] != 'n']} - sage: G.plot(vertex_labels=False, vertex_size=20, vertex_colors=dic) # optional - sage.plot + sage: G.plot(vertex_labels=False, vertex_size=20, vertex_colors=dic) # optional - sage.combinat sage.plot Graphics object consisting of ... graphics primitives .. PLOT:: @@ -2212,21 +2212,21 @@ def RandomUnitDiskGraph(n, radius=.1, side=1, seed=None): sage: from sage.misc.randstate import current_randstate sage: seed = current_randstate().seed() - sage: G = graphs.RandomUnitDiskGraph(20, radius=.5, side=1, seed=seed) - sage: H = graphs.RandomUnitDiskGraph(20, radius=.2, side=1, seed=seed) - sage: H.is_subgraph(G, induced=False) + sage: G = graphs.RandomUnitDiskGraph(20, radius=.5, side=1, seed=seed) # optional - scipy + sage: H = graphs.RandomUnitDiskGraph(20, radius=.2, side=1, seed=seed) # optional - scipy + sage: H.is_subgraph(G, induced=False) # optional - scipy True - sage: H.size() <= G.size() + sage: H.size() <= G.size() # optional - scipy True - sage: Gpos = G.get_pos() - sage: Hpos = H.get_pos() - sage: all(Gpos[u] == Hpos[u] for u in G) + sage: Gpos = G.get_pos() # optional - scipy + sage: Hpos = H.get_pos() # optional - scipy + sage: all(Gpos[u] == Hpos[u] for u in G) # optional - scipy True When the radius is more than `\sqrt{2 \text{side}}`, the graph is a clique:: - sage: G = graphs.RandomUnitDiskGraph(10, radius=2, side=1) - sage: G.is_clique() + sage: G = graphs.RandomUnitDiskGraph(10, radius=2, side=1) # optional - scipy + sage: G.is_clique() # optional - scipy True """ if seed is not None: diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index d7d06530c93..f7bf81db7a4 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -2332,19 +2332,19 @@ def distance_matrix(self, vertices=None, *, base_ring=None, **kwds): EXAMPLES:: sage: d = DiGraph({1: [2, 3], 2: [3], 3: [4], 4: [1]}) - sage: d.distance_matrix() + sage: d.distance_matrix() # optional - sage.modules [0 1 1 2] [3 0 1 2] [2 3 0 1] [1 2 2 0] - sage: d.distance_matrix(vertices=[4, 3, 2, 1]) + sage: d.distance_matrix(vertices=[4, 3, 2, 1]) # optional - sage.modules [0 2 2 1] [1 0 3 2] [2 1 0 3] [2 1 1 0] sage: G = graphs.CubeGraph(3) - sage: G.distance_matrix() + sage: G.distance_matrix() # optional - sage.modules [0 1 1 2 1 2 2 3] [1 0 2 1 2 1 3 2] [1 2 0 1 2 3 1 2] @@ -2358,7 +2358,8 @@ def distance_matrix(self, vertices=None, *, base_ring=None, **kwds): of the distance matrix of any tree of order `n` is `(-1)^{n-1}(n-1)2^{n-2}`:: - sage: all(T.distance_matrix().det() == (-1)^9*(9)*2^8 for T in graphs.trees(10)) + sage: all(T.distance_matrix().det() == (-1)^9*(9)*2^8 # optional - sage.modules + ....: for T in graphs.trees(10)) True .. SEEALSO:: @@ -2371,18 +2372,18 @@ def distance_matrix(self, vertices=None, *, base_ring=None, **kwds): Asking for an immutable matrix:: sage: G = Graph([(0, 1)]) - sage: G.distance_matrix().is_immutable() + sage: G.distance_matrix().is_immutable() # optional - sage.modules False - sage: G.distance_matrix(immutable=True).is_immutable() + sage: G.distance_matrix(immutable=True).is_immutable() # optional - sage.modules True Specifying a base ring:: sage: G = Graph([(0, 1)]) - sage: G.distance_matrix(vertices=[0, 1], base_ring=ZZ) + sage: G.distance_matrix(vertices=[0, 1], base_ring=ZZ) # optional - sage.modules [0 1] [1 0] - sage: G.distance_matrix(vertices=[0, 1], base_ring=RDF) + sage: G.distance_matrix(vertices=[0, 1], base_ring=RDF) # optional - sage.modules [0.0 1.0] [1.0 0.0] @@ -2390,7 +2391,7 @@ def distance_matrix(self, vertices=None, *, base_ring=None, **kwds): constructor:: sage: G = Graph([(0, 1)]) - sage: G.distance_matrix(vertices=[0, 1], weight_function=lambda e:2) + sage: G.distance_matrix(vertices=[0, 1], weight_function=lambda e:2) # optional - sage.modules [0 2] [2 0] """ @@ -2468,15 +2469,15 @@ def weighted_adjacency_matrix(self, sparse=True, vertices=None, sage: G = Graph(sparse=True, weighted=True) sage: G.add_edges([(0, 1, 1), (1, 2, 2), (0, 2, 3), (0, 3, 4)]) - sage: M = G.weighted_adjacency_matrix(); M + sage: M = G.weighted_adjacency_matrix(); M # optional - sage.modules [0 1 3 4] [1 0 2 0] [3 2 0 0] [4 0 0 0] - sage: H = Graph(data=M, format='weighted_adjacency_matrix', sparse=True) - sage: H == G + sage: H = Graph(data=M, format='weighted_adjacency_matrix', sparse=True) # optional - sage.modules + sage: H == G # optional - sage.modules True - sage: G.weighted_adjacency_matrix(vertices=[3, 2, 1, 0]) + sage: G.weighted_adjacency_matrix(vertices=[3, 2, 1, 0]) # optional - sage.modules [0 0 0 4] [0 0 2 3] [0 2 0 1] @@ -2484,7 +2485,8 @@ def weighted_adjacency_matrix(self, sparse=True, vertices=None, Using a different matrix implementation:: - sage: M = G.weighted_adjacency_matrix(sparse=False, base_ring=ZZ, implementation='numpy'); M + sage: M = G.weighted_adjacency_matrix(sparse=False, base_ring=ZZ, # optional - numpy sage.modules + ....: implementation='numpy'); M [0 1 3 4] [1 0 2 0] [3 2 0 0] @@ -2492,22 +2494,23 @@ def weighted_adjacency_matrix(self, sparse=True, vertices=None, As an immutable matrix:: - sage: M = G.weighted_adjacency_matrix(immutable=True); M + sage: M = G.weighted_adjacency_matrix(immutable=True); M # optional - sage.modules [0 1 3 4] [1 0 2 0] [3 2 0 0] [4 0 0 0] - sage: M[2, 2] = 1 + sage: M[2, 2] = 1 # optional - sage.modules Traceback (most recent call last): ... - ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M). + ValueError: matrix is immutable; please change a copy instead + (i.e., use copy(M) to change a copy of M). TESTS: The following doctest verifies that :trac:`4888` is fixed:: sage: G = DiGraph({0:{}, 1:{0:1}, 2:{0:1}}, weighted=True, sparse=True) - sage: G.weighted_adjacency_matrix() + sage: G.weighted_adjacency_matrix() # optional - sage.modules [0 0 0] [1 0 0] [1 0 0] @@ -2518,8 +2521,9 @@ def weighted_adjacency_matrix(self, sparse=True, vertices=None, sage: G.weighted_adjacency_matrix() Traceback (most recent call last): ... - ValueError: cannot find the weight of (0, 1, None). Consider setting parameter 'default_weight' - sage: G.weighted_adjacency_matrix(default_weight=3) + ValueError: cannot find the weight of (0, 1, None). + Consider setting parameter 'default_weight' + sage: G.weighted_adjacency_matrix(default_weight=3) # optional - sage.modules [0 3] [3 0] sage: G = Graph([(0, 1, 'a')]) @@ -2642,33 +2646,33 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl sage: G = Graph(sparse=True) sage: G.add_edges([(0, 1, 1), (1, 2, 2), (0, 2, 3), (0, 3, 4)]) - sage: M = G.kirchhoff_matrix(weighted=True); M + sage: M = G.kirchhoff_matrix(weighted=True); M # optional - sage.modules [ 8 -1 -3 -4] [-1 3 -2 0] [-3 -2 5 0] [-4 0 0 4] - sage: M = G.kirchhoff_matrix(); M + sage: M = G.kirchhoff_matrix(); M # optional - sage.modules [ 3 -1 -1 -1] [-1 2 -1 0] [-1 -1 2 0] [-1 0 0 1] - sage: M = G.laplacian_matrix(normalized=True); M # optional - sage.symbolic + sage: M = G.laplacian_matrix(normalized=True); M # optional - sage.modules sage.symbolic [ 1 -1/6*sqrt(3)*sqrt(2) -1/6*sqrt(3)*sqrt(2) -1/3*sqrt(3)] [-1/6*sqrt(3)*sqrt(2) 1 -1/2 0] [-1/6*sqrt(3)*sqrt(2) -1/2 1 0] [ -1/3*sqrt(3) 0 0 1] - sage: M = G.kirchhoff_matrix(weighted=True, signless=True); M + sage: M = G.kirchhoff_matrix(weighted=True, signless=True); M # optional - sage.modules [8 1 3 4] [1 3 2 0] [3 2 5 0] [4 0 0 4] sage: G = Graph({0: [], 1: [2]}) - sage: G.laplacian_matrix(normalized=True) + sage: G.laplacian_matrix(normalized=True) # optional - sage.modules [ 0 0 0] [ 0 1 -1] [ 0 -1 1] - sage: G.laplacian_matrix(normalized=True,signless=True) + sage: G.laplacian_matrix(normalized=True, signless=True) # optional - sage.modules [0 0 0] [0 1 1] [0 1 1] @@ -2676,14 +2680,14 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl A weighted directed graph with loops, changing the variable ``indegree`` :: sage: G = DiGraph({1: {1: 2, 2: 3}, 2: {1: 4}}, weighted=True, sparse=True) - sage: G.laplacian_matrix() + sage: G.laplacian_matrix() # optional - sage.modules [ 4 -3] [-4 3] :: sage: G = DiGraph({1: {1: 2, 2: 3}, 2: {1: 4}}, weighted=True, sparse=True) - sage: G.laplacian_matrix(indegree=False) + sage: G.laplacian_matrix(indegree=False) # optional - sage.modules [ 3 -3] [-4 4] @@ -2692,12 +2696,12 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl sage: G = Graph(sparse=True) sage: G.add_edges([(0, 1, 1), (1, 2, 2), (0, 2, 3), (0, 3, 4)]) - sage: M = G.kirchhoff_matrix(vertices=[3, 2, 1, 0]); M + sage: M = G.kirchhoff_matrix(vertices=[3, 2, 1, 0]); M # optional - sage.modules [ 1 0 0 -1] [ 0 2 -1 -1] [ 0 -1 2 -1] [-1 -1 -1 3] - sage: M = G.kirchhoff_matrix(weighted=True, vertices=[3, 2, 1, 0]); M + sage: M = G.kirchhoff_matrix(weighted=True, vertices=[3, 2, 1, 0]); M # optional - sage.modules [ 4 0 0 -4] [ 0 5 -2 -3] [ 0 -2 3 -1] @@ -2707,8 +2711,8 @@ def kirchhoff_matrix(self, weighted=None, indegree=True, normalized=False, signl immutable:: sage: G = Graph([(0, 1)]) - sage: M = G.kirchhoff_matrix(vertices=[0, 1], immutable=True) - sage: M.is_immutable() + sage: M = G.kirchhoff_matrix(vertices=[0, 1], immutable=True) # optional - sage.modules + sage: M.is_immutable() # optional - sage.modules True """ from sage.matrix.constructor import diagonal_matrix @@ -22547,7 +22551,10 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input=True, c sage: G.relabel( [ i+1 for i in range(G.order()) ], inplace=True ) sage: G.relabel( [ i+1 for i in range(G.order()) ], inplace=True ) """ - from sage.groups.perm_gps.permgroup_element import PermutationGroupElement + try: + from sage.groups.perm_gps.permgroup_element import PermutationGroupElement + except ImportError: + PermutationGroupElement = () if not inplace: G = copy(self) diff --git a/src/sage/graphs/generic_graph_pyx.pyx b/src/sage/graphs/generic_graph_pyx.pyx index 712c2d955f0..89514e5ecbc 100644 --- a/src/sage/graphs/generic_graph_pyx.pyx +++ b/src/sage/graphs/generic_graph_pyx.pyx @@ -650,7 +650,7 @@ cdef class SubgraphSearch: EXAMPLES:: sage: g = graphs.PetersenGraph() - sage: g.subgraph_search(graphs.CycleGraph(5)) + sage: g.subgraph_search(graphs.CycleGraph(5)) # optional - sage.modules Subgraph of (Petersen graph): Graph on 5 vertices TESTS: @@ -664,7 +664,7 @@ cdef class SubgraphSearch: Traceback (most recent call last): ... ValueError: Searched graph should have at least 2 vertices. - sage: SubgraphSearch(Graph(5), Graph(2)) + sage: SubgraphSearch(Graph(5), Graph(2)) # optional - sage.modules """ if H.order() <= 1: @@ -690,8 +690,8 @@ cdef class SubgraphSearch: sage: from sage.graphs.generic_graph_pyx import SubgraphSearch sage: g = graphs.PathGraph(5) sage: h = graphs.PathGraph(3) - sage: S = SubgraphSearch(g, h) - sage: for p in S: + sage: S = SubgraphSearch(g, h) # optional - sage.modules + sage: for p in S: # optional - sage.modules ....: print(p) [0, 1, 2] [1, 2, 3] @@ -721,8 +721,8 @@ cdef class SubgraphSearch: sage: from sage.graphs.generic_graph_pyx import SubgraphSearch sage: g = graphs.PathGraph(5) sage: h = graphs.PathGraph(3) - sage: S = SubgraphSearch(g, h) - sage: S.cardinality() + sage: S = SubgraphSearch(g, h) # optional - sage.modules + sage: S.cardinality() # optional - sage.modules 6 """ if self.nh > self.ng: @@ -756,18 +756,18 @@ cdef class SubgraphSearch: sage: from sage.graphs.generic_graph_pyx import SubgraphSearch sage: g = graphs.PathGraph(5) sage: h = graphs.PathGraph(3) - sage: S = SubgraphSearch(g, h) - sage: S.__next__() + sage: S = SubgraphSearch(g, h) # optional - sage.modules + sage: S.__next__() # optional - sage.modules [0, 1, 2] - sage: S._initialization() - sage: S.__next__() + sage: S._initialization() # optional - sage.modules + sage: S.__next__() # optional - sage.modules [0, 1, 2] TESTS: Check that :trac:`21828` is fixed:: - sage: Poset().is_incomparable_chain_free(1,1) # indirect doctest + sage: Poset().is_incomparable_chain_free(1,1) # indirect doctest # optional - sage.modules True """ cdef int i @@ -802,7 +802,7 @@ cdef class SubgraphSearch: EXAMPLES:: sage: g = graphs.PetersenGraph() - sage: g.subgraph_search(graphs.CycleGraph(5)) + sage: g.subgraph_search(graphs.CycleGraph(5)) # optional - sage.modules Subgraph of (Petersen graph): Graph on 5 vertices """ self.mem = MemoryAllocator() @@ -883,8 +883,8 @@ cdef class SubgraphSearch: sage: from sage.graphs.generic_graph_pyx import SubgraphSearch sage: g = graphs.PathGraph(5) sage: h = graphs.PathGraph(3) - sage: S = SubgraphSearch(g, h) - sage: S.__next__() + sage: S = SubgraphSearch(g, h) # optional - sage.modules + sage: S.__next__() # optional - sage.modules [0, 1, 2] """ if not self.ng: diff --git a/src/sage/graphs/graph_decompositions/bandwidth.pyx b/src/sage/graphs/graph_decompositions/bandwidth.pyx index 874787d4713..d72c6e5ff80 100644 --- a/src/sage/graphs/graph_decompositions/bandwidth.pyx +++ b/src/sage/graphs/graph_decompositions/bandwidth.pyx @@ -160,7 +160,7 @@ def bandwidth(G, k=None): False sage: bandwidth(G) (5, [0, 4, 5, 8, 1, 9, 3, 7, 6, 2]) - sage: G.adjacency_matrix(vertices=[0, 4, 5, 8, 1, 9, 3, 7, 6, 2]) + sage: G.adjacency_matrix(vertices=[0, 4, 5, 8, 1, 9, 3, 7, 6, 2]) # optional - sage.modules [0 1 1 0 1 0 0 0 0 0] [1 0 0 0 0 1 1 0 0 0] [1 0 0 1 0 0 0 1 0 0] @@ -174,7 +174,7 @@ def bandwidth(G, k=None): sage: G = graphs.ChvatalGraph() sage: bandwidth(G) (6, [0, 5, 9, 4, 10, 1, 6, 11, 3, 8, 7, 2]) - sage: G.adjacency_matrix(vertices=[0, 5, 9, 4, 10, 1, 6, 11, 3, 8, 7, 2]) + sage: G.adjacency_matrix(vertices=[0, 5, 9, 4, 10, 1, 6, 11, 3, 8, 7, 2]) # optional - sage.modules [0 0 1 1 0 1 1 0 0 0 0 0] [0 0 0 1 1 1 0 1 0 0 0 0] [1 0 0 0 1 0 0 1 1 0 0 0] diff --git a/src/sage/graphs/graph_decompositions/graph_products.pyx b/src/sage/graphs/graph_decompositions/graph_products.pyx index ed85f6f7ef2..0a948360096 100644 --- a/src/sage/graphs/graph_decompositions/graph_products.pyx +++ b/src/sage/graphs/graph_decompositions/graph_products.pyx @@ -206,8 +206,8 @@ def is_cartesian_product(g, certificate=False, relabeling=False): Wagner's Graph (:trac:`13599`):: - sage: g = graphs.WagnerGraph() - sage: g.is_cartesian_product() + sage: g = graphs.WagnerGraph() # optional - networkx + sage: g.is_cartesian_product() # optional - networkx False Empty and one-element graph (:trac:`19546`):: diff --git a/src/sage/graphs/graph_decompositions/modular_decomposition.py b/src/sage/graphs/graph_decompositions/modular_decomposition.py index 0c1ae4da5b3..794c1d95d7b 100644 --- a/src/sage/graphs/graph_decompositions/modular_decomposition.py +++ b/src/sage/graphs/graph_decompositions/modular_decomposition.py @@ -16,8 +16,12 @@ # **************************************************************************** from enum import Enum + +from sage.misc.lazy_import import lazy_import from sage.misc.random_testing import random_testing +lazy_import('sage.groups.perm_gps.permgroup_element', 'PermutationGroupElement') + class NodeType(Enum): """ @@ -606,7 +610,7 @@ def habib_maurer_algorithm(graph, g_classes=None): decompositions. :: sage: from sage.graphs.graph_decompositions.modular_decomposition import permute_decomposition - sage: permute_decomposition(2, habib_maurer_algorithm, 20, 0.5) + sage: permute_decomposition(2, habib_maurer_algorithm, 20, 0.5) # optional - sage.groups """ if graph.is_directed(): raise ValueError("Graph must be undirected") @@ -1167,7 +1171,6 @@ def relabel_tree(root, perm): 2 1 """ - from sage.groups.perm_gps.permgroup_element import PermutationGroupElement # If perm is not a dictionary, we build one ! if perm is None: diff --git a/src/sage/graphs/graph_decompositions/vertex_separation.pyx b/src/sage/graphs/graph_decompositions/vertex_separation.pyx index 98ab0800e52..6773f1d6581 100644 --- a/src/sage/graphs/graph_decompositions/vertex_separation.pyx +++ b/src/sage/graphs/graph_decompositions/vertex_separation.pyx @@ -766,12 +766,12 @@ def vertex_separation(G, algorithm="BAB", cut_off=None, upper_bound=None, verbos Comparison of methods:: sage: from sage.graphs.graph_decompositions.vertex_separation import vertex_separation - sage: G = digraphs.DeBruijn(2,3) - sage: vs,L = vertex_separation(G, algorithm="BAB"); vs + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: vs,L = vertex_separation(G, algorithm="BAB"); vs # optional - sage.combinat 2 - sage: vs,L = vertex_separation(G, algorithm="exponential"); vs + sage: vs,L = vertex_separation(G, algorithm="exponential"); vs # optional - sage.combinat 2 - sage: vs,L = vertex_separation(G, algorithm="MILP"); vs + sage: vs,L = vertex_separation(G, algorithm="MILP"); vs # optional - sage.combinat 2 sage: G = graphs.Grid2dGraph(3,3) sage: vs,L = vertex_separation(G, algorithm="BAB"); vs @@ -954,8 +954,8 @@ def vertex_separation_exp(G, verbose=False): Graphs with non-integer vertices:: sage: from sage.graphs.graph_decompositions.vertex_separation import vertex_separation_exp - sage: D=digraphs.DeBruijn(2,3) - sage: vertex_separation_exp(D) + sage: D = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: vertex_separation_exp(D) # optional - sage.combinat (2, ['000', '001', '100', '010', '101', '011', '110', '111']) Given a too large graph:: @@ -1211,12 +1211,12 @@ def width_of_path_decomposition(G, L): Path decomposition of a BalancedTree:: sage: from sage.graphs.graph_decompositions import vertex_separation - sage: G = graphs.BalancedTree(3,2) - sage: pw, L = vertex_separation.path_decomposition(G) - sage: pw == vertex_separation.width_of_path_decomposition(G, L) + sage: G = graphs.BalancedTree(3,2) # optional - networkx + sage: pw, L = vertex_separation.path_decomposition(G) # optional - networkx + sage: pw == vertex_separation.width_of_path_decomposition(G, L) # optional - networkx True - sage: L.reverse() - sage: pw == vertex_separation.width_of_path_decomposition(G, L) + sage: L.reverse() # optional - networkx + sage: pw == vertex_separation.width_of_path_decomposition(G, L) # optional - networkx False Directed path decomposition of a circuit:: @@ -1305,9 +1305,9 @@ def _vertex_separation_MILP_formulation(G, integrality=False, solver=None): EXAMPLES:: sage: from sage.graphs.graph_decompositions.vertex_separation import _vertex_separation_MILP_formulation - sage: G = digraphs.DeBruijn(2,3) - sage: p, x, u, y, z = _vertex_separation_MILP_formulation(G) - sage: p + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: p, x, u, y, z = _vertex_separation_MILP_formulation(G) # optional - sage.combinat + sage: p # optional - sage.combinat Mixed Integer Program (minimization, 193 variables, 449 constraints) """ from sage.graphs.graph import Graph @@ -1420,12 +1420,12 @@ def vertex_separation_MILP(G, integrality=False, solver=None, verbose=0, Vertex separation of a De Bruijn digraph:: sage: from sage.graphs.graph_decompositions import vertex_separation - sage: G = digraphs.DeBruijn(2,3) - sage: vs, L = vertex_separation.vertex_separation_MILP(G); vs + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: vs, L = vertex_separation.vertex_separation_MILP(G); vs # optional - sage.combinat 2 - sage: vs == vertex_separation.width_of_path_decomposition(G, L) + sage: vs == vertex_separation.width_of_path_decomposition(G, L) # optional - sage.combinat True - sage: vse, Le = vertex_separation.vertex_separation(G); vse + sage: vse, Le = vertex_separation.vertex_separation(G); vse # optional - sage.combinat 2 The vertex separation of a circuit is 1:: diff --git a/src/sage/graphs/graph_input.py b/src/sage/graphs/graph_input.py index 1c952fcceae..39b22a44b56 100644 --- a/src/sage/graphs/graph_input.py +++ b/src/sage/graphs/graph_input.py @@ -185,8 +185,9 @@ def from_seidel_adjacency_matrix(G, M): sage: from sage.graphs.graph_input import from_seidel_adjacency_matrix sage: g = Graph() - sage: from_seidel_adjacency_matrix(g, graphs.PetersenGraph().seidel_adjacency_matrix()) - sage: g.is_isomorphic(graphs.PetersenGraph()) + sage: sam = graphs.PetersenGraph().seidel_adjacency_matrix() # optional - sage.modules + sage: from_seidel_adjacency_matrix(g, sam) # optional - sage.modules + sage: g.is_isomorphic(graphs.PetersenGraph()) # optional - sage.modules True """ from sage.structure.element import is_Matrix @@ -235,8 +236,8 @@ def from_adjacency_matrix(G, M, loops=False, multiedges=False, weighted=False): sage: from sage.graphs.graph_input import from_adjacency_matrix sage: g = Graph() - sage: from_adjacency_matrix(g, graphs.PetersenGraph().adjacency_matrix()) - sage: g.is_isomorphic(graphs.PetersenGraph()) + sage: from_adjacency_matrix(g, graphs.PetersenGraph().adjacency_matrix()) # optional - sage.modules + sage: g.is_isomorphic(graphs.PetersenGraph()) # optional - sage.modules True """ from sage.structure.element import is_Matrix @@ -311,8 +312,8 @@ def from_incidence_matrix(G, M, loops=False, multiedges=False, weighted=False): sage: from sage.graphs.graph_input import from_incidence_matrix sage: g = Graph() - sage: from_incidence_matrix(g, graphs.PetersenGraph().incidence_matrix()) - sage: g.is_isomorphic(graphs.PetersenGraph()) + sage: from_incidence_matrix(g, graphs.PetersenGraph().incidence_matrix()) # optional - sage.modules + sage: g.is_isomorphic(graphs.PetersenGraph()) # optional - sage.modules True """ from sage.structure.element import is_Matrix @@ -377,38 +378,37 @@ def from_oriented_incidence_matrix(G, M, loops=False, multiedges=False, weighted sage: from sage.graphs.graph_input import from_oriented_incidence_matrix sage: g = DiGraph() - sage: from_oriented_incidence_matrix(g, digraphs.Circuit(10).incidence_matrix()) - sage: g.is_isomorphic(digraphs.Circuit(10)) + sage: im = digraphs.Circuit(10).incidence_matrix() # optional - sage.modules + sage: from_oriented_incidence_matrix(g, im) # optional - sage.modules + sage: g.is_isomorphic(digraphs.Circuit(10)) # optional - sage.modules True TESTS: Fix bug reported in :trac:`22985`:: - sage: DiGraph(matrix ([[1,0,0,1],[0,0,1,1],[0,0,1,1]]).transpose()) + sage: DiGraph(matrix ([[1,0,0,1],[0,0,1,1],[0,0,1,1]]).transpose()) # optional - sage.modules Traceback (most recent call last): ... ValueError: each column represents an edge: -1 goes to 1 Handle incidence matrix containing a column with only zeros (:trac:`29275`):: - sage: m = Matrix([[0,1],[0,-1],[0,0]]) - sage: m + sage: m = Matrix([[0,1],[0,-1],[0,0]]); m # optional - sage.modules [ 0 1] [ 0 -1] [ 0 0] - sage: G = DiGraph(m,format='incidence_matrix') - sage: list(G.edges(sort=True, labels=False)) + sage: G = DiGraph(m, format='incidence_matrix') # optional - sage.modules + sage: list(G.edges(sort=True, labels=False)) # optional - sage.modules [(1, 0)] Handle incidence matrix [[1],[-1]] (:trac:`29275`):: - sage: m = Matrix([[1],[-1]]) - sage: m + sage: m = Matrix([[1],[-1]]); m # optional - sage.modules [ 1] [-1] - sage: G = DiGraph(m,format='incidence_matrix') - sage: list(G.edges(sort=True, labels=False)) + sage: G = DiGraph(m, format='incidence_matrix') # optional - sage.modules + sage: list(G.edges(sort=True, labels=False)) # optional - sage.modules [(1, 0)] """ from sage.structure.element import is_Matrix diff --git a/src/sage/graphs/graph_list.py b/src/sage/graphs/graph_list.py index ea84b183fb2..4a43987a79b 100644 --- a/src/sage/graphs/graph_list.py +++ b/src/sage/graphs/graph_list.py @@ -266,9 +266,9 @@ def to_graphics_array(graph_list, **kwds): options, all of which are available from :func:`to_graphics_array`:: sage: glist = [] - sage: for _ in range(10): + sage: for _ in range(10): # optional - networkx ....: glist.append(graphs.RandomLobster(41, .3, .4)) - sage: graphs_list.to_graphics_array(glist, layout='spring', vertex_size=20) # optional - sage.plot + sage: graphs_list.to_graphics_array(glist, layout='spring', vertex_size=20) # optional - networkx sage.plot Graphics Array of size 3 x 4 """ from sage.graphs import graph diff --git a/src/sage/graphs/graph_plot_js.py b/src/sage/graphs/graph_plot_js.py index 44b6274cf4c..ad846d7a474 100644 --- a/src/sage/graphs/graph_plot_js.py +++ b/src/sage/graphs/graph_plot_js.py @@ -174,14 +174,14 @@ def gen_html_code(G, sage: graphs.DodecahedralGraph().show(method="js") # optional -- internet sage.plot - sage: g = digraphs.DeBruijn(2, 2) - sage: g.allow_multiple_edges(True) - sage: g.add_edge("10", "10", "a") - sage: g.add_edge("10", "10", "b") - sage: g.add_edge("10", "10", "c") - sage: g.add_edge("10", "10", "d") - sage: g.add_edge("01", "11", "1") - sage: g.show(method="js", vertex_labels=True,edge_labels=True, # optional - sage.plot + sage: g = digraphs.DeBruijn(2, 2) # optional - sage.combinat + sage: g.allow_multiple_edges(True) # optional - sage.combinat + sage: g.add_edge("10", "10", "a") # optional - sage.combinat + sage: g.add_edge("10", "10", "b") # optional - sage.combinat + sage: g.add_edge("10", "10", "c") # optional - sage.combinat + sage: g.add_edge("10", "10", "d") # optional - sage.combinat + sage: g.add_edge("01", "11", "1") # optional - sage.combinat + sage: g.show(method="js", vertex_labels=True,edge_labels=True, # optional - sage.combinat sage.plot ....: link_distance=200, gravity=.05, charge=-500, ....: edge_partition=[[("11", "12", "2"), ("21", "21", "a")]], ....: edge_thickness=4) diff --git a/src/sage/graphs/hypergraph_generators.py b/src/sage/graphs/hypergraph_generators.py index a106f3fc7d8..c3e42da9565 100644 --- a/src/sage/graphs/hypergraph_generators.py +++ b/src/sage/graphs/hypergraph_generators.py @@ -306,34 +306,34 @@ def BinomialRandomUniform(self, n, k, p): EXAMPLES:: - sage: hypergraphs.BinomialRandomUniform(50, 3, 1).num_blocks() + sage: hypergraphs.BinomialRandomUniform(50, 3, 1).num_blocks() # optional - numpy 19600 - sage: hypergraphs.BinomialRandomUniform(50, 3, 0).num_blocks() + sage: hypergraphs.BinomialRandomUniform(50, 3, 0).num_blocks() # optional - numpy 0 TESTS:: - sage: hypergraphs.BinomialRandomUniform(50, 3, -0.1) + sage: hypergraphs.BinomialRandomUniform(50, 3, -0.1) # optional - numpy Traceback (most recent call last): ... ValueError: edge probability should be in [0,1] - sage: hypergraphs.BinomialRandomUniform(50, 3, 1.1) + sage: hypergraphs.BinomialRandomUniform(50, 3, 1.1) # optional - numpy Traceback (most recent call last): ... ValueError: edge probability should be in [0,1] - sage: hypergraphs.BinomialRandomUniform(-50, 3, 0.17) + sage: hypergraphs.BinomialRandomUniform(-50, 3, 0.17) # optional - numpy Traceback (most recent call last): ... ValueError: number of vertices should be non-negative - sage: hypergraphs.BinomialRandomUniform(50.9, 3, 0.17) + sage: hypergraphs.BinomialRandomUniform(50.9, 3, 0.17) # optional - numpy Traceback (most recent call last): ... ValueError: number of vertices should be an integer - sage: hypergraphs.BinomialRandomUniform(50, -3, 0.17) + sage: hypergraphs.BinomialRandomUniform(50, -3, 0.17) # optional - numpy Traceback (most recent call last): ... ValueError: the uniformity should be non-negative - sage: hypergraphs.BinomialRandomUniform(50, I, 0.17) + sage: hypergraphs.BinomialRandomUniform(50, I, 0.17) # optional - numpy Traceback (most recent call last): ... ValueError: the uniformity should be an integer diff --git a/src/sage/graphs/isoperimetric_inequalities.pyx b/src/sage/graphs/isoperimetric_inequalities.pyx index b7f6510ba94..b6dfa40d06d 100644 --- a/src/sage/graphs/isoperimetric_inequalities.pyx +++ b/src/sage/graphs/isoperimetric_inequalities.pyx @@ -209,8 +209,8 @@ def edge_isoperimetric_number(g): In general, for `d`-regular graphs the edge-isoperimetric number is `d` times larger than the Cheeger constant of the graph:: - sage: g = graphs.RandomRegular(3, 10) - sage: g.edge_isoperimetric_number() == g.cheeger_constant() * 3 + sage: g = graphs.RandomRegular(3, 10) # optional - networkx + sage: g.edge_isoperimetric_number() == g.cheeger_constant() * 3 # optional - networkx True And the edge-isoperimetric constant of a disconnected graph is `0`:: diff --git a/src/sage/graphs/line_graph.pyx b/src/sage/graphs/line_graph.pyx index 25cd48de951..656c9c08909 100644 --- a/src/sage/graphs/line_graph.pyx +++ b/src/sage/graphs/line_graph.pyx @@ -176,8 +176,8 @@ def is_line_graph(g, certificate=False): This is indeed the subgraph returned:: - sage: C = graphs.PetersenGraph().is_line_graph(certificate=True)[1] - sage: C.is_isomorphic(graphs.ClawGraph()) + sage: C = graphs.PetersenGraph().is_line_graph(certificate=True)[1] # optional - sage.modules + sage: C.is_isomorphic(graphs.ClawGraph()) # optional - sage.modules True The house graph is a line graph:: @@ -188,11 +188,11 @@ def is_line_graph(g, certificate=False): But what is the graph whose line graph is the house ?:: - sage: is_line, R, isom = g.is_line_graph(certificate=True) - sage: R.sparse6_string() + sage: is_line, R, isom = g.is_line_graph(certificate=True) # optional - sage.modules + sage: R.sparse6_string() # optional - sage.modules ':DaHI~' - sage: R.show() # optional - sage.plot - sage: isom + sage: R.show() # optional - sage.modules sage.plot + sage: isom # optional - sage.modules {0: (0, 1), 1: (0, 2), 2: (1, 3), 3: (2, 3), 4: (3, 4)} TESTS: @@ -201,8 +201,8 @@ def is_line_graph(g, certificate=False): sage: g = 2 * graphs.CycleGraph(3) sage: gl = g.line_graph().relabel(inplace=False) - sage: new_g = gl.is_line_graph(certificate=True)[1] - sage: g.line_graph().is_isomorphic(gl) + sage: new_g = gl.is_line_graph(certificate=True)[1] # optional - sage.modules + sage: g.line_graph().is_isomorphic(gl) # optional - sage.modules True Verify that :trac:`29740` is fixed:: @@ -309,12 +309,12 @@ def line_graph(g, labels=True): sage: h = g.line_graph() sage: h.vertices(sort=True) [(0, 1, None), - (0, 2, None), - (0, 3, None), - (1, 2, None), - (1, 3, None), - (2, 3, None)] - sage: h.am() + (0, 2, None), + (0, 3, None), + (1, 2, None), + (1, 3, None), + (2, 3, None)] + sage: h.am() # optional - sage.modules [0 1 1 1 1 0] [1 0 1 1 0 1] [1 1 0 0 1 1] @@ -330,11 +330,11 @@ def line_graph(g, labels=True): sage: h = g.line_graph() sage: h.vertices(sort=True) [(1, 2, None), - (1, 3, None), - (1, 4, None), - (2, 3, None), - (2, 4, None), - (3, 4, None)] + (1, 3, None), + (1, 4, None), + (2, 3, None), + (2, 4, None), + (3, 4, None)] sage: h.edges(sort=True) [((1, 2, None), (2, 3, None), None), ((1, 2, None), (2, 4, None), None), diff --git a/src/sage/graphs/partial_cube.py b/src/sage/graphs/partial_cube.py index bce06dee677..f7bb3e25173 100644 --- a/src/sage/graphs/partial_cube.py +++ b/src/sage/graphs/partial_cube.py @@ -110,8 +110,8 @@ def breadth_first_level_search(G, start): EXAMPLES:: - sage: H = digraphs.DeBruijn(3,2) - sage: list(sage.graphs.partial_cube.breadth_first_level_search(H, '00')) + sage: H = digraphs.DeBruijn(3,2) # optional - sage.combinat + sage: list(sage.graphs.partial_cube.breadth_first_level_search(H, '00')) # optional - sage.combinat [{'00': {'01', '02'}}, {'01': {'10', '11', '12'}, '02': {'20', '21', '22'}}, {'10': set(), @@ -162,9 +162,9 @@ def depth_first_traversal(G, start): EXAMPLES:: - sage: H = digraphs.DeBruijn(3,2) - sage: t = list(sage.graphs.partial_cube.depth_first_traversal(H, '00')) - sage: len(t) + sage: H = digraphs.DeBruijn(3,2) # optional - sage.combinat + sage: t = list(sage.graphs.partial_cube.depth_first_traversal(H, '00')) # optional - sage.combinat + sage: len(t) # optional - sage.combinat 16 """ neighbors = G.neighbor_out_iterator diff --git a/src/sage/graphs/spanning_tree.pyx b/src/sage/graphs/spanning_tree.pyx index 2fb5124596f..179625ab743 100644 --- a/src/sage/graphs/spanning_tree.pyx +++ b/src/sage/graphs/spanning_tree.pyx @@ -569,11 +569,12 @@ def filter_kruskal_iterator(G, threshold=10000, by_weight=True, weight_function= :func:`filter_kruskal_iterator` are the same:: sage: from sage.graphs.spanning_tree import kruskal_iterator - sage: G = graphs.RandomBarabasiAlbert(50, 2) - sage: for u, v in G.edge_iterator(labels=False): + sage: G = graphs.RandomBarabasiAlbert(50, 2) # optional - networkx + sage: for u, v in G.edge_iterator(labels=False): # optional - networkx ....: G.set_edge_label(u, v, randint(1, 10)) - sage: G.weighted(True) - sage: sum(e[2] for e in kruskal_iterator(G)) == sum(e[2] for e in filter_kruskal_iterator(G, threshold=20)) + sage: G.weighted(True) # optional - networkx + sage: sum(e[2] for e in kruskal_iterator(G)) == sum(e[2] # optional - networkx + ....: for e in filter_kruskal_iterator(G, threshold=20)) True TESTS: @@ -999,11 +1000,11 @@ def random_spanning_tree(G, output_as_graph=False, by_weight=False, weight_funct Check that the spanning tree returned when using weights is a tree:: - sage: G = graphs.RandomBarabasiAlbert(50, 2) - sage: for u, v in G.edge_iterator(labels=False): + sage: G = graphs.RandomBarabasiAlbert(50, 2) # optional - networkx + sage: for u, v in G.edge_iterator(labels=False): # optional - networkx ....: G.set_edge_label(u, v, randint(1, 10)) - sage: T = G.random_spanning_tree(by_weight=True, output_as_graph=True) - sage: T.is_tree() + sage: T = G.random_spanning_tree(by_weight=True, output_as_graph=True) # optional - networkx + sage: T.is_tree() # optional - networkx True TESTS:: @@ -1087,12 +1088,12 @@ def spanning_trees(g, labels=False): sage: G = Graph([(1,2),(1,2),(1,3),(1,3),(2,3),(1,4)], multiedges=True) sage: len(list(G.spanning_trees())) 8 - sage: G.spanning_trees_count() + sage: G.spanning_trees_count() # optional - sage.modules 8 sage: G = Graph([(1,2),(2,3),(3,1),(3,4),(4,5),(4,5),(4,6)], multiedges=True) sage: len(list(G.spanning_trees())) 6 - sage: G.spanning_trees_count() + sage: G.spanning_trees_count() # optional - sage.modules 6 .. SEEALSO:: diff --git a/src/sage/graphs/strongly_regular_db.pyx b/src/sage/graphs/strongly_regular_db.pyx index 24f471edd4e..4a72a2da568 100644 --- a/src/sage/graphs/strongly_regular_db.pyx +++ b/src/sage/graphs/strongly_regular_db.pyx @@ -30,21 +30,22 @@ Functions import json import os +from libc.math cimport sqrt, floor +from libc.stdint cimport uint_fast32_t + +from sage.arith.misc import divisors, is_prime_power, is_square from sage.categories.sets_cat import EmptySetError -from sage.misc.unknown import Unknown -from sage.arith.misc import is_square -from sage.arith.misc import is_prime_power -from sage.arith.misc import divisors -from sage.misc.cachefunc import cached_function -from sage.combinat.designs.orthogonal_arrays import orthogonal_array -from sage.combinat.designs.bibd import balanced_incomplete_block_design from sage.graphs.graph import Graph -from libc.math cimport sqrt, floor -from sage.matrix.constructor import Matrix -from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF -from sage.coding.linear_code import LinearCode +from sage.misc.cachefunc import cached_function +from sage.misc.lazy_import import LazyImport +from sage.misc.unknown import Unknown from sage.rings.sum_of_squares cimport two_squares_c -from libc.stdint cimport uint_fast32_t + +orthogonal_array = LazyImport('sage.combinat.designs.orthogonal_arrays', 'orthogonal_array') +balanced_incomplete_block_design = LazyImport('sage.combinat.designs.bibd', 'balanced_incomplete_block_design') +GF = LazyImport('sage.rings.finite_rings.finite_field_constructor', 'GF') +Matrix = LazyImport('sage.matrix.constructor', 'Matrix') +LinearCode = LazyImport('sage.coding.linear_code', 'LinearCode') cdef dict _brouwer_database = None _small_srg_database = None diff --git a/src/sage/graphs/traversals.pyx b/src/sage/graphs/traversals.pyx index e07c502973e..9ebc253b6f9 100644 --- a/src/sage/graphs/traversals.pyx +++ b/src/sage/graphs/traversals.pyx @@ -338,16 +338,16 @@ def lex_BFS(G, reverse=False, tree=False, initial_vertex=None, algorithm="fast") Different orderings for different traversals:: - sage: G = digraphs.DeBruijn(2,3) - sage: G.lex_BFS(initial_vertex='000', algorithm="fast") + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: G.lex_BFS(initial_vertex='000', algorithm="fast") # optional - sage.combinat ['000', '001', '100', '010', '011', '110', '101', '111'] - sage: G.lex_BFS(initial_vertex='000', algorithm="slow") + sage: G.lex_BFS(initial_vertex='000', algorithm="slow") # optional - sage.combinat ['000', '001', '100', '010', '011', '110', '101', '111'] - sage: G.lex_DFS(initial_vertex='000') + sage: G.lex_DFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '101', '110', '011', '111'] - sage: G.lex_UP(initial_vertex='000') + sage: G.lex_UP(initial_vertex='000') # optional - sage.combinat ['000', '001', '010', '101', '110', '111', '011', '100'] - sage: G.lex_DOWN(initial_vertex='000') + sage: G.lex_DOWN(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '011', '010', '110', '111', '101'] TESTS: @@ -541,14 +541,14 @@ def lex_UP(G, reverse=False, tree=False, initial_vertex=None): Different orderings for different traversals:: - sage: G = digraphs.DeBruijn(2,3) - sage: G.lex_BFS(initial_vertex='000') + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: G.lex_BFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '011', '110', '101', '111'] - sage: G.lex_DFS(initial_vertex='000') + sage: G.lex_DFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '101', '110', '011', '111'] - sage: G.lex_UP(initial_vertex='000') + sage: G.lex_UP(initial_vertex='000') # optional - sage.combinat ['000', '001', '010', '101', '110', '111', '011', '100'] - sage: G.lex_DOWN(initial_vertex='000') + sage: G.lex_DOWN(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '011', '010', '110', '111', '101'] TESTS: @@ -714,14 +714,14 @@ def lex_DFS(G, reverse=False, tree=False, initial_vertex=None): Different orderings for different traversals:: - sage: G = digraphs.DeBruijn(2,3) - sage: G.lex_BFS(initial_vertex='000') + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: G.lex_BFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '011', '110', '101', '111'] - sage: G.lex_DFS(initial_vertex='000') + sage: G.lex_DFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '101', '110', '011', '111'] - sage: G.lex_UP(initial_vertex='000') + sage: G.lex_UP(initial_vertex='000') # optional - sage.combinat ['000', '001', '010', '101', '110', '111', '011', '100'] - sage: G.lex_DOWN(initial_vertex='000') + sage: G.lex_DOWN(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '011', '010', '110', '111', '101'] TESTS: @@ -889,14 +889,14 @@ def lex_DOWN(G, reverse=False, tree=False, initial_vertex=None): Different orderings for different traversals:: - sage: G = digraphs.DeBruijn(2,3) - sage: G.lex_BFS(initial_vertex='000') + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: G.lex_BFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '011', '110', '101', '111'] - sage: G.lex_DFS(initial_vertex='000') + sage: G.lex_DFS(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '010', '101', '110', '011', '111'] - sage: G.lex_UP(initial_vertex='000') + sage: G.lex_UP(initial_vertex='000') # optional - sage.combinat ['000', '001', '010', '101', '110', '111', '011', '100'] - sage: G.lex_DOWN(initial_vertex='000') + sage: G.lex_DOWN(initial_vertex='000') # optional - sage.combinat ['000', '001', '100', '011', '010', '110', '111', '101'] TESTS: diff --git a/src/sage/graphs/views.pyx b/src/sage/graphs/views.pyx index 51a4a738e46..c49511207e5 100644 --- a/src/sage/graphs/views.pyx +++ b/src/sage/graphs/views.pyx @@ -175,11 +175,11 @@ cdef class EdgesView: With a directed graph:: - sage: G = digraphs.DeBruijn(2, 2) - sage: E = EdgesView(G, labels=False, sort=True); E + sage: G = digraphs.DeBruijn(2, 2) # optional - sage.combinat + sage: E = EdgesView(G, labels=False, sort=True); E # optional - sage.combinat [('00', '00'), ('00', '01'), ('01', '10'), ('01', '11'), ('10', '00'), ('10', '01'), ('11', '10'), ('11', '11')] - sage: E = EdgesView(G, labels=False, sort=True, key=lambda e:(e[1], e[0])); E + sage: E = EdgesView(G, labels=False, sort=True, key=lambda e:(e[1], e[0])); E # optional - sage.combinat [('00', '00'), ('10', '00'), ('00', '01'), ('10', '01'), ('01', '10'), ('11', '10'), ('01', '11'), ('11', '11')] From 8c37271865d225c5cb0d4201cf2fd28c1e387568 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 27 May 2023 00:37:27 -0700 Subject: [PATCH 31/56] sage.graphs: Add # optional --- .../graphs/base/static_sparse_backend.pyx | 6 +- src/sage/graphs/bipartite_graph.py | 20 +- src/sage/graphs/bliss.pyx | 10 +- src/sage/graphs/edge_connectivity.pyx | 15 +- src/sage/graphs/generators/degree_sequence.py | 8 +- src/sage/graphs/generators/random.py | 10 +- src/sage/graphs/generators/smallgraphs.py | 373 +++---- src/sage/graphs/generic_graph.py | 941 +++++++++--------- src/sage/graphs/generic_graph_pyx.pyx | 2 +- 9 files changed, 718 insertions(+), 667 deletions(-) diff --git a/src/sage/graphs/base/static_sparse_backend.pyx b/src/sage/graphs/base/static_sparse_backend.pyx index b8b32405515..a8de583d4db 100644 --- a/src/sage/graphs/base/static_sparse_backend.pyx +++ b/src/sage/graphs/base/static_sparse_backend.pyx @@ -671,10 +671,10 @@ cdef class StaticSparseBackend(CGraphBackend): :: sage: from sage.graphs.base.static_sparse_backend import StaticSparseBackend - sage: g = StaticSparseBackend(digraphs.DeBruijn(3, 2)) - sage: g.has_edge('00', '01', '1') + sage: g = StaticSparseBackend(digraphs.DeBruijn(3, 2)) # optional - sage.combinat + sage: g.has_edge('00', '01', '1') # optional - sage.combinat True - sage: g.has_edge('00', '01', '0') + sage: g.has_edge('00', '01', '0') # optional - sage.combinat False """ try: diff --git a/src/sage/graphs/bipartite_graph.py b/src/sage/graphs/bipartite_graph.py index c30ed062e50..aa5c411f3f0 100644 --- a/src/sage/graphs/bipartite_graph.py +++ b/src/sage/graphs/bipartite_graph.py @@ -1291,10 +1291,10 @@ def is_bipartite(self, certificate=False): EXAMPLES:: - sage: g = BipartiteGraph(graphs.RandomBipartite(3, 3, .5)) - sage: g.is_bipartite() + sage: g = BipartiteGraph(graphs.RandomBipartite(3, 3, .5)) # optional - numpy + sage: g.is_bipartite() # optional - numpy True - sage: g.is_bipartite(certificate=True) # random + sage: g.is_bipartite(certificate=True) # random # optional - numpy (True, {(0, 0): 0, (0, 1): 0, (0, 2): 0, (1, 0): 1, (1, 1): 1, (1, 2): 1}) TESTS:: @@ -1627,7 +1627,7 @@ def perfect_matchings(self, labels=False): sage: B = BipartiteGraph(graphs.CompleteBipartiteGraph(4, 4)) sage: len(list(B.perfect_matchings())) 24 - sage: B.matching_polynomial(algorithm='rook')(0) + sage: B.matching_polynomial(algorithm='rook')(0) # optional - sage.modules 24 TESTS:: @@ -2099,7 +2099,7 @@ class :class:`MixedIntegerLinearProgram Maximum matching in a cycle graph:: sage: G = BipartiteGraph(graphs.CycleGraph(10)) - sage: G.matching() + sage: G.matching() # optional - networkx [(0, 1, None), (2, 3, None), (4, 5, None), (6, 7, None), (8, 9, None)] The size of a maximum matching in a complete bipartite graph using @@ -2126,7 +2126,7 @@ class :class:`MixedIntegerLinearProgram sage: B = BipartiteGraph([(u,v,2) for u,v in G.edges(sort=True, labels=0)]) sage: sorted(B.matching(use_edge_labels=True)) [(0, 3, 2), (1, 2, 2)] - sage: B.matching(use_edge_labels=True, value_only=True) + sage: B.matching(use_edge_labels=True, value_only=True) # optional - networkx 4 sage: B.matching(use_edge_labels=True, value_only=True, algorithm='Edmonds') 4 @@ -2140,9 +2140,9 @@ class :class:`MixedIntegerLinearProgram Traceback (most recent call last): ... ValueError: use_edge_labels cannot be used with "Hopcroft-Karp" or "Eppstein" - sage: B.matching(use_edge_labels=False, value_only=True, algorithm='Hopcroft-Karp') + sage: B.matching(use_edge_labels=False, value_only=True, algorithm='Hopcroft-Karp') # optional - networkx 2 - sage: B.matching(use_edge_labels=False, value_only=True, algorithm='Eppstein') + sage: B.matching(use_edge_labels=False, value_only=True, algorithm='Eppstein') # optional - networkx 2 sage: B.matching(use_edge_labels=False, value_only=True, algorithm='Edmonds') 2 @@ -2286,9 +2286,9 @@ def vertex_cover(self, algorithm="Konig", value_only=False, On the Cycle Graph:: sage: B = BipartiteGraph(graphs.CycleGraph(6)) - sage: len(B.vertex_cover()) + sage: len(B.vertex_cover()) # optional - networkx 3 - sage: B.vertex_cover(value_only=True) + sage: B.vertex_cover(value_only=True) # optional - networkx 3 The two algorithms should return the same result:: diff --git a/src/sage/graphs/bliss.pyx b/src/sage/graphs/bliss.pyx index 86af7ea988e..24e32c35a7c 100644 --- a/src/sage/graphs/bliss.pyx +++ b/src/sage/graphs/bliss.pyx @@ -479,11 +479,11 @@ cpdef canonical_form(G, partition=None, return_graph=False, use_edge_labels=True Check that it works with non hashable non sortable edge labels (relying on string representations of the labels):: - sage: g1 = Graph([(0, 1, matrix(ZZ, 2)), (0, 2, RDF.pi()), (1, 2, 'a')]) - sage: g2 = Graph([(1, 2, matrix(ZZ, 2)), (2, 0, RDF.pi()), (0, 1, 'a')]) - sage: g1can = canonical_form(g1, use_edge_labels=True) # optional - bliss - sage: g2can = canonical_form(g2, use_edge_labels=True) # optional - bliss - sage: g1can == g2can # optional - bliss + sage: g1 = Graph([(0, 1, matrix(ZZ, 2)), (0, 2, RDF.pi()), (1, 2, 'a')]) # optional - sage.modules + sage: g2 = Graph([(1, 2, matrix(ZZ, 2)), (2, 0, RDF.pi()), (0, 1, 'a')]) # optional - sage.modules + sage: g1can = canonical_form(g1, use_edge_labels=True) # optional - bliss sage.modules + sage: g2can = canonical_form(g2, use_edge_labels=True) # optional - bliss sage.modules + sage: g1can == g2can # optional - bliss sage.modules True Check that :trac:`32395` is fixed:: diff --git a/src/sage/graphs/edge_connectivity.pyx b/src/sage/graphs/edge_connectivity.pyx index 2bcfcc9beaf..c4cf6a4f81b 100644 --- a/src/sage/graphs/edge_connectivity.pyx +++ b/src/sage/graphs/edge_connectivity.pyx @@ -72,12 +72,15 @@ cdef class GabowEdgeConnectivity: Check that we get the same result when with and without the DFS-based speed-up initialization proposed in [GKLP2021]_:: - sage: G = graphs.RandomBarabasiAlbert(100, 2) - sage: D = DiGraph(G) - sage: ec1 = GabowEdgeConnectivity(D, dfs_preprocessing=False).edge_connectivity() - sage: ec2 = GabowEdgeConnectivity(D, dfs_preprocessing=True).edge_connectivity() - sage: ec3 = GabowEdgeConnectivity(D, dfs_preprocessing=True, use_rec=True).edge_connectivity() - sage: ec1 == ec2 and ec2 == ec3 + sage: G = graphs.RandomBarabasiAlbert(100, 2) # optional - networkx + sage: D = DiGraph(G) # optional - networkx + sage: ec1 = GabowEdgeConnectivity(D, # optional - networkx + ....: dfs_preprocessing=False).edge_connectivity() + sage: ec2 = GabowEdgeConnectivity(D, # optional - networkx + ....: dfs_preprocessing=True).edge_connectivity() + sage: ec3 = GabowEdgeConnectivity(D, dfs_preprocessing=True, # optional - networkx + ....: use_rec=True).edge_connectivity() + sage: ec1 == ec2 and ec2 == ec3 # optional - networkx True TESTS: diff --git a/src/sage/graphs/generators/degree_sequence.py b/src/sage/graphs/generators/degree_sequence.py index 52eeb8ac633..071878d124e 100644 --- a/src/sage/graphs/generators/degree_sequence.py +++ b/src/sage/graphs/generators/degree_sequence.py @@ -93,15 +93,15 @@ def DegreeSequenceBipartite(s1, s2): If we are given as sequences ``[2,2,2,2,2]`` and ``[5,5]`` we are given as expected the complete bipartite graph `K_{2,5}`:: - sage: g = graphs.DegreeSequenceBipartite([2,2,2,2,2],[5,5]) - sage: g.is_isomorphic(graphs.CompleteBipartiteGraph(5,2)) + sage: g = graphs.DegreeSequenceBipartite([2,2,2,2,2],[5,5]) # optional - sage.modules + sage: g.is_isomorphic(graphs.CompleteBipartiteGraph(5,2)) # optional - sage.modules True Some sequences being incompatible if, for example, their sums are different, the functions raises a ``ValueError`` when no graph corresponding to the degree sequences exists:: - sage: g = graphs.DegreeSequenceBipartite([2,2,2,2,1],[5,5]) + sage: g = graphs.DegreeSequenceBipartite([2,2,2,2,1],[5,5]) # optional - sage.modules Traceback (most recent call last): ... ValueError: there exists no bipartite graph corresponding to the given degree sequences @@ -110,7 +110,7 @@ def DegreeSequenceBipartite(s1, s2): :trac:`12155`:: - sage: graphs.DegreeSequenceBipartite([2,2,2,2,2],[5,5]).complement() + sage: graphs.DegreeSequenceBipartite([2,2,2,2,2],[5,5]).complement() # optional - sage.modules Graph on 7 vertices """ from sage.combinat.integer_vector import gale_ryser_theorem diff --git a/src/sage/graphs/generators/random.py b/src/sage/graphs/generators/random.py index 37b8a0d31a7..288515ac397 100644 --- a/src/sage/graphs/generators/random.py +++ b/src/sage/graphs/generators/random.py @@ -164,20 +164,20 @@ def RandomBarabasiAlbert(n, m, seed=None): sage: g = [] sage: j = [] - sage: for i in range(1,10): + sage: for i in range(1,10): # optional - networkx ....: k = graphs.RandomBarabasiAlbert(i+3, 3) ....: g.append(k) - sage: for i in range(3): # optional - sage.plot + sage: for i in range(3): # optional - networkx sage.plot ....: n = [] ....: for m in range(3): ....: n.append(g[3*i + m].plot(vertex_size=50, vertex_labels=False)) ....: j.append(n) - sage: G = graphics_array(j) # optional - sage.plot - sage: G.show() # long time # optional - sage.plot + sage: G = graphics_array(j) # optional - networkx sage.plot + sage: G.show() # long time # optional - networkx sage.plot When `m = 1`, the generated graph is a tree:: - sage: graphs.RandomBarabasiAlbert(6, 1).is_tree() + sage: graphs.RandomBarabasiAlbert(6, 1).is_tree() # optional - networkx True """ if seed is None: diff --git a/src/sage/graphs/generators/smallgraphs.py b/src/sage/graphs/generators/smallgraphs.py index f25d5b4e561..36275b2ce57 100644 --- a/src/sage/graphs/generators/smallgraphs.py +++ b/src/sage/graphs/generators/smallgraphs.py @@ -139,21 +139,21 @@ def HarriesGraph(embedding=1): EXAMPLES:: - sage: g = graphs.HarriesGraph() - sage: g.order() + sage: g = graphs.HarriesGraph() # optional - networkx + sage: g.order() # optional - networkx 70 - sage: g.size() + sage: g.size() # optional - networkx 105 - sage: g.girth() + sage: g.girth() # optional - networkx 10 - sage: g.diameter() + sage: g.diameter() # optional - networkx 6 - sage: g.show(figsize=[10, 10]) # long time - sage: graphs.HarriesGraph(embedding=2).show(figsize=[10, 10]) # long time + sage: g.show(figsize=[10, 10]) # long time # optional - networkx sage.plot + sage: graphs.HarriesGraph(embedding=2).show(figsize=[10, 10]) # long time # optional - networkx sage.plot TESTS:: - sage: graphs.HarriesGraph(embedding=3) + sage: graphs.HarriesGraph(embedding=3) # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -257,25 +257,25 @@ def HarriesWongGraph(embedding=1): EXAMPLES:: - sage: g = graphs.HarriesWongGraph() - sage: g.order() + sage: g = graphs.HarriesWongGraph() # optional - networkx + sage: g.order() # optional - networkx 70 - sage: g.size() + sage: g.size() # optional - networkx 105 - sage: g.girth() + sage: g.girth() # optional - networkx 10 - sage: g.diameter() + sage: g.diameter() # optional - networkx 6 - sage: orbits = g.automorphism_group(orbits=True)[-1] # long time - sage: g.show(figsize=[15, 15], partition=orbits) # long time + sage: orbits = g.automorphism_group(orbits=True)[-1] # long time # optional - networkx sage.groups + sage: g.show(figsize=[15, 15], partition=orbits) # long time # optional - networkx sage.groups sage.plot Alternative embedding:: - sage: graphs.HarriesWongGraph(embedding=2).show() # long time + sage: graphs.HarriesWongGraph(embedding=2).show() # long time # optional - networkx sage.plot TESTS:: - sage: graphs.HarriesWongGraph(embedding=3) + sage: graphs.HarriesWongGraph(embedding=3) # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -679,7 +679,7 @@ def HallJankoGraph(from_string=True): sage: g = graphs.HallJankoGraph() sage: g.is_regular(36) True - sage: g.is_vertex_transitive() + sage: g.is_vertex_transitive() # optional - sage.groups True Is it really strongly regular with parameters 14, 12? :: @@ -804,20 +804,20 @@ def Balaban10Cage(embedding=1): EXAMPLES:: - sage: g = graphs.Balaban10Cage() - sage: g.girth() + sage: g = graphs.Balaban10Cage() # optional - networkx + sage: g.girth() # optional - networkx 10 - sage: g.chromatic_number() + sage: g.chromatic_number() # optional - networkx 2 - sage: g.diameter() + sage: g.diameter() # optional - networkx 6 - sage: g.is_hamiltonian() + sage: g.is_hamiltonian() # optional - networkx True - sage: g.show(figsize=[10,10]) # long time + sage: g.show(figsize=[10,10]) # long time # optional - networkx sage.plot TESTS:: - sage: graphs.Balaban10Cage(embedding='foo') + sage: graphs.Balaban10Cage(embedding='foo') # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -897,7 +897,7 @@ def Balaban11Cage(embedding=1): 11 sage: g.diameter() 8 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 64 Our many embeddings:: @@ -905,9 +905,9 @@ def Balaban11Cage(embedding=1): sage: g1 = graphs.Balaban11Cage(embedding=1) sage: g2 = graphs.Balaban11Cage(embedding=2) sage: g3 = graphs.Balaban11Cage(embedding=3) - sage: g1.show(figsize=[10,10]) # long time - sage: g2.show(figsize=[10,10]) # long time - sage: g3.show(figsize=[10,10]) # long time + sage: g1.show(figsize=[10,10]) # long time # optional - sage.plot + sage: g2.show(figsize=[10,10]) # long time # optional - sage.plot + sage: g3.show(figsize=[10,10]) # long time # optional - sage.plot Proof that the embeddings are the same graph:: @@ -1114,26 +1114,26 @@ def BiggsSmithGraph(embedding=1): Basic properties:: - sage: g = graphs.BiggsSmithGraph() - sage: g.order() + sage: g = graphs.BiggsSmithGraph() # optional - networkx + sage: g.order() # optional - networkx 102 - sage: g.size() + sage: g.size() # optional - networkx 153 - sage: g.girth() + sage: g.girth() # optional - networkx 9 - sage: g.diameter() + sage: g.diameter() # optional - networkx 7 - sage: g.automorphism_group().cardinality() # long time + sage: g.automorphism_group().cardinality() # long time # optional - networkx 2448 - sage: g.show(figsize=[10, 10]) # long time + sage: g.show(figsize=[10, 10]) # long time # optional - networkx sage.plot The other embedding:: - sage: graphs.BiggsSmithGraph(embedding=2).show() # long time + sage: graphs.BiggsSmithGraph(embedding=2).show() # long time # optional - networkx TESTS:: - sage: graphs.BiggsSmithGraph(embedding='xyzzy') + sage: graphs.BiggsSmithGraph(embedding='xyzzy') # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -1199,16 +1199,16 @@ def BlanusaFirstSnarkGraph(): EXAMPLES:: - sage: g = graphs.BlanusaFirstSnarkGraph() - sage: g.order() + sage: g = graphs.BlanusaFirstSnarkGraph() # optional - sage.groups + sage: g.order() # optional - sage.groups 18 - sage: g.size() + sage: g.size() # optional - sage.groups 27 - sage: g.diameter() + sage: g.diameter() # optional - sage.groups 4 - sage: g.girth() + sage: g.girth() # optional - sage.groups 5 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 8 """ g = Graph({17: [4, 7, 1], 0: [5], 3: [8], 13: [9], 12: [16], @@ -1234,16 +1234,16 @@ def BlanusaSecondSnarkGraph(): EXAMPLES:: - sage: g = graphs.BlanusaSecondSnarkGraph() - sage: g.order() + sage: g = graphs.BlanusaSecondSnarkGraph() # optional - sage.groups + sage: g.order() # optional - sage.groups 18 - sage: g.size() + sage: g.size() # optional - sage.groups 27 - sage: g.diameter() + sage: g.diameter() # optional - sage.groups 4 - sage: g.girth() + sage: g.girth() # optional - sage.groups 5 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 4 """ c0 = (-1, 0) @@ -1361,18 +1361,18 @@ def BrouwerHaemersGraph(): EXAMPLES:: - sage: g = graphs.BrouwerHaemersGraph() - sage: g + sage: g = graphs.BrouwerHaemersGraph() # optional - sage.modules + sage: g # optional - sage.modules Brouwer-Haemers: Graph on 81 vertices It is indeed strongly regular with parameters `(81,20,1,6)`:: - sage: g.is_strongly_regular(parameters=True) # long time + sage: g.is_strongly_regular(parameters=True) # long time # optional - sage.modules (81, 20, 1, 6) Its has as eigenvalues `20,2` and `-7`:: - sage: set(g.spectrum()) == {20,2,-7} + sage: set(g.spectrum()) == {20,2,-7} # optional - sage.modules True """ from sage.rings.finite_rings.finite_field_constructor import FiniteField @@ -1419,16 +1419,16 @@ def BuckyBall(): The Bucky Ball can also be created by extracting the 1-skeleton of the Bucky Ball polyhedron, but this is much slower:: - sage: g = polytopes.buckyball().vertex_graph() - sage: g.remove_loops() + sage: g = polytopes.buckyball().vertex_graph() # optional - sage.geometry.polyhedron + sage: g.remove_loops() # optional - sage.geometry.polyhedron sage: h = graphs.BuckyBall() - sage: g.is_isomorphic(h) + sage: g.is_isomorphic(h) # optional - sage.geometry.polyhedron True The graph is returned along with an attractive embedding:: sage: g = graphs.BuckyBall() # long time - sage: g.plot(vertex_labels=False, vertex_size=10).show() # long time + sage: g.plot(vertex_labels=False, vertex_size=10).show() # long time # optional - sage.plot """ edges = [(0, 2), (0, 48), (0, 59), (1, 3), (1, 9), (1, 58), (2, 3), (2, 36), (3, 17), (4, 6), (4, 8), (4, 12), @@ -1735,12 +1735,12 @@ def CameronGraph(): EXAMPLES:: - sage: g = graphs.CameronGraph() - sage: g.order() + sage: g = graphs.CameronGraph() # optional - sage.groups + sage: g.order() # optional - sage.groups 231 - sage: g.size() + sage: g.size() # optional - sage.groups 3465 - sage: g.is_strongly_regular(parameters = True) # long time + sage: g.is_strongly_regular(parameters=True) # long time # optional - sage.groups (231, 30, 9, 3) """ from sage.groups.perm_gps.permgroup_named import MathieuGroup @@ -1828,7 +1828,7 @@ def ClebschGraph(): EXAMPLES:: sage: g = graphs.ClebschGraph() - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 1920 sage: g.girth() 4 @@ -1836,7 +1836,7 @@ def ClebschGraph(): 4 sage: g.diameter() 2 - sage: g.show(figsize=[10, 10]) # long time + sage: g.show(figsize=[10, 10]) # long time # optional - sage.plot """ g = Graph(pos={}) x = 0 @@ -1865,7 +1865,7 @@ def CoxeterGraph(): EXAMPLES:: sage: g = graphs.CoxeterGraph() - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 336 sage: g.girth() 7 @@ -1873,7 +1873,7 @@ def CoxeterGraph(): 3 sage: g.diameter() 4 - sage: g.show(figsize=[10, 10]) # long time + sage: g.show(figsize=[10, 10]) # long time # optional - sage.plot """ g = Graph({ 27: [6, 22, 14], @@ -1931,10 +1931,10 @@ def DesarguesGraph(): EXAMPLES:: sage: D = graphs.DesarguesGraph() - sage: L = graphs.LCFGraph(20,[5,-5,9,-9],5) - sage: D.is_isomorphic(L) + sage: L = graphs.LCFGraph(20,[5,-5,9,-9],5) # optional - networkx + sage: D.is_isomorphic(L) # optional - networkx True - sage: D.show() # long time + sage: D.show() # long time # optional - sage.plot """ from sage.graphs.generators.families import GeneralizedPetersenGraph G = GeneralizedPetersenGraph(10, 3) @@ -2085,22 +2085,22 @@ def HortonGraph(): EXAMPLES:: - sage: g = graphs.HortonGraph() - sage: g.order() + sage: g = graphs.HortonGraph() # optional - networkx + sage: g.order() # optional - networkx 96 - sage: g.size() + sage: g.size() # optional - networkx 144 - sage: g.radius() + sage: g.radius() # optional - networkx 10 - sage: g.diameter() + sage: g.diameter() # optional - networkx 10 - sage: g.girth() + sage: g.girth() # optional - networkx 6 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - networkx 96 - sage: g.chromatic_number() + sage: g.chromatic_number() # optional - networkx 2 - sage: g.is_hamiltonian() # not tested -- veeeery long + sage: g.is_hamiltonian() # not tested -- veeeery long # optional - networkx False """ g = Graph(name="Horton Graph") @@ -2374,17 +2374,17 @@ def F26AGraph(): EXAMPLES:: - sage: g = graphs.F26AGraph(); g + sage: g = graphs.F26AGraph(); g # optional - networkx F26A Graph: Graph on 26 vertices - sage: g.order(),g.size() + sage: g.order(), g.size() # optional - networkx (26, 39) - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - networkx 78 - sage: g.girth() + sage: g.girth() # optional - networkx 6 - sage: g.is_bipartite() + sage: g.is_bipartite() # optional - networkx True - sage: g.characteristic_polynomial().factor() + sage: g.characteristic_polynomial().factor() # optional - networkx (x - 3) * (x + 3) * (x^4 - 5*x^2 + 3)^6 """ from sage.graphs.generators.families import LCFGraph @@ -2435,26 +2435,26 @@ def FolkmanGraph(): EXAMPLES:: - sage: g = graphs.FolkmanGraph() - sage: g.order() + sage: g = graphs.FolkmanGraph() # optional - networkx + sage: g.order() # optional - networkx 20 - sage: g.size() + sage: g.size() # optional - networkx 40 - sage: g.diameter() + sage: g.diameter() # optional - networkx 4 - sage: g.girth() + sage: g.girth() # optional - networkx 4 - sage: g.charpoly().factor() + sage: g.charpoly().factor() # optional - networkx (x - 4) * (x + 4) * x^10 * (x^2 - 6)^4 - sage: g.chromatic_number() + sage: g.chromatic_number() # optional - networkx 2 - sage: g.is_eulerian() + sage: g.is_eulerian() # optional - networkx True - sage: g.is_hamiltonian() + sage: g.is_hamiltonian() # optional - networkx True - sage: g.is_vertex_transitive() + sage: g.is_vertex_transitive() # optional - networkx False - sage: g.is_bipartite() + sage: g.is_bipartite() # optional - networkx True """ from sage.graphs.generators.families import LCFGraph @@ -2471,18 +2471,18 @@ def FosterGraph(): EXAMPLES:: - sage: g = graphs.FosterGraph() - sage: g.order() + sage: g = graphs.FosterGraph() # optional - networkx + sage: g.order() # optional - networkx 90 - sage: g.size() + sage: g.size() # optional - networkx 135 - sage: g.diameter() + sage: g.diameter() # optional - networkx 8 - sage: g.girth() + sage: g.girth() # optional - networkx 10 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - networkx 4320 - sage: g.is_hamiltonian() + sage: g.is_hamiltonian() # optional - networkx True """ from sage.graphs.generators.families import LCFGraph @@ -2565,18 +2565,18 @@ def FruchtGraph(): EXAMPLES:: - sage: FRUCHT = graphs.FruchtGraph() - sage: FRUCHT + sage: FRUCHT = graphs.FruchtGraph() # optional - networkx + sage: FRUCHT # optional - networkx Frucht graph: Graph on 12 vertices - sage: FRUCHT.graph6_string() + sage: FRUCHT.graph6_string() # optional - networkx 'KhCKM?_EGK?L' - sage: (graphs.FruchtGraph()).show() # long time + sage: (graphs.FruchtGraph()).show() # long time # optional - networkx TESTS:: - sage: import networkx - sage: G = graphs.FruchtGraph() - sage: G.is_isomorphic(Graph(networkx.frucht_graph())) + sage: import networkx # optional - networkx + sage: G = graphs.FruchtGraph() # optional - networkx + sage: G.is_isomorphic(Graph(networkx.frucht_graph())) # optional - networkx True """ edges = {0: [1, 6, 7], 1: [2, 7], 2: [3, 8], 3: [4, 9], 4: [5, 9], @@ -2888,8 +2888,8 @@ def HerschelGraph(): sage: G.chromatic_number() 2 - sage: ag = G.automorphism_group() - sage: ag.is_isomorphic(DihedralGroup(6)) + sage: ag = G.automorphism_group() # optional - sage.groups + sage: ag.is_isomorphic(DihedralGroup(6)) # optional - sage.groups True """ edge_dict = { @@ -2919,9 +2919,9 @@ def GritsenkoGraph(): EXAMPLES:: - sage: H = graphs.GritsenkoGraph(); H + sage: H = graphs.GritsenkoGraph(); H # optional - sage.groups Gritsenko strongly regular graph: Graph on 65 vertices - sage: H.is_strongly_regular(parameters=True) + sage: H.is_strongly_regular(parameters=True) # optional - sage.groups (65, 32, 15, 16) """ from sage.groups.perm_gps.permgroup import PermutationGroup @@ -3000,13 +3000,13 @@ def HigmanSimsGraph(relabel=True): which is of index 2 and is simple. It is known as the Higman-Sims group:: sage: H = graphs.HigmanSimsGraph() - sage: G = H.automorphism_group() - sage: g=G.order(); g + sage: G = H.automorphism_group() # optional - sage.groups + sage: g = G.order(); g # optional - sage.groups 88704000 - sage: K = G.normal_subgroups()[1] - sage: K.is_simple() + sage: K = G.normal_subgroups()[1] # optional - sage.groups + sage: K.is_simple() # optional - sage.groups True - sage: g//K.order() + sage: g//K.order() # optional - sage.groups 2 AUTHOR: @@ -3192,7 +3192,7 @@ def HoffmanGraph(): 3 sage: g.diameter() 4 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 48 """ g = Graph({ @@ -3231,7 +3231,7 @@ def HoltGraph(): Holt graph: Graph on 27 vertices sage: g.is_regular() True - sage: g.is_vertex_transitive() + sage: g.is_vertex_transitive() # optional - sage.groups True sage: g.chromatic_number() 3 @@ -3243,7 +3243,7 @@ def HoltGraph(): 3 sage: g.girth() 5 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 54 """ g = Graph(loops=False, name="Holt graph", pos={}) @@ -3324,7 +3324,7 @@ def Klein3RegularGraph(): (56, 84) sage: g.girth() 7 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 336 sage: g.chromatic_number() 3 @@ -3357,7 +3357,7 @@ def Klein7RegularGraph(): (24, 84) sage: g.girth() 3 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 336 sage: g.chromatic_number() 4 @@ -3413,21 +3413,21 @@ def LjubljanaGraph(embedding=1): EXAMPLES:: - sage: g = graphs.LjubljanaGraph() - sage: g.order() + sage: g = graphs.LjubljanaGraph() # optional - networkx + sage: g.order() # optional - networkx 112 - sage: g.size() + sage: g.size() # optional - networkx 168 - sage: g.girth() + sage: g.girth() # optional - networkx 10 - sage: g.diameter() + sage: g.diameter() # optional - networkx 8 - sage: g.show(figsize=[10, 10]) # long time - sage: graphs.LjubljanaGraph(embedding=2).show(figsize=[10, 10]) # long time + sage: g.show(figsize=[10, 10]) # long time # optional - networkx sage.plot + sage: graphs.LjubljanaGraph(embedding=2).show(figsize=[10, 10]) # long time # optional - networkx sage.plot TESTS:: - sage: graphs.LjubljanaGraph(embedding=3) + sage: graphs.LjubljanaGraph(embedding=3) # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -3518,12 +3518,12 @@ def M22Graph(): EXAMPLES:: - sage: g = graphs.M22Graph() - sage: g.order() + sage: g = graphs.M22Graph() # optional - sage.groups + sage: g.order() # optional - sage.groups 77 - sage: g.size() + sage: g.size() # optional - sage.groups 616 - sage: g.is_strongly_regular(parameters = True) + sage: g.is_strongly_regular(parameters=True) # optional - sage.groups (77, 16, 0, 4) """ from sage.groups.perm_gps.permgroup_named import MathieuGroup @@ -3561,11 +3561,11 @@ def MarkstroemGraph(): True sage: g.is_regular(3) True - sage: g.subgraph_search(graphs.CycleGraph(4)) is None + sage: g.subgraph_search(graphs.CycleGraph(4)) is None # optional - sage.modules True - sage: g.subgraph_search(graphs.CycleGraph(8)) is None + sage: g.subgraph_search(graphs.CycleGraph(8)) is None # optional - sage.modules True - sage: g.subgraph_search(graphs.CycleGraph(16)) + sage: g.subgraph_search(graphs.CycleGraph(16)) # optional - sage.modules Subgraph of (Markstroem Graph): Graph on 16 vertices """ g = Graph(name="Markstroem Graph") @@ -3602,21 +3602,21 @@ def McGeeGraph(embedding=2): EXAMPLES:: - sage: g = graphs.McGeeGraph() - sage: g.order() + sage: g = graphs.McGeeGraph() # optional - networkx + sage: g.order() # optional - networkx 24 - sage: g.size() + sage: g.size() # optional - networkx 36 - sage: g.girth() + sage: g.girth() # optional - networkx 7 - sage: g.diameter() + sage: g.diameter() # optional - networkx 4 - sage: g.show() # optional - sage.plot - sage: graphs.McGeeGraph(embedding=1).show() # long time # optional - sage.plot + sage: g.show() # optional - networkx sage.plot + sage: graphs.McGeeGraph(embedding=1).show() # long time # optional - networkx sage.plot TESTS:: - sage: graphs.McGeeGraph(embedding=3) + sage: graphs.McGeeGraph(embedding=3) # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -3830,7 +3830,7 @@ def NauruGraph(embedding=2): Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 - sage: graphs.NauruGraph(embedding=1).is_isomorphic(g) + sage: graphs.NauruGraph(embedding=1).is_isomorphic(g) # optional - networkx True """ @@ -3858,9 +3858,9 @@ def PappusGraph(): sage: G = graphs.PappusGraph() sage: G.show() # long time # optional - sage.plot - sage: L = graphs.LCFGraph(18, [5,7,-7,7,-7,-5], 3) - sage: L.show() # long time # optional - sage.plot - sage: G.is_isomorphic(L) + sage: L = graphs.LCFGraph(18, [5,7,-7,7,-7,-5], 3) # optional - networkx + sage: L.show() # long time # optional - networkx sage.plot + sage: G.is_isomorphic(L) # optional - networkx True """ edges = {0: [1, 5, 6], 1: [2, 7], 2: [3, 8], 3: [4, 9], 4: [5, 10], 5: [11], @@ -3970,22 +3970,23 @@ def RobertsonGraph(): EXAMPLES:: - sage: g = graphs.RobertsonGraph() - sage: g.order() + sage: g = graphs.RobertsonGraph() # optional - networkx + sage: g.order() # optional - networkx 19 - sage: g.size() + sage: g.size() # optional - networkx 38 - sage: g.diameter() + sage: g.diameter() # optional - networkx 3 - sage: g.girth() + sage: g.girth() # optional - networkx 5 - sage: g.charpoly().factor() - (x - 4) * (x - 1)^2 * (x^2 + x - 5) * (x^2 + x - 1) * (x^2 - 3)^2 * (x^2 + x - 4)^2 * (x^2 + x - 3)^2 - sage: g.chromatic_number() + sage: g.charpoly().factor() # optional - networkx + (x - 4) * (x - 1)^2 * (x^2 + x - 5) * (x^2 + x - 1) + * (x^2 - 3)^2 * (x^2 + x - 4)^2 * (x^2 + x - 3)^2 + sage: g.chromatic_number() # optional - networkx 3 - sage: g.is_hamiltonian() + sage: g.is_hamiltonian() # optional - networkx True - sage: g.is_vertex_transitive() + sage: g.is_vertex_transitive() # optional - networkx False """ from sage.graphs.generators.families import LCFGraph @@ -4023,7 +4024,7 @@ def SchlaefliGraph(): The graph is vertex-transitive:: - sage: S.is_vertex_transitive() + sage: S.is_vertex_transitive() # optional - sage.groups True The neighborhood of each vertex is isomorphic to the complement of the @@ -4235,7 +4236,7 @@ def SousselierGraph(): 2 sage: g.diameter() 3 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 2 sage: g.is_hamiltonian() False @@ -4342,9 +4343,9 @@ def TietzeGraph(): 3 sage: g.girth() 3 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 12 - sage: g.automorphism_group().is_isomorphic(groups.permutation.Dihedral(6)) + sage: g.automorphism_group().is_isomorphic(groups.permutation.Dihedral(6)) # optional - sage.groups True """ g = Graph([(0, 9), (3, 10), (6, 11), (1, 5), (2, 7), (4, 8)], @@ -4396,7 +4397,7 @@ def TruncatedTetrahedralGraph(): Truncated Tetrahedron: Graph on 12 vertices sage: g.order(), g.size() (12, 18) - sage: g.is_isomorphic(polytopes.simplex(3).truncation().graph()) + sage: g.is_isomorphic(polytopes.simplex(3).truncation().graph()) # optional - sage.geometry.polyhedron True """ g = Graph(':K`ESwC_EOyDl\\MCi', loops=False, multiedges=False) @@ -4415,16 +4416,16 @@ def Tutte12Cage(): EXAMPLES:: - sage: g = graphs.Tutte12Cage() - sage: g.order() + sage: g = graphs.Tutte12Cage() # optional - networkx + sage: g.order() # optional - networkx 126 - sage: g.size() + sage: g.size() # optional - networkx 189 - sage: g.girth() + sage: g.girth() # optional - networkx 12 - sage: g.diameter() + sage: g.diameter() # optional - networkx 6 - sage: g.show() # optional - sage.plot + sage: g.show() # optional - networkx sage.plot """ L = [17, 27, -13, -59, -35, 35, -11, 13, -53, 53, -27, 21, 57, 11, -21, -57, 59, -17] @@ -4448,21 +4449,21 @@ def TutteCoxeterGraph(embedding=2): EXAMPLES:: - sage: g = graphs.TutteCoxeterGraph() - sage: g.order() + sage: g = graphs.TutteCoxeterGraph() # optional - networkx + sage: g.order() # optional - networkx 30 - sage: g.size() + sage: g.size() # optional - networkx 45 - sage: g.girth() + sage: g.girth() # optional - networkx 8 - sage: g.diameter() + sage: g.diameter() # optional - networkx 4 - sage: g.show() # optional - sage.plot - sage: graphs.TutteCoxeterGraph(embedding=1).show() # long time + sage: g.show() # optional - networkx sage.plot + sage: graphs.TutteCoxeterGraph(embedding=1).show() # long time # optional - networkx sage.plot TESTS:: - sage: graphs.TutteCoxeterGraph(embedding=3) + sage: graphs.TutteCoxeterGraph(embedding=3) # optional - networkx Traceback (most recent call last): ... ValueError: the value of embedding must be 1 or 2 @@ -4515,7 +4516,7 @@ def TutteGraph(): 3 sage: g.girth() 4 - sage: g.automorphism_group().cardinality() + sage: g.automorphism_group().cardinality() # optional - sage.groups 3 sage: g.is_hamiltonian() False @@ -4561,16 +4562,16 @@ def WagnerGraph(): EXAMPLES:: - sage: g = graphs.WagnerGraph() - sage: g.order() + sage: g = graphs.WagnerGraph() # optional - networkx + sage: g.order() # optional - networkx 8 - sage: g.size() + sage: g.size() # optional - networkx 12 - sage: g.girth() + sage: g.girth() # optional - networkx 4 - sage: g.diameter() + sage: g.diameter() # optional - networkx 2 - sage: g.show() # optional - sage.plot + sage: g.show() # optional - networkx sage.plot """ from sage.graphs.generators.families import LCFGraph g = LCFGraph(8, [4], 8) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index f7bf81db7a4..440a0f4275f 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -909,7 +909,7 @@ def _latex_(self): sage: from sage.graphs.graph_latex import check_tkz_graph sage: check_tkz_graph() # random - depends on TeX installation sage: g = graphs.CompleteGraph(2) - sage: print(g._latex_()) + sage: print(g._latex_()) # optional - sage.plot \begin{tikzpicture} \definecolor{cv0}{rgb}{0.0,0.0,0.0} \definecolor{cfv0}{rgb}{1.0,1.0,1.0} @@ -946,21 +946,21 @@ def _matrix_(self, R=None, vertices=None): EXAMPLES:: sage: G = graphs.CompleteBipartiteGraph(2, 3) - sage: m = matrix(G); m.parent() + sage: m = matrix(G); m.parent() # optional - sage.modules Full MatrixSpace of 5 by 5 dense matrices over Integer Ring - sage: m + sage: m # optional - sage.modules [0 0 1 1 1] [0 0 1 1 1] [1 1 0 0 0] [1 1 0 0 0] [1 1 0 0 0] - sage: G._matrix_() + sage: G._matrix_() # optional - sage.modules [0 0 1 1 1] [0 0 1 1 1] [1 1 0 0 0] [1 1 0 0 0] [1 1 0 0 0] - sage: factor(m.charpoly()) + sage: factor(m.charpoly()) # optional - sage.modules x^3 * (x^2 - 6) """ return self.am(vertices=vertices, base_ring=R) @@ -1369,24 +1369,24 @@ def export_to_file(self, filename, format=None, **kwds): sage: g = graphs.PetersenGraph() sage: filename = tmp_filename(ext=".pajek") - sage: g.export_to_file(filename) + sage: g.export_to_file(filename) # optional - networkx sage: import networkx # optional - networkx sage: G_networkx = networkx.read_pajek(filename) # optional - networkx sage: Graph(G_networkx).is_isomorphic(g) # optional - networkx True sage: filename = tmp_filename(ext=".edgelist") - sage: g.export_to_file(filename, data=False) + sage: g.export_to_file(filename, data=False) # optional - networkx sage: h = Graph(networkx.read_edgelist(filename)) # optional - networkx sage: g.is_isomorphic(h) # optional - networkx True TESTS:: - sage: g.export_to_file("hey", format="When I feel heavy metaaaaaallll...") + sage: g.export_to_file("hey", format="When I feel heavy metaaaaaallll...") # optional - networkx Traceback (most recent call last): ... ValueError: format 'When I feel heavy metaaaaaallll...' unknown - sage: g.export_to_file("my_file.Yeeeeppeeeeee") + sage: g.export_to_file("my_file.Yeeeeppeeeeee") # optional - networkx Traceback (most recent call last): ... RuntimeError: the file format could not be guessed from 'my_file.Yeeeeppeeeeee' @@ -1508,20 +1508,24 @@ def networkx_graph(self, weight_function=None): EXAMPLES:: sage: G = graphs.TetrahedralGraph() - sage: N = G.networkx_graph() - sage: type(N) + sage: N = G.networkx_graph() # optional - networkx + sage: type(N) # optional - networkx sage: def weight_fn(e): ....: return e[2] sage: G1 = Graph([(1,2,1), (1,3,4), (2,3,3), (3,4,4)]) - sage: H = G1.networkx_graph(weight_function=weight_fn) - sage: H.edges(data=True) - EdgeDataView([(1, 2, {'weight': 1}), (1, 3, {'weight': 4}), (2, 3, {'weight': 3}), (3, 4, {'weight': 4})]) - sage: G2 = DiGraph([(1,2,1), (1,3,4), (2,3,3), (3,4,4), (3,4,5)], multiedges=True) - sage: H = G2.networkx_graph(weight_function=weight_fn) - sage: H.edges(data=True) - OutMultiEdgeDataView([(1, 2, {'weight': 1}), (1, 3, {'weight': 4}), (2, 3, {'weight': 3}), (3, 4, {'weight': 5}), (3, 4, {'weight': 4})]) + sage: H = G1.networkx_graph(weight_function=weight_fn) # optional - networkx + sage: H.edges(data=True) # optional - networkx + EdgeDataView([(1, 2, {'weight': 1}), (1, 3, {'weight': 4}), + (2, 3, {'weight': 3}), (3, 4, {'weight': 4})]) + sage: G2 = DiGraph([(1,2,1), (1,3,4), (2,3,3), (3,4,4), (3,4,5)], + ....: multiedges=True) + sage: H = G2.networkx_graph(weight_function=weight_fn) # optional - networkx + sage: H.edges(data=True) # optional - networkx + OutMultiEdgeDataView([(1, 2, {'weight': 1}), (1, 3, {'weight': 4}), + (2, 3, {'weight': 3}), (3, 4, {'weight': 5}), + (3, 4, {'weight': 4})]) """ if weight_function is not None: @@ -1908,7 +1912,7 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds EXAMPLES:: sage: G = graphs.CubeGraph(4) - sage: G.adjacency_matrix() + sage: G.adjacency_matrix() # optional - sage.modules [0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0] [1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0] [1 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0] @@ -1928,7 +1932,7 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds :: - sage: matrix(GF(2),G) # matrix over GF(2) + sage: matrix(GF(2), G) # matrix over GF(2) # optional - sage.modules sage.rings.finite_rings [0 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0] [1 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0] [1 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0] @@ -1948,8 +1952,9 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds :: - sage: D = DiGraph({0: [1, 2, 3], 1: [0, 2], 2: [3], 3: [4], 4: [0, 5], 5: [1]}) - sage: D.adjacency_matrix() + sage: D = DiGraph({0: [1, 2, 3], 1: [0, 2], 2: [3], + ....: 3: [4], 4: [0, 5], 5: [1]}) + sage: D.adjacency_matrix() # optional - sage.modules [0 1 1 1 0 0] [1 0 1 0 0 0] [0 0 0 1 0 0] @@ -1959,7 +1964,7 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds A different ordering of the vertices:: - sage: graphs.PathGraph(5).adjacency_matrix(vertices=[2, 4, 1, 3, 0]) + sage: graphs.PathGraph(5).adjacency_matrix(vertices=[2, 4, 1, 3, 0]) # optional - sage.modules [0 0 1 1 0] [0 0 0 1 0] [1 0 0 0 1] @@ -1968,18 +1973,19 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds A different base ring:: - sage: graphs.PathGraph(5).adjacency_matrix(base_ring=RDF) + sage: graphs.PathGraph(5).adjacency_matrix(base_ring=RDF) # optional - sage.modules [0.0 1.0 0.0 0.0 0.0] [1.0 0.0 1.0 0.0 0.0] [0.0 1.0 0.0 1.0 0.0] [0.0 0.0 1.0 0.0 1.0] [0.0 0.0 0.0 1.0 0.0] - sage: type(_) + sage: type(_) # optional - sage.modules A different matrix implementation:: - sage: graphs.PathGraph(5).adjacency_matrix(sparse=False, implementation='numpy') + sage: graphs.PathGraph(5).adjacency_matrix(sparse=False, # optional - sage.modules + ....: implementation='numpy') [0 1 0 0 0] [1 0 1 0 0] [0 1 0 1 0] @@ -1990,7 +1996,8 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds As an immutable matrix:: - sage: M = graphs.PathGraph(5).adjacency_matrix(sparse=False, immutable=True); M + sage: M = graphs.PathGraph(5).adjacency_matrix(sparse=False, # optional - sage.modules + ....: immutable=True); M [0 1 0 0 0] [1 0 1 0 0] [0 1 0 1 0] @@ -1999,21 +2006,23 @@ def adjacency_matrix(self, sparse=None, vertices=None, *, base_ring=None, **kwds sage: M[2, 2] = 1 Traceback (most recent call last): ... - ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M). + ValueError: matrix is immutable; please change a copy instead + (i.e., use copy(M) to change a copy of M). TESTS:: - sage: graphs.CubeGraph(8).adjacency_matrix().parent() + sage: graphs.CubeGraph(8).adjacency_matrix().parent() # optional - sage.modules Full MatrixSpace of 256 by 256 dense matrices over Integer Ring - sage: graphs.CubeGraph(9).adjacency_matrix().parent() + sage: graphs.CubeGraph(9).adjacency_matrix().parent() # optional - sage.modules Full MatrixSpace of 512 by 512 sparse matrices over Integer Ring - sage: Graph([(i,i+1) for i in range(500)]+[(0,1),], multiedges=True).adjacency_matrix().parent() + sage: Graph([(i, i+1) for i in range(500)] + [(0,1),], # optional - sage.modules + ....: multiedges=True).adjacency_matrix().parent() Full MatrixSpace of 501 by 501 dense matrices over Integer Ring - sage: graphs.PathGraph(5).adjacency_matrix(vertices=[0,0,0,0,0]) + sage: graphs.PathGraph(5).adjacency_matrix(vertices=[0,0,0,0,0]) # optional - sage.modules Traceback (most recent call last): ... ValueError: ``vertices`` must be a permutation of the vertices - sage: graphs.PathGraph(5).adjacency_matrix(vertices=[1,2,3]) + sage: graphs.PathGraph(5).adjacency_matrix(vertices=[1,2,3]) # optional - sage.modules Traceback (most recent call last): ... ValueError: ``vertices`` must be a permutation of the vertices @@ -2120,7 +2129,7 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None EXAMPLES:: sage: G = graphs.PetersenGraph() - sage: G.incidence_matrix() + sage: G.incidence_matrix() # optional - sage.modules [1 1 1 0 0 0 0 0 0 0 0 0 0 0 0] [1 0 0 1 1 0 0 0 0 0 0 0 0 0 0] [0 0 0 1 0 1 1 0 0 0 0 0 0 0 0] @@ -2131,7 +2140,7 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None [0 0 0 0 0 0 1 0 0 0 1 0 0 0 1] [0 0 0 0 0 0 0 0 1 0 0 1 1 0 0] [0 0 0 0 0 0 0 0 0 1 0 0 0 1 1] - sage: G.incidence_matrix(oriented=True) + sage: G.incidence_matrix(oriented=True) # optional - sage.modules [-1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0] [ 1 0 0 -1 -1 0 0 0 0 0 0 0 0 0 0] [ 0 0 0 1 0 -1 -1 0 0 0 0 0 0 0 0] @@ -2144,18 +2153,18 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None [ 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1] sage: G = digraphs.Circulant(4, [1, 3]) - sage: G.incidence_matrix() + sage: G.incidence_matrix() # optional - sage.modules [-1 -1 1 0 0 0 1 0] [ 1 0 -1 -1 1 0 0 0] [ 0 0 0 1 -1 -1 0 1] [ 0 1 0 0 0 1 -1 -1] - sage: graphs.CompleteGraph(3).incidence_matrix() + sage: graphs.CompleteGraph(3).incidence_matrix() # optional - sage.modules [1 1 0] [1 0 1] [0 1 1] sage: G = Graph([(0, 0), (0, 1), (0, 1)], loops=True, multiedges=True) - sage: G.incidence_matrix(oriented=False) + sage: G.incidence_matrix(oriented=False) # optional - sage.modules [2 1 1] [0 1 1] @@ -2164,30 +2173,30 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None Kirchhoff matrix:: sage: G = graphs.PetersenGraph() - sage: m = G.incidence_matrix(oriented=True) - sage: m * m.transpose() == G.kirchhoff_matrix() + sage: m = G.incidence_matrix(oriented=True) # optional - sage.modules + sage: m * m.transpose() == G.kirchhoff_matrix() # optional - sage.modules True sage: K = graphs.CompleteGraph(3) - sage: m = K.incidence_matrix(oriented=True) - sage: m * m.transpose() == K.kirchhoff_matrix() + sage: m = K.incidence_matrix(oriented=True) # optional - sage.modules + sage: m * m.transpose() == K.kirchhoff_matrix() # optional - sage.modules True sage: H = Graph([(0, 0), (0, 1), (0, 1)], loops=True, multiedges=True) - sage: m = H.incidence_matrix(oriented=True) - sage: m * m.transpose() == H.kirchhoff_matrix() + sage: m = H.incidence_matrix(oriented=True) # optional - sage.modules + sage: m * m.transpose() == H.kirchhoff_matrix() # optional - sage.modules True A different ordering of the vertices:: sage: P5 = graphs.PathGraph(5) - sage: P5.incidence_matrix() + sage: P5.incidence_matrix() # optional - sage.modules [1 0 0 0] [1 1 0 0] [0 1 1 0] [0 0 1 1] [0 0 0 1] - sage: P5.incidence_matrix(vertices=[2, 4, 1, 3, 0]) + sage: P5.incidence_matrix(vertices=[2, 4, 1, 3, 0]) # optional - sage.modules [0 1 1 0] [0 0 0 1] [1 1 0 0] @@ -2197,13 +2206,13 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None A different ordering of the edges:: sage: E = list(P5.edge_iterator(labels=False)) - sage: P5.incidence_matrix(edges=E[::-1]) + sage: P5.incidence_matrix(edges=E[::-1]) # optional - sage.modules [0 0 0 1] [0 0 1 1] [0 1 1 0] [1 1 0 0] [1 0 0 0] - sage: P5.incidence_matrix(vertices=[2, 4, 1, 3, 0], edges=E[::-1]) + sage: P5.incidence_matrix(vertices=[2, 4, 1, 3, 0], edges=E[::-1]) # optional - sage.modules [0 1 1 0] [1 0 0 0] [0 0 1 1] @@ -2212,7 +2221,7 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None A different base ring:: - sage: P5.incidence_matrix(base_ring=RDF) + sage: P5.incidence_matrix(base_ring=RDF) # optional - sage.modules [1.0 0.0 0.0 0.0] [1.0 1.0 0.0 0.0] [0.0 1.0 1.0 0.0] @@ -2221,29 +2230,30 @@ def incidence_matrix(self, oriented=None, sparse=True, vertices=None, edges=None Creating an immutable matrix:: - sage: m = P5.incidence_matrix(immutable=True); m + sage: m = P5.incidence_matrix(immutable=True); m # optional - sage.modules [1 0 0 0] [1 1 0 0] [0 1 1 0] [0 0 1 1] [0 0 0 1] - sage: m[1,2] = 1 + sage: m[1,2] = 1 # optional - sage.modules Traceback (most recent call last): ... - ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M). + ValueError: matrix is immutable; please change a copy instead + (i.e., use copy(M) to change a copy of M). TESTS:: sage: P5 = graphs.PathGraph(5) - sage: P5.incidence_matrix(vertices=[1] * P5.order()) + sage: P5.incidence_matrix(vertices=[1] * P5.order()) # optional - sage.modules Traceback (most recent call last): ... ValueError: ``vertices`` must be a permutation of the vertices - sage: P5.incidence_matrix(edges=[(0, 1)] * P5.size()) + sage: P5.incidence_matrix(edges=[(0, 1)] * P5.size()) # optional - sage.modules Traceback (most recent call last): ... ValueError: ``edges`` must be a permutation of the edges - sage: P5.incidence_matrix(edges=P5.edges(sort=False, labels=True)) + sage: P5.incidence_matrix(edges=P5.edges(sort=False, labels=True)) # optional - sage.modules [1 0 0 0] [1 1 0 0] [0 1 1 0] @@ -2518,7 +2528,7 @@ def weighted_adjacency_matrix(self, sparse=True, vertices=None, Check error message for non numerical edge weights (:trac:`33562`):: sage: G = Graph([(0, 1)]) - sage: G.weighted_adjacency_matrix() + sage: G.weighted_adjacency_matrix() # optional - sage.modules Traceback (most recent call last): ... ValueError: cannot find the weight of (0, 1, None). @@ -2527,7 +2537,7 @@ def weighted_adjacency_matrix(self, sparse=True, vertices=None, [0 3] [3 0] sage: G = Graph([(0, 1, 'a')]) - sage: G.weighted_adjacency_matrix() + sage: G.weighted_adjacency_matrix() # optional - sage.modules Traceback (most recent call last): ... TypeError: Cannot convert NoneType to sage.structure.parent.Parent @@ -3964,21 +3974,21 @@ def antisymmetric(self): A directed acyclic graph is antisymmetric:: - sage: G = digraphs.RandomDirectedGNR(20, 0.5) - sage: G.antisymmetric() + sage: G = digraphs.RandomDirectedGNR(20, 0.5) # optional - networkx + sage: G.antisymmetric() # optional - networkx True Loops are allowed:: - sage: G.allow_loops(True) - sage: G.add_edge(0, 0) - sage: G.antisymmetric() + sage: G.allow_loops(True) # optional - networkx + sage: G.add_edge(0, 0) # optional - networkx + sage: G.antisymmetric() # optional - networkx True An undirected graph is never antisymmetric unless it is just a union of isolated vertices (with possible loops):: - sage: graphs.RandomGNP(20, 0.5).antisymmetric() + sage: graphs.RandomGNP(20, 0.5).antisymmetric() # optional - networkx False sage: Graph(3).antisymmetric() True @@ -4060,7 +4070,7 @@ def is_bipartite(self, certificate=False): True sage: graphs.CycleGraph(5).is_bipartite() False - sage: graphs.RandomBipartite(10, 10, 0.7).is_bipartite() + sage: graphs.RandomBipartite(10, 10, 0.7).is_bipartite() # optional - numpy True A random graph is very rarely bipartite:: @@ -4664,37 +4674,45 @@ def min_spanning_tree(self, sage: weight = lambda e: 1 / ((e[0] + 1) * (e[1] + 1)) sage: sorted(g.min_spanning_tree(weight_function=weight)) [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)] - sage: sorted(g.min_spanning_tree(weight_function=weight, algorithm='Kruskal_Boost')) + sage: sorted(g.min_spanning_tree(weight_function=weight, + ....: algorithm='Kruskal_Boost')) [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)] sage: g = graphs.PetersenGraph() sage: g.allow_multiple_edges(True) sage: g.add_edges(g.edge_iterator()) sage: sorted(g.min_spanning_tree()) - [(0, 1, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 6, None), (3, 8, None), (5, 7, None), (5, 8, None), (6, 9, None)] + [(0, 1, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 6, None), + (3, 8, None), (5, 7, None), (5, 8, None), (6, 9, None)] Boruvka's algorithm:: sage: sorted(g.min_spanning_tree(algorithm='Boruvka')) - [(0, 1, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 6, None), (2, 3, None), (2, 7, None), (3, 8, None), (4, 9, None)] + [(0, 1, None), (0, 4, None), (0, 5, None), (1, 2, None), (1, 6, None), + (2, 3, None), (2, 7, None), (3, 8, None), (4, 9, None)] Prim's algorithm:: sage: g = graphs.CompleteGraph(5) - sage: sorted(g.min_spanning_tree(algorithm='Prim_edge', starting_vertex=2, weight_function=weight)) + sage: sorted(g.min_spanning_tree(algorithm='Prim_edge', + ....: starting_vertex=2, weight_function=weight)) [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)] - sage: sorted(g.min_spanning_tree(algorithm='Prim_fringe', starting_vertex=2, weight_function=weight)) + sage: sorted(g.min_spanning_tree(algorithm='Prim_fringe', + ....: starting_vertex=2, weight_function=weight)) [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)] - sage: sorted(g.min_spanning_tree(weight_function=weight, algorithm='Prim_Boost')) + sage: sorted(g.min_spanning_tree(weight_function=weight, + ....: algorithm='Prim_Boost')) [(0, 4, None), (1, 4, None), (2, 4, None), (3, 4, None)] NetworkX algorithm:: - sage: sorted(g.min_spanning_tree(algorithm='NetworkX')) + sage: sorted(g.min_spanning_tree(algorithm='NetworkX')) # optional - networkx [(0, 1, None), (0, 2, None), (0, 3, None), (0, 4, None)] More complicated weights:: - sage: G = Graph([(0,1,{'name':'a','weight':1}), (0,2,{'name':'b','weight':3}), (1,2,{'name':'b','weight':1})]) + sage: G = Graph([(0, 1, {'name': 'a', 'weight': 1}), + ....: (0, 2, {'name': 'b', 'weight': 3}), + ....: (1, 2, {'name': 'b', 'weight': 1})]) sage: sorted(G.min_spanning_tree(weight_function=lambda e: e[2]['weight'])) [(0, 1, {'name': 'a', 'weight': 1}), (1, 2, {'name': 'b', 'weight': 1})] @@ -4738,7 +4756,7 @@ def min_spanning_tree(self, [(0, 1, 1), (1, 2, 1)] sage: sorted(g.min_spanning_tree(algorithm='Prim_Boost')) [(0, 1, 1), (1, 2, 1)] - sage: sorted(g.min_spanning_tree(algorithm='NetworkX')) + sage: sorted(g.min_spanning_tree(algorithm='NetworkX')) # optional - networkx [(0, 1, 1), (1, 2, 1)] sage: sorted(g.min_spanning_tree(algorithm='Boruvka')) [(0, 1, 1), (1, 2, 1)] @@ -4760,7 +4778,7 @@ def min_spanning_tree(self, [(0, 2, 10), (1, 2, 1)] sage: sorted(g.min_spanning_tree(algorithm='Prim_Boost', weight_function=weight)) [(0, 2, 10), (1, 2, 1)] - sage: sorted(g.min_spanning_tree(algorithm='NetworkX', weight_function=weight)) + sage: sorted(g.min_spanning_tree(algorithm='NetworkX', weight_function=weight)) # optional - networkx [(0, 2, 10), (1, 2, 1)] sage: sorted(g.min_spanning_tree(algorithm='Boruvka', weight_function=weight)) [(0, 2, 10), (1, 2, 1)] @@ -4959,13 +4977,13 @@ def spanning_trees_count(self, root_vertex=None): :: - sage: M = matrix(3, 3, [0, 1, 0, 0, 0, 1, 1, 1, 0]) - sage: D = DiGraph(M) - sage: D.spanning_trees_count() + sage: M = matrix(3, 3, [0, 1, 0, 0, 0, 1, 1, 1, 0]) # optional - sage.modules + sage: D = DiGraph(M) # optional - sage.modules + sage: D.spanning_trees_count() # optional - sage.modules 1 - sage: D.spanning_trees_count(0) + sage: D.spanning_trees_count(0) # optional - sage.modules 1 - sage: D.spanning_trees_count(2) + sage: D.spanning_trees_count(2) # optional - sage.modules 2 """ if not self.order(): @@ -5023,33 +5041,35 @@ def cycle_basis(self, output='vertex'): A cycle basis in Petersen's Graph :: sage: g = graphs.PetersenGraph() - sage: g.cycle_basis() - [[1, 6, 8, 5, 0], [4, 9, 6, 8, 5, 0], [7, 9, 6, 8, 5], [4, 3, 8, 5, 0], [1, 2, 3, 8, 5, 0], [7, 2, 3, 8, 5]] + sage: g.cycle_basis() # optional - networkx + [[1, 6, 8, 5, 0], [4, 9, 6, 8, 5, 0], [7, 9, 6, 8, 5], + [4, 3, 8, 5, 0], [1, 2, 3, 8, 5, 0], [7, 2, 3, 8, 5]] One can also get the result as a list of lists of edges:: - sage: g.cycle_basis(output='edge') + sage: g.cycle_basis(output='edge') # optional - networkx [[(1, 6, None), (6, 8, None), (8, 5, None), (5, 0, None), - (0, 1, None)], [(4, 9, None), (9, 6, None), (6, 8, None), - (8, 5, None), (5, 0, None), (0, 4, None)], [(7, 9, None), - (9, 6, None), (6, 8, None), (8, 5, None), (5, 7, None)], - [(4, 3, None), (3, 8, None), (8, 5, None), (5, 0, None), - (0, 4, None)], [(1, 2, None), (2, 3, None), (3, 8, None), - (8, 5, None), (5, 0, None), (0, 1, None)], [(7, 2, None), - (2, 3, None), (3, 8, None), (8, 5, None), (5, 7, None)]] + (0, 1, None)], [(4, 9, None), (9, 6, None), (6, 8, None), + (8, 5, None), (5, 0, None), (0, 4, None)], [(7, 9, None), + (9, 6, None), (6, 8, None), (8, 5, None), (5, 7, None)], + [(4, 3, None), (3, 8, None), (8, 5, None), (5, 0, None), + (0, 4, None)], [(1, 2, None), (2, 3, None), (3, 8, None), + (8, 5, None), (5, 0, None), (0, 1, None)], [(7, 2, None), + (2, 3, None), (3, 8, None), (8, 5, None), (5, 7, None)]] Checking the given cycles are algebraically free:: - sage: g = graphs.RandomGNP(30, .4) - sage: basis = g.cycle_basis() + sage: g = graphs.RandomGNP(30, .4) # optional - networkx + sage: basis = g.cycle_basis() # optional - networkx Building the space of (directed) edges over `Z/2Z`. On the way, building a dictionary associating a unique vector to each undirected edge:: sage: m = g.size() - sage: edge_space = VectorSpace(FiniteField(2), m) - sage: edge_vector = dict(zip(g.edges(labels=False, sort=False), edge_space.basis())) - sage: for (u, v), vec in list(edge_vector.items()): + sage: edge_space = VectorSpace(FiniteField(2), m) # optional - sage.modules sage.rings.finite_rings + sage: edge_vector = dict(zip(g.edges(labels=False, sort=False), # optional - sage.modules sage.rings.finite_rings + ....: edge_space.basis())) + sage: for (u, v), vec in list(edge_vector.items()): # optional - sage.modules sage.rings.finite_rings ....: edge_vector[(v, u)] = vec Defining a lambda function associating a vector to the vertices of a @@ -5060,27 +5080,29 @@ def cycle_basis(self, output='vertex'): Finally checking the cycles are a free set:: - sage: basis_as_vectors = [cycle_to_vector(_) for _ in basis] - sage: edge_space.span(basis_as_vectors).rank() == len(basis) + sage: basis_as_vectors = [cycle_to_vector(_) for _ in basis] # optional - sage.modules sage.rings.finite_rings + sage: edge_space.span(basis_as_vectors).rank() == len(basis) # optional - sage.modules sage.rings.finite_rings True For undirected graphs with multiple edges:: - sage: G = Graph([(0, 2, 'a'), (0, 2, 'b'), (0, 1, 'c'), (1, 2, 'd')], multiedges=True) - sage: G.cycle_basis() + sage: G = Graph([(0, 2, 'a'), (0, 2, 'b'), (0, 1, 'c'), (1, 2, 'd')], + ....: multiedges=True) + sage: G.cycle_basis() # optional - networkx [[0, 2], [2, 1, 0]] - sage: G.cycle_basis(output='edge') + sage: G.cycle_basis(output='edge') # optional - networkx [[(0, 2, 'a'), (2, 0, 'b')], [(2, 1, 'd'), (1, 0, 'c'), (0, 2, 'a')]] - sage: H = Graph([(1, 2), (2, 3), (2, 3), (3, 4), (1, 4), (1, 4), (4, 5), (5, 6), (4, 6), (6, 7)], multiedges=True) - sage: H.cycle_basis() + sage: H = Graph([(1, 2), (2, 3), (2, 3), (3, 4), (1, 4), + ....: (1, 4), (4, 5), (5, 6), (4, 6), (6, 7)], multiedges=True) + sage: H.cycle_basis() # optional - networkx [[1, 4], [2, 3], [4, 3, 2, 1], [6, 5, 4]] Disconnected graph:: sage: G.add_cycle(["Hey", "Wuuhuu", "Really ?"]) - sage: [sorted(c) for c in G.cycle_basis()] + sage: [sorted(c) for c in G.cycle_basis()] # optional - networkx [['Hey', 'Really ?', 'Wuuhuu'], [0, 2], [0, 1, 2]] - sage: [sorted(c) for c in G.cycle_basis(output='edge')] + sage: [sorted(c) for c in G.cycle_basis(output='edge')] # optional - networkx [[('Hey', 'Wuuhuu', None), ('Really ?', 'Hey', None), ('Wuuhuu', 'Really ?', None)], @@ -5091,13 +5113,13 @@ def cycle_basis(self, output='vertex'): sage: G = graphs.CycleGraph(3) sage: G.allow_multiple_edges(True) - sage: G.cycle_basis() + sage: G.cycle_basis() # optional - networkx [[2, 1, 0]] Not yet implemented for directed graphs:: sage: G = DiGraph([(0, 2, 'a'), (0, 1, 'c'), (1, 2, 'd')]) - sage: G.cycle_basis() + sage: G.cycle_basis() # optional - networkx Traceback (most recent call last): ... NotImplementedError: not implemented for directed graphs @@ -5106,10 +5128,11 @@ def cycle_basis(self, output='vertex'): :trac:`27538`:: - sage: G= Graph([(1, 2, 'a'), (2, 3, 'b'), (2, 3, 'c'), (3, 4, 'd'), (3, 4, 'e'), (4, 1, 'f')], multiedges=True) - sage: G.cycle_basis() + sage: G = Graph([(1, 2, 'a'), (2, 3, 'b'), (2, 3, 'c'), + ....: (3, 4, 'd'), (3, 4, 'e'), (4, 1, 'f')], multiedges=True) + sage: G.cycle_basis() # optional - networkx [[2, 3], [4, 3, 2, 1], [4, 3, 2, 1]] - sage: G.cycle_basis(output='edge') + sage: G.cycle_basis(output='edge') # optional - networkx [[(2, 3, 'b'), (3, 2, 'c')], [(4, 3, 'd'), (3, 2, 'b'), (2, 1, 'a'), (1, 4, 'f')], [(4, 3, 'e'), (3, 2, 'b'), (2, 1, 'a'), (1, 4, 'f')]] @@ -5184,14 +5207,15 @@ def minimum_cycle_basis(self, algorithm=None, weight_function=None, by_weight=Fa EXAMPLES:: - sage: g = Graph([(1, 2, 3), (2, 3, 5), (3, 4, 8), (4, 1, 13), (1, 3, 250), (5, 6, 9), (6, 7, 17), (7, 5, 20)]) + sage: g = Graph([(1, 2, 3), (2, 3, 5), (3, 4, 8), (4, 1, 13), + ....: (1, 3, 250), (5, 6, 9), (6, 7, 17), (7, 5, 20)]) sage: sorted(g.minimum_cycle_basis(by_weight=True)) [[1, 2, 3], [1, 2, 3, 4], [5, 6, 7]] sage: sorted(g.minimum_cycle_basis(by_weight=False)) [[1, 2, 3], [1, 3, 4], [5, 6, 7]] - sage: sorted(g.minimum_cycle_basis(by_weight=True, algorithm='NetworkX')) + sage: sorted(g.minimum_cycle_basis(by_weight=True, algorithm='NetworkX')) # optional - networkx [[1, 2, 3], [1, 2, 3, 4], [5, 6, 7]] - sage: g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX') + sage: g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX') # optional - networkx [[1, 2, 3], [1, 3, 4], [5, 6, 7]] :: @@ -5199,7 +5223,7 @@ def minimum_cycle_basis(self, algorithm=None, weight_function=None, by_weight=Fa sage: g = Graph([(1, 2), (2, 3), (3, 4), (4, 5), (5, 1), (5, 3)]) sage: sorted(g.minimum_cycle_basis(by_weight=False)) [[1, 2, 3, 5], [3, 4, 5]] - sage: sorted(g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX')) + sage: sorted(g.minimum_cycle_basis(by_weight=False, algorithm='NetworkX')) # optional - networkx [[1, 2, 3, 5], [3, 4, 5]] TESTS:: @@ -5328,7 +5352,7 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, se :: sage: g = graphs.PetersenGraph() - sage: (g.is_planar(kuratowski=True))[1].adjacency_matrix() + sage: (g.is_planar(kuratowski=True))[1].adjacency_matrix() # optional - sage.modules [0 1 0 0 0 1 0 0 0] [1 0 1 0 0 0 1 0 0] [0 1 0 1 0 0 0 1 0] @@ -5355,15 +5379,18 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, se sage: G.is_planar(on_embedding={}) Traceback (most recent call last): ... - NotImplementedError: cannot compute with embeddings of multiple-edged or looped graphs + NotImplementedError: cannot compute with embeddings of + multiple-edged or looped graphs sage: G.is_planar(set_pos=True) Traceback (most recent call last): ... - NotImplementedError: cannot compute with embeddings of multiple-edged or looped graphs + NotImplementedError: cannot compute with embeddings of + multiple-edged or looped graphs sage: G.is_planar(set_embedding=True) Traceback (most recent call last): ... - NotImplementedError: cannot compute with embeddings of multiple-edged or looped graphs + NotImplementedError: cannot compute with embeddings of + multiple-edged or looped graphs sage: G.is_planar(kuratowski=True) (True, None) @@ -5704,11 +5731,11 @@ def layout_planar(self, set_embedding=False, on_embedding=None, 7: [2, 4], 8: [1, 6], 9: [2, 5]} - sage: g = graphs.BalancedTree(3, 4) - sage: pos = g.layout(layout='planar', save_pos=True, test=True) - sage: pos[0] + sage: g = graphs.BalancedTree(3, 4) # optional - networkx + sage: pos = g.layout(layout='planar', save_pos=True, test=True) # optional - networkx + sage: pos[0] # optional - networkx [0, 119] - sage: pos[120] + sage: pos[120] # optional - networkx [21, 37] sage: g = graphs.CycleGraph(7) sage: g.layout(layout='planar', save_pos=True, test=True) @@ -5730,20 +5757,21 @@ def layout_planar(self, set_embedding=False, on_embedding=None, Choose the embedding:: sage: H = graphs.LadderGraph(4) - sage: em = {0:[1,4], 4:[0,5], 1:[5,2,0], 5:[4,6,1], 2:[1,3,6], 6:[7,5,2], 3:[7,2], 7:[3,6]} + sage: em = {0:[1,4], 4:[0,5], 1:[5,2,0], 5:[4,6,1], + ....: 2:[1,3,6], 6:[7,5,2], 3:[7,2], 7:[3,6]} sage: p = H.layout_planar(on_embedding=em) - sage: p # random + sage: p # random {2: [8.121320343559642, 1], - 3: [2.1213203435596424, 6], - 7: [3.1213203435596424, 0], - 0: [5.121320343559642, 3], - 1: [3.1213203435596424, 5], - 4: [4.121320343559642, 3], - 5: [4.121320343559642, 2], - 6: [3.1213203435596424, 1], - 9: [9.698670612749268, 1], - 8: [8.698670612749268, 1], - 10: [9.698670612749268, 0]} + 3: [2.1213203435596424, 6], + 7: [3.1213203435596424, 0], + 0: [5.121320343559642, 3], + 1: [3.1213203435596424, 5], + 4: [4.121320343559642, 3], + 5: [4.121320343559642, 2], + 6: [3.1213203435596424, 1], + 9: [9.698670612749268, 1], + 8: [8.698670612749268, 1], + 10: [9.698670612749268, 0]} TESTS:: @@ -5751,7 +5779,8 @@ def layout_planar(self, set_embedding=False, on_embedding=None, sage: G.layout(layout='planar', external_face=(1, 2)) Traceback (most recent call last): ... - ValueError: (1, 2) is not an edge of Graph on 4 vertices but has been provided as an edge of the external face + ValueError: (1, 2) is not an edge of Graph on 4 vertices + but has been provided as an edge of the external face Check the dependence of the computed position on the given combinatorial embedding (:trac:`28152`):: @@ -10132,12 +10161,14 @@ def _build_flow_graph(self, flow, integer): The method removes zero-cost flow cycles and updates the values accordingly:: - sage: g = digraphs.DeBruijn(2,3) - sage: flow = {('001', '010'): 1, ('010', '100'): 1, ('010', '101'): 1, ('101', '010'): 1} + sage: g = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: flow = {('001', '010'): 1, ('010', '100'): 1, + ....: ('010', '101'): 1, ('101', '010'): 1} sage: flow_graph = g._build_flow_graph(flow, True) sage: flow_graph.edges(sort=True) [('001', '010', 1), ('010', '100', 1)] - sage: flow = {('001', '010'): 2, ('010', '101'): 3, ('101', '011'): 2, ('101', '010'): 1} + sage: flow = {('001', '010'): 2, ('010', '101'): 3, + ....: ('101', '011'): 2, ('101', '010'): 1} sage: flow_graph = g._build_flow_graph(flow, True) sage: flow_graph.edges(sort=True) [('001', '010', 2), ('010', '101', 2), ('101', '011', 2)] @@ -10449,54 +10480,55 @@ def pagerank(self, alpha=0.85, personalization=None, by_weight=False, EXAMPLES:: sage: G = graphs.CycleGraph(4) - sage: G.pagerank(algorithm="Networkx") + sage: G.pagerank(algorithm="Networkx") # optional - networkx {0: 0.25, 1: 0.25, 2: 0.25, 3: 0.25} - sage: G.pagerank(alpha=0.50, algorithm="igraph") # optional - python_igraph # abs tol 1e-9 + sage: G.pagerank(alpha=0.50, algorithm="igraph") # abs tol 1e-9, optional - python_igraph {0: 0.25, 1: 0.25, 2: 0.25, 3: 0.25} - sage: G = Graph([(1, 2, 40), (2, 3, 50), (3, 4, 60), (1, 4, 70), (4, 5, 80), (5, 6, 20)]) - sage: G.pagerank(algorithm="NetworkX") # abs tol 1e-9 + sage: G = Graph([(1, 2, 40), (2, 3, 50), (3, 4, 60), + ....: (1, 4, 70), (4, 5, 80), (5, 6, 20)]) + sage: G.pagerank(algorithm="NetworkX") # abs tol 1e-9 # optional - networkx {1: 0.16112205885619563, 2: 0.1619531043247219, 3: 0.16112205885619563, 4: 0.2374999999999999, 5: 0.17775588228760858, 6: 0.100546895675278} - sage: G.pagerank(algorithm="NetworkX", by_weight=True) # abs tol 1e-9 + sage: G.pagerank(algorithm="NetworkX", by_weight=True) # abs tol 1e-9 # optional - networkx {1: 0.16459583718588994, 2: 0.13977928595154515, 3: 0.16539840184339605, 4: 0.3063198690713853, 5: 0.1700057609707141, 6: 0.05390084497706962} - sage: G.pagerank(algorithm="Scipy") # abs tol 1e-9 + sage: G.pagerank(algorithm="Scipy") # abs tol 1e-9 # optional - scipy {1: 0.16112205885619563, 2: 0.1619531043247219, 3: 0.16112205885619563, 4: 0.2374999999999999, 5: 0.17775588228760858, 6: 0.100546895675278} - sage: G.pagerank(algorithm="Scipy", by_weight=True) # abs tol 1e-9 + sage: G.pagerank(algorithm="Scipy", by_weight=True) # abs tol 1e-9 # optional - scipy {1: 0.16459583718588994, 2: 0.13977928595154515, 3: 0.16539840184339605, 4: 0.3063198690713853, 5: 0.1700057609707141, 6: 0.05390084497706962} - sage: G.pagerank(algorithm="igraph") # optional - python_igraph # abs tol 1e-9 + sage: G.pagerank(algorithm="igraph") # abs tol 1e-9, optional - python_igraph {1: 0.16112198303979128, 2: 0.16195368558382262, 3: 0.16112198303979125, 4: 0.23749999999999993, 5: 0.17775603392041744, 6: 0.10054631441617742} - sage: G.pagerank() # abs tol 1e-9 + sage: G.pagerank() # abs tol 1e-9 {1: 0.16112205885619563, 2: 0.1619531043247219, 3: 0.16112205885619563, 4: 0.2374999999999999, 5: 0.17775588228760858, 6: 0.100546895675278} - sage: G.pagerank(by_weight=True) # abs tol 1e-9 + sage: G.pagerank(by_weight=True) # abs tol 1e-9 {1: 0.16459583718588994, 2: 0.13977928595154515, 3: 0.16539840184339605, @@ -10507,7 +10539,8 @@ def pagerank(self, alpha=0.85, personalization=None, by_weight=False, TESTS:: sage: G = Graph([(1, 2), (2, 3), (3, 4), (1, 3)]) - sage: G.pagerank(algorithm="NetworkX", personalization={1:0, 2:3, 3:-2, 4:-1}) + sage: G.pagerank(algorithm="NetworkX", # optional - networkx + ....: personalization={1:0, 2:3, 3:-2, 4:-1}) Traceback (most recent call last): ... ZeroDivisionError... @@ -12946,13 +12979,13 @@ def degree(self, vertices=None, labels=False): returned list is the degree of the `i`-th vertex in the list ``list(self)``:: - sage: D = digraphs.DeBruijn(4, 2) - sage: D.delete_vertex('20') - sage: print(D.degree()) + sage: D = digraphs.DeBruijn(4, 2) # optional - sage.combinat + sage: D.delete_vertex('20') # optional - sage.combinat + sage: print(D.degree()) # optional - sage.combinat [7, 7, 6, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 7, 8] - sage: print(D.degree(vertices=list(D))) + sage: print(D.degree(vertices=list(D))) # optional - sage.combinat [7, 7, 6, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 7, 8] - sage: print(D.degree(vertices=D.vertices(sort=False))) + sage: print(D.degree(vertices=D.vertices(sort=False))) # optional - sage.combinat [7, 7, 6, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 7, 8] """ if labels: @@ -13090,11 +13123,11 @@ def degree_iterator(self, vertices=None, labels=False): When ``vertices=None`` yields values in the order of ``list(D)``:: sage: V = list(D) - sage: D = digraphs.DeBruijn(4, 2) - sage: D.delete_vertex('20') - sage: print(list(D.degree_iterator())) + sage: D = digraphs.DeBruijn(4, 2) # optional - sage.combinat + sage: D.delete_vertex('20') # optional - sage.combinat + sage: print(list(D.degree_iterator())) # optional - sage.combinat [7, 7, 6, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 7, 8] - sage: print([D.degree(v) for v in D]) + sage: print([D.degree(v) for v in D]) # optional - sage.combinat [7, 7, 6, 7, 8, 8, 7, 8, 8, 7, 8, 8, 8, 7, 8] """ if vertices is None: @@ -13725,99 +13758,99 @@ def subgraph_search(self, G, induced=False): The Petersen graph contains the path graph `P_5`:: sage: g = graphs.PetersenGraph() - sage: h1 = g.subgraph_search(graphs.PathGraph(5)); h1 + sage: h1 = g.subgraph_search(graphs.PathGraph(5)); h1 # optional - sage.modules Subgraph of (Petersen graph): Graph on 5 vertices - sage: h1.vertices(sort=True); h1.edges(sort=True, labels=False) + sage: h1.vertices(sort=True); h1.edges(sort=True, labels=False) # optional - sage.modules [0, 1, 2, 3, 4] [(0, 1), (1, 2), (2, 3), (3, 4)] - sage: I1 = g.subgraph_search(graphs.PathGraph(5), induced=True); I1 + sage: I1 = g.subgraph_search(graphs.PathGraph(5), induced=True); I1 # optional - sage.modules Subgraph of (Petersen graph): Graph on 5 vertices - sage: I1.vertices(sort=True); I1.edges(sort=True, labels=False) + sage: I1.vertices(sort=True); I1.edges(sort=True, labels=False) # optional - sage.modules [0, 1, 2, 3, 8] [(0, 1), (1, 2), (2, 3), (3, 8)] It also contains the claw `K_{1,3}`:: - sage: h2 = g.subgraph_search(graphs.ClawGraph()); h2 + sage: h2 = g.subgraph_search(graphs.ClawGraph()); h2 # optional - sage.modules Subgraph of (Petersen graph): Graph on 4 vertices - sage: h2.vertices(sort=True); h2.edges(sort=True, labels=False) + sage: h2.vertices(sort=True); h2.edges(sort=True, labels=False) # optional - sage.modules [0, 1, 4, 5] [(0, 1), (0, 4), (0, 5)] - sage: I2 = g.subgraph_search(graphs.ClawGraph(), induced=True); I2 + sage: I2 = g.subgraph_search(graphs.ClawGraph(), induced=True); I2 # optional - sage.modules Subgraph of (Petersen graph): Graph on 4 vertices - sage: I2.vertices(sort=True); I2.edges(sort=True, labels=False) + sage: I2.vertices(sort=True); I2.edges(sort=True, labels=False) # optional - sage.modules [0, 1, 4, 5] [(0, 1), (0, 4), (0, 5)] Of course the induced copies are isomorphic to the graphs we were looking for:: - sage: I1.is_isomorphic(graphs.PathGraph(5)) + sage: I1.is_isomorphic(graphs.PathGraph(5)) # optional - sage.modules True - sage: I2.is_isomorphic(graphs.ClawGraph()) + sage: I2.is_isomorphic(graphs.ClawGraph()) # optional - sage.modules True However, the Petersen graph does not contain a subgraph isomorphic to `K_3`:: - sage: g.subgraph_search(graphs.CompleteGraph(3)) is None + sage: g.subgraph_search(graphs.CompleteGraph(3)) is None # optional - sage.modules True Nor does it contain a nonempty induced subgraph isomorphic to `P_6`:: - sage: g.subgraph_search(graphs.PathGraph(6), induced=True) is None + sage: g.subgraph_search(graphs.PathGraph(6), induced=True) is None # optional - sage.modules True The empty graph is a subgraph of every graph:: - sage: g.subgraph_search(graphs.EmptyGraph()) + sage: g.subgraph_search(graphs.EmptyGraph()) # optional - sage.modules Graph on 0 vertices - sage: g.subgraph_search(graphs.EmptyGraph(), induced=True) + sage: g.subgraph_search(graphs.EmptyGraph(), induced=True) # optional - sage.modules Graph on 0 vertices The subgraph may just have edges missing:: sage: k3 = graphs.CompleteGraph(3); p3 = graphs.PathGraph(3) sage: k3.relabel(list('abc')) - sage: s = k3.subgraph_search(p3) - sage: s.edges(sort=True, labels=False) + sage: s = k3.subgraph_search(p3) # optional - sage.modules + sage: s.edges(sort=True, labels=False) # optional - sage.modules [('a', 'b'), ('b', 'c')] Of course, `P_3` is not an induced subgraph of `K_3`, though:: sage: k3 = graphs.CompleteGraph(3); p3 = graphs.PathGraph(3) sage: k3.relabel(list('abc')) - sage: k3.subgraph_search(p3, induced=True) is None + sage: k3.subgraph_search(p3, induced=True) is None # optional - sage.modules True If the graph has labels, the labels are just ignored:: sage: g.set_vertex(0, 'foo') - sage: c = g.subgraph_search(graphs.PathGraph(5)) - sage: c.get_vertices() + sage: c = g.subgraph_search(graphs.PathGraph(5)) # optional - sage.modules + sage: c.get_vertices() # optional - sage.modules {0: 'foo', 1: None, 2: None, 3: None, 4: None} TESTS: Inside of a small graph (:trac:`13906`):: - sage: Graph(5).subgraph_search(Graph(1)) + sage: Graph(5).subgraph_search(Graph(1)) # optional - sage.modules Graph on 1 vertex For labelled edges (:trac:`14999`):: sage: G = graphs.CompleteGraph(10) - sage: C = G.subgraph_search(graphs.CycleGraph(4)) - sage: C.size() + sage: C = G.subgraph_search(graphs.CycleGraph(4)) # optional - sage.modules + sage: C.size() # optional - sage.modules 4 - sage: C.edges(sort=True) + sage: C.edges(sort=True) # optional - sage.modules [(0, 1, None), (0, 3, None), (1, 2, None), (2, 3, None)] sage: for (u,v) in G.edges(sort=True, labels=False): ....: G.set_edge_label(u, v, u) - sage: C = G.subgraph_search(graphs.CycleGraph(4)) - sage: C.edges(sort=True) + sage: C = G.subgraph_search(graphs.CycleGraph(4)) # optional - sage.modules + sage: C.edges(sort=True) # optional - sage.modules [(0, 1, 0), (0, 3, 0), (1, 2, 1), (2, 3, 2)] """ @@ -13858,12 +13891,12 @@ def subgraph_search_count(self, G, induced=False): Counting the number of paths `P_5` in a PetersenGraph:: sage: g = graphs.PetersenGraph() - sage: g.subgraph_search_count(graphs.PathGraph(5)) + sage: g.subgraph_search_count(graphs.PathGraph(5)) # optional - sage.modules 240 Requiring these subgraphs be induced:: - sage: g.subgraph_search_count(graphs.PathGraph(5), induced=True) + sage: g.subgraph_search_count(graphs.PathGraph(5), induced=True) # optional - sage.modules 120 If we define the graph `T_k` (the transitive tournament on `k` vertices) @@ -13872,36 +13905,36 @@ def subgraph_search_count(self, G, induced=False): `0`:: sage: T5 = digraphs.TransitiveTournament(5) - sage: T5.subgraph_search_count(digraphs.Circuit(3)) + sage: T5.subgraph_search_count(digraphs.Circuit(3)) # optional - sage.modules 0 If we count instead the number of `T_3` in `T_5`, we expect the answer to be `\binom{5}{3}`:: sage: T3 = digraphs.TransitiveTournament(3) - sage: T5.subgraph_search_count(T3) + sage: T5.subgraph_search_count(T3) # optional - sage.modules 10 sage: binomial(5,3) 10 - sage: T3.is_isomorphic(T5.subgraph(vertices=[0, 1, 2])) + sage: T3.is_isomorphic(T5.subgraph(vertices=[0, 1, 2])) # optional - sage.modules True The empty graph is a subgraph of every graph:: - sage: g.subgraph_search_count(graphs.EmptyGraph()) + sage: g.subgraph_search_count(graphs.EmptyGraph()) # optional - sage.modules 1 If the graph has vertex labels or edge labels, the label is just ignored:: sage: g.set_vertex(0, 'foo') - sage: g.subgraph_search_count(graphs.PathGraph(5)) + sage: g.subgraph_search_count(graphs.PathGraph(5)) # optional - sage.modules 240 TESTS: Inside of a small graph (:trac:`13906`):: - sage: Graph(5).subgraph_search_count(Graph(1)) + sage: Graph(5).subgraph_search_count(Graph(1)) # optional - sage.modules 5 """ from sage.graphs.generic_graph_pyx import SubgraphSearch @@ -13968,7 +14001,7 @@ def subgraph_search_iterator(self, G, induced=False, return_graphs=True): sage: g = graphs.PathGraph(5) sage: P3 = graphs.PathGraph(3) - sage: for p in g.subgraph_search_iterator(P3, return_graphs=False): + sage: for p in g.subgraph_search_iterator(P3, return_graphs=False): # optional - sage.modules ....: print(p) [0, 1, 2] [1, 2, 3] @@ -13976,7 +14009,7 @@ def subgraph_search_iterator(self, G, induced=False, return_graphs=True): [2, 3, 4] [3, 2, 1] [4, 3, 2] - sage: for p in g.subgraph_search_iterator(P3, return_graphs=True): + sage: for p in g.subgraph_search_iterator(P3, return_graphs=True): # optional - sage.modules ....: print(p) Subgraph of (Path graph) Subgraph of (Path graph) @@ -13984,13 +14017,13 @@ def subgraph_search_iterator(self, G, induced=False, return_graphs=True): Subgraph of (Path graph) Subgraph of (Path graph) Subgraph of (Path graph) - sage: all(h.is_isomorphic(P3) for h in g.subgraph_search_iterator(P3)) + sage: all(h.is_isomorphic(P3) for h in g.subgraph_search_iterator(P3)) # optional - sage.modules True If the graph has vertex labels or edge labels, the label is just ignored:: sage: g.set_vertex(0, 'foo') - sage: for p in g.subgraph_search_iterator(P3, return_graphs=False): + sage: for p in g.subgraph_search_iterator(P3, return_graphs=False): # optional - sage.modules ....: print(p) [0, 1, 2] [1, 2, 3] @@ -14003,45 +14036,47 @@ def subgraph_search_iterator(self, G, induced=False, return_graphs=True): sage: H = graphs.HouseGraph() sage: P4 = graphs.PathGraph(4) - sage: all(h.is_isomorphic(P4) for h in H.subgraph_search_iterator(P4, induced=True)) + sage: all(h.is_isomorphic(P4) # optional - sage.modules + ....: for h in H.subgraph_search_iterator(P4, induced=True)) True - sage: sum(1 for h in H.subgraph_search_iterator(P4, induced=True)) + sage: sum(1 for h in H.subgraph_search_iterator(P4, induced=True)) # optional - sage.modules 4 - sage: sum(1 for h in H.subgraph_search_iterator(P4, induced=False)) + sage: sum(1 for h in H.subgraph_search_iterator(P4, induced=False)) # optional - sage.modules 20 Search for subdigraphs:: sage: H = digraphs.Complete(5) sage: P4 = digraphs.Path(4) - sage: sum(1 for _ in H.subgraph_search_iterator(P4, induced=True)) + sage: sum(1 for _ in H.subgraph_search_iterator(P4, induced=True)) # optional - sage.modules 0 - sage: sum(1 for _ in H.subgraph_search_iterator(P4, induced=False)) + sage: sum(1 for _ in H.subgraph_search_iterator(P4, induced=False)) # optional - sage.modules 120 This method also works for bipartite graphs:: sage: K33 = BipartiteGraph(graphs.CompleteBipartiteGraph(3, 3)) sage: K22 = BipartiteGraph(graphs.CompleteBipartiteGraph(2, 2)) - sage: sum(1 for _ in K33.subgraph_search_iterator(K22)) + sage: sum(1 for _ in K33.subgraph_search_iterator(K22)) # optional - sage.modules 72 TESTS: Inside of a small graph (:trac:`13906`):: - sage: list(Graph(5).subgraph_search_iterator(Graph(1))) - [Graph on 1 vertex, Graph on 1 vertex, Graph on 1 vertex, Graph on 1 vertex, Graph on 1 vertex] + sage: list(Graph(5).subgraph_search_iterator(Graph(1))) # optional - sage.modules + [Graph on 1 vertex, Graph on 1 vertex, Graph on 1 vertex, + Graph on 1 vertex, Graph on 1 vertex] Check that the behavior of the method is consistent (:trac:`34004`):: sage: g = graphs.CycleGraph(3) - sage: for i in range(3): + sage: for i in range(3): # optional - sage.modules ....: g.subgraph_search_iterator(graphs.PathGraph(i)) sage: K4 = digraphs.Complete(4) sage: K3 = digraphs.Complete(3) - sage: for g in K4.subgraph_search_iterator(K3, return_graphs=True): + sage: for g in K4.subgraph_search_iterator(K3, return_graphs=True): # optional - sage.modules ....: print(type(g)) ....: break sage: K33 = BipartiteGraph(graphs.CompleteBipartiteGraph(3, 3)) sage: K22 = BipartiteGraph(graphs.CompleteBipartiteGraph(2, 2)) - sage: for b in K33.subgraph_search_iterator(K22, return_graphs=True): + sage: for b in K33.subgraph_search_iterator(K22, return_graphs=True): # optional - sage.modules ....: print(type(b)) ....: break sage: P5 = graphs.PathGraph(5) - sage: for b in K33.subgraph_search_iterator(P5, return_graphs=True): + sage: for b in K33.subgraph_search_iterator(P5, return_graphs=True): # optional - sage.modules ....: print(type(b)) ....: break - sage: for b in Graph(K33).subgraph_search_iterator(K22, return_graphs=True): + sage: for b in Graph(K33).subgraph_search_iterator(K22, return_graphs=True): # optional - sage.modules ....: print(type(b)) ....: break @@ -14147,7 +14182,7 @@ def is_chordal(self, certificate=False, algorithm="B"): cycle of length at least 4). Alternatively, chordality can be defined using a Perfect Elimination - Order : + Order: A Perfect Elimination Order of a graph `G` is an ordering `v_1,...,v_n` of its vertex set such that for all `i`, the neighbors of `v_i` whose @@ -14209,20 +14244,21 @@ def is_chordal(self, certificate=False, algorithm="B"): The same goes with the product of a random lobster (which is a tree) and a Complete Graph :: - sage: g = graphs.RandomLobster(10, .5, .5).lexicographic_product(graphs.CompleteGraph(3)) - sage: g.is_chordal() + sage: grl = graphs.RandomLobster(10, .5, .5) # optional - networkx + sage: g = grl.lexicographic_product(graphs.CompleteGraph(3)) # optional - networkx + sage: g.is_chordal() # optional - networkx True The disjoint union of chordal graphs is still chordal:: - sage: (2 * g).is_chordal() + sage: (2 * g).is_chordal() # optional - networkx True Let us check the certificate given by Sage is indeed a perfect elimination order:: - sage: _, peo = g.is_chordal(certificate=True) - sage: for v in peo: + sage: _, peo = g.is_chordal(certificate=True) # optional - networkx + sage: for v in peo: # optional - networkx ....: if not g.subgraph(g.neighbors(v)).is_clique(): ....: raise ValueError("this should never happen") ....: g.delete_vertex(v) @@ -14442,27 +14478,27 @@ def is_circulant(self, certificate=False): The Petersen graph is not a circulant graph:: sage: g = graphs.PetersenGraph() - sage: g.is_circulant() + sage: g.is_circulant() # optional - sage.groups False A cycle is obviously a circulant graph, but several sets of parameters can be used to define it:: sage: g = graphs.CycleGraph(5) - sage: g.is_circulant(certificate=True) + sage: g.is_circulant(certificate=True) # optional - sage.groups (True, [(5, [1, 4]), (5, [2, 3])]) The same goes for directed graphs:: sage: g = digraphs.Circuit(5) - sage: g.is_circulant(certificate=True) + sage: g.is_circulant(certificate=True) # optional - sage.groups (True, [(5, [1]), (5, [3]), (5, [2]), (5, [4])]) With this information, it is very easy to create (and plot) all possible drawings of a circulant graph:: sage: g = graphs.CirculantGraph(13, [2, 3, 10, 11]) - sage: for param in g.is_circulant(certificate=True)[1]: + sage: for param in g.is_circulant(certificate=True)[1]: # optional - sage.groups ....: graphs.CirculantGraph(*param) Circulant graph ([2, 3, 10, 11]): Graph on 13 vertices Circulant graph ([1, 5, 8, 12]): Graph on 13 vertices @@ -14470,13 +14506,13 @@ def is_circulant(self, certificate=False): TESTS:: - sage: digraphs.DeBruijn(3,1).is_circulant(certificate=True) + sage: digraphs.DeBruijn(3,1).is_circulant(certificate=True) # optional - sage.combinat sage.groups (True, [(3, [0, 1, 2])]) - sage: Graph(1).is_circulant(certificate=True) + sage: Graph(1).is_circulant(certificate=True) # optional - sage.groups (True, (1, [])) - sage: Graph(0).is_circulant(certificate=True) + sage: Graph(0).is_circulant(certificate=True) # optional - sage.groups (True, (0, [])) - sage: Graph({0: [0]}).is_circulant(certificate=True) + sage: Graph({0: [0]}).is_circulant(certificate=True) # optional - sage.groups (True, (1, [0])) """ self._scream_if_not_simple(allow_loops=True) @@ -15066,11 +15102,11 @@ def is_subgraph(self, other, induced=True, up_to_isomorphism=False): sage: p11 = graphs.PathGraph(11) sage: p15 = graphs.PathGraph(15) sage: g = graphs.Grid2dGraph(4, 4) - sage: p15.is_subgraph(g, induced=False, up_to_isomorphism=True) + sage: p15.is_subgraph(g, induced=False, up_to_isomorphism=True) # optional - sage.modules True - sage: p15.is_subgraph(g, induced=True, up_to_isomorphism=True) + sage: p15.is_subgraph(g, induced=True, up_to_isomorphism=True) # optional - sage.modules False - sage: p11.is_subgraph(g, induced=True, up_to_isomorphism=True) + sage: p11.is_subgraph(g, induced=True, up_to_isomorphism=True) # optional - sage.modules True TESTS: @@ -15148,7 +15184,7 @@ def cluster_triangles(self, nbunch=None, implementation=None): :: sage: G = graphs.RandomGNP(20, .3) - sage: d1 = G.cluster_triangles(implementation="networkx") + sage: d1 = G.cluster_triangles(implementation="networkx") # optional - networkx sage: d2 = G.cluster_triangles(implementation="dense_copy") sage: d3 = G.cluster_triangles(implementation="sparse_copy") sage: d1 == d2 and d1 == d3 @@ -15156,7 +15192,7 @@ def cluster_triangles(self, nbunch=None, implementation=None): TESTS:: - sage: DiGraph().cluster_triangles(implementation="networkx") + sage: DiGraph().cluster_triangles(implementation="networkx") # optional - networkx Traceback (most recent call last): ... ValueError: the 'networkx' implementation does not support directed graphs @@ -15216,7 +15252,7 @@ def clustering_average(self, implementation=None): sage: (graphs.FruchtGraph()).clustering_average() 1/4 - sage: (graphs.FruchtGraph()).clustering_average(implementation='networkx') + sage: (graphs.FruchtGraph()).clustering_average(implementation='networkx') # optional - networkx 0.25 TESTS: @@ -15231,9 +15267,11 @@ def clustering_average(self, implementation=None): The result is the same with all implementations:: sage: G = graphs.RandomGNM(10,20) + sage: impls = ['boost','sparse_copy','dense_copy'] + sage: impls += ['networkx'] # optional - networkx sage: coeffs = [G.clustering_average(implementation=impl) - ....: for impl in ['boost','sparse_copy','dense_copy','networkx']] - sage: max(coeffs)-min(coeffs) # tol abs 1e-12 + ....: for impl in impls] + sage: max(coeffs) - min(coeffs) # tol abs 1e-12 0 """ @@ -15310,10 +15348,10 @@ def clustering_coeff(self, sage: (graphs.FruchtGraph()).clustering_coeff(weight=True) {0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0, - 3: 0.3333333333333333, 4: 0.3333333333333333, - 5: 0.3333333333333333, 6: 0.3333333333333333, - 7: 0.3333333333333333, 8: 0, 9: 0.3333333333333333, - 10: 0.3333333333333333, 11: 0} + 3: 0.3333333333333333, 4: 0.3333333333333333, + 5: 0.3333333333333333, 6: 0.3333333333333333, + 7: 0.3333333333333333, 8: 0, 9: 0.3333333333333333, + 10: 0.3333333333333333, 11: 0} sage: (graphs.FruchtGraph()).clustering_coeff(nodes=[0,1,2]) {0: 0.3333333333333333, 1: 0.3333333333333333, 2: 0.0} @@ -15416,7 +15454,7 @@ def cluster_transitivity(self): EXAMPLES:: - sage: graphs.FruchtGraph().cluster_transitivity() + sage: graphs.FruchtGraph().cluster_transitivity() # optional - networkx 0.25 """ import networkx @@ -15621,7 +15659,7 @@ def girth(self, certificate=False): Issue :trac:`12355`:: - sage: H=Graph([(0, 1), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 6), (2, 5), (3, 4), (5, 6)]) + sage: H = Graph([(0, 1), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 6), (2, 5), (3, 4), (5, 6)]) sage: H.girth() 3 @@ -15651,13 +15689,13 @@ def girth(self, certificate=False): sage: g = digraphs.Circuit(6) sage: g.girth() 6 - sage: g = digraphs.RandomDirectedGNC(10) - sage: g.girth() + sage: g = digraphs.RandomDirectedGNC(10) # optional - networkx + sage: g.girth() # optional - networkx +Infinity - sage: g = DiGraph([(0, 1), (1, 2), (1, 3), (2, 3), (3, 4), (4, 0)]) - sage: g.girth() + sage: g = DiGraph([(0, 1), (1, 2), (1, 3), (2, 3), (3, 4), (4, 0)]) # optional - networkx + sage: g.girth() # optional - networkx 4 - sage: Graph(g).girth() + sage: Graph(g).girth() # optional - networkx 3 """ # Cases where girth <= 2 @@ -15708,10 +15746,10 @@ def odd_girth(self, algorithm="bfs", certificate=False): The McGee graph has girth 7 and therefore its odd girth is 7 as well:: - sage: G = graphs.McGeeGraph() - sage: G.girth() + sage: G = graphs.McGeeGraph() # optional - networkx + sage: G.girth() # optional - networkx 7 - sage: G.odd_girth() + sage: G.odd_girth() # optional - networkx 7 Any complete (directed) graph on more than 2 vertices contains @@ -15736,15 +15774,15 @@ def odd_girth(self, algorithm="bfs", certificate=False): The odd girth of a (directed) graph with loops is 1:: - sage: G = graphs.RandomGNP(10, .5) - sage: G.allow_loops(True) - sage: G.add_edge(0, 0) - sage: G.odd_girth() + sage: G = graphs.RandomGNP(10, .5) # optional - networkx + sage: G.allow_loops(True) # optional - networkx + sage: G.add_edge(0, 0) # optional - networkx + sage: G.odd_girth() # optional - networkx 1 - sage: G = digraphs.RandomDirectedGNP(10, .5) - sage: G.allow_loops(True) - sage: G.add_edge(0, 0) - sage: G.odd_girth() + sage: G = digraphs.RandomDirectedGNP(10, .5) # optional - networkx + sage: G.allow_loops(True) # optional - networkx + sage: G.add_edge(0, 0) # optional - networkx + sage: G.odd_girth() # optional - networkx 1 .. SEEALSO:: @@ -15957,9 +15995,9 @@ def centrality_betweenness(self, k=None, normalized=True, weight=None, TESTS:: - sage: tests = ([graphs.RandomGNP(30,.1) for i in range(10)]+ + sage: tests = ([graphs.RandomGNP(30,.1) for i in range(10)]+ # optional - networkx ....: [digraphs.RandomDirectedGNP(30,.1) for i in range(10)]) - sage: for g in tests: + sage: for g in tests: # optional - networkx ....: r1 = g.centrality_betweenness(algorithm="Sage",exact=0) ....: r2 = g.centrality_betweenness(algorithm="Sage",exact=1) ....: r3 = g.centrality_betweenness(algorithm="NetworkX") @@ -16465,9 +16503,9 @@ def shortest_path(self, u, v, by_weight=False, algorithm=None, [4, 17, 16, 12, 13, 9] sage: D.shortest_path(4, 9, algorithm='BFS') [4, 3, 2, 1, 8, 9] - sage: D.shortest_path(4, 8, algorithm='Dijkstra_NetworkX') + sage: D.shortest_path(4, 8, algorithm='Dijkstra_NetworkX') # optional - networkx [4, 3, 2, 1, 8] - sage: D.shortest_path(4, 8, algorithm='Dijkstra_Bid_NetworkX') + sage: D.shortest_path(4, 8, algorithm='Dijkstra_Bid_NetworkX') # optional - networkx [4, 3, 2, 1, 8] sage: D.shortest_path(4, 9, algorithm='Dijkstra_Bid') [4, 3, 19, 0, 10, 9] @@ -16476,15 +16514,18 @@ def shortest_path(self, u, v, by_weight=False, algorithm=None, sage: D.delete_edges(D.edges_incident(13)) sage: D.shortest_path(13, 4) [] - sage: G = Graph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2}}, sparse = True) + sage: G = Graph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2}}, + ....: sparse=True) sage: G.plot(edge_labels=True).show() # long time sage: G.shortest_path(0, 3) [0, 4, 3] sage: G.shortest_path(0, 3, by_weight=True) [0, 1, 2, 3] - sage: G.shortest_path(0, 3, by_weight=True, algorithm='Dijkstra_NetworkX') + sage: G.shortest_path(0, 3, by_weight=True, # optional - networkx + ....: algorithm='Dijkstra_NetworkX') [0, 1, 2, 3] - sage: G.shortest_path(0, 3, by_weight=True, algorithm='Dijkstra_Bid_NetworkX') + sage: G.shortest_path(0, 3, by_weight=True, # optional - networkx + ....: algorithm='Dijkstra_Bid_NetworkX') [0, 1, 2, 3] TESTS: @@ -16522,15 +16563,11 @@ def shortest_path(self, u, v, by_weight=False, algorithm=None, sage: G = Graph() sage: G.add_vertices([1, 2]) - sage: for alg in ['BFS', 'BFS_Bid', 'Dijkstra_NetworkX', 'Dijkstra_Bid_NetworkX', - ....: 'Dijkstra_Bid', 'Bellman-Ford_Boost']: - ....: G.shortest_path(1, 2, algorithm=alg) - [] - [] - [] - [] - [] - [] + sage: algs = ['BFS', 'BFS_Bid', 'Dijkstra_Bid', 'Bellman-Ford_Boost'] + sage: algs += ['Dijkstra_NetworkX', 'Dijkstra_Bid_NetworkX'] # optional - networkx + sage: all(G.shortest_path(1, 2, algorithm=alg) == [] + ....: for alg in algs) + True .. TODO:: @@ -16651,9 +16688,9 @@ def shortest_path_length(self, u, v, by_weight=False, algorithm=None, 5 sage: D.shortest_path_length(4, 9, algorithm='BFS') 5 - sage: D.shortest_path_length(4, 9, algorithm='Dijkstra_NetworkX') + sage: D.shortest_path_length(4, 9, algorithm='Dijkstra_NetworkX') # optional - networkx 5 - sage: D.shortest_path_length(4, 9, algorithm='Dijkstra_Bid_NetworkX') + sage: D.shortest_path_length(4, 9, algorithm='Dijkstra_Bid_NetworkX') # optional - networkx 5 sage: D.shortest_path_length(4, 9, algorithm='Dijkstra_Bid') 5 @@ -16664,31 +16701,37 @@ def shortest_path_length(self, u, v, by_weight=False, algorithm=None, sage: D.delete_edges(D.edges_incident(13)) sage: D.shortest_path_length(13, 4) +Infinity - sage: G = Graph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2}}, sparse = True) - sage: G.plot(edge_labels=True).show() # long time + sage: G = Graph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2}}, + ....: sparse=True) + sage: G.plot(edge_labels=True).show() # long time sage: G.shortest_path_length(0, 3) 2 sage: G.shortest_path_length(0, 3, by_weight=True) 3 - sage: G.shortest_path_length(0, 3, by_weight=True, algorithm='Dijkstra_NetworkX') + sage: G.shortest_path_length(0, 3, by_weight=True, # optional - networkx + ....: algorithm='Dijkstra_NetworkX') 3 - sage: G.shortest_path_length(0, 3, by_weight=True, algorithm='Dijkstra_Bid_NetworkX') + sage: G.shortest_path_length(0, 3, by_weight=True, # optional - networkx + ....: algorithm='Dijkstra_Bid_NetworkX') 3 If Dijkstra is used with negative weights, usually it raises an error:: - sage: G = DiGraph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: -2}}, sparse = True) + sage: G = DiGraph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: -2}}, + ....: sparse=True) sage: G.shortest_path_length(4, 1, by_weight=True, algorithm=None) Traceback (most recent call last): ... ValueError: the graph contains an edge with negative weight - sage: G.shortest_path_length(4, 1, by_weight=True, algorithm='Bellman-Ford_Boost') + sage: G.shortest_path_length(4, 1, by_weight=True, + ....: algorithm='Bellman-Ford_Boost') -1 However, sometimes the result may be wrong, and no error is raised:: - sage: G = DiGraph([(0,1,1),(1,2,1),(0,3,1000),(3,4,-3000), (4,2,1000)]) - sage: G.shortest_path_length(0, 2, by_weight=True, algorithm='Bellman-Ford_Boost') + sage: G = DiGraph([(0,1,1), (1,2,1), (0,3,1000), (3,4,-3000), (4,2,1000)]) + sage: G.shortest_path_length(0, 2, by_weight=True, + ....: algorithm='Bellman-Ford_Boost') -1000 sage: G.shortest_path_length(0, 2, by_weight=True) 2 @@ -16710,15 +16753,11 @@ def shortest_path_length(self, u, v, by_weight=False, algorithm=None, sage: G = Graph() sage: G.add_vertices([1, 2]) - sage: for alg in ['BFS', 'BFS_Bid', 'Dijkstra_NetworkX', 'Dijkstra_Bid_NetworkX', - ....: 'Dijkstra_Bid', 'Bellman-Ford_Boost']: - ....: G.shortest_path_length(1, 2, algorithm=alg) - +Infinity - +Infinity - +Infinity - +Infinity - +Infinity - +Infinity + sage: algs = ['BFS', 'BFS_Bid', 'Dijkstra_Bid', 'Bellman-Ford_Boost'] + sage: algs += ['Dijkstra_NetworkX', 'Dijkstra_Bid_NetworkX'] # optional - networkx + sage: all(G.shortest_path_length(1, 2, algorithm=alg) == Infinity + ....: for alg in algs) + True """ if not self.has_vertex(u): raise ValueError("vertex '{}' is not in the (di)graph".format(u)) @@ -17219,20 +17258,23 @@ def shortest_path_lengths(self, u, by_weight=False, algorithm=None, sage: D = graphs.DodecahedralGraph() sage: D.shortest_path_lengths(0) - {0: 0, 1: 1, 2: 2, 3: 2, 4: 3, 5: 4, 6: 3, 7: 3, 8: 2, 9: 2, 10: 1, 11: 2, 12: 3, 13: 3, 14: 4, 15: 5, 16: 4, 17: 3, 18: 2, 19: 1} + {0: 0, 1: 1, 2: 2, 3: 2, 4: 3, 5: 4, 6: 3, 7: 3, 8: 2, 9: 2, 10: 1, + 11: 2, 12: 3, 13: 3, 14: 4, 15: 5, 16: 4, 17: 3, 18: 2, 19: 1} Weighted case:: - sage: G = Graph( { 0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2} }, sparse=True) - sage: G.plot(edge_labels=True).show() # long time + sage: G = Graph({0: {1: 1}, 1: {2: 1}, 2: {3: 1}, 3: {4: 2}, 4: {0: 2}}, + ....: sparse=True) + sage: G.plot(edge_labels=True).show() # long time # optional - sage.plot sage: G.shortest_path_lengths(0, by_weight=True) {0: 0, 1: 1, 2: 2, 3: 3, 4: 2} Using a weight function:: - sage: D = DiGraph([(0,1,{'weight':1}),(1,2,{'weight':3}),(0,2,{'weight':5})]) - sage: weight_function = lambda e:e[2]['weight'] - sage: D.shortest_path_lengths(1, algorithm='Dijkstra_NetworkX', by_weight=False) + sage: D = DiGraph([(0,1,{'weight':1}), (1,2,{'weight':3}), (0,2,{'weight':5})]) + sage: weight_function = lambda e: e[2]['weight'] + sage: D.shortest_path_lengths(1, algorithm='Dijkstra_NetworkX', # optional - networkx + ....: by_weight=False) {1: 0, 2: 1} sage: D.shortest_path_lengths(0, weight_function=weight_function) {0: 0, 1: 1, 2: 4} @@ -17241,13 +17283,13 @@ def shortest_path_lengths(self, u, by_weight=False, algorithm=None, Negative weights:: - sage: D = DiGraph([(0,1,{'weight':-1}),(1,2,{'weight':3}),(0,2,{'weight':5})]) + sage: D = DiGraph([(0,1,{'weight':-1}), (1,2,{'weight':3}), (0,2,{'weight':5})]) sage: D.shortest_path_lengths(0, weight_function=weight_function) {0: 0, 1: -1, 2: 2} Negative cycles:: - sage: D = DiGraph([(0,1,{'weight':-5}),(1,2,{'weight':3}),(2,0,{'weight':1})]) + sage: D = DiGraph([(0,1,{'weight':-5}), (1,2,{'weight':3}), (2,0,{'weight':1})]) sage: D.shortest_path_lengths(0, weight_function=weight_function) Traceback (most recent call last): ... @@ -17257,7 +17299,7 @@ def shortest_path_lengths(self, u, by_weight=False, algorithm=None, sage: g = graphs.Grid2dGraph(5,5) sage: d1 = g.shortest_path_lengths((0,0), algorithm="BFS") - sage: d2 = g.shortest_path_lengths((0,0), algorithm="Dijkstra_NetworkX") + sage: d2 = g.shortest_path_lengths((0,0), algorithm="Dijkstra_NetworkX") # optional - networkx sage: d3 = g.shortest_path_lengths((0,0), algorithm="Dijkstra_Boost") sage: d4 = g.shortest_path_lengths((0,0), algorithm="Bellman-Ford_Boost") sage: d1 == d2 == d3 == d4 @@ -18604,7 +18646,8 @@ def to_simple(self, to_undirected=True, keep_label='any', immutable=None): EXAMPLES:: sage: G = DiGraph(loops=True, multiedges=True, sparse=True) - sage: G.add_edges([(0, 0, None), (1, 1, None), (2, 2, None), (2, 3, 1), (2, 3, 2), (3, 2, None)]) + sage: G.add_edges([(0, 0, None), (1, 1, None), (2, 2, None), + ....: (2, 3, 1), (2, 3, 2), (3, 2, None)]) sage: G.edges(sort=True, labels=False) [(0, 0), (1, 1), (2, 2), (2, 3), (2, 3), (3, 2)] sage: H = G.to_simple() @@ -18850,9 +18893,9 @@ def cartesian_product(self, other): Cartesian product of digraphs:: sage: P = DiGraph([(0, 1)]) - sage: B = digraphs.DeBruijn(['a', 'b'], 2) - sage: Q = P.cartesian_product(B) - sage: Q.edges(sort=True, labels=None) + sage: B = digraphs.DeBruijn(['a', 'b'], 2) # optional - sage.combinat + sage: Q = P.cartesian_product(B) # optional - sage.combinat + sage: Q.edges(sort=True, labels=None) # optional - sage.combinat [((0, 'aa'), (0, 'aa')), ((0, 'aa'), (0, 'ab')), ((0, 'aa'), (1, 'aa')), ((0, 'ab'), (0, 'ba')), ((0, 'ab'), (0, 'bb')), ((0, 'ab'), (1, 'ab')), @@ -18863,10 +18906,10 @@ def cartesian_product(self, other): ((1, 'ab'), (1, 'ba')), ((1, 'ab'), (1, 'bb')), ((1, 'ba'), (1, 'aa')), ((1, 'ba'), (1, 'ab')), ((1, 'bb'), (1, 'ba')), ((1, 'bb'), (1, 'bb'))] - sage: Q.strongly_connected_components_digraph().num_verts() + sage: Q.strongly_connected_components_digraph().num_verts() # optional - sage.combinat 2 - sage: V = Q.strongly_connected_component_containing_vertex((0, 'aa')) - sage: B.is_isomorphic(Q.subgraph(V)) + sage: V = Q.strongly_connected_component_containing_vertex((0, 'aa')) # optional - sage.combinat + sage: B.is_isomorphic(Q.subgraph(V)) # optional - sage.combinat True """ self._scream_if_not_simple(allow_loops=True) @@ -19101,13 +19144,13 @@ def strong_product(self, other): Counting the edges (see :trac:`13699`):: - sage: g = graphs.RandomGNP(5, .5) - sage: gn,gm = g.order(), g.size() - sage: h = graphs.RandomGNP(5, .5) - sage: hn,hm = h.order(), h.size() - sage: product_size = g.strong_product(h).size() - sage: expected = gm * hn + hm * gn + 2 * gm * hm - sage: product_size == expected + sage: g = graphs.RandomGNP(5, .5) # optional - networkx + sage: gn,gm = g.order(), g.size() # optional - networkx + sage: h = graphs.RandomGNP(5, .5) # optional - networkx + sage: hn,hm = h.order(), h.size() # optional - networkx + sage: product_size = g.strong_product(h).size() # optional - networkx + sage: expected = gm * hn + hm * gn + 2 * gm * hm # optional - networkx + sage: product_size == expected # optional - networkx True """ self._scream_if_not_simple(allow_loops=True) @@ -19495,8 +19538,8 @@ def latex_options(self): sage: opts = g.latex_options() sage: opts LaTeX options for Petersen graph: {} - sage: opts.set_option('tkz_style', 'Classic') - sage: opts + sage: opts.set_option('tkz_style', 'Classic') # optional - sage.plot + sage: opts # optional - sage.plot LaTeX options for Petersen graph: {'tkz_style': 'Classic'} """ if self._latex_opts is None: @@ -19524,9 +19567,9 @@ def set_latex_options(self, **kwds): EXAMPLES:: sage: g = graphs.PetersenGraph() - sage: g.set_latex_options(tkz_style='Welsh') - sage: opts = g.latex_options() - sage: opts.get_option('tkz_style') + sage: g.set_latex_options(tkz_style='Welsh') # optional - sage.plot + sage: opts = g.latex_options() # optional - sage.plot + sage: opts.get_option('tkz_style') # optional - sage.plot 'Welsh' """ opts = self.latex_options() @@ -19895,9 +19938,10 @@ def layout_forest(self, tree_orientation="down", forest_roots=None, sage: G.plot(pos=p) # random # optional - sage.plot Graphics object consisting of 28 graphics primitives - sage: H = graphs.PathGraph(5) + graphs.PathGraph(5) + graphs.BalancedTree(2,2) - sage: p = H.layout_forest(forest_roots=[14,3]) - sage: H.plot(pos=p) # optional - sage.plot + sage: P5 = graphs.PathGraph(5) + sage: H = P5 + P5 + graphs.BalancedTree(2,2) # optional - networkx + sage: p = H.layout_forest(forest_roots=[14,3]) # optional - networkx + sage: H.plot(pos=p) # optional - networkx sage.plot Graphics object consisting of 32 graphics primitives TESTS:: @@ -19967,16 +20011,16 @@ def layout_tree(self, tree_orientation="down", tree_root=None, sage: G.plot(layout="tree", tree_orientation="right") # optional - sage.plot Graphics object consisting of 160 graphics primitives - sage: T = graphs.RandomLobster(25, 0.3, 0.3) - sage: T.show(layout='tree', tree_orientation='up') # optional - sage.plot + sage: T = graphs.RandomLobster(25, 0.3, 0.3) # optional - networkx + sage: T.show(layout='tree', tree_orientation='up') # optional - networkx sage.plot sage: G = graphs.HoffmanSingletonGraph() sage: T = Graph() sage: T.add_edges(G.min_spanning_tree(starting_vertex=0)) sage: T.show(layout='tree', tree_root=0) # optional - sage.plot - sage: G = graphs.BalancedTree(2, 2) - sage: G.layout_tree(tree_root=0) + sage: G = graphs.BalancedTree(2, 2) # optional - networkx + sage: G.layout_tree(tree_root=0) # optional - networkx {0: [1.5, 0], 1: [2.5, -1], 2: [0.5, -1], @@ -19985,8 +20029,8 @@ def layout_tree(self, tree_orientation="down", tree_root=None, 5: [1.0, -2], 6: [0.0, -2]} - sage: G = graphs.BalancedTree(2, 4) - sage: G.plot(layout="tree", tree_root=0, tree_orientation="up") # optional - sage.plot + sage: G = graphs.BalancedTree(2, 4) # optional - networkx + sage: G.plot(layout="tree", tree_root=0, tree_orientation="up") # optional - networkx sage.plot Graphics object consisting of 62 graphics primitives Using the embedding when it exists:: @@ -20009,8 +20053,8 @@ def layout_tree(self, tree_orientation="down", tree_root=None, TESTS:: - sage: G = graphs.BalancedTree(2, 2) - sage: G.layout_tree(tree_root=0, tree_orientation='left') + sage: G = graphs.BalancedTree(2, 2) # optional - networkx + sage: G.layout_tree(tree_root=0, tree_orientation='left') # optional - networkx {0: [0, 1.5], 1: [-1, 2.5], 2: [-1, 0.5], @@ -20192,8 +20236,8 @@ def layout_graphviz(self, dim=2, prog='dot', **options): Graphics object consisting of 29 graphics primitives sage: g.plot(layout="graphviz", prog="fdp") # optional - dot2tex graphviz Graphics object consisting of 29 graphics primitives - sage: g = graphs.BalancedTree(5,2) - sage: g.plot(layout="graphviz", prog="circo") # optional - dot2tex graphviz + sage: g = graphs.BalancedTree(5,2) # optional - networkx + sage: g.plot(layout="graphviz", prog="circo") # optional - dot2tex graphviz networkx Graphics object consisting of 62 graphics primitives .. TODO:: @@ -20505,7 +20549,7 @@ def _rich_repr_(self, display_manager, **kwds): sage: dm.preferences.supplemental_plot 'never' sage: del dm.preferences.supplemental_plot - sage: graphs.RandomGNP(20,0.0) + sage: graphs.RandomGNP(20,0.0) # optional - networkx RandomGNP(20,0.000000000000000): Graph on 20 vertices (use the .plot() method to plot) sage: dm.preferences.supplemental_plot = 'never' """ @@ -20965,10 +21009,10 @@ def plot3d(self, bgcolor=(1, 1, 1), We plot a fairly complicated Cayley graph:: - sage: A5 = AlternatingGroup(5); A5 + sage: A5 = AlternatingGroup(5); A5 # optional - sage.groups Alternating group of order 5!/2 as a permutation group - sage: G = A5.cayley_graph() - sage: G.plot3d(vertex_size=0.03, edge_size=0.01, # long time, optional - sage.plot + sage: G = A5.cayley_graph() # optional - sage.groups + sage: G.plot3d(vertex_size=0.03, edge_size=0.01, # long time, optional - sage.groups sage.plot ....: vertex_colors={(1,1,1): list(G)}, bgcolor=(0,0,0), ....: color_by_label=True, iterations=200) Graphics3d Object @@ -21222,10 +21266,10 @@ def show3d(self, bgcolor=(1, 1, 1), vertex_colors=None, vertex_size=0.06, We plot a fairly complicated Cayley graph:: - sage: A5 = AlternatingGroup(5); A5 + sage: A5 = AlternatingGroup(5); A5 # optional - sage.groups Alternating group of order 5!/2 as a permutation group - sage: G = A5.cayley_graph() - sage: G.show3d(vertex_size=0.03, # long time, optional - sage.plot + sage: G = A5.cayley_graph() # optional - sage.groups + sage: G.show3d(vertex_size=0.03, # long time, optional - sage.groups sage.plot ....: edge_size=0.01, edge_size2=0.02, ....: vertex_colors={(1,1,1): list(G)}, bgcolor=(0,0,0), ....: color_by_label=True, iterations=200) @@ -21691,12 +21735,12 @@ def graphviz_string(self, **options): The following digraph has vertices with newlines in their string representations:: - sage: m1 = matrix(3, 3) - sage: m2 = matrix(3, 3, 1) - sage: m1.set_immutable() - sage: m2.set_immutable() - sage: g = DiGraph({m1: [m2]}) - sage: print(g.graphviz_string()) + sage: m1 = matrix(3, 3) # optional - sage.modules + sage: m2 = matrix(3, 3, 1) # optional - sage.modules + sage: m1.set_immutable() # optional - sage.modules + sage: m2.set_immutable() # optional - sage.modules + sage: g = DiGraph({m1: [m2]}) # optional - sage.modules + sage: print(g.graphviz_string()) # optional - sage.modules digraph { node_0 [label="[0 0 0]\n\ [0 0 0]\n\ @@ -22007,26 +22051,26 @@ def spectrum(self, laplacian=False): EXAMPLES:: sage: P = graphs.PetersenGraph() - sage: P.spectrum() + sage: P.spectrum() # optional - sage.modules [3, 1, 1, 1, 1, 1, -2, -2, -2, -2] - sage: P.spectrum(laplacian=True) + sage: P.spectrum(laplacian=True) # optional - sage.modules [5, 5, 5, 5, 2, 2, 2, 2, 2, 0] sage: D = P.to_directed() sage: D.delete_edge(7, 9) - sage: D.spectrum() + sage: D.spectrum() # optional - sage.modules [2.9032119259..., 1, 1, 1, 1, 0.8060634335..., -1.7092753594..., -2, -2, -2] :: sage: C = graphs.CycleGraph(8) - sage: C.spectrum() + sage: C.spectrum() # optional - sage.modules [2, 1.4142135623..., 1.4142135623..., 0, 0, -1.4142135623..., -1.4142135623..., -2] A digraph may have complex eigenvalues. Previously, the complex parts of graph eigenvalues were being dropped. For a 3-cycle, we have:: sage: T = DiGraph({0: [1], 1: [2], 2: [0]}) - sage: T.spectrum() + sage: T.spectrum() # optional - sage.modules [1, -0.5000000000... + 0.8660254037...*I, -0.5000000000... - 0.8660254037...*I] TESTS: @@ -22040,10 +22084,10 @@ def spectrum(self, laplacian=False): eigenvalues. :: sage: H = graphs.HoffmanSingletonGraph() - sage: evals = H.spectrum() - sage: lap = [7 - x for x in evals] - sage: lap.sort(reverse=True) - sage: lap == H.spectrum(laplacian=True) + sage: evals = H.spectrum() # optional - sage.modules + sage: lap = [7 - x for x in evals] # optional - sage.modules + sage: lap.sort(reverse=True) # optional - sage.modules + sage: lap == H.spectrum(laplacian=True) # optional - sage.modules True """ # Ideally the spectrum should return something like a Factorization object @@ -22089,11 +22133,11 @@ def characteristic_polynomial(self, var='x', laplacian=False): EXAMPLES:: sage: P = graphs.PetersenGraph() - sage: P.characteristic_polynomial() + sage: P.characteristic_polynomial() # optional - sage.modules x^10 - 15*x^8 + 75*x^6 - 24*x^5 - 165*x^4 + 120*x^3 + 120*x^2 - 160*x + 48 - sage: P.charpoly() + sage: P.charpoly() # optional - sage.modules x^10 - 15*x^8 + 75*x^6 - 24*x^5 - 165*x^4 + 120*x^3 + 120*x^2 - 160*x + 48 - sage: P.characteristic_polynomial(laplacian=True) + sage: P.characteristic_polynomial(laplacian=True) # optional - sage.modules x^10 - 30*x^9 + 390*x^8 - 2880*x^7 + 13305*x^6 - 39882*x^5 + 77640*x^4 - 94800*x^3 + 66000*x^2 - 20000*x """ @@ -22129,7 +22173,7 @@ def eigenvectors(self, laplacian=False): EXAMPLES:: sage: P = graphs.PetersenGraph() - sage: P.eigenvectors() + sage: P.eigenvectors() # optional - sage.modules [(3, [ (1, 1, 1, 1, 1, 1, 1, 1, 1, 1) ], 1), (-2, [ @@ -22149,7 +22193,7 @@ def eigenvectors(self, laplacian=False): graph is regular. However, since the output also contains the eigenvalues, the two outputs are slightly different:: - sage: P.eigenvectors(laplacian=True) + sage: P.eigenvectors(laplacian=True) # optional - sage.modules [(0, [ (1, 1, 1, 1, 1, 1, 1, 1, 1, 1) ], 1), (5, [ @@ -22168,7 +22212,7 @@ def eigenvectors(self, laplacian=False): :: sage: C = graphs.CycleGraph(8) - sage: C.eigenvectors() + sage: C.eigenvectors() # optional - sage.modules [(2, [ (1, 1, 1, 1, 1, 1, 1, 1) @@ -22198,7 +22242,7 @@ def eigenvectors(self, laplacian=False): graph eigenvalues were being dropped. For a 3-cycle, we have:: sage: T = DiGraph({0:[1], 1:[2], 2:[0]}) - sage: T.eigenvectors() + sage: T.eigenvectors() # optional - sage.modules [(1, [ (1, 1, 1) @@ -22239,7 +22283,7 @@ def eigenspaces(self, laplacian=False): EXAMPLES:: sage: P = graphs.PetersenGraph() - sage: P.eigenspaces() + sage: P.eigenspaces() # optional - sage.modules [ (3, Vector space of degree 10 and dimension 1 over Rational Field User basis matrix: @@ -22263,7 +22307,7 @@ def eigenspaces(self, laplacian=False): graph is regular. However, since the output also contains the eigenvalues, the two outputs are slightly different:: - sage: P.eigenspaces(laplacian=True) + sage: P.eigenspaces(laplacian=True) # optional - sage.modules [ (0, Vector space of degree 10 and dimension 1 over Rational Field User basis matrix: @@ -22288,7 +22332,7 @@ def eigenspaces(self, laplacian=False): corresponding eigenspace:: sage: C = graphs.CycleGraph(8) - sage: C.eigenspaces() + sage: C.eigenspaces() # optional - sage.modules [ (2, Vector space of degree 8 and dimension 1 over Rational Field User basis matrix: @@ -22311,7 +22355,7 @@ def eigenspaces(self, laplacian=False): we have:: sage: T = DiGraph({0: [1], 1: [2], 2: [0]}) - sage: T.eigenspaces() + sage: T.eigenspaces() # optional - sage.modules [ (1, Vector space of degree 3 and dimension 1 over Rational Field User basis matrix: @@ -22389,7 +22433,7 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input=True, c EXAMPLES:: sage: G = graphs.PathGraph(3) - sage: G.am() + sage: G.am() # optional - sage.modules [0 1 0] [1 0 1] [0 1 0] @@ -22397,7 +22441,7 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input=True, c Relabeling using a dictionary. Note that the dictionary does not define the new label of vertex `0`:: - sage: G.relabel({1:2,2:1}, inplace=False).am() + sage: G.relabel({1:2,2:1}, inplace=False).am() # optional - sage.modules [0 0 1] [0 0 1] [1 1 0] @@ -22407,21 +22451,22 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input=True, c vertices have an image can require some time, and this feature can be disabled (at your own risk):: - sage: G.relabel({1:2,2:1}, inplace=False, complete_partial_function=False).am() + sage: G.relabel({1:2,2:1}, inplace=False, # optional - sage.modules + ....: complete_partial_function=False).am() Traceback (most recent call last): ... KeyError: 0 Relabeling using a list:: - sage: G.relabel([0,2,1], inplace=False).am() + sage: G.relabel([0,2,1], inplace=False).am() # optional - sage.modules [0 0 1] [0 0 1] [1 1 0] Relabeling using an iterable:: - sage: G.relabel(iter((0,2,1)), inplace=False).am() + sage: G.relabel(iter((0,2,1)), inplace=False).am() # optional - sage.modules [0 0 1] [0 0 1] [1 1 0] @@ -22432,7 +22477,7 @@ def relabel(self, perm=None, inplace=True, return_map=False, check_input=True, c sage: from sage.groups.perm_gps.permgroup_named import SymmetricGroup # optional - sage.groups sage: S = SymmetricGroup(3) # optional - sage.groups sage: gamma = S('(1,2)') # optional - sage.groups - sage: G.relabel(gamma, inplace=False).am() # optional - sage.groups + sage: G.relabel(gamma, inplace=False).am() # optional - sage.groups sage.modules [0 0 1] [0 0 1] [1 1 0] @@ -22715,7 +22760,7 @@ def is_equitable(self, partition, quotient_matrix=False): False sage: G.is_equitable([[0,4],[1,3,5,9],[2,6,8,7]]) True - sage: G.is_equitable([[0,4],[1,3,5,9],[2,6,8,7]], quotient_matrix=True) + sage: G.is_equitable([[0,4],[1,3,5,9],[2,6,8,7]], quotient_matrix=True) # optional - sage.modules [1 2 0] [1 0 2] [0 2 1] @@ -23239,13 +23284,13 @@ def is_vertex_transitive(self, partition=None, verbosity=0, sage: G.is_vertex_transitive() False sage: P = graphs.PetersenGraph() - sage: P.is_vertex_transitive() + sage: P.is_vertex_transitive() # optional - sage.groups True sage: D = graphs.DodecahedralGraph() - sage: D.is_vertex_transitive() + sage: D.is_vertex_transitive() # optional - sage.groups True - sage: R = graphs.RandomGNP(2000, .01) - sage: R.is_vertex_transitive() + sage: R = graphs.RandomGNP(2000, .01) # optional - networkx + sage: R.is_vertex_transitive() # optional - networkx False """ if partition is None: @@ -23756,7 +23801,7 @@ class by some canonization function `c`. If `G` and `H` are graphs, sage: P = graphs.PetersenGraph() sage: DP = P.to_directed() - sage: DP.canonical_label(algorithm='sage').adjacency_matrix() + sage: DP.canonical_label(algorithm='sage').adjacency_matrix() # optional - sage.modules [0 0 0 0 0 0 0 1 1 1] [0 0 0 0 1 0 1 0 0 1] [0 0 0 1 0 0 1 0 1 0] @@ -23774,10 +23819,12 @@ class by some canonization function `c`. If `G` and `H` are graphs, sage: G.add_edges( [(0,1,'a'),(1,2,'b'),(2,3,'c'),(3,4,'b'),(4,0,'a')] ) sage: G.canonical_label(edge_labels=True) Graph on 5 vertices - sage: G.canonical_label(edge_labels=True, algorithm="bliss", certificate=True) # optional - bliss + sage: G.canonical_label(edge_labels=True, algorithm="bliss", # optional - bliss + ....: certificate=True) (Graph on 5 vertices, {0: 4, 1: 3, 2: 1, 3: 0, 4: 2}) - sage: G.canonical_label(edge_labels=True, algorithm="sage", certificate=True) + sage: G.canonical_label(edge_labels=True, algorithm="sage", + ....: certificate=True) (Graph on 5 vertices, {0: 4, 1: 3, 2: 0, 3: 1, 4: 2}) Another example where different canonization algorithms give @@ -23785,10 +23832,10 @@ class by some canonization function `c`. If `G` and `H` are graphs, sage: g = Graph({'a': ['b'], 'c': ['d']}) sage: g_sage = g.canonical_label(algorithm='sage') - sage: g_bliss = g.canonical_label(algorithm='bliss') # optional - bliss + sage: g_bliss = g.canonical_label(algorithm='bliss') # optional - bliss sage: g_sage.edges(sort=True, labels=False) [(0, 3), (1, 2)] - sage: g_bliss.edges(sort=True, labels=False) # optional - bliss + sage: g_bliss.edges(sort=True, labels=False) # optional - bliss [(0, 1), (2, 3)] TESTS:: @@ -23796,7 +23843,7 @@ class by some canonization function `c`. If `G` and `H` are graphs, sage: G = Graph([['a', 'b'], [('a', 'b')]]) sage: G.canonical_label(algorithm='sage', certificate=True) (Graph on 2 vertices, {'a': 0, 'b': 1}) - sage: G.canonical_label(algorithm='bliss', certificate=True) # optional - bliss + sage: G.canonical_label(algorithm='bliss', certificate=True) # optional - bliss (Graph on 2 vertices, {'a': 1, 'b': 0}) Check for immutable graphs (:trac:`16602`):: @@ -23978,15 +24025,15 @@ def is_cayley(self, return_group=False, mapping=False, A Petersen Graph is not a Cayley graph:: sage: g = graphs.PetersenGraph() - sage: g.is_cayley() + sage: g.is_cayley() # optional - sage.groups False A Cayley digraph is a Cayley graph:: - sage: C7 = groups.permutation.Cyclic(7) + sage: C7 = groups.permutation.Cyclic(7) # optional - sage.groups sage: S = [(1,2,3,4,5,6,7), (1,3,5,7,2,4,6), (1,5,2,6,3,7,4)] - sage: d = C7.cayley_graph(generators=S) - sage: d.is_cayley() + sage: d = C7.cayley_graph(generators=S) # optional - sage.groups + sage: d.is_cayley() # optional - sage.groups True Graphs with loops and multiedges will have identity and repeated @@ -24260,7 +24307,7 @@ def katz_matrix(self, alpha, nonedgesonly=False, vertices=None): We find the Katz matrix of an undirected 4-cycle. :: sage: G = graphs.CycleGraph(4) - sage: G.katz_matrix(1/20) + sage: G.katz_matrix(1/20) # optional - sage.modules [1/198 5/99 1/198 5/99] [ 5/99 1/198 5/99 1/198] [1/198 5/99 1/198 5/99] @@ -24269,7 +24316,7 @@ def katz_matrix(self, alpha, nonedgesonly=False, vertices=None): We find the Katz matrix of an undirected 4-cycle with all entries other than those which correspond to non-edges zeroed out. :: - sage: G.katz_matrix(1/20, True) + sage: G.katz_matrix(1/20, True) # optional - sage.modules [ 0 0 1/198 0] [ 0 0 0 1/198] [1/198 0 0 0] @@ -24281,7 +24328,7 @@ def katz_matrix(self, alpha, nonedgesonly=False, vertices=None): We find the Katz matrix in a fan on 6 vertices. :: sage: H = Graph([(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(1,2),(2,3),(3,4),(4,5)]) - sage: H.katz_matrix(1/10) + sage: H.katz_matrix(1/10) # optional - sage.modules [ 169/2256 545/4512 25/188 605/4512 25/188 545/4512 485/4512] [ 545/4512 7081/297792 4355/37224 229/9024 595/37224 4073/297792 109/9024] [ 25/188 4355/37224 172/4653 45/376 125/4653 595/37224 5/376] @@ -24297,22 +24344,22 @@ def katz_matrix(self, alpha, nonedgesonly=False, vertices=None): TESTS:: - sage: (graphs.CompleteGraph(4)).katz_matrix(1/4) + sage: (graphs.CompleteGraph(4)).katz_matrix(1/4) # optional - sage.modules [3/5 4/5 4/5 4/5] [4/5 3/5 4/5 4/5] [4/5 4/5 3/5 4/5] [4/5 4/5 4/5 3/5] - sage: (graphs.CompleteGraph(4)).katz_matrix(1/4, nonedgesonly=True) + sage: (graphs.CompleteGraph(4)).katz_matrix(1/4, nonedgesonly=True) # optional - sage.modules [0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0] - sage: (graphs.PathGraph(4)).katz_matrix(1/4, nonedgesonly=False) + sage: (graphs.PathGraph(4)).katz_matrix(1/4, nonedgesonly=False) # optional - sage.modules [15/209 60/209 16/209 4/209] [60/209 31/209 64/209 16/209] [16/209 64/209 31/209 60/209] [ 4/209 16/209 60/209 15/209] - sage: (graphs.PathGraph(4)).katz_matrix(1/4, nonedgesonly=True) + sage: (graphs.PathGraph(4)).katz_matrix(1/4, nonedgesonly=True) # optional - sage.modules [ 0 0 16/209 4/209] [ 0 0 0 16/209] [16/209 0 0 0] @@ -24377,7 +24424,7 @@ def katz_centrality(self, alpha, u=None): all 4 vertices have the same centrality) :: sage: G = graphs.CycleGraph(4) - sage: G.katz_centrality(1/20) + sage: G.katz_centrality(1/20) # optional - sage.modules {0: 1/9, 1: 1/9, 2: 1/9, 3: 1/9} Note that in the below example the nodes having indegree `0` also have @@ -24386,7 +24433,7 @@ def katz_centrality(self, alpha, u=None): sage: G = DiGraph({1: [10], 2:[10,11], 3:[10,11], 4:[], 5:[11, 4], 6:[11], ....: 7:[10,11], 8:[10,11], 9:[10], 10:[11, 5, 8], 11:[6]}) - sage: G.katz_centrality(.85) # rel tol 1e-14 + sage: G.katz_centrality(.85) # rel tol 1e-14 # optional - sage.modules {1: 0.000000000000000, 2: 0.000000000000000, 3: 0.000000000000000, @@ -24407,15 +24454,15 @@ def katz_centrality(self, alpha, u=None): TESTS:: - sage: graphs.PathGraph(3).katz_centrality(1/20) + sage: graphs.PathGraph(3).katz_centrality(1/20) # optional - sage.modules {0: 11/199, 1: 21/199, 2: 11/199} - sage: graphs.PathGraph(4).katz_centrality(1/20) + sage: graphs.PathGraph(4).katz_centrality(1/20) # optional - sage.modules {0: 21/379, 1: 41/379, 2: 41/379, 3: 21/379} - sage: graphs.PathGraph(3).katz_centrality(1/20,2) + sage: graphs.PathGraph(3).katz_centrality(1/20,2) # optional - sage.modules 11/199 - sage: graphs.PathGraph(4).katz_centrality(1/20,3) + sage: graphs.PathGraph(4).katz_centrality(1/20,3) # optional - sage.modules 21/379 - sage: (graphs.PathGraph(3) + graphs.PathGraph(4)).katz_centrality(1/20) + sage: (graphs.PathGraph(3) + graphs.PathGraph(4)).katz_centrality(1/20) # optional - sage.modules {0: 11/199, 1: 21/199, 2: 11/199, 3: 21/379, 4: 41/379, 5: 41/379, 6: 21/379} """ @@ -24466,29 +24513,29 @@ def edge_polytope(self, backend=None): The EP of a `4`-cycle is a square:: sage: G = graphs.CycleGraph(4) - sage: P = G.edge_polytope(); P + sage: P = G.edge_polytope(); P # optional - sage.geometry.polyhedron A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 4 vertices The EP of a complete graph on `4` vertices is cross polytope:: sage: G = graphs.CompleteGraph(4) - sage: P = G.edge_polytope(); P + sage: P = G.edge_polytope(); P # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 6 vertices - sage: P.is_combinatorially_isomorphic(polytopes.cross_polytope(3)) + sage: P.is_combinatorially_isomorphic(polytopes.cross_polytope(3)) # optional - sage.geometry.polyhedron True The EP of a graph is isomorphic to the subdirect sum of its connected components EPs:: sage: n = randint(3, 6) - sage: G1 = graphs.RandomGNP(n, 0.2) + sage: G1 = graphs.RandomGNP(n, 0.2) # optional - networkx sage: n = randint(3, 6) - sage: G2 = graphs.RandomGNP(n, 0.2) - sage: G = G1.disjoint_union(G2) - sage: P = G.edge_polytope() - sage: P1 = G1.edge_polytope() - sage: P2 = G2.edge_polytope() - sage: P.is_combinatorially_isomorphic(P1.subdirect_sum(P2)) + sage: G2 = graphs.RandomGNP(n, 0.2) # optional - networkx + sage: G = G1.disjoint_union(G2) # optional - networkx + sage: P = G.edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P1 = G1.edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P2 = G2.edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P.is_combinatorially_isomorphic(P1.subdirect_sum(P2)) # optional - networkx sage.geometry.polyhedron True All trees on `n` vertices have isomorphic EPs:: @@ -24496,9 +24543,9 @@ def edge_polytope(self, backend=None): sage: n = randint(4, 10) sage: G1 = graphs.RandomTree(n) sage: G2 = graphs.RandomTree(n) - sage: P1 = G1.edge_polytope() - sage: P2 = G2.edge_polytope() - sage: P1.is_combinatorially_isomorphic(P2) + sage: P1 = G1.edge_polytope() # optional - sage.geometry.polyhedron + sage: P2 = G2.edge_polytope() # optional - sage.geometry.polyhedron + sage: P1.is_combinatorially_isomorphic(P2) # optional - sage.geometry.polyhedron True However, there are still many different EPs:: @@ -24506,14 +24553,14 @@ def edge_polytope(self, backend=None): sage: len(list(graphs(5))) 34 sage: polys = [] - sage: for G in graphs(5): + sage: for G in graphs(5): # optional - sage.geometry.polyhedron ....: P = G.edge_polytope() ....: for P1 in polys: ....: if P.is_combinatorially_isomorphic(P1): ....: break ....: else: ....: polys.append(P) - sage: len(polys) + sage: len(polys) # optional - sage.geometry.polyhedron 19 TESTS: @@ -24521,7 +24568,7 @@ def edge_polytope(self, backend=None): Obtain the EP with unsortable vertices:: sage: G = Graph([[1, (1, 2)]]) - sage: G.edge_polytope() + sage: G.edge_polytope() # optional - sage.geometry.polyhedron A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex """ from sage.matrix.special import identity_matrix @@ -24552,17 +24599,17 @@ def symmetric_edge_polytope(self, backend=None): The SEP of a `4`-cycle is a cube:: sage: G = graphs.CycleGraph(4) - sage: P = G.symmetric_edge_polytope(); P + sage: P = G.symmetric_edge_polytope(); P # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 8 vertices - sage: P.is_combinatorially_isomorphic(polytopes.cube()) + sage: P.is_combinatorially_isomorphic(polytopes.cube()) # optional - sage.geometry.polyhedron True The SEP of a complete graph on `4` vertices is a cuboctahedron:: sage: G = graphs.CompleteGraph(4) - sage: P = G.symmetric_edge_polytope(); P + sage: P = G.symmetric_edge_polytope(); P # optional - sage.geometry.polyhedron A 3-dimensional polyhedron in ZZ^4 defined as the convex hull of 12 vertices - sage: P.is_combinatorially_isomorphic(polytopes.cuboctahedron()) + sage: P.is_combinatorially_isomorphic(polytopes.cuboctahedron()) # optional - sage.geometry.polyhedron True The SEP of a graph with edges on `n` vertices has dimension `n` @@ -24570,26 +24617,26 @@ def symmetric_edge_polytope(self, backend=None): sage: n = randint(5, 12) sage: G = Graph() - sage: while not G.num_edges(): + sage: while not G.num_edges(): # optional - networkx ....: G = graphs.RandomGNP(n, 0.2) - sage: P = G.symmetric_edge_polytope() - sage: P.ambient_dim() == n + sage: P = G.symmetric_edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P.ambient_dim() == n # optional - networkx sage.geometry.polyhedron True - sage: P.dim() == n - G.connected_components_number() + sage: P.dim() == n - G.connected_components_number() # optional - networkx sage.geometry.polyhedron True The SEP of a graph is isomorphic to the subdirect sum of its connected components SEP's:: sage: n = randint(3, 6) - sage: G1 = graphs.RandomGNP(n, 0.2) + sage: G1 = graphs.RandomGNP(n, 0.2) # optional - networkx sage: n = randint(3, 6) - sage: G2 = graphs.RandomGNP(n, 0.2) - sage: G = G1.disjoint_union(G2) - sage: P = G.symmetric_edge_polytope() - sage: P1 = G1.symmetric_edge_polytope() - sage: P2 = G2.symmetric_edge_polytope() - sage: P.is_combinatorially_isomorphic(P1.subdirect_sum(P2)) + sage: G2 = graphs.RandomGNP(n, 0.2) # optional - networkx + sage: G = G1.disjoint_union(G2) # optional - networkx + sage: P = G.symmetric_edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P1 = G1.symmetric_edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P2 = G2.symmetric_edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: P.is_combinatorially_isomorphic(P1.subdirect_sum(P2)) # optional - networkx sage.geometry.polyhedron True All trees on `n` vertices have isomorphic SEPs:: @@ -24597,9 +24644,9 @@ def symmetric_edge_polytope(self, backend=None): sage: n = randint(4, 10) sage: G1 = graphs.RandomTree(n) sage: G2 = graphs.RandomTree(n) - sage: P1 = G1.symmetric_edge_polytope() - sage: P2 = G2.symmetric_edge_polytope() - sage: P1.is_combinatorially_isomorphic(P2) + sage: P1 = G1.symmetric_edge_polytope() # optional - sage.geometry.polyhedron + sage: P2 = G2.symmetric_edge_polytope() # optional - sage.geometry.polyhedron + sage: P1.is_combinatorially_isomorphic(P2) # optional - sage.geometry.polyhedron True However, there are still many different SEPs:: @@ -24607,7 +24654,7 @@ def symmetric_edge_polytope(self, backend=None): sage: len(list(graphs(5))) 34 sage: polys = [] - sage: for G in graphs(5): + sage: for G in graphs(5): # optional - sage.geometry.polyhedron ....: P = G.symmetric_edge_polytope() ....: for P1 in polys: ....: if P.is_combinatorially_isomorphic(P1): @@ -24626,24 +24673,24 @@ def symmetric_edge_polytope(self, backend=None): sage: G2.add_edges([[0, 7], [7, 3]]) sage: G1.is_isomorphic(G2) False - sage: P1 = G1.symmetric_edge_polytope() - sage: P2 = G2.symmetric_edge_polytope() - sage: P1.is_combinatorially_isomorphic(P2) + sage: P1 = G1.symmetric_edge_polytope() # optional - sage.geometry.polyhedron + sage: P2 = G2.symmetric_edge_polytope() # optional - sage.geometry.polyhedron + sage: P1.is_combinatorially_isomorphic(P2) # optional - sage.geometry.polyhedron True Apparently, glueing two graphs together on a vertex gives isomorphic SEPs:: sage: n = randint(3, 7) - sage: g1 = graphs.RandomGNP(n, 0.2) - sage: g2 = graphs.RandomGNP(n, 0.2) - sage: G = g1.disjoint_union(g2) - sage: H = copy(G) - sage: G.merge_vertices(((0, randrange(n)), (1, randrange(n)))) - sage: H.merge_vertices(((0, randrange(n)), (1, randrange(n)))) - sage: PG = G.symmetric_edge_polytope() - sage: PH = H.symmetric_edge_polytope() - sage: PG.is_combinatorially_isomorphic(PH) + sage: g1 = graphs.RandomGNP(n, 0.2) # optional - networkx + sage: g2 = graphs.RandomGNP(n, 0.2) # optional - networkx + sage: G = g1.disjoint_union(g2) # optional - networkx + sage: H = copy(G) # optional - networkx + sage: G.merge_vertices(((0, randrange(n)), (1, randrange(n)))) # optional - networkx + sage: H.merge_vertices(((0, randrange(n)), (1, randrange(n)))) # optional - networkx + sage: PG = G.symmetric_edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: PH = H.symmetric_edge_polytope() # optional - networkx sage.geometry.polyhedron + sage: PG.is_combinatorially_isomorphic(PH) # optional - networkx sage.geometry.polyhedron True TESTS: @@ -24651,7 +24698,7 @@ def symmetric_edge_polytope(self, backend=None): Obtain the SEP with unsortable vertices:: sage: G = Graph([[1, (1, 2)]]) - sage: G.symmetric_edge_polytope() + sage: G.symmetric_edge_polytope() # optional - sage.geometry.polyhedron A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices """ from itertools import chain diff --git a/src/sage/graphs/generic_graph_pyx.pyx b/src/sage/graphs/generic_graph_pyx.pyx index 89514e5ecbc..520ea4283e2 100644 --- a/src/sage/graphs/generic_graph_pyx.pyx +++ b/src/sage/graphs/generic_graph_pyx.pyx @@ -660,7 +660,7 @@ cdef class SubgraphSearch: computations with it:: sage: from sage.graphs.generic_graph_pyx import SubgraphSearch - sage: SubgraphSearch(Graph(5), Graph(1)) + sage: SubgraphSearch(Graph(5), Graph(1)) # optional - sage.modules Traceback (most recent call last): ... ValueError: Searched graph should have at least 2 vertices. From b47a16ca1a07fba06111ad16505d367cdd7fe34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 4 Jun 2023 09:49:55 +0200 Subject: [PATCH 32/56] cython-lint for imports in rings (mostly in padics) --- src/sage/rings/finite_rings/element_ntl_gf2e.pyx | 7 ++++--- src/sage/rings/padics/local_generic_element.pyx | 2 +- src/sage/rings/padics/morphism.pyx | 12 ++++-------- src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx | 5 ----- src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx | 12 +++--------- src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx | 13 +++---------- src/sage/rings/padics/padic_ext_element.pyx | 8 +++----- src/sage/rings/padics/padic_generic_element.pyx | 8 +++----- src/sage/rings/padics/pow_computer_ext.pyx | 9 +++------ src/sage/rings/padics/pow_computer_relative.pyx | 14 ++++---------- src/sage/rings/polynomial/laurent_polynomial.pyx | 5 +---- .../rings/polynomial/laurent_polynomial_mpair.pyx | 6 +----- .../rings/polynomial/polynomial_zmod_flint.pyx | 7 +++---- 13 files changed, 33 insertions(+), 75 deletions(-) diff --git a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx index f6fa95241dc..55fcf329b6c 100644 --- a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx @@ -15,15 +15,15 @@ AUTHORS: - Martin Albrecht (2007-10) """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 Martin Albrecht # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from cysignals.memory cimport check_malloc, sig_free from cysignals.signals cimport sig_on, sig_off @@ -372,6 +372,7 @@ cdef class Cache_ntl_gf2e(Cache_base): if isinstance(e, Gen): sig_on() t = (e).g + sig_off() if typ(t) == t_FFELT: t = FF_to_FpXQ(t) else: diff --git a/src/sage/rings/padics/local_generic_element.pyx b/src/sage/rings/padics/local_generic_element.pyx index 8df39a52363..5a757de50bb 100644 --- a/src/sage/rings/padics/local_generic_element.pyx +++ b/src/sage/rings/padics/local_generic_element.pyx @@ -23,7 +23,7 @@ AUTHORS: # **************************************************************************** from sage.rings.infinity import infinity -from sage.structure.element cimport ModuleElement, RingElement, CommutativeRingElement +from sage.structure.element cimport CommutativeRingElement from sage.structure.element import coerce_binop from itertools import islice diff --git a/src/sage/rings/padics/morphism.pyx b/src/sage/rings/padics/morphism.pyx index a24fea29ea3..73ae1d53471 100644 --- a/src/sage/rings/padics/morphism.pyx +++ b/src/sage/rings/padics/morphism.pyx @@ -1,31 +1,27 @@ """ Frobenius endomorphisms on p-adic fields """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013 Xavier Caruso # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.rings.integer cimport Integer from sage.rings.infinity import Infinity -from sage.rings.ring import CommutativeRing from sage.categories.homset import Hom from sage.structure.element cimport Element from sage.structure.richcmp cimport (richcmp, rich_to_bool, - richcmp_not_equal) + richcmp_not_equal) from sage.rings.morphism cimport RingHomomorphism from .padic_generic import pAdicGeneric -from sage.categories.morphism cimport Morphism - cdef class FrobeniusEndomorphism_padics(RingHomomorphism): """ diff --git a/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx index ce11925e3a1..979f9d54ba5 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CA_element.pyx @@ -175,7 +175,6 @@ from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class -from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext from sage.rings.padics.padic_generic_element cimport pAdicGenericElement from sage.libs.pari.all import pari_gen from sage.interfaces.abc import GpElement @@ -184,10 +183,6 @@ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing from sage.rings.padics.padic_ext_element cimport pAdicExtElement from sage.rings.padics.precision_error import PrecisionError -from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX -from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX_small_Eis -from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX_big_Eis - cdef object infinity from sage.rings.infinity import infinity diff --git a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx index 82982a40045..e3bd45e9037 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx @@ -176,8 +176,7 @@ AUTHORS: - Julian Rueth (2014-05-09): enable caching through ``_cache_key`` """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 David Roe # William Stein # 2014 Julian Rueth @@ -186,8 +185,8 @@ AUTHORS: # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from cysignals.signals cimport sig_on, sig_off from sage.ext.stdsage cimport PY_NEW @@ -201,7 +200,6 @@ from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class -from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext from sage.rings.padics.padic_generic_element cimport pAdicGenericElement from sage.libs.pari.all import pari_gen from sage.interfaces.abc import GpElement @@ -209,13 +207,9 @@ from sage.rings.finite_rings.integer_mod import is_IntegerMod from sage.rings.padics.padic_ext_element cimport pAdicExtElement from sage.rings.padics.precision_error import PrecisionError -from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX_small_Eis from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX_big_Eis from sage.rings.finite_rings.integer_mod_ring import IntegerModRing -from sage.rings.padics.unramified_extension_generic import UnramifiedExtensionGeneric - -from sage.rings.real_double cimport RealDoubleElement cdef object infinity from sage.rings.infinity import infinity diff --git a/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx index 2f8db3f78f6..9dec3affd53 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_FM_element.pyx @@ -113,8 +113,7 @@ AUTHORS: - David Roe (2008-01-01) initial version """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 David Roe # William Stein # @@ -122,18 +121,14 @@ AUTHORS: # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from cysignals.signals cimport sig_on, sig_off include "sage/libs/ntl/decl.pxi" from sage.structure.richcmp cimport rich_to_bool -from sage.structure.element cimport Element -from sage.rings.padics.padic_printing cimport pAdicPrinter_class -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.rings.integer_ring import ZZ from sage.rings.integer cimport Integer from sage.rings.padics.padic_generic_element cimport pAdicGenericElement from sage.rings.padics.padic_ext_element cimport pAdicExtElement @@ -144,13 +139,11 @@ from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class -from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext from sage.rings.rational cimport Rational from sage.libs.pari.all import pari_gen from sage.interfaces.abc import GpElement from sage.rings.finite_rings.integer_mod import is_IntegerMod from sage.rings.finite_rings.integer_mod_ring import IntegerModRing -from sage.rings.padics.pow_computer_ext cimport PowComputer_ZZ_pX_FM_Eis cdef class pAdicZZpXFMElement(pAdicZZpXElement): diff --git a/src/sage/rings/padics/padic_ext_element.pyx b/src/sage/rings/padics/padic_ext_element.pyx index 2728506f709..94a7d93c727 100644 --- a/src/sage/rings/padics/padic_ext_element.pyx +++ b/src/sage/rings/padics/padic_ext_element.pyx @@ -16,8 +16,7 @@ AUTHORS: - Julian Rueth (2012-10-18): added residue """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007-2010 David Roe # 2012 Julian Rueth # @@ -25,11 +24,10 @@ AUTHORS: # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.rings.padics.pow_computer cimport PowComputer_class -from sage.rings.integer import Integer from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p cdef class pAdicExtElement(pAdicGenericElement): diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx index 1315c6f9a74..a1beaa5110a 100644 --- a/src/sage/rings/padics/padic_generic_element.pyx +++ b/src/sage/rings/padics/padic_generic_element.pyx @@ -14,8 +14,7 @@ AUTHORS: - Julian Rueth: fixes for exp() and log(), implemented gcd, xgcd """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007-2013 David Roe # 2007 William Stein # 2013-2014 Julian Rueth @@ -24,11 +23,10 @@ AUTHORS: # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.ext.stdsage cimport PY_NEW -from cysignals.memory cimport sig_malloc, sig_free cimport sage.rings.padics.local_generic_element from sage.libs.gmp.mpz cimport mpz_set_si diff --git a/src/sage/rings/padics/pow_computer_ext.pyx b/src/sage/rings/padics/pow_computer_ext.pyx index fe60e6bde33..060e22719df 100644 --- a/src/sage/rings/padics/pow_computer_ext.pyx +++ b/src/sage/rings/padics/pow_computer_ext.pyx @@ -42,8 +42,7 @@ AUTHORS: - David Roe (2008-01-01) initial version """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 David Roe # William Stein # @@ -51,8 +50,8 @@ AUTHORS: # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from cpython.list cimport * from cpython.dict cimport * @@ -61,9 +60,7 @@ from cysignals.signals cimport sig_on, sig_off include "sage/libs/ntl/decl.pxi" -import weakref from sage.misc.misc import cputime -from sage.rings.infinity import infinity from sage.libs.gmp.mpz cimport * from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_factory from sage.libs.ntl.ntl_ZZ_pContext import ZZ_pContext_factory diff --git a/src/sage/rings/padics/pow_computer_relative.pyx b/src/sage/rings/padics/pow_computer_relative.pyx index 29cee93968c..39051a681de 100644 --- a/src/sage/rings/padics/pow_computer_relative.pyx +++ b/src/sage/rings/padics/pow_computer_relative.pyx @@ -17,7 +17,7 @@ AUTHORS: - David Roe, Julian Rüth (2017-06-11): initial version """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2017 David Roe # 2017 Julian Rüth # @@ -25,19 +25,13 @@ AUTHORS: # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** -from cysignals.memory cimport sig_malloc, sig_free -from cysignals.signals cimport sig_on, sig_off - -from sage.libs.gmp.mpz cimport mpz_init, mpz_clear, mpz_pow_ui - -from cpython.object cimport Py_EQ, Py_NE from sage.rings.integer cimport Integer -from sage.rings.integer_ring import ZZ from sage.misc.cachefunc import cached_method + cdef class PowComputer_relative(PowComputer_class): r""" Base class for a ``PowComputer`` for use in `p`-adics implemented by Sage diff --git a/src/sage/rings/polynomial/laurent_polynomial.pyx b/src/sage/rings/polynomial/laurent_polynomial.pyx index 8a4c88045e5..1634e061d28 100644 --- a/src/sage/rings/polynomial/laurent_polynomial.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial.pyx @@ -1,7 +1,6 @@ r""" Elements of Laurent polynomial rings """ - # **************************************************************************** # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -9,17 +8,15 @@ Elements of Laurent polynomial rings # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - -from sage.rings.integer cimport Integer from sage.categories.map cimport Map from sage.structure.element import coerce_binop, parent from sage.structure.factorization import Factorization from sage.misc.derivative import multi_derivative -from sage.rings.polynomial.polydict cimport monomial_exponent from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.polynomial.polynomial_ring import is_PolynomialRing from sage.structure.richcmp cimport richcmp, rich_to_bool + cdef class LaurentPolynomial(CommutativeAlgebraElement): """ Base class for Laurent polynomials. diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index 4597219b678..b442c073250 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -1,7 +1,6 @@ r""" Elements of multivariate Laurent polynomial rings """ - # **************************************************************************** # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -11,14 +10,11 @@ Elements of multivariate Laurent polynomial rings # **************************************************************************** from sage.rings.integer cimport Integer -from sage.categories.map cimport Map from sage.structure.element cimport CommutativeAlgebraElement, Element, ModuleElement, RingElement -from sage.structure.element import is_Element, coerce_binop, parent +from sage.structure.element import coerce_binop, parent from sage.structure.factorization import Factorization from sage.misc.derivative import multi_derivative from sage.rings.polynomial.polydict cimport monomial_exponent -from sage.rings.polynomial.polynomial_element import Polynomial -from sage.structure.richcmp cimport richcmp, rich_to_bool from sage.matrix.matrix0 cimport Matrix diff --git a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx index 6f30bf046d5..253ab949fcc 100644 --- a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx @@ -30,17 +30,16 @@ AUTHORS: - Burcin Erocal (2008-11) initial implementation - Martin Albrecht (2009-01) another initial implementation """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2009-2010 Burcin Erocal # Copyright (C) 2009 Martin Albrecht # # Distributed under the terms of the GNU General Public License (GPL), # version 2 or any later version. The full text of the GPL is available at: -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.libs.ntl.ntl_lzz_pX import ntl_zz_pX -from sage.structure.factorization import Factorization from sage.structure.element cimport parent from sage.structure.element import coerce_binop from sage.rings.polynomial.polynomial_integer_dense_flint cimport Polynomial_integer_dense_flint From bcbb8fc31ca5686fdc5acaaef8360c8d6a0dce1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 4 Jun 2023 10:39:58 +0200 Subject: [PATCH 33/56] cython-lint for imports in libs/ --- src/sage/libs/eclib/homspace.pyx | 6 ++--- src/sage/libs/eclib/mwrank.pyx | 2 -- src/sage/libs/gap/element.pyx | 3 --- src/sage/libs/giac/giac.pyx | 2 +- src/sage/libs/lcalc/lcalc_Lfunction.pyx | 10 +++---- .../libs/linbox/linbox_flint_interface.pyx | 12 ++++----- src/sage/libs/mpmath/ext_impl.pyx | 2 +- src/sage/libs/mpmath/ext_libmp.pyx | 3 --- src/sage/libs/mpmath/ext_main.pyx | 2 +- src/sage/libs/ntl/ntl_GF2.pyx | 8 +++--- src/sage/libs/ntl/ntl_GF2E.pyx | 2 +- src/sage/libs/ntl/ntl_GF2X.pyx | 2 -- src/sage/libs/ntl/ntl_ZZ.pyx | 3 +-- src/sage/libs/ntl/ntl_ZZX.pyx | 3 --- src/sage/libs/ntl/ntl_ZZ_p.pyx | 5 ++-- src/sage/libs/ntl/ntl_ZZ_pE.pyx | 6 ----- src/sage/libs/ntl/ntl_ZZ_pEContext.pyx | 4 +-- src/sage/libs/ntl/ntl_ZZ_pEX.pyx | 4 --- src/sage/libs/ntl/ntl_ZZ_pX.pyx | 2 +- src/sage/libs/ntl/ntl_lzz_p.pyx | 1 - src/sage/libs/ntl/ntl_lzz_pX.pyx | 1 - src/sage/libs/pari/convert_flint.pyx | 8 +++--- src/sage/libs/pari/convert_gmp.pyx | 4 +-- src/sage/libs/pari/convert_sage.pyx | 8 +++--- src/sage/libs/singular/function.pyx | 4 +-- src/sage/libs/singular/option.pyx | 8 +++--- src/sage/libs/singular/polynomial.pyx | 2 +- src/sage/libs/singular/ring.pyx | 26 +++++++++---------- src/sage/libs/singular/singular.pyx | 5 ++-- 29 files changed, 53 insertions(+), 95 deletions(-) diff --git a/src/sage/libs/eclib/homspace.pyx b/src/sage/libs/eclib/homspace.pyx index 090fa3b693d..dc52b144328 100644 --- a/src/sage/libs/eclib/homspace.pyx +++ b/src/sage/libs/eclib/homspace.pyx @@ -3,18 +3,16 @@ from cysignals.signals cimport sig_on, sig_off from cython.operator cimport dereference as deref from cython.operator cimport preincrement as inc -from libcpp.map cimport map -from ..eclib cimport vec, svec, mat, smat +from ..eclib cimport svec, mat, smat from .mat cimport MatrixFactory from sage.matrix.matrix_space import MatrixSpace -from sage.matrix.matrix_integer_sparse cimport Matrix_integer_sparse from sage.rings.integer_ring import ZZ -from sage.rings.integer cimport Integer cdef MatrixFactory MF = MatrixFactory() + cdef class ModularSymbols: """ Class of Cremona Modular Symbols of given level and sign (and weight 2). diff --git a/src/sage/libs/eclib/mwrank.pyx b/src/sage/libs/eclib/mwrank.pyx index e3b0b6b0000..11219ddefa6 100644 --- a/src/sage/libs/eclib/mwrank.pyx +++ b/src/sage/libs/eclib/mwrank.pyx @@ -18,9 +18,7 @@ EXAMPLES:: sage: t [[1:2:1]] """ - import os -import sys from cysignals.memory cimport sig_free from cysignals.signals cimport sig_on, sig_off diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index d9b47f19509..27d8098dddf 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -5,7 +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. """ - # **************************************************************************** # Copyright (C) 2012 Volker Braun # @@ -24,8 +23,6 @@ from .libgap import libgap from .util cimport * from .util import GAPError from sage.cpython.string cimport str_to_bytes, char_to_str -from sage.misc.cachefunc import cached_method -from sage.structure.sage_object cimport SageObject from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.real_double import RDF diff --git a/src/sage/libs/giac/giac.pyx b/src/sage/libs/giac/giac.pyx index 69ccf6426e4..a78e2199725 100644 --- a/src/sage/libs/giac/giac.pyx +++ b/src/sage/libs/giac/giac.pyx @@ -151,7 +151,7 @@ import math # sage includes from sage.ext.stdsage cimport PY_NEW -from sage.libs.gmp.mpz cimport mpz_t, mpz_init_set +from sage.libs.gmp.mpz cimport mpz_set from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ diff --git a/src/sage/libs/lcalc/lcalc_Lfunction.pyx b/src/sage/libs/lcalc/lcalc_Lfunction.pyx index a59a2207867..6e9005c502b 100644 --- a/src/sage/libs/lcalc/lcalc_Lfunction.pyx +++ b/src/sage/libs/lcalc/lcalc_Lfunction.pyx @@ -949,17 +949,17 @@ def Lfunction_from_character(chi, type="complex"): OMEGA=1.0/ ( CCC(0,1)**a * (CCC(modulus)).sqrt()/chi.gauss_sum() ) if type == "complex": - dir_coeffs = [CCC(chi(n)) for n in xrange(1, modulus + 1)] + dir_coeffs = [CCC(chi(n)) for n in range(1, modulus + 1)] return Lfunction_C("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues) if type not in ["double", "int"]: raise ValueError("unknown type") if chi.order() != 2: raise ValueError("For non quadratic characters you must use type=\"complex\"") if type == "double": - dir_coeffs = [RRR(chi(n)) for n in xrange(1, modulus + 1)] + dir_coeffs = [RRR(chi(n)) for n in range(1, modulus + 1)] return Lfunction_D("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues) if type == "int": - dir_coeffs = [Integer(chi(n)) for n in xrange(1, modulus + 1)] + dir_coeffs = [Integer(chi(n)) for n in range(1, modulus + 1)] return Lfunction_I("", 1,dir_coeffs, period,Q,OMEGA,[.5],[a/2.],poles,residues) @@ -990,15 +990,13 @@ def Lfunction_from_elliptic_curve(E, number_of_coeffs=10000): True sage: (L.value(0.5, derivative=1) - 0.305999773835200).abs() < 1e-6 True - """ - import sage.libs.lcalc.lcalc_Lfunction Q = RRR(E.conductor()).sqrt() / RRR(2 * pi) poles = [] residues = [] dir_coeffs = E.anlist(number_of_coeffs) dir_coeffs = [RRR(dir_coeffs[i]) / (RRR(i)).sqrt() - for i in xrange(1, number_of_coeffs)] + for i in range(1, number_of_coeffs)] OMEGA = E.root_number() return Lfunction_D("", 2, dir_coeffs, 0, Q, OMEGA, [1], [.5], poles, residues) diff --git a/src/sage/libs/linbox/linbox_flint_interface.pyx b/src/sage/libs/linbox/linbox_flint_interface.pyx index 337cdf65754..415cd473947 100644 --- a/src/sage/libs/linbox/linbox_flint_interface.pyx +++ b/src/sage/libs/linbox/linbox_flint_interface.pyx @@ -21,7 +21,7 @@ and C. Pernet. The functions available are: - ``void linbox_fmpz_mat_det(fmpz_t det, fmpz_mat_t A)``: set ``det`` to the determinant of the square matrix ``A`` """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 Martin Albrecht # Copyright (C) 2008 Clement Pernet # Copyright (C) 2017-2018 Vincent Delecroix @@ -30,15 +30,13 @@ and C. Pernet. The functions available are: # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** -from sage.libs.gmp.types cimport mpz_t, mpz_srcptr, mpz_ptr -from sage.libs.gmp.mpz cimport mpz_set -from sage.libs.flint.types cimport fmpz, fmpz_t +from sage.libs.flint.types cimport fmpz_t from sage.libs.flint.fmpz cimport fmpz_get_mpz, fmpz_set_mpz from sage.libs.flint.fmpz_mat cimport fmpz_mat_entry, fmpz_mat_nrows, fmpz_mat_ncols -from sage.libs.flint.fmpz_poly cimport fmpz_poly_set_coeff_mpz, fmpz_poly_fit_length, _fmpz_poly_set_length, fmpz_poly_one +from sage.libs.flint.fmpz_poly cimport fmpz_poly_set_coeff_mpz, fmpz_poly_fit_length, _fmpz_poly_set_length cimport sage.libs.linbox.givaro as givaro cimport sage.libs.linbox.linbox as linbox diff --git a/src/sage/libs/mpmath/ext_impl.pyx b/src/sage/libs/mpmath/ext_impl.pyx index 2d1382ef6f1..97a9ad39b9e 100644 --- a/src/sage/libs/mpmath/ext_impl.pyx +++ b/src/sage/libs/mpmath/ext_impl.pyx @@ -1898,7 +1898,7 @@ cdef MPF_complex_pow_re(MPF *zre, MPF *zim, MPF *xre, MPF *xim, MPF *y, MPopts o xret = MPF_to_tuple(xre) ximt = MPF_to_tuple(xim) yret = MPF_to_tuple(y) - from mpmath.libmp import mpc_pow_mpf, fzero + from mpmath.libmp import mpc_pow_mpf vr, vi = mpc_pow_mpf((xret, ximt), yret, opts.prec, rndmode_to_python(opts.rounding)) MPF_set_tuple(zre, vr) diff --git a/src/sage/libs/mpmath/ext_libmp.pyx b/src/sage/libs/mpmath/ext_libmp.pyx index 6f4ab6b2914..2a5799e3513 100644 --- a/src/sage/libs/mpmath/ext_libmp.pyx +++ b/src/sage/libs/mpmath/ext_libmp.pyx @@ -4,9 +4,6 @@ Faster versions of some key functions in mpmath.libmp from .ext_impl cimport * from sage.libs.gmp.all cimport * -from sage.rings.integer cimport Integer - -from .ext_impl import exp_fixed, cos_sin_fixed, log_int_fixed # Note: not thread-safe cdef MPF tmp1 diff --git a/src/sage/libs/mpmath/ext_main.pyx b/src/sage/libs/mpmath/ext_main.pyx index e2cb779dd4d..237a6aa0cc3 100644 --- a/src/sage/libs/mpmath/ext_main.pyx +++ b/src/sage/libs/mpmath/ext_main.pyx @@ -480,7 +480,7 @@ cdef class Context: 100 sage: mp.prec = 53 """ - return libmp.prec_to_dps(global_opts.prec) + return prec_to_dps(global_opts.prec) dps = property(_get_dps, _set_dps, doc=_get_dps.__doc__) prec = property(_get_prec, _set_prec, doc=_get_dps.__doc__) diff --git a/src/sage/libs/ntl/ntl_GF2.pyx b/src/sage/libs/ntl/ntl_GF2.pyx index d6ada6cb100..7bbdaa09d05 100644 --- a/src/sage/libs/ntl/ntl_GF2.pyx +++ b/src/sage/libs/ntl/ntl_GF2.pyx @@ -5,7 +5,7 @@ # distutils: extra_link_args = NTL_LIBEXTRA # distutils: language = c++ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2007 Martin Albrecht # # Distributed under the terms of the GNU General Public License (GPL) @@ -17,10 +17,9 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** -from cysignals.signals cimport sig_on, sig_off from sage.ext.cplusplus cimport ccrepr, ccreadstr include 'misc.pxi' @@ -28,7 +27,6 @@ include 'decl.pxi' from cpython.object cimport Py_EQ, Py_NE from sage.rings.integer cimport Integer -from sage.rings.integer_ring cimport IntegerRing_class ############################################################################## # GF2: Bits diff --git a/src/sage/libs/ntl/ntl_GF2E.pyx b/src/sage/libs/ntl/ntl_GF2E.pyx index 54c7eef492a..c78fd6704db 100644 --- a/src/sage/libs/ntl/ntl_GF2E.pyx +++ b/src/sage/libs/ntl/ntl_GF2E.pyx @@ -33,7 +33,7 @@ from .ntl_GF2X cimport ntl_GF2X from .ntl_GF2EContext cimport ntl_GF2EContext_class from .ntl_GF2EContext import ntl_GF2EContext from sage.libs.ntl.ntl_ZZ import unpickle_class_args -from sage.misc.randstate cimport randstate, current_randstate +from sage.misc.randstate cimport current_randstate ############################################################################## diff --git a/src/sage/libs/ntl/ntl_GF2X.pyx b/src/sage/libs/ntl/ntl_GF2X.pyx index d4581467952..787169e6dc7 100644 --- a/src/sage/libs/ntl/ntl_GF2X.pyx +++ b/src/sage/libs/ntl/ntl_GF2X.pyx @@ -21,7 +21,6 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from cysignals.signals cimport sig_on, sig_off from sage.ext.cplusplus cimport ccrepr, ccreadstr include 'misc.pxi' @@ -29,7 +28,6 @@ include 'decl.pxi' from cpython.object cimport Py_EQ, Py_NE from sage.rings.integer cimport Integer -from sage.misc.superseded import deprecation_cython as deprecation from .ntl_ZZ import unpickle_class_value from .ntl_GF2 cimport ntl_GF2 diff --git a/src/sage/libs/ntl/ntl_ZZ.pyx b/src/sage/libs/ntl/ntl_ZZ.pyx index 8786675e6b9..41e14fdcf09 100644 --- a/src/sage/libs/ntl/ntl_ZZ.pyx +++ b/src/sage/libs/ntl/ntl_ZZ.pyx @@ -28,9 +28,8 @@ include 'decl.pxi' from sage.rings.integer cimport Integer from sage.libs.ntl.convert cimport PyLong_to_ZZ, mpz_to_ZZ -from sage.misc.randstate cimport randstate, current_randstate +from sage.misc.randstate cimport current_randstate from cpython.object cimport Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE -from cpython.int cimport PyInt_AS_LONG cdef make_ZZ(ZZ_c* x): diff --git a/src/sage/libs/ntl/ntl_ZZX.pyx b/src/sage/libs/ntl/ntl_ZZX.pyx index e369f7152e4..891a28d0fb1 100644 --- a/src/sage/libs/ntl/ntl_ZZX.pyx +++ b/src/sage/libs/ntl/ntl_ZZX.pyx @@ -32,10 +32,7 @@ from cpython.object cimport Py_EQ, Py_NE from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ from sage.libs.ntl.ntl_ZZ import unpickle_class_value -from sage.rings.integer import Integer from sage.rings.integer_ring import IntegerRing -from sage.rings.integer cimport Integer -from sage.rings.integer_ring cimport IntegerRing_class from sage.arith.power cimport generic_power_pos ZZ = IntegerRing() diff --git a/src/sage/libs/ntl/ntl_ZZ_p.pyx b/src/sage/libs/ntl/ntl_ZZ_p.pyx index b5511abb891..d032d9b81b9 100644 --- a/src/sage/libs/ntl/ntl_ZZ_p.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_p.pyx @@ -17,7 +17,7 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from cysignals.signals cimport sig_on, sig_off @@ -32,7 +32,6 @@ from sage.rings.integer_ring import IntegerRing from sage.rings.integer cimport Integer from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ from sage.rings.rational cimport Rational -from sage.rings.integer_ring cimport IntegerRing_class from sage.libs.ntl.ntl_ZZ import unpickle_class_args from sage.libs.ntl.convert cimport PyLong_to_ZZ, mpz_to_ZZ @@ -40,7 +39,7 @@ from sage.libs.ntl.convert cimport PyLong_to_ZZ, mpz_to_ZZ from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext -from sage.misc.randstate cimport randstate, current_randstate +from sage.misc.randstate cimport current_randstate ZZ_sage = IntegerRing() diff --git a/src/sage/libs/ntl/ntl_ZZ_pE.pyx b/src/sage/libs/ntl/ntl_ZZ_pE.pyx index ed45e34f0be..790d5c59648 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pE.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pE.pyx @@ -28,19 +28,13 @@ include 'decl.pxi' from cpython.object cimport Py_EQ, Py_NE -from sage.rings.integer import Integer from sage.rings.integer_ring import IntegerRing from sage.rings.integer cimport Integer from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p from sage.rings.integer cimport Integer -from sage.rings.integer_ring cimport IntegerRing_class from sage.libs.ntl.convert cimport PyLong_to_ZZ, mpz_to_ZZ -from sage.libs.ntl.ntl_ZZ import unpickle_class_args - -from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class -from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext from sage.libs.ntl.ntl_ZZ_pEContext cimport ntl_ZZ_pEContext_class from sage.libs.ntl.ntl_ZZ_pEContext import ntl_ZZ_pEContext diff --git a/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx b/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx index b6ff3c66b01..fca10d5667f 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx @@ -17,7 +17,7 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** include 'misc.pxi' @@ -25,8 +25,6 @@ include 'decl.pxi' from sage.ext.cplusplus cimport ccrepr from sage.libs.ntl.ntl_ZZ_pX cimport ntl_ZZ_pX -from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext -from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ ZZ_pEContextDict = {} diff --git a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx index d5f10218a77..7d2d4bae905 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx @@ -36,14 +36,10 @@ include 'misc.pxi' include 'decl.pxi' from cpython.object cimport Py_EQ, Py_NE -from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ -from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p from sage.libs.ntl.ntl_ZZ_pE cimport ntl_ZZ_pE -from sage.libs.ntl.ntl_ZZ_pX cimport ntl_ZZ_pX from sage.libs.ntl.ntl_ZZ_pEContext cimport ntl_ZZ_pEContext_class from sage.libs.ntl.ntl_ZZ_pEContext import ntl_ZZ_pEContext from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class -from sage.libs.ntl.ntl_ZZ import unpickle_class_args from sage.arith.power cimport generic_power_pos ############################################################################## diff --git a/src/sage/libs/ntl/ntl_ZZ_pX.pyx b/src/sage/libs/ntl/ntl_ZZ_pX.pyx index 5021846b1e0..a8c0666ebc3 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pX.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pX.pyx @@ -34,7 +34,7 @@ from sage.libs.ntl.ntl_ZZ_p cimport ntl_ZZ_p from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class from sage.libs.ntl.ntl_ZZ_pContext import ntl_ZZ_pContext from sage.libs.ntl.ntl_ZZ import unpickle_class_args -from sage.misc.randstate cimport randstate, current_randstate +from sage.misc.randstate cimport current_randstate from sage.libs.gmp.mpz cimport * diff --git a/src/sage/libs/ntl/ntl_lzz_p.pyx b/src/sage/libs/ntl/ntl_lzz_p.pyx index 983e3056404..161d0782bc2 100644 --- a/src/sage/libs/ntl/ntl_lzz_p.pyx +++ b/src/sage/libs/ntl/ntl_lzz_p.pyx @@ -43,7 +43,6 @@ from cpython.object cimport Py_EQ, Py_NE from sage.rings.integer import Integer from sage.rings.integer_ring import IntegerRing from sage.rings.integer cimport Integer -from sage.rings.integer_ring cimport IntegerRing_class from sage.rings.finite_rings.integer_mod cimport IntegerMod_gmp, IntegerMod_int, IntegerMod_int64 diff --git a/src/sage/libs/ntl/ntl_lzz_pX.pyx b/src/sage/libs/ntl/ntl_lzz_pX.pyx index 98bd0d58658..24b503a9a62 100644 --- a/src/sage/libs/ntl/ntl_lzz_pX.pyx +++ b/src/sage/libs/ntl/ntl_lzz_pX.pyx @@ -34,7 +34,6 @@ from cpython.object cimport Py_EQ, Py_NE from sage.rings.integer import Integer from sage.rings.integer_ring import IntegerRing from sage.rings.integer cimport Integer -from sage.rings.integer_ring cimport IntegerRing_class from sage.rings.finite_rings.integer_mod cimport IntegerMod_gmp, IntegerMod_int, IntegerMod_int64 diff --git a/src/sage/libs/pari/convert_flint.pyx b/src/sage/libs/pari/convert_flint.pyx index 4c4be33ccef..07dd6cfc3dd 100644 --- a/src/sage/libs/pari/convert_flint.pyx +++ b/src/sage/libs/pari/convert_flint.pyx @@ -9,19 +9,19 @@ AUTHORS: generic C-interface in ``Pari`` (:trac:`20241`) """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2016 Luca De Feo # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from cysignals.signals cimport sig_on -from sage.libs.flint.fmpz cimport fmpz_get_mpz, COEFF_IS_MPZ, COEFF_TO_PTR, fmpz_is_one +from sage.libs.flint.fmpz cimport COEFF_IS_MPZ, COEFF_TO_PTR, fmpz_is_one from sage.libs.flint.fmpq cimport fmpq_numref, fmpq_denref from sage.libs.flint.fmpz_mat cimport fmpz_mat_nrows, fmpz_mat_ncols, fmpz_mat_entry from sage.libs.flint.fmpq_mat cimport fmpq_mat_nrows, fmpq_mat_ncols, fmpq_mat_entry diff --git a/src/sage/libs/pari/convert_gmp.pyx b/src/sage/libs/pari/convert_gmp.pyx index a39caa379b4..fcd212a8703 100644 --- a/src/sage/libs/pari/convert_gmp.pyx +++ b/src/sage/libs/pari/convert_gmp.pyx @@ -17,10 +17,10 @@ AUTHORS: # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** -from cysignals.signals cimport sig_on, sig_off +from cysignals.signals cimport sig_on from sage.libs.gmp.all cimport * diff --git a/src/sage/libs/pari/convert_sage.pyx b/src/sage/libs/pari/convert_sage.pyx index 1d1db834f6e..71a1744698e 100644 --- a/src/sage/libs/pari/convert_sage.pyx +++ b/src/sage/libs/pari/convert_sage.pyx @@ -2,7 +2,7 @@ r""" Convert PARI objects to Sage types """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2016 Jeroen Demeyer # Copyright (C) 2016 Luca De Feo # Copyright (C) 2016 Vincent Delecroix @@ -11,8 +11,8 @@ Convert PARI objects to Sage types # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from cysignals.signals cimport sig_on, sig_off @@ -20,9 +20,7 @@ from cypari2.types cimport (GEN, typ, t_INT, t_FRAC, t_REAL, t_COMPLEX, t_INTMOD, t_PADIC, t_INFINITY, t_VEC, t_COL, t_VECSMALL, t_MAT, t_STR, lg, precp) -from cypari2.pari_instance cimport prec_words_to_bits from cypari2.paridecl cimport * -from cypari2.gen cimport objtogen from cypari2.stack cimport new_gen from .convert_gmp cimport INT_to_mpz, new_gen_from_mpz_t, new_gen_from_mpq_t, INTFRAC_to_mpq diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index 229f6695e09..411b5eae678 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -93,11 +93,11 @@ from sage.rings.polynomial.plural cimport NCPolynomialRing_plural, NCPolynomial_ from sage.rings.polynomial.multi_polynomial_ideal import NCPolynomialIdeal from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal from sage.rings.polynomial.multi_polynomial_ideal_libsingular cimport sage_ideal_to_singular_ideal, singular_ideal_to_sage_sequence -from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence, PolynomialSequence_generic +from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence_generic from sage.libs.singular.decl cimport * from sage.libs.singular.option import opt_ctx -from sage.libs.singular.polynomial cimport singular_vector_maximal_component, singular_polynomial_check +from sage.libs.singular.polynomial cimport singular_vector_maximal_component from sage.libs.singular.singular cimport sa2si, si2sa, si2sa_intvec from sage.libs.singular.singular import error_messages diff --git a/src/sage/libs/singular/option.pyx b/src/sage/libs/singular/option.pyx index fc3b576ff71..d35415c2864 100644 --- a/src/sage/libs/singular/option.pyx +++ b/src/sage/libs/singular/option.pyx @@ -93,12 +93,12 @@ AUTHOR: - Martin Albrecht (2010-01): better interface, verbosity options - Simon King (2010-07): Python-ic option names; deg_bound and mult_bound """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010 Martin Albrecht # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.libs.singular.decl cimport singular_options, singular_verbose_options, Kstd1_deg, Kstd1_mu @@ -108,7 +108,7 @@ from sage.libs.singular.decl cimport OPT_WEIGHTM, Sy_bit from sage.libs.singular.decl cimport V_SHOW_MEM, V_YACC, V_REDEFINE, V_READING, V_LOAD_LIB, V_DEBUG_LIB from sage.libs.singular.decl cimport V_LOAD_PROC, V_DEF_RES, V_SHOW_USE, V_IMAP, V_PROMPT -from sage.libs.singular.decl cimport V_NSB, V_CONTENTSB, V_CANCELUNIT, V_DEG_STOP +from sage.libs.singular.decl cimport V_NSB, V_CONTENTSB, V_CANCELUNIT _options_py_to_singular={'return_sb':'returnSB', 'fast_hc':'fastHC', diff --git a/src/sage/libs/singular/polynomial.pyx b/src/sage/libs/singular/polynomial.pyx index 1a6dad39a6b..9f81a20b0a7 100644 --- a/src/sage/libs/singular/polynomial.pyx +++ b/src/sage/libs/singular/polynomial.pyx @@ -32,7 +32,7 @@ from sage.libs.singular.decl cimport p_Copy, p_Add_q, p_Neg, pp_Mult_nn, p_GetCo from sage.libs.singular.decl cimport p_GetMaxExp, pp_Mult_qq, pPower, p_String, p_GetExp, p_LDeg from sage.libs.singular.decl cimport n_Delete, idInit, fast_map_common_subexp, id_Delete from sage.libs.singular.decl cimport omAlloc0, omStrDup, omFree -from sage.libs.singular.decl cimport p_GetComp, p_SetComp +from sage.libs.singular.decl cimport p_GetComp from sage.libs.singular.decl cimport pSubst from sage.libs.singular.decl cimport p_Normalize from sage.libs.singular.decl cimport ndCopyMap, maMapPoly diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index 04bd16e8784..56dc364219c 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -9,30 +9,28 @@ AUTHORS: - Miguel Marco (2021): added transcendental extensions over Q """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2009 Martin Albrecht # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.cpython.string cimport str_to_bytes from sage.libs.gmp.types cimport __mpz_struct -from sage.libs.gmp.mpz cimport mpz_init_set_ui, mpz_init_set +from sage.libs.gmp.mpz cimport mpz_init_set_ui -from sage.libs.singular.decl cimport number, poly, ring, currRing -from sage.libs.singular.decl cimport rChangeCurrRing, rCopy0, rComplete, rDelete, idInit -from sage.libs.singular.decl cimport omAlloc0, omStrDup, omAlloc, omAlloc0Bin, sip_sring_bin, rnumber_bin +from sage.libs.singular.decl cimport ring, currRing +from sage.libs.singular.decl cimport rChangeCurrRing, rComplete, rDelete, idInit +from sage.libs.singular.decl cimport omAlloc0, omStrDup, omAlloc from sage.libs.singular.decl cimport ringorder_dp, ringorder_Dp, ringorder_lp, ringorder_rp, ringorder_ds, ringorder_Ds, ringorder_ls, ringorder_M, ringorder_c, ringorder_C, ringorder_wp, ringorder_Wp, ringorder_ws, ringorder_Ws, ringorder_a, rRingOrder_t -from sage.libs.singular.decl cimport p_Copy, prCopyR -from sage.libs.singular.decl cimport n_unknown, n_Zp, n_Q, n_R, n_GF, n_long_R, n_algExt,n_transExt,n_long_C, n_Z, n_Zn, n_Znm, n_Z2m, n_CF -from sage.libs.singular.decl cimport n_coeffType, cfInitCharProc -from sage.libs.singular.decl cimport rDefault, GFInfo, ZnmInfo, nInitChar, AlgExtInfo, nRegister, naInitChar, TransExtInfo +from sage.libs.singular.decl cimport prCopyR +from sage.libs.singular.decl cimport n_unknown, n_algExt, n_transExt, n_Z, n_Zn, n_Znm, n_Z2m +from sage.libs.singular.decl cimport n_coeffType +from sage.libs.singular.decl cimport rDefault, GFInfo, ZnmInfo, nInitChar, AlgExtInfo, TransExtInfo - -from sage.rings.integer cimport Integer from sage.rings.integer_ring cimport IntegerRing_class from sage.rings.integer_ring import ZZ import sage.rings.abc @@ -46,7 +44,7 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.polynomial_ring import PolynomialRing_field -from sage.rings.fraction_field import FractionField_generic, FractionField_1poly_field +from sage.rings.fraction_field import FractionField_generic from cpython.object cimport Py_EQ, Py_NE diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 8924789c141..f357ce611c9 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -37,18 +37,17 @@ from sage.rings.integer_ring cimport IntegerRing_class from sage.rings.finite_rings.integer_mod_ring import IntegerModRing_generic from sage.rings.finite_rings.finite_field_base import FiniteField from sage.rings.polynomial.polynomial_ring import PolynomialRing_field -from sage.rings.fraction_field import FractionField_generic, FractionField_1poly_field +from sage.rings.fraction_field import FractionField_generic from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn from sage.rings.finite_rings.finite_field_givaro import FiniteField_givaro from sage.rings.finite_rings.finite_field_ntl_gf2e import FiniteField_ntl_gf2e -from sage.libs.pari.all import pari from sage.libs.gmp.all cimport * from sage.cpython.string import FS_ENCODING from sage.cpython.string cimport str_to_bytes, char_to_str, bytes_to_str -from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular, MPolynomialRing_libsingular +from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular ctypedef struct fraction "fractionObject": poly *numerator From 69d298f98d894abdfd75f9b78d943b401896b03f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 4 Jun 2023 11:28:05 +0200 Subject: [PATCH 34/56] add back import --- src/sage/rings/polynomial/polynomial_zmod_flint.pyx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx index 253ab949fcc..60ad8d82966 100644 --- a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx @@ -40,6 +40,7 @@ AUTHORS: # **************************************************************************** from sage.libs.ntl.ntl_lzz_pX import ntl_zz_pX +from sage.structure.factorization import Factorization # removing breaks build from sage.structure.element cimport parent from sage.structure.element import coerce_binop from sage.rings.polynomial.polynomial_integer_dense_flint cimport Polynomial_integer_dense_flint From 0ee75fc92b85320b7c82097757738d23ef6644b3 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 3 Jun 2023 20:53:55 +0100 Subject: [PATCH 35/56] provide matrix_symbolic_sparse class This is needed in particulat to specialize echelonize(), cf #35653 --- src/doc/en/reference/matrices/index.rst | 1 + src/sage/matrix/matrix_space.py | 14 + src/sage/matrix/matrix_symbolic_dense.pyx | 2 +- src/sage/matrix/matrix_symbolic_sparse.pxd | 4 + src/sage/matrix/matrix_symbolic_sparse.pyx | 1034 ++++++++++++++++++++ 5 files changed, 1054 insertions(+), 1 deletion(-) create mode 100644 src/sage/matrix/matrix_symbolic_sparse.pxd create mode 100644 src/sage/matrix/matrix_symbolic_sparse.pyx diff --git a/src/doc/en/reference/matrices/index.rst b/src/doc/en/reference/matrices/index.rst index 25aed6c2cb3..fb06992c1e1 100644 --- a/src/doc/en/reference/matrices/index.rst +++ b/src/doc/en/reference/matrices/index.rst @@ -79,6 +79,7 @@ objects like operation tables (e.g. the multiplication table of a group). sage/matrix/matrix_modn_dense_float sage/matrix/matrix_modn_sparse sage/matrix/matrix_symbolic_dense + sage/matrix/matrix_symbolic_sparse sage/matrix/matrix_complex_double_dense sage/matrix/matrix_complex_ball_dense sage/matrix/matrix_polynomial_dense diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 995d085573d..7652493e0b2 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -170,6 +170,8 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): sage: type(matrix(SR, 2, 2, 0)) + sage: type(matrix(SR, 2, 2, 0, sparse=True)) + sage: type(matrix(GF(7), 2, range(4))) sage: type(matrix(GF(16007), 2, range(4))) @@ -400,6 +402,18 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): if isinstance(R, (sage.rings.abc.RealDoubleField, sage.rings.abc.ComplexDoubleField)): from . import matrix_double_sparse return matrix_double_sparse.Matrix_double_sparse + try: + from sage.symbolic.ring import SR + except ImportError: + pass + else: + if R is SR: + try: + from . import matrix_symbolic_sparse + except ImportError: + pass + else: + return matrix_symbolic_sparse.Matrix_symbolic_sparse # the fallback from sage.matrix.matrix_generic_sparse import Matrix_generic_sparse diff --git a/src/sage/matrix/matrix_symbolic_dense.pyx b/src/sage/matrix/matrix_symbolic_dense.pyx index 5a6fda44d57..0df43084de2 100644 --- a/src/sage/matrix/matrix_symbolic_dense.pyx +++ b/src/sage/matrix/matrix_symbolic_dense.pyx @@ -1,5 +1,5 @@ """ -Symbolic matrices +Symbolic dense matrices EXAMPLES:: diff --git a/src/sage/matrix/matrix_symbolic_sparse.pxd b/src/sage/matrix/matrix_symbolic_sparse.pxd new file mode 100644 index 00000000000..897754c837d --- /dev/null +++ b/src/sage/matrix/matrix_symbolic_sparse.pxd @@ -0,0 +1,4 @@ +from .matrix_generic_sparse cimport Matrix_generic_sparse + +cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): + pass diff --git a/src/sage/matrix/matrix_symbolic_sparse.pyx b/src/sage/matrix/matrix_symbolic_sparse.pyx new file mode 100644 index 00000000000..01c4cee86a1 --- /dev/null +++ b/src/sage/matrix/matrix_symbolic_sparse.pyx @@ -0,0 +1,1034 @@ +""" +Symbolic sparse matrices + +EXAMPLES:: + + sage: matrix(SR, 2, 2, range(4), sparse=True) + [0 1] + [2 3] + sage: matrix(SR, 2, 2, var('t'), sparse=True) + [t 0] + [0 t] + +Arithmetic:: + + sage: -matrix(SR, 2, range(4), sparse=True) + [ 0 -1] + [-2 -3] + sage: m = matrix(SR, 2, [1..4], sparse=True); sqrt(2)*m + [ sqrt(2) 2*sqrt(2)] + [3*sqrt(2) 4*sqrt(2)] + sage: m = matrix(SR, 4, [1..4^2], sparse=True) + sage: m * m + [ 90 100 110 120] + [202 228 254 280] + [314 356 398 440] + [426 484 542 600] + + sage: m = matrix(SR, 3, [1, 2, 3], sparse=True); m + [1] + [2] + [3] + sage: m.transpose() * m + [14] + +Computing inverses:: + + sage: M = matrix(SR, 2, var('a,b,c,d'), sparse=True) + sage: ~M + [1/a - b*c/(a^2*(b*c/a - d)) b/(a*(b*c/a - d))] + [ c/(a*(b*c/a - d)) -1/(b*c/a - d)] + sage: (~M*M).simplify_rational() + [1 0] + [0 1] + sage: M = matrix(SR, 3, 3, range(9), sparse=True) - var('t') + sage: (~M * M).simplify_rational() + [1 0 0] + [0 1 0] + [0 0 1] + + sage: matrix(SR, 1, 1, 1, sparse=True).inverse() + [1] + sage: matrix(SR, 0, 0, sparse=True).inverse() + [] + sage: matrix(SR, 3, 0, sparse=True).inverse() + Traceback (most recent call last): + ... + ArithmeticError: self must be a square matrix + +Transposition:: + + sage: m = matrix(SR, 2, [sqrt(2), -1, pi, e^2], sparse=True) + sage: m.transpose() + [sqrt(2) pi] + [ -1 e^2] + +``.T`` is a convenient shortcut for the transpose:: + + sage: m.T + [sqrt(2) pi] + [ -1 e^2] + +Test pickling:: + + sage: m = matrix(SR, 2, [sqrt(2), 3, pi, e], sparse=True); m + [sqrt(2) 3] + [ pi e] + sage: TestSuite(m).run() + +Comparison:: + + sage: m = matrix(SR, 2, [sqrt(2), 3, pi, e], sparse=True) + sage: m == m + True + sage: m != 3 + True + sage: m = matrix(SR,2,[1..4], sparse=True); n = m^2 + sage: (exp(m+n) - exp(m)*exp(n)).simplify_rational() == 0 # indirect test + True + + +Determinant:: + + sage: M = matrix(SR, 2, 2, [x,2,3,4], sparse=True) + sage: M.determinant() + 4*x - 6 + sage: M = matrix(SR, 3,3,range(9), sparse=True) + sage: M.det() + 0 + sage: t = var('t') + sage: M = matrix(SR, 2, 2, [cos(t), sin(t), -sin(t), cos(t)], sparse=True) + sage: M.det() + cos(t)^2 + sin(t)^2 + sage: M = matrix([[sqrt(x),0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1]], sparse=True) + sage: det(M) + sqrt(x) + +Permanents:: + + sage: M = matrix(SR, 2, 2, [x,2,3,4], sparse=True) + sage: M.permanent() + 4*x + 6 + +Rank:: + + sage: M = matrix(SR, 5, 5, range(25), sparse=True) + sage: M.rank() + 2 + sage: M = matrix(SR, 5, 5, range(25), sparse=True) - var('t') + sage: M.rank() + 5 + + .. warning:: + + :meth:`rank` may return the wrong answer if it cannot determine that a + matrix element that is equivalent to zero is indeed so. + +Copying symbolic matrices:: + + sage: m = matrix(SR, 2, [sqrt(2), 3, pi, e], sparse=True) + sage: n = copy(m) + sage: n[0,0] = sin(1) + sage: m + [sqrt(2) 3] + [ pi e] + sage: n + [sin(1) 3] + [ pi e] + +Conversion to Maxima:: + + sage: m = matrix(SR, 2, [sqrt(2), 3, pi, e], sparse=True) + sage: m._maxima_() + matrix([sqrt(2),3],[%pi,%e]) + +TESTS: + +Check that :trac:`12778` is fixed:: + + sage: M = Matrix([[1, 0.9, 1/5, x^2], [2, 1.9, 2/5, x^3], [3, 2.9, 3/5, x^4]], sparse=True); M + [ 1 0.900000000000000 1/5 x^2] + [ 2 1.90000000000000 2/5 x^3] + [ 3 2.90000000000000 3/5 x^4] + sage: parent(M) + Full MatrixSpace of 3 by 4 sparse matrices over Symbolic Ring + +Check that :issue:`35653` is fixed:: + + sage: diagonal_matrix([x]).inverse() + [1/x] + sage: M = MatrixSpace(SR,2,2,sparse=True) + sage: M([[x,0],[0,x]]).inverse() + [1/x 0] + [ 0 1/x] +""" +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.structure.element cimport ModuleElement, RingElement, Element +from sage.structure.factorization import Factorization + +from .matrix_generic_sparse cimport Matrix_generic_sparse +from .constructor import matrix + +cdef maxima + +from sage.calculus.calculus import symbolic_expression_from_maxima_string, maxima + +cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): + def echelonize(self, **kwds): + """ + Echelonize using the classical algorithm. + + + TESTS:: + + sage: m = matrix([[cos(pi/5), sin(pi/5)], [-sin(pi/5), cos(pi/5)]]) + sage: m.echelonize(); m + [1 0] + [0 1] + """ + return super().echelonize(algorithm="classical", **kwds) + + def eigenvalues(self, extend=True): + """ + Compute the eigenvalues by solving the characteristic + polynomial in maxima. + + The argument ``extend`` is ignored but kept for compatibility with + other matrix classes. + + EXAMPLES:: + + sage: a=matrix(SR,[[1,2],[3,4]]) + sage: a.eigenvalues() + [-1/2*sqrt(33) + 5/2, 1/2*sqrt(33) + 5/2] + + TESTS: + + Check for :trac:`31700`:: + + sage: m = matrix([[cos(pi/5), sin(pi/5)], [-sin(pi/5), cos(pi/5)]]) + sage: t = linear_transformation(m) + sage: t.eigenvalues() + [1/4*sqrt(5) - 1/4*sqrt(2*sqrt(5) - 10) + 1/4, + 1/4*sqrt(5) + 1/4*sqrt(2*sqrt(5) - 10) + 1/4] + """ + maxima_evals = self._maxima_(maxima).eigenvalues()._sage_() + if not len(maxima_evals): + raise ArithmeticError("could not determine eigenvalues exactly using symbolic matrices; try using a different type of matrix via self.change_ring(), if possible") + return sum([[ev] * int(mult) for ev, mult in zip(*maxima_evals)], []) + + def eigenvectors_left(self, other=None): + r""" + Compute the left eigenvectors of a matrix. + + INPUT: + + - ``other`` -- a square matrix `B` (default: ``None``) in a generalized + eigenvalue problem; if ``None``, an ordinary eigenvalue problem is + solved (currently supported only if the base ring of ``self`` is + ``RDF`` or ``CDF``) + + OUTPUT: + + For each distinct eigenvalue, returns a list of the form (e,V,n) + where e is the eigenvalue, V is a list of eigenvectors forming a + basis for the corresponding left eigenspace, and n is the + algebraic multiplicity of the eigenvalue. + + EXAMPLES:: + + sage: A = matrix(SR,3,3,range(9)); A + [0 1 2] + [3 4 5] + [6 7 8] + sage: es = A.eigenvectors_left(); es + [(-3*sqrt(6) + 6, [(1, -1/5*sqrt(6) + 4/5, -2/5*sqrt(6) + 3/5)], 1), + (3*sqrt(6) + 6, [(1, 1/5*sqrt(6) + 4/5, 2/5*sqrt(6) + 3/5)], 1), + (0, [(1, -2, 1)], 1)] + sage: eval, [evec], mult = es[0] + sage: delta = eval*evec - evec*A + sage: abs(abs(delta)) < 1e-10 + 3/5*sqrt(((2*sqrt(6) - 3)*(sqrt(6) - 2) + 7*sqrt(6) - 18)^2 + ((sqrt(6) - 2)*(sqrt(6) - 4) + 6*sqrt(6) - 14)^2) < (1.00000000000000e-10) + sage: abs(abs(delta)).n() < 1e-10 + True + + :: + + sage: A = matrix(SR, 2, 2, var('a,b,c,d')) + sage: A.eigenvectors_left() + [(1/2*a + 1/2*d - 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2), [(1, -1/2*(a - d + sqrt(a^2 + 4*b*c - 2*a*d + d^2))/c)], 1), (1/2*a + 1/2*d + 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2), [(1, -1/2*(a - d - sqrt(a^2 + 4*b*c - 2*a*d + d^2))/c)], 1)] + sage: es = A.eigenvectors_left(); es + [(1/2*a + 1/2*d - 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2), [(1, -1/2*(a - d + sqrt(a^2 + 4*b*c - 2*a*d + d^2))/c)], 1), (1/2*a + 1/2*d + 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2), [(1, -1/2*(a - d - sqrt(a^2 + 4*b*c - 2*a*d + d^2))/c)], 1)] + sage: eval, [evec], mult = es[0] + sage: delta = eval*evec - evec*A + sage: delta.apply_map(lambda x: x.full_simplify()) + (0, 0) + + This routine calls Maxima and can struggle with even small matrices + with a few variables, such as a `3\times 3` matrix with three variables. + However, if the entries are integers or rationals it can produce exact + values in a reasonable time. These examples create 0-1 matrices from + the adjacency matrices of graphs and illustrate how the format and type + of the results differ when the base ring changes. First for matrices + over the rational numbers, then the same matrix but viewed as a symbolic + matrix. :: + + sage: G=graphs.CycleGraph(5) + sage: am = G.adjacency_matrix() + sage: spectrum = am.eigenvectors_left() + sage: qqbar_evalue = spectrum[2][0] + sage: type(qqbar_evalue) + + sage: qqbar_evalue + 0.618033988749895? + + sage: am = G.adjacency_matrix().change_ring(SR) + sage: spectrum = am.eigenvectors_left() + sage: symbolic_evalue = spectrum[2][0] + sage: type(symbolic_evalue) + + sage: symbolic_evalue + 1/2*sqrt(5) - 1/2 + + sage: bool(qqbar_evalue == symbolic_evalue) + True + + A slightly larger matrix with a "nice" spectrum. :: + + sage: G = graphs.CycleGraph(6) + sage: am = G.adjacency_matrix().change_ring(SR) + sage: am.eigenvectors_left() + [(-1, [(1, 0, -1, 1, 0, -1), (0, 1, -1, 0, 1, -1)], 2), (1, [(1, 0, -1, -1, 0, 1), (0, 1, 1, 0, -1, -1)], 2), (-2, [(1, -1, 1, -1, 1, -1)], 1), (2, [(1, 1, 1, 1, 1, 1)], 1)] + + TESTS:: + + sage: A = matrix(SR, [[1, 2], [3, 4]]) + sage: B = matrix(SR, [[1, 1], [0, 1]]) + sage: A.eigenvectors_left(B) + Traceback (most recent call last): + ... + NotImplementedError: generalized eigenvector decomposition is + implemented for RDF and CDF, but not for Symbolic Ring + + Check that :trac:`23332` is fixed:: + + sage: matrix([[x, x^2], [1, 0]]).eigenvectors_left() + [(-1/2*x*(sqrt(5) - 1), [(1, -1/2*x*(sqrt(5) + 1))], 1), + (1/2*x*(sqrt(5) + 1), [(1, 1/2*x*(sqrt(5) - 1))], 1)] + """ + if other is not None: + raise NotImplementedError('generalized eigenvector decomposition ' + 'is implemented for RDF and CDF, but ' + 'not for %s' % self.base_ring()) + + from sage.modules.free_module_element import vector + from sage.rings.integer_ring import ZZ + + [evals, mults], evecs = self.transpose()._maxima_(maxima).eigenvectors()._sage_() + result = [] + for e, evec, m in zip(evals, evecs, mults): + result.append((e, [vector(v) for v in evec], ZZ(m))) + + return result + + def eigenvectors_right(self, other=None): + r""" + Compute the right eigenvectors of a matrix. + + INPUT: + + - ``other`` -- a square matrix `B` (default: ``None``) in a generalized + eigenvalue problem; if ``None``, an ordinary eigenvalue problem is + solved (currently supported only if the base ring of ``self`` is + ``RDF`` or ``CDF``) + + OUTPUT: + + For each distinct eigenvalue, returns a list of the form (e,V,n) + where e is the eigenvalue, V is a list of eigenvectors forming a + basis for the corresponding right eigenspace, and n is the + algebraic multiplicity of the eigenvalue. + + EXAMPLES:: + + sage: A = matrix(SR,2,2,range(4)); A + [0 1] + [2 3] + sage: right = A.eigenvectors_right(); right + [(-1/2*sqrt(17) + 3/2, [(1, -1/2*sqrt(17) + 3/2)], 1), (1/2*sqrt(17) + 3/2, [(1, 1/2*sqrt(17) + 3/2)], 1)] + + The right eigenvectors are nothing but the left eigenvectors of the + transpose matrix:: + + sage: left = A.transpose().eigenvectors_left(); left + [(-1/2*sqrt(17) + 3/2, [(1, -1/2*sqrt(17) + 3/2)], 1), (1/2*sqrt(17) + 3/2, [(1, 1/2*sqrt(17) + 3/2)], 1)] + sage: right[0][1] == left[0][1] + True + + TESTS:: + + sage: A = matrix(SR, [[1, 2], [3, 4]]) + sage: B = matrix(SR, [[1, 1], [0, 1]]) + sage: A.eigenvectors_right(B) + Traceback (most recent call last): + ... + NotImplementedError: generalized eigenvector decomposition is + implemented for RDF and CDF, but not for Symbolic Ring + + Check that :trac:`23332` is fixed:: + + sage: matrix([[x, x^2], [1, 0]]).eigenvectors_right() + [(-1/2*x*(sqrt(5) - 1), [(1, -1/2*(sqrt(5) + 1)/x)], 1), + (1/2*x*(sqrt(5) + 1), [(1, 1/2*(sqrt(5) - 1)/x)], 1)] + """ + return self.transpose().eigenvectors_left(other=other) + + def exp(self): + r""" + Return the matrix exponential of this matrix `X`, which is the matrix + + .. MATH:: + + e^X = \sum_{k=0}^{\infty} \frac{X^k}{k!}. + + This function depends on maxima's matrix exponentiation + function, which does not deal well with floating point + numbers. If the matrix has floating point numbers, they will + be rounded automatically to rational numbers during the + computation. + + EXAMPLES:: + + sage: m = matrix(SR,2, [0,x,x,0]); m + [0 x] + [x 0] + sage: m.exp() + [1/2*(e^(2*x) + 1)*e^(-x) 1/2*(e^(2*x) - 1)*e^(-x)] + [1/2*(e^(2*x) - 1)*e^(-x) 1/2*(e^(2*x) + 1)*e^(-x)] + sage: exp(m) + [1/2*(e^(2*x) + 1)*e^(-x) 1/2*(e^(2*x) - 1)*e^(-x)] + [1/2*(e^(2*x) - 1)*e^(-x) 1/2*(e^(2*x) + 1)*e^(-x)] + + Exponentiation works on 0x0 and 1x1 matrices, but the 1x1 example + requires a patched version of maxima (:trac:`32898`) for now:: + + sage: m = matrix(SR,0,[]); m + [] + sage: m.exp() + [] + sage: m = matrix(SR,1,[2]); m + [2] + sage: m.exp() # not tested, requires patched maxima + [e^2] + + Commuting matrices `m, n` have the property that + `e^{m+n} = e^m e^n` (but non-commuting matrices need not):: + + sage: m = matrix(SR,2,[1..4]); n = m^2 + sage: m*n + [ 37 54] + [ 81 118] + sage: n*m + [ 37 54] + [ 81 118] + + sage: a = exp(m+n) - exp(m)*exp(n) + sage: a.simplify_rational() == 0 + True + + The input matrix must be square:: + + sage: m = matrix(SR,2,3,[1..6]); exp(m) + Traceback (most recent call last): + ... + ValueError: exp only defined on square matrices + + In this example we take the symbolic answer and make it + numerical at the end:: + + sage: exp(matrix(SR, [[1.2, 5.6], [3,4]])).change_ring(RDF) # rel tol 1e-15 + [ 346.5574872980695 661.7345909344504] + [354.50067371488416 677.4247827652946] + + Another example involving the reversed identity matrix, which + we clumsily create:: + + sage: m = identity_matrix(SR,4); m = matrix(list(reversed(m.rows()))) * x + sage: exp(m) + [1/2*(e^(2*x) + 1)*e^(-x) 0 0 1/2*(e^(2*x) - 1)*e^(-x)] + [ 0 1/2*(e^(2*x) + 1)*e^(-x) 1/2*(e^(2*x) - 1)*e^(-x) 0] + [ 0 1/2*(e^(2*x) - 1)*e^(-x) 1/2*(e^(2*x) + 1)*e^(-x) 0] + [1/2*(e^(2*x) - 1)*e^(-x) 0 0 1/2*(e^(2*x) + 1)*e^(-x)] + """ + if not self.is_square(): + raise ValueError("exp only defined on square matrices") + if self.nrows() == 0: + return self + # Maxima's matrixexp function chokes on floating point numbers + # so we automatically convert floats to rationals by passing + # keepfloat: false + m = self._maxima_(maxima) + z = maxima('matrixexp(%s), keepfloat: false' % m.name()) + if self.nrows() == 1: + # We do the following, because Maxima stupidly exp's 1x1 + # matrices into non-matrices! + z = maxima('matrix([%s])' % z.name()) + + return z._sage_() + + def charpoly(self, var='x', algorithm=None): + r""" + Compute the characteristic polynomial of ``self``, using maxima. + + .. NOTE:: + + The characteristic polynomial is defined as `\det(xI-A)`. + + INPUT: + + - ``var`` -- (default: 'x') name of variable of charpoly + + EXAMPLES:: + + sage: M = matrix(SR, 2, 2, var('a,b,c,d')) + sage: M.charpoly('t') + t^2 + (-a - d)*t - b*c + a*d + sage: matrix(SR, 5, [1..5^2]).charpoly() + x^5 - 65*x^4 - 250*x^3 + + TESTS: + + The cached polynomial should be independent of the ``var`` + argument (:trac:`12292`). We check (indirectly) that the + second call uses the cached value by noting that its result is + not cached:: + + sage: M = MatrixSpace(SR, 2, sparse=True) + sage: A = M(range(0, 2^2)) + sage: type(A) + + sage: A.charpoly('x') + x^2 - 3*x - 2 + sage: A.charpoly('y') + y^2 - 3*y - 2 + sage: A._cache['charpoly'] + x^2 - 3*x - 2 + + Ensure the variable name of the polynomial does not conflict + with variables used within the matrix (:trac:`14403`):: + + sage: Matrix(SR, [[sqrt(x), x],[1,x]], sparse=True).charpoly().list() + [x^(3/2) - x, -x - sqrt(x), 1] + + Test that :trac:`13711` is fixed:: + + sage: matrix([[sqrt(2), -1], [pi, e^2]], sparse=True).charpoly() + x^2 + (-sqrt(2) - e^2)*x + pi + sqrt(2)*e^2 + + Test that :trac:`26427` is fixed:: + + sage: M = matrix(SR, 7, 7, SR.var('a', 49), sparse=True) + sage: M.charpoly().degree() # long time + 7 + """ + cache_key = 'charpoly' + cp = self.fetch(cache_key) + if cp is not None: + return cp.change_variable_name(var) + from sage.symbolic.ring import SR + + # We must not use a variable name already present in the matrix + vname = 'do_not_use_this_name_in_a_matrix_youll_compute_a_charpoly_of' + vsym = SR(vname) + + cp = self._maxima_(maxima).charpoly(vname)._sage_().expand() + cp = [cp.coefficient(vsym, i) for i in range(self.nrows() + 1)] + cp = SR[var](cp) + + # Maxima has the definition det(matrix-xI) instead of + # det(xI-matrix), which is what Sage uses elsewhere. We + # correct for the discrepancy. + if self.nrows() % 2 == 1: + cp = -cp + + self.cache(cache_key, cp) + return cp + + def minpoly(self, var='x'): + """ + Return the minimal polynomial of ``self``. + + EXAMPLES:: + + sage: M = Matrix.identity(SR, 2) + sage: M.minpoly() + x - 1 + + sage: t = var('t') + sage: m = matrix(2, [1, 2, 4, t]) + sage: m.minimal_polynomial() + x^2 + (-t - 1)*x + t - 8 + + TESTS: + + Check that the variable `x` can occur in the matrix:: + + sage: m = matrix([[x]]) + sage: m.minimal_polynomial('y') + y - x + + """ + mp = self.fetch('minpoly') + if mp is None: + mp = self._maxima_lib_().jordan().minimalPoly().expand() + d = mp.hipow('x') + mp = [mp.coeff('x', i) for i in xrange(int(d) + 1)] + mp = PolynomialRing(self.base_ring(), 'x')(mp) + self.cache('minpoly', mp) + return mp.change_variable_name(var) + + def fcp(self, var='x'): + """ + Return the factorization of the characteristic polynomial of ``self``. + + INPUT: + + - ``var`` -- (default: 'x') name of variable of charpoly + + EXAMPLES:: + + sage: a = matrix(SR,[[1,2],[3,4]]) + sage: a.fcp() + x^2 - 5*x - 2 + sage: [i for i in a.fcp()] + [(x^2 - 5*x - 2, 1)] + sage: a = matrix(SR,[[1,0],[0,2]]) + sage: a.fcp() + (x - 2) * (x - 1) + sage: [i for i in a.fcp()] + [(x - 2, 1), (x - 1, 1)] + sage: a = matrix(SR, 5, [1..5^2]) + sage: a.fcp() + (x^2 - 65*x - 250) * x^3 + sage: list(a.fcp()) + [(x^2 - 65*x - 250, 1), (x, 3)] + + """ + from sage.symbolic.ring import SR + sub_dict = {var: SR.var(var)} + return Factorization(self.charpoly(var).subs(**sub_dict).factor_list()) + + def jordan_form(self, subdivide=True, transformation=False): + """ + Return a Jordan normal form of ``self``. + + INPUT: + + - ``self`` -- a square matrix + + - ``subdivide`` -- boolean (default: ``True``) + + - ``transformation`` -- boolean (default: ``False``) + + OUTPUT: + + If ``transformation`` is ``False``, only a Jordan normal form + (unique up to the ordering of the Jordan blocks) is returned. + Otherwise, a pair ``(J, P)`` is returned, where ``J`` is a + Jordan normal form and ``P`` is an invertible matrix such that + ``self`` equals ``P * J * P^(-1)``. + + If ``subdivide`` is ``True``, the Jordan blocks in the + returned matrix ``J`` are indicated by a subdivision in + the sense of :meth:`~sage.matrix.matrix2.subdivide`. + + EXAMPLES: + + We start with some examples of diagonalisable matrices:: + + sage: a,b,c,d = var('a,b,c,d') + sage: matrix([a]).jordan_form() + [a] + sage: matrix([[a, 0], [1, d]]).jordan_form(subdivide=True) + [d|0] + [-+-] + [0|a] + sage: matrix([[a, 0], [1, d]]).jordan_form(subdivide=False) + [d 0] + [0 a] + sage: matrix([[a, x, x], [0, b, x], [0, 0, c]]).jordan_form() + [c|0|0] + [-+-+-] + [0|b|0] + [-+-+-] + [0|0|a] + + In the following examples, we compute Jordan forms of some + non-diagonalisable matrices:: + + sage: matrix([[a, a], [0, a]]).jordan_form() + [a 1] + [0 a] + sage: matrix([[a, 0, b], [0, c, 0], [0, 0, a]]).jordan_form() + [c|0 0] + [-+---] + [0|a 1] + [0|0 a] + + The following examples illustrate the ``transformation`` flag. + Note that symbolic expressions may need to be simplified to + make consistency checks succeed:: + + sage: A = matrix([[x - a*c, a^2], [-c^2, x + a*c]]) + sage: J, P = A.jordan_form(transformation=True) + sage: J, P + ( + [x 1] [-a*c 1] + [0 x], [-c^2 0] + ) + sage: A1 = P * J * ~P; A1 + [ -a*c + x (a*c - x)*a/c + a*x/c] + [ -c^2 a*c + x] + sage: A1.simplify_rational() == A + True + + sage: B = matrix([[a, b, c], [0, a, d], [0, 0, a]]) + sage: J, T = B.jordan_form(transformation=True) + sage: J, T + ( + [a 1 0] [b*d c 0] + [0 a 1] [ 0 d 0] + [0 0 a], [ 0 0 1] + ) + sage: (B * T).simplify_rational() == T * J + True + + Finally, some examples involving square roots:: + + sage: matrix([[a, -b], [b, a]]).jordan_form() + [a - I*b| 0] + [-------+-------] + [ 0|a + I*b] + sage: matrix([[a, b], [c, d]]).jordan_form(subdivide=False) + [1/2*a + 1/2*d - 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2) 0] + [ 0 1/2*a + 1/2*d + 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2)] + """ + A = self._maxima_lib_() + jordan_info = A.jordan() + J = jordan_info.dispJordan()._sage_() + if subdivide: + v = [x[1] for x in jordan_info] + w = [sum(v[0:i]) for i in xrange(1, len(v))] + J.subdivide(w, w) + if transformation: + P = A.diag_mode_matrix(jordan_info)._sage_() + return J, P + else: + return J + + def simplify(self): + """ + Simplify ``self``. + + EXAMPLES:: + + sage: var('x,y,z') + (x, y, z) + sage: m = matrix([[z, (x+y)/(x+y)], [x^2, y^2+2]]); m + [ z 1] + [ x^2 y^2 + 2] + sage: m.simplify() + [ z 1] + [ x^2 y^2 + 2] + """ + return self.parent()([x.simplify() for x in self.list()]) + + def simplify_trig(self): + """ + EXAMPLES:: + + sage: theta = var('theta') + sage: M = matrix(SR, 2, 2, [cos(theta), sin(theta), -sin(theta), cos(theta)]) + sage: ~M + [1/cos(theta) - sin(theta)^2/((sin(theta)^2/cos(theta) + cos(theta))*cos(theta)^2) -sin(theta)/((sin(theta)^2/cos(theta) + cos(theta))*cos(theta))] + [ sin(theta)/((sin(theta)^2/cos(theta) + cos(theta))*cos(theta)) 1/(sin(theta)^2/cos(theta) + cos(theta))] + sage: (~M).simplify_trig() + [ cos(theta) -sin(theta)] + [ sin(theta) cos(theta)] + """ + return self._maxima_(maxima).trigexpand().trigsimp()._sage_() + + def simplify_rational(self): + """ + EXAMPLES:: + + sage: M = matrix(SR, 3, 3, range(9)) - var('t') + sage: (~M*M)[0,0] + t*(3*(2/t + (6/t + 7)/((t - 3/t - 4)*t))*(2/t + (6/t + 5)/((t - 3/t + - 4)*t))/(t - (6/t + 7)*(6/t + 5)/(t - 3/t - 4) - 12/t - 8) + 1/t + + 3/((t - 3/t - 4)*t^2)) - 6*(2/t + (6/t + 5)/((t - 3/t - 4)*t))/(t - + (6/t + 7)*(6/t + 5)/(t - 3/t - 4) - 12/t - 8) - 3*(6/t + 7)*(2/t + + (6/t + 5)/((t - 3/t - 4)*t))/((t - (6/t + 7)*(6/t + 5)/(t - 3/t - + 4) - 12/t - 8)*(t - 3/t - 4)) - 3/((t - 3/t - 4)*t) + sage: expand((~M*M)[0,0]) + 1 + sage: (~M * M).simplify_rational() + [1 0 0] + [0 1 0] + [0 0 1] + """ + return self._maxima_(maxima).fullratsimp()._sage_() + + def simplify_full(self): + """ + Simplify a symbolic matrix by calling + :meth:`Expression.simplify_full()` componentwise. + + INPUT: + + - ``self`` -- the matrix whose entries we should simplify. + + OUTPUT: + + A copy of ``self`` with all of its entries simplified. + + EXAMPLES: + + Symbolic matrices will have their entries simplified:: + + sage: a,n,k = SR.var('a,n,k') + sage: f1 = sin(x)^2 + cos(x)^2 + sage: f2 = sin(x/(x^2 + x)) + sage: f3 = binomial(n,k)*factorial(k)*factorial(n-k) + sage: f4 = x*sin(2)/(x^a) + sage: A = matrix(SR, [[f1,f2],[f3,f4]]) + sage: A.simplify_full() + [ 1 sin(1/(x + 1))] + [ factorial(n) x^(-a + 1)*sin(2)] + + """ + M = self.parent() + return M([expr.simplify_full() for expr in self]) + + def canonicalize_radical(self): + r""" + Choose a canonical branch of each entry of ``self`` by calling + :meth:`Expression.canonicalize_radical()` componentwise. + + EXAMPLES:: + + sage: var('x','y') + (x, y) + sage: l1 = [sqrt(2)*sqrt(3)*sqrt(6) , log(x*y)] + sage: l2 = [sin(x/(x^2 + x)) , 1] + sage: m = matrix([l1, l2]) + sage: m + [sqrt(6)*sqrt(3)*sqrt(2) log(x*y)] + [ sin(x/(x^2 + x)) 1] + sage: m.canonicalize_radical() + [ 6 log(x) + log(y)] + [ sin(1/(x + 1)) 1] + """ + M = self.parent() + return M([expr.canonicalize_radical() for expr in self]) + + def factor(self): + """ + Operate point-wise on each element. + + EXAMPLES:: + + sage: M = matrix(SR, 2, 2, x^2 - 2*x + 1); M + [x^2 - 2*x + 1 0] + [ 0 x^2 - 2*x + 1] + sage: M.factor() + [(x - 1)^2 0] + [ 0 (x - 1)^2] + """ + return self._maxima_(maxima).factor()._sage_() + + def expand(self): + """ + Operate point-wise on each element. + + EXAMPLES:: + + sage: M = matrix(2, 2, range(4)) - var('x') + sage: M*M + [ x^2 + 2 -2*x + 3] + [ -4*x + 6 (x - 3)^2 + 2] + sage: (M*M).expand() + [ x^2 + 2 -2*x + 3] + [ -4*x + 6 x^2 - 6*x + 11] + """ + from sage.misc.call import attrcall + return self.apply_map(attrcall('expand')) + + def variables(self): + """ + Return the variables of ``self``. + + EXAMPLES:: + + sage: var('a,b,c,x,y') + (a, b, c, x, y) + sage: m = matrix([[x, x+2], [x^2, x^2+2]]); m + [ x x + 2] + [ x^2 x^2 + 2] + sage: m.variables() + (x,) + sage: m = matrix([[a, b+c], [x^2, y^2+2]]); m + [ a b + c] + [ x^2 y^2 + 2] + sage: m.variables() + (a, b, c, x, y) + """ + vars = set(sum([op.variables() for op in self.list()], ())) + return tuple(sorted(vars, key=repr)) + + def arguments(self): + """ + Return a tuple of the arguments that ``self`` can take. + + EXAMPLES:: + + sage: var('x,y,z') + (x, y, z) + sage: M = MatrixSpace(SR,2,2) + sage: M(x).arguments() + (x,) + sage: M(x+sin(x)).arguments() + (x,) + """ + return self.variables() + + def number_of_arguments(self): + """ + Return the number of arguments that ``self`` can take. + + EXAMPLES:: + + sage: var('a,b,c,x,y') + (a, b, c, x, y) + sage: m = matrix([[a, (x+y)/(x+y)], [x^2, y^2+2]]); m + [ a 1] + [ x^2 y^2 + 2] + sage: m.number_of_arguments() + 3 + """ + return len(self.variables()) + + def __call__(self, *args, **kwargs): + """ + EXAMPLES:: + + sage: var('x,y,z') + (x, y, z) + sage: M = MatrixSpace(SR,2,2) + sage: h = M(sin(x)+cos(x)) + sage: h + [cos(x) + sin(x) 0] + [ 0 cos(x) + sin(x)] + sage: h(x=1) + [cos(1) + sin(1) 0] + [ 0 cos(1) + sin(1)] + sage: h(x=x) + [cos(x) + sin(x) 0] + [ 0 cos(x) + sin(x)] + + sage: h = M((sin(x)+cos(x)).function(x)) + sage: h + [cos(x) + sin(x) 0] + [ 0 cos(x) + sin(x)] + + sage: f = M([0,x,y,z]); f + [0 x] + [y z] + sage: f.arguments() + (x, y, z) + sage: f() + [0 x] + [y z] + sage: f(x=1) + [0 1] + [y z] + sage: f(x=1,y=2) + [0 1] + [2 z] + sage: f(x=1,y=2,z=3) + [0 1] + [2 3] + sage: f({x:1,y:2,z:3}) + [0 1] + [2 3] + + TESTS:: + + sage: f(1, x=2) + Traceback (most recent call last): + ... + ValueError: args and kwargs cannot both be specified + sage: f(x=1,y=2,z=3,t=4) + [0 1] + [2 3] + + sage: h(1) + Traceback (most recent call last): + ... + ValueError: use named arguments, like EXPR(x=..., y=...) + """ + if kwargs and args: + raise ValueError("args and kwargs cannot both be specified") + + if args: + if len(args) == 1 and isinstance(args[0], dict): + kwargs = {repr(x): vx for x, vx in args[0].iteritems()} + else: + raise ValueError('use named arguments, like EXPR(x=..., y=...)') + + new_entries = [] + for entry in self.list(): + try: + new_entries.append(entry(**kwargs)) + except ValueError: + new_entries.append(entry) + + return self.parent(new_entries) + + cdef bint get_is_zero_unsafe(self, Py_ssize_t i, Py_ssize_t j) except -1: + r""" + Return 1 if the entry ``(i, j)`` is zero, otherwise 0. + + EXAMPLES:: + + sage: M = matrix(SR, [[0,1,0],[0,0,0]], sparse=True) + sage: M.zero_pattern_matrix() # indirect doctest + [1 0 1] + [1 1 1] + """ + entry = self.get_unsafe(i, j) + # See if we can avoid the full proof machinery that the entry is 0 + if entry.is_trivial_zero(): + return 1 + if entry: + return 0 + else: + return 1 + + def function(self, *args): + """ + Return a matrix over a callable symbolic expression ring. + + EXAMPLES:: + + sage: x, y = var('x,y') + sage: v = matrix([[x,y],[x*sin(y), 0]], sparse=True) + sage: w = v.function([x,y]); w + [ (x, y) |--> x (x, y) |--> y] + [(x, y) |--> x*sin(y) (x, y) |--> 0] + sage: w.parent() + Full MatrixSpace of 2 by 2 sparse matrices over Callable function ring with arguments (x, y) + """ + from sage.symbolic.callable import CallableSymbolicExpressionRing + return matrix(CallableSymbolicExpressionRing(args), + self.nrows(), self.ncols(), self.list(), sparse=True) From 095d4612e275de43e1f933453d313f54026c4908 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 3 Jun 2023 21:05:41 +0100 Subject: [PATCH 36/56] correct spacing to please linter --- src/sage/matrix/matrix_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 7652493e0b2..5de43333072 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -405,7 +405,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): try: from sage.symbolic.ring import SR except ImportError: - pass + pass else: if R is SR: try: From e73cf1b1ca66380e645f28831827d5d6871316ec Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sun, 4 Jun 2023 10:37:21 +0100 Subject: [PATCH 37/56] sparse=True in all examples/tests, fix for jordan_form() --- src/sage/matrix/matrix_symbolic_sparse.pyx | 109 +++++++++++---------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/src/sage/matrix/matrix_symbolic_sparse.pyx b/src/sage/matrix/matrix_symbolic_sparse.pyx index 01c4cee86a1..c03dba4e109 100644 --- a/src/sage/matrix/matrix_symbolic_sparse.pyx +++ b/src/sage/matrix/matrix_symbolic_sparse.pyx @@ -181,7 +181,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): TESTS:: - sage: m = matrix([[cos(pi/5), sin(pi/5)], [-sin(pi/5), cos(pi/5)]]) + sage: m = matrix([[cos(pi/5), sin(pi/5)], [-sin(pi/5), cos(pi/5)]], sparse=True) sage: m.echelonize(); m [1 0] [0 1] @@ -198,7 +198,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): EXAMPLES:: - sage: a=matrix(SR,[[1,2],[3,4]]) + sage: a=matrix(SR,[[1,2],[3,4]], sparse=True) sage: a.eigenvalues() [-1/2*sqrt(33) + 5/2, 1/2*sqrt(33) + 5/2] @@ -206,7 +206,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): Check for :trac:`31700`:: - sage: m = matrix([[cos(pi/5), sin(pi/5)], [-sin(pi/5), cos(pi/5)]]) + sage: m = matrix([[cos(pi/5), sin(pi/5)], [-sin(pi/5), cos(pi/5)]], sparse=True) sage: t = linear_transformation(m) sage: t.eigenvalues() [1/4*sqrt(5) - 1/4*sqrt(2*sqrt(5) - 10) + 1/4, @@ -237,7 +237,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): EXAMPLES:: - sage: A = matrix(SR,3,3,range(9)); A + sage: A = matrix(SR,3,3,range(9), sparse=True); A [0 1 2] [3 4 5] [6 7 8] @@ -254,7 +254,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): :: - sage: A = matrix(SR, 2, 2, var('a,b,c,d')) + sage: A = matrix(SR, 2, 2, var('a,b,c,d'), sparse=True) sage: A.eigenvectors_left() [(1/2*a + 1/2*d - 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2), [(1, -1/2*(a - d + sqrt(a^2 + 4*b*c - 2*a*d + d^2))/c)], 1), (1/2*a + 1/2*d + 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2), [(1, -1/2*(a - d - sqrt(a^2 + 4*b*c - 2*a*d + d^2))/c)], 1)] sage: es = A.eigenvectors_left(); es @@ -274,7 +274,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): matrix. :: sage: G=graphs.CycleGraph(5) - sage: am = G.adjacency_matrix() + sage: am = G.adjacency_matrix(sparse=True) sage: spectrum = am.eigenvectors_left() sage: qqbar_evalue = spectrum[2][0] sage: type(qqbar_evalue) @@ -282,7 +282,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): sage: qqbar_evalue 0.618033988749895? - sage: am = G.adjacency_matrix().change_ring(SR) + sage: am = G.adjacency_matrix(sparse=True).change_ring(SR) sage: spectrum = am.eigenvectors_left() sage: symbolic_evalue = spectrum[2][0] sage: type(symbolic_evalue) @@ -296,14 +296,14 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): A slightly larger matrix with a "nice" spectrum. :: sage: G = graphs.CycleGraph(6) - sage: am = G.adjacency_matrix().change_ring(SR) + sage: am = G.adjacency_matrix(sparse=True).change_ring(SR) sage: am.eigenvectors_left() [(-1, [(1, 0, -1, 1, 0, -1), (0, 1, -1, 0, 1, -1)], 2), (1, [(1, 0, -1, -1, 0, 1), (0, 1, 1, 0, -1, -1)], 2), (-2, [(1, -1, 1, -1, 1, -1)], 1), (2, [(1, 1, 1, 1, 1, 1)], 1)] TESTS:: - sage: A = matrix(SR, [[1, 2], [3, 4]]) - sage: B = matrix(SR, [[1, 1], [0, 1]]) + sage: A = matrix(SR, [[1, 2], [3, 4]], sparse=True) + sage: B = matrix(SR, [[1, 1], [0, 1]], sparse=True) sage: A.eigenvectors_left(B) Traceback (most recent call last): ... @@ -312,7 +312,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): Check that :trac:`23332` is fixed:: - sage: matrix([[x, x^2], [1, 0]]).eigenvectors_left() + sage: matrix([[x, x^2], [1, 0]], sparse=True).eigenvectors_left() [(-1/2*x*(sqrt(5) - 1), [(1, -1/2*x*(sqrt(5) + 1))], 1), (1/2*x*(sqrt(5) + 1), [(1, 1/2*x*(sqrt(5) - 1))], 1)] """ @@ -351,7 +351,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): EXAMPLES:: - sage: A = matrix(SR,2,2,range(4)); A + sage: A = matrix(SR,2,2,range(4), sparse=True); A [0 1] [2 3] sage: right = A.eigenvectors_right(); right @@ -367,8 +367,8 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): TESTS:: - sage: A = matrix(SR, [[1, 2], [3, 4]]) - sage: B = matrix(SR, [[1, 1], [0, 1]]) + sage: A = matrix(SR, [[1, 2], [3, 4]], sparse=True) + sage: B = matrix(SR, [[1, 1], [0, 1]], sparse=True) sage: A.eigenvectors_right(B) Traceback (most recent call last): ... @@ -377,7 +377,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): Check that :trac:`23332` is fixed:: - sage: matrix([[x, x^2], [1, 0]]).eigenvectors_right() + sage: matrix([[x, x^2], [1, 0]], sparse=True).eigenvectors_right() [(-1/2*x*(sqrt(5) - 1), [(1, -1/2*(sqrt(5) + 1)/x)], 1), (1/2*x*(sqrt(5) + 1), [(1, 1/2*(sqrt(5) - 1)/x)], 1)] """ @@ -399,7 +399,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): EXAMPLES:: - sage: m = matrix(SR,2, [0,x,x,0]); m + sage: m = matrix(SR,2, [0,x,x,0], sparse=True); m [0 x] [x 0] sage: m.exp() @@ -412,11 +412,11 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): Exponentiation works on 0x0 and 1x1 matrices, but the 1x1 example requires a patched version of maxima (:trac:`32898`) for now:: - sage: m = matrix(SR,0,[]); m + sage: m = matrix(SR,0,[], sparse=True); m [] sage: m.exp() [] - sage: m = matrix(SR,1,[2]); m + sage: m = matrix(SR,1,[2], sparse=True); m [2] sage: m.exp() # not tested, requires patched maxima [e^2] @@ -424,7 +424,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): Commuting matrices `m, n` have the property that `e^{m+n} = e^m e^n` (but non-commuting matrices need not):: - sage: m = matrix(SR,2,[1..4]); n = m^2 + sage: m = matrix(SR,2,[1..4], sparse=True); n = m^2 sage: m*n [ 37 54] [ 81 118] @@ -438,7 +438,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): The input matrix must be square:: - sage: m = matrix(SR,2,3,[1..6]); exp(m) + sage: m = matrix(SR,2,3,[1..6], sparse=True); exp(m) Traceback (most recent call last): ... ValueError: exp only defined on square matrices @@ -446,14 +446,15 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): In this example we take the symbolic answer and make it numerical at the end:: - sage: exp(matrix(SR, [[1.2, 5.6], [3,4]])).change_ring(RDF) # rel tol 1e-15 + sage: exp(matrix(SR, [[1.2, 5.6], [3,4]], sparse=True)).change_ring(RDF) # rel tol 1e-15 [ 346.5574872980695 661.7345909344504] [354.50067371488416 677.4247827652946] Another example involving the reversed identity matrix, which we clumsily create:: - sage: m = identity_matrix(SR,4); m = matrix(list(reversed(m.rows()))) * x + sage: m = identity_matrix(SR,4, sparse=True) + sage: m = matrix(list(reversed(m.rows())), sparse=True) * x sage: exp(m) [1/2*(e^(2*x) + 1)*e^(-x) 0 0 1/2*(e^(2*x) - 1)*e^(-x)] [ 0 1/2*(e^(2*x) + 1)*e^(-x) 1/2*(e^(2*x) - 1)*e^(-x) 0] @@ -490,10 +491,10 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): EXAMPLES:: - sage: M = matrix(SR, 2, 2, var('a,b,c,d')) + sage: M = matrix(SR, 2, 2, var('a,b,c,d'), sparse=True) sage: M.charpoly('t') t^2 + (-a - d)*t - b*c + a*d - sage: matrix(SR, 5, [1..5^2]).charpoly() + sage: matrix(SR, 5, [1..5^2], sparse=True).charpoly() x^5 - 65*x^4 - 250*x^3 TESTS: @@ -560,12 +561,12 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): EXAMPLES:: - sage: M = Matrix.identity(SR, 2) + sage: M = Matrix.identity(SR, 2, sparse=True) sage: M.minpoly() x - 1 sage: t = var('t') - sage: m = matrix(2, [1, 2, 4, t]) + sage: m = matrix(2, [1, 2, 4, t], sparse=True) sage: m.minimal_polynomial() x^2 + (-t - 1)*x + t - 8 @@ -573,7 +574,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): Check that the variable `x` can occur in the matrix:: - sage: m = matrix([[x]]) + sage: m = matrix([[x]], sparse=True) sage: m.minimal_polynomial('y') y - x @@ -597,17 +598,17 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): EXAMPLES:: - sage: a = matrix(SR,[[1,2],[3,4]]) + sage: a = matrix(SR,[[1,2],[3,4]], sparse=True) sage: a.fcp() x^2 - 5*x - 2 sage: [i for i in a.fcp()] [(x^2 - 5*x - 2, 1)] - sage: a = matrix(SR,[[1,0],[0,2]]) + sage: a = matrix(SR,[[1,0],[0,2]], sparse=True) sage: a.fcp() (x - 2) * (x - 1) sage: [i for i in a.fcp()] [(x - 2, 1), (x - 1, 1)] - sage: a = matrix(SR, 5, [1..5^2]) + sage: a = matrix(SR, 5, [1..5^2], sparse=True) sage: a.fcp() (x^2 - 65*x - 250) * x^3 sage: list(a.fcp()) @@ -647,16 +648,16 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): We start with some examples of diagonalisable matrices:: sage: a,b,c,d = var('a,b,c,d') - sage: matrix([a]).jordan_form() + sage: matrix([a], sparse=True).jordan_form() [a] - sage: matrix([[a, 0], [1, d]]).jordan_form(subdivide=True) + sage: matrix([[a, 0], [1, d]], sparse=True).jordan_form(subdivide=True) [d|0] [-+-] [0|a] - sage: matrix([[a, 0], [1, d]]).jordan_form(subdivide=False) + sage: matrix([[a, 0], [1, d]], sparse=True).jordan_form(subdivide=False) [d 0] [0 a] - sage: matrix([[a, x, x], [0, b, x], [0, 0, c]]).jordan_form() + sage: matrix([[a, x, x], [0, b, x], [0, 0, c]], sparse=True).jordan_form() [c|0|0] [-+-+-] [0|b|0] @@ -666,10 +667,10 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): In the following examples, we compute Jordan forms of some non-diagonalisable matrices:: - sage: matrix([[a, a], [0, a]]).jordan_form() + sage: matrix([[a, a], [0, a]], sparse=True).jordan_form() [a 1] [0 a] - sage: matrix([[a, 0, b], [0, c, 0], [0, 0, a]]).jordan_form() + sage: matrix([[a, 0, b], [0, c, 0], [0, 0, a]], sparse=True).jordan_form() [c|0 0] [-+---] [0|a 1] @@ -679,7 +680,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): Note that symbolic expressions may need to be simplified to make consistency checks succeed:: - sage: A = matrix([[x - a*c, a^2], [-c^2, x + a*c]]) + sage: A = matrix([[x - a*c, a^2], [-c^2, x + a*c]], sparse=True) sage: J, P = A.jordan_form(transformation=True) sage: J, P ( @@ -692,7 +693,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): sage: A1.simplify_rational() == A True - sage: B = matrix([[a, b, c], [0, a, d], [0, 0, a]]) + sage: B = matrix([[a, b, c], [0, a, d], [0, 0, a]], sparse=True) sage: J, T = B.jordan_form(transformation=True) sage: J, T ( @@ -705,24 +706,24 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): Finally, some examples involving square roots:: - sage: matrix([[a, -b], [b, a]]).jordan_form() + sage: matrix([[a, -b], [b, a]], sparse=True).jordan_form() [a - I*b| 0] [-------+-------] [ 0|a + I*b] - sage: matrix([[a, b], [c, d]]).jordan_form(subdivide=False) + sage: matrix([[a, b], [c, d]], sparse=True).jordan_form(subdivide=False) [1/2*a + 1/2*d - 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2) 0] [ 0 1/2*a + 1/2*d + 1/2*sqrt(a^2 + 4*b*c - 2*a*d + d^2)] """ A = self._maxima_lib_() jordan_info = A.jordan() - J = jordan_info.dispJordan()._sage_() + J = matrix(jordan_info.dispJordan()._sage_(), sparse=True) if subdivide: v = [x[1] for x in jordan_info] w = [sum(v[0:i]) for i in xrange(1, len(v))] J.subdivide(w, w) if transformation: P = A.diag_mode_matrix(jordan_info)._sage_() - return J, P + return J, matrix(P, sparse=True) else: return J @@ -734,7 +735,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): sage: var('x,y,z') (x, y, z) - sage: m = matrix([[z, (x+y)/(x+y)], [x^2, y^2+2]]); m + sage: m = matrix([[z, (x+y)/(x+y)], [x^2, y^2+2]], sparse=True); m [ z 1] [ x^2 y^2 + 2] sage: m.simplify() @@ -748,7 +749,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): EXAMPLES:: sage: theta = var('theta') - sage: M = matrix(SR, 2, 2, [cos(theta), sin(theta), -sin(theta), cos(theta)]) + sage: M = matrix(SR, 2, 2, [cos(theta), sin(theta), -sin(theta), cos(theta)], sparse=True) sage: ~M [1/cos(theta) - sin(theta)^2/((sin(theta)^2/cos(theta) + cos(theta))*cos(theta)^2) -sin(theta)/((sin(theta)^2/cos(theta) + cos(theta))*cos(theta))] [ sin(theta)/((sin(theta)^2/cos(theta) + cos(theta))*cos(theta)) 1/(sin(theta)^2/cos(theta) + cos(theta))] @@ -762,7 +763,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): """ EXAMPLES:: - sage: M = matrix(SR, 3, 3, range(9)) - var('t') + sage: M = matrix(SR, 3, 3, range(9), sparse=True) - var('t') sage: (~M*M)[0,0] t*(3*(2/t + (6/t + 7)/((t - 3/t - 4)*t))*(2/t + (6/t + 5)/((t - 3/t - 4)*t))/(t - (6/t + 7)*(6/t + 5)/(t - 3/t - 4) - 12/t - 8) + 1/t + @@ -801,7 +802,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): sage: f2 = sin(x/(x^2 + x)) sage: f3 = binomial(n,k)*factorial(k)*factorial(n-k) sage: f4 = x*sin(2)/(x^a) - sage: A = matrix(SR, [[f1,f2],[f3,f4]]) + sage: A = matrix(SR, [[f1,f2],[f3,f4]], sparse=True) sage: A.simplify_full() [ 1 sin(1/(x + 1))] [ factorial(n) x^(-a + 1)*sin(2)] @@ -821,7 +822,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): (x, y) sage: l1 = [sqrt(2)*sqrt(3)*sqrt(6) , log(x*y)] sage: l2 = [sin(x/(x^2 + x)) , 1] - sage: m = matrix([l1, l2]) + sage: m = matrix([l1, l2], sparse=True) sage: m [sqrt(6)*sqrt(3)*sqrt(2) log(x*y)] [ sin(x/(x^2 + x)) 1] @@ -838,14 +839,14 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): EXAMPLES:: - sage: M = matrix(SR, 2, 2, x^2 - 2*x + 1); M + sage: M = matrix(SR, 2, 2, x^2 - 2*x + 1, sparse=True); M [x^2 - 2*x + 1 0] [ 0 x^2 - 2*x + 1] sage: M.factor() [(x - 1)^2 0] [ 0 (x - 1)^2] """ - return self._maxima_(maxima).factor()._sage_() + return matrix(self._maxima_(maxima).factor()._sage_(), sparse=True) def expand(self): """ @@ -872,12 +873,12 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): sage: var('a,b,c,x,y') (a, b, c, x, y) - sage: m = matrix([[x, x+2], [x^2, x^2+2]]); m + sage: m = matrix([[x, x+2], [x^2, x^2+2]], sparse=True); m [ x x + 2] [ x^2 x^2 + 2] sage: m.variables() (x,) - sage: m = matrix([[a, b+c], [x^2, y^2+2]]); m + sage: m = matrix([[a, b+c], [x^2, y^2+2]], sparse=True); m [ a b + c] [ x^2 y^2 + 2] sage: m.variables() @@ -894,7 +895,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): sage: var('x,y,z') (x, y, z) - sage: M = MatrixSpace(SR,2,2) + sage: M = MatrixSpace(SR,2,2, sparse=True) sage: M(x).arguments() (x,) sage: M(x+sin(x)).arguments() @@ -910,7 +911,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): sage: var('a,b,c,x,y') (a, b, c, x, y) - sage: m = matrix([[a, (x+y)/(x+y)], [x^2, y^2+2]]); m + sage: m = matrix([[a, (x+y)/(x+y)], [x^2, y^2+2]], sparse=True); m [ a 1] [ x^2 y^2 + 2] sage: m.number_of_arguments() @@ -924,7 +925,7 @@ cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): sage: var('x,y,z') (x, y, z) - sage: M = MatrixSpace(SR,2,2) + sage: M = MatrixSpace(SR,2,2, sparse=True) sage: h = M(sin(x)+cos(x)) sage: h [cos(x) + sin(x) 0] From 128c13727cda9984612eaae19cca178435804025 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sun, 4 Jun 2023 11:06:02 +0100 Subject: [PATCH 38/56] vector_symbolic_sparse: needed for matrix_symbolic_sparse without it, simplify_full() and canonicalize_radical() do not work also fixed docs by adding few */modules/*sparse* missing in the index --- src/doc/en/reference/modules/index.rst | 4 + src/sage/modules/free_module.py | 10 +- src/sage/modules/vector_symbolic_dense.py | 4 +- src/sage/modules/vector_symbolic_sparse.py | 118 +++++++++++++++++++++ 4 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 src/sage/modules/vector_symbolic_sparse.py diff --git a/src/doc/en/reference/modules/index.rst b/src/doc/en/reference/modules/index.rst index 8bf760a6ed8..93a337db04c 100644 --- a/src/doc/en/reference/modules/index.rst +++ b/src/doc/en/reference/modules/index.rst @@ -99,10 +99,14 @@ Vectors :maxdepth: 1 sage/modules/vector_integer_dense + sage/modules/vector_integer_sparse sage/modules/vector_mod2_dense sage/modules/vector_modn_dense + sage/modules/vector_modn_sparse sage/modules/vector_rational_dense + sage/modules/vector_rational_sparse sage/modules/vector_symbolic_dense + sage/modules/vector_symbolic_sparse sage/modules/vector_callable_symbolic_dense sage/modules/vector_double_dense sage/modules/vector_real_double_dense diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 6e648c6bd70..8b1cc879d27 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -8184,9 +8184,13 @@ def element_class(R, is_sparse): elif isinstance(R, sage.rings.abc.CallableSymbolicExpressionRing) and not is_sparse: import sage.modules.vector_callable_symbolic_dense return sage.modules.vector_callable_symbolic_dense.Vector_callable_symbolic_dense - elif isinstance(R, sage.rings.abc.SymbolicRing) and not is_sparse: - import sage.modules.vector_symbolic_dense - return sage.modules.vector_symbolic_dense.Vector_symbolic_dense + elif isinstance(R, sage.rings.abc.SymbolicRing): + if not is_sparse: + import sage.modules.vector_symbolic_dense + return sage.modules.vector_symbolic_dense.Vector_symbolic_dense + else: + import sage.modules.vector_symbolic_sparse + return sage.modules.vector_symbolic_sparse.Vector_symbolic_sparse if is_sparse: return free_module_element.FreeModuleElement_generic_sparse diff --git a/src/sage/modules/vector_symbolic_dense.py b/src/sage/modules/vector_symbolic_dense.py index 200d82ebf15..e4d9efff0b3 100644 --- a/src/sage/modules/vector_symbolic_dense.py +++ b/src/sage/modules/vector_symbolic_dense.py @@ -1,7 +1,7 @@ """ -Vectors over the symbolic ring +Dense vectors over the symbolic ring -Implements vectors over the symbolic ring. +Implements dense vectors over the symbolic ring. AUTHORS: diff --git a/src/sage/modules/vector_symbolic_sparse.py b/src/sage/modules/vector_symbolic_sparse.py new file mode 100644 index 00000000000..30ec55214c6 --- /dev/null +++ b/src/sage/modules/vector_symbolic_sparse.py @@ -0,0 +1,118 @@ +""" +Sparse vectors over the symbolic ring + +Implements vectors over the symbolic ring. + +AUTHORS: + +- Robert Bradshaw (2011-05-25): Added more element-wise simplification methods + +- Joris Vankerschaver (2011-05-15): Initial version + +- Dima Pasechnik (2023-06-04): cloning from the dense case + +EXAMPLES:: + + sage: x, y = var('x, y') + sage: u = vector([sin(x)^2 + cos(x)^2, log(2*y) + log(3*y)], sparse=True); u + (cos(x)^2 + sin(x)^2, log(3*y) + log(2*y)) + sage: type(u) + + sage: u.simplify_full() + (1, log(3*y) + log(2*y)) + +TESTS: + +Check that the outcome of arithmetic with symbolic vectors is again +a symbolic vector (:trac:`11549`):: + + sage: v = vector(SR, [1, 2], sparse=True) + sage: w = vector(SR, [sin(x), 0], sparse=True) + sage: type(v) + + sage: type(w) + + sage: type(v + w) + + sage: type(-v) + + sage: type(5*w) + + +Test pickling/unpickling:: + + sage: u = vector(SR, [sin(x^2)], sparse=True) + sage: loads(dumps(u)) == u + True + +""" + +#***************************************************************************** +# Copyright (C) 2011 Joris Vankerschaver (jv@caltech.edu) +# +# Distributed under the terms of the GNU General Public License (GPL) +# as published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# http://www.gnu.org/licenses/ +#***************************************************************************** + +from . import free_module_element +from sage.symbolic.expression import Expression + + +def apply_map(phi): + """ + Returns a function that applies phi to its argument. + + EXAMPLES:: + + sage: from sage.modules.vector_symbolic_sparse import apply_map + sage: v = vector([1,2,3], sparse=True) + sage: f = apply_map(lambda x: x+1) + sage: f(v) + (2, 3, 4) + + """ + def apply(self, *args, **kwds): + """ + Generic function used to implement common symbolic operations + elementwise as methods of a vector. + + EXAMPLES:: + + sage: var('x,y') + (x, y) + sage: v = vector([sin(x)^2 + cos(x)^2, log(x*y), sin(x/(x^2 + x)), factorial(x+1)/factorial(x)], sparse=True) + sage: v.simplify_trig() + (1, log(x*y), sin(1/(x + 1)), factorial(x + 1)/factorial(x)) + sage: v.canonicalize_radical() + (cos(x)^2 + sin(x)^2, log(x) + log(y), sin(1/(x + 1)), factorial(x + 1)/factorial(x)) + sage: v.simplify_rational() + (cos(x)^2 + sin(x)^2, log(x*y), sin(1/(x + 1)), factorial(x + 1)/factorial(x)) + sage: v.simplify_factorial() + (cos(x)^2 + sin(x)^2, log(x*y), sin(x/(x^2 + x)), x + 1) + sage: v.simplify_full() + (1, log(x*y), sin(1/(x + 1)), x + 1) + + sage: v = vector([sin(2*x), sin(3*x)], sparse=True) + sage: v.simplify_trig() + (2*cos(x)*sin(x), (4*cos(x)^2 - 1)*sin(x)) + sage: v.simplify_trig(False) + (sin(2*x), sin(3*x)) + sage: v.simplify_trig(expand=False) + (sin(2*x), sin(3*x)) + """ + return self.apply_map(lambda x: phi(x, *args, **kwds)) + apply.__doc__ += "\nSee Expression." + phi.__name__ + "() for optional arguments." + return apply + + +class Vector_symbolic_sparse(free_module_element.FreeModuleElement_generic_sparse): + pass + +# Add elementwise methods. +for method in ['simplify', 'simplify_factorial', + 'simplify_log', 'simplify_rational', + 'simplify_trig', 'simplify_full', 'trig_expand', + 'canonicalize_radical', 'trig_reduce']: + setattr(Vector_symbolic_sparse, method, apply_map(getattr(Expression, method))) From 1e8b313bca8687558f14231d11375a9a3f152cd2 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 22 May 2023 12:14:10 +0100 Subject: [PATCH 39/56] remove obsolete .zenodo.json* files, update CITATION.cff the latter overrides the former, cf https://github.com/citation-file-format/citation-file-format/issues/374 This will fix https://github.com/sagemath/sage/issues/35659 --- .zenodo.json.in | 27 --------------------------- CITATION.cff | 4 ++-- 2 files changed, 2 insertions(+), 29 deletions(-) delete mode 100644 .zenodo.json.in diff --git a/.zenodo.json.in b/.zenodo.json.in deleted file mode 100644 index 744e020705a..00000000000 --- a/.zenodo.json.in +++ /dev/null @@ -1,27 +0,0 @@ -{ - "description": "Mirror of the Sage https://sagemath.org/ source tree", - "license": "other-open", - "title": "sagemath/sage: ${SAGE_VERSION}", - "version": "${SAGE_VERSION}", - "upload_type": "software", - "publication_date": "${SAGE_RELEASE_DATE}", - "creators": [ - { - "affiliation": "SageMath.org", - "name": "The SageMath Developers" - } - ], - "access_right": "open", - "related_identifiers": [ - { - "scheme": "url", - "identifier": "https://github.com/sagemath/sage/tree/${SAGE_VERSION}", - "relation": "isSupplementTo" - }, - { - "scheme": "doi", - "identifier": "10.5281/zenodo.593563", - "relation": "isNewVersionOf" - } - ] -} diff --git a/CITATION.cff b/CITATION.cff index d97e13cb2cb..c5d6e71ae60 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: 9.5 +version: 10.0 doi: 10.5281/zenodo.593563 -date-released: 2022-01-18 +date-released: 2023-05-20 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" From afd0acbb75ed3e0367408a369086f5f143a03c71 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 22 May 2023 12:25:06 +0100 Subject: [PATCH 40/56] remove the creation of zenodo json --- src/bin/sage-update-version | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/bin/sage-update-version b/src/bin/sage-update-version index 40df8926f74..d38392d907f 100755 --- a/src/bin/sage-update-version +++ b/src/bin/sage-update-version @@ -86,15 +86,9 @@ echo "$SAGE_VERSION_BANNER" > "$SAGE_ROOT/VERSION.txt" # Regenerate auto-generated files tarball "$SAGE_ROOT/bootstrap" -s -# Create json file for Zenodo -export SAGE_VERSION -export SAGE_RELEASE_DATE -envsubst <"$SAGE_ROOT/.zenodo.json.in" >"$SAGE_ROOT/.zenodo.json" - # Commit auto-generated changes git commit -m "Updated SageMath version to $SAGE_VERSION" -- \ "$SAGE_ROOT/VERSION.txt" \ - "$SAGE_ROOT/.zenodo.json" \ "$SAGE_SRC/sage/version.py" \ "$SAGE_SRC/VERSION.txt" \ "$SAGE_SRC/bin/sage-version.sh" \ From 9d49ed25b1d87374f0e40d6521d0bce6430faab7 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 22 May 2023 23:21:41 +0100 Subject: [PATCH 41/56] generate CITATION.cff from a template --- CITATION.cff.in | 11 +++++++++++ src/bin/sage-update-version | 6 ++++++ 2 files changed, 17 insertions(+) create mode 100644 CITATION.cff.in diff --git a/CITATION.cff.in b/CITATION.cff.in new file mode 100644 index 00000000000..bf7d5d3e58c --- /dev/null +++ b/CITATION.cff.in @@ -0,0 +1,11 @@ +cff-version: 1.2.0 +message: "If you use this software, please cite it as below." +title: SageMath +abstract: SageMath is a free open-source mathematics software system. +authors: +- name: "The SageMath Developers" +version: ${SAGE_VERSION} +doi: 10.5281/zenodo.593563 +date-released: ${SAGE_RELEASE_DATE} +repository-code: "https://github.com/sagemath/sage" +url: "https://www.sagemath.org/" diff --git a/src/bin/sage-update-version b/src/bin/sage-update-version index d38392d907f..0aa1ded9e18 100755 --- a/src/bin/sage-update-version +++ b/src/bin/sage-update-version @@ -86,11 +86,17 @@ echo "$SAGE_VERSION_BANNER" > "$SAGE_ROOT/VERSION.txt" # Regenerate auto-generated files tarball "$SAGE_ROOT/bootstrap" -s +# Create CITATION file for Zenodo-GitHub integration +export SAGE_VERSION +export SAGE_RELEASE_DATE +envsubst <"$SAGE_ROOT/CITATION.cff.in" >"$SAGE_ROOT/CITATION.cff" + # Commit auto-generated changes git commit -m "Updated SageMath version to $SAGE_VERSION" -- \ "$SAGE_ROOT/VERSION.txt" \ "$SAGE_SRC/sage/version.py" \ "$SAGE_SRC/VERSION.txt" \ + "$SAGE_SRC/CITATION.cff" \ "$SAGE_SRC/bin/sage-version.sh" \ "$SAGE_ROOT/build/pkgs/configure/checksums.ini" \ "$SAGE_ROOT/build/pkgs/configure/package-version.txt" \ From 532b0ded7ebf7792c152d54eda948a99fda4f9d8 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 3 Jun 2023 10:23:20 +0100 Subject: [PATCH 42/56] fix location of CITATION.cff for git to check in --- src/bin/sage-update-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/sage-update-version b/src/bin/sage-update-version index 0aa1ded9e18..fd6d2a8dcf3 100755 --- a/src/bin/sage-update-version +++ b/src/bin/sage-update-version @@ -96,7 +96,7 @@ git commit -m "Updated SageMath version to $SAGE_VERSION" -- \ "$SAGE_ROOT/VERSION.txt" \ "$SAGE_SRC/sage/version.py" \ "$SAGE_SRC/VERSION.txt" \ - "$SAGE_SRC/CITATION.cff" \ + "$SAGE_ROOT/CITATION.cff" \ "$SAGE_SRC/bin/sage-version.sh" \ "$SAGE_ROOT/build/pkgs/configure/checksums.ini" \ "$SAGE_ROOT/build/pkgs/configure/package-version.txt" \ From d75ffed5837992673bd7fe526a7f366a6cc3f003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 4 Jun 2023 13:20:30 +0200 Subject: [PATCH 43/56] some pep8 cleanup in rigged-configurations --- .../bij_abstract_class.py | 30 +++++----- .../rigged_configurations/bij_infinity.py | 6 +- .../rigged_configurations/bij_type_A.py | 10 ++-- .../rigged_configurations/bij_type_A2_dual.py | 12 ++-- .../rigged_configurations/bij_type_A2_even.py | 10 ++-- .../rigged_configurations/bij_type_A2_odd.py | 10 ++-- .../rigged_configurations/bij_type_B.py | 56 +++++++++---------- .../rigged_configurations/bij_type_C.py | 14 ++--- .../rigged_configurations/bij_type_D.py | 24 ++++---- .../rigged_configurations/bij_type_D_tri.py | 26 ++++----- .../bij_type_D_twisted.py | 16 +++--- .../rigged_configurations/bij_type_E67.py | 28 +++++----- .../rigged_configurations/kleber_tree.py | 6 +- .../rigged_configurations/rc_crystal.py | 4 +- .../rigged_configuration_element.py | 12 ++-- .../tensor_product_kr_tableaux.py | 18 +++--- .../tensor_product_kr_tableaux_element.py | 28 +++++----- 17 files changed, 155 insertions(+), 155 deletions(-) diff --git a/src/sage/combinat/rigged_configurations/bij_abstract_class.py b/src/sage/combinat/rigged_configurations/bij_abstract_class.py index c06680c4cf2..66ad0ac37ce 100644 --- a/src/sage/combinat/rigged_configurations/bij_abstract_class.py +++ b/src/sage/combinat/rigged_configurations/bij_abstract_class.py @@ -17,7 +17,7 @@ - Travis Scrimshaw (2011-04-15): Initial version """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011, 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -29,8 +29,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from copy import deepcopy from sage.misc.abstract_method import abstract_method @@ -120,19 +120,19 @@ def run(self, verbose=False): """ if verbose: from sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element \ - import TensorProductOfKirillovReshetikhinTableauxElement + import TensorProductOfKirillovReshetikhinTableauxElement for cur_crystal in reversed(self.tp_krt): target = cur_crystal.parent()._r # Iterate through the columns for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))): - self.cur_path.insert(0, []) # Prepend an empty list + self.cur_path.insert(0, []) # Prepend an empty list self.cur_dims.insert(0, [0, 1]) for letter in reversed(cur_column): self.cur_dims[0][0] = self._next_index(self.cur_dims[0][0], target) - val = letter.value # Convert from a CrystalOfLetter to an Integer + val = letter.value # Convert from a CrystalOfLetter to an Integer if verbose: print("====================") @@ -142,7 +142,7 @@ def run(self, verbose=False): print("--------------------\n") # Build the next state - self.cur_path[0].insert(0, [letter]) # Prepend the value + self.cur_path[0].insert(0, [letter]) # Prepend the value self.next_state(val) # If we've split off a column, we need to merge the current column @@ -166,7 +166,7 @@ def run(self, verbose=False): for a in range(self.n): self._update_vacancy_nums(a) - self.ret_rig_con.set_immutable() # Return it to immutable + self.ret_rig_con.set_immutable() # Return it to immutable return self.ret_rig_con @abstract_method @@ -220,7 +220,7 @@ def _update_vacancy_nums(self, a): """ # Check to make sure we have a valid index (currently removed) # If the current tableau is empty, there is nothing to do - if not self.ret_rig_con[a]: # Check to see if we have vacancy numbers + if not self.ret_rig_con[a]: # Check to see if we have vacancy numbers return # Setup the first block @@ -268,7 +268,7 @@ def _update_partition_values(self, a): pos = 0 width = rigged_partition[index] val = rigged_partition.rigging[index] - for i in reversed(range(index-1)): + for i in reversed(range(index - 1)): if rigged_partition[i] > width or rigged_partition.rigging[i] >= val: pos = i + 1 break @@ -333,7 +333,7 @@ def __init__(self, RC_element): # This is a dummy edge to start the process cp = RC_element.__copy__() cp.set_immutable() - self._graph = [ [[], (cp, 0)] ] + self._graph = [[[], (cp, 0)]] def __eq__(self, rhs): r""" @@ -414,7 +414,7 @@ def run(self, verbose=False, build_graph=False): y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) - while self.cur_dims[0][0]: # > 0: + while self.cur_dims[0][0]: # > 0: if verbose: print("====================") print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) @@ -427,16 +427,16 @@ def run(self, verbose=False, build_graph=False): b = self.next_state(ht) # Make sure we have a crystal letter - ret_crystal_path[-1].append(letters(b)) # Append the rank + ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) - self.cur_dims.pop(0) # Pop off the leading column + self.cur_dims.pop(0) # Pop off the leading column if build_graph: - self._graph.pop(0) # Remove the dummy at the start + self._graph.pop(0) # Remove the dummy at the start from sage.graphs.digraph import DiGraph from sage.graphs.dot2tex_utils import have_dot2tex self._graph = DiGraph(self._graph, format="list_of_edges") diff --git a/src/sage/combinat/rigged_configurations/bij_infinity.py b/src/sage/combinat/rigged_configurations/bij_infinity.py index fa1067ccd93..8d9700e168a 100644 --- a/src/sage/combinat/rigged_configurations/bij_infinity.py +++ b/src/sage/combinat/rigged_configurations/bij_infinity.py @@ -175,13 +175,13 @@ def _call_(self, x): if ct.type() == 'D': lam[-2] = max(lam[-2], lam[-1]) lam.pop() - l = sum([ [[r+1,1]]*v for r,v in enumerate(lam[:-1]) ], []) + l = sum([[[r+1, 1]]*v for r, v in enumerate(lam[:-1])], []) n = len(I) - l = l + sum([ [[n,1], [n-1,1]] for k in range(lam[-1])], []) + l = l + sum([[[n,1], [n-1,1]] for k in range(lam[-1])], []) else: if ct.type() == 'B': lam[-1] *= 2 - l = sum([ [[r,1]]*lam[i] for i,r in enumerate(I) ], []) + l = sum([[[r, 1]]*lam[i] for i, r in enumerate(I)], []) RC = RiggedConfigurations(ct.affine(), reversed(l)) elt = RC(x) diff --git a/src/sage/combinat/rigged_configurations/bij_type_A.py b/src/sage/combinat/rigged_configurations/bij_type_A.py index a700b0b4ba7..198ba0fc433 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_A.py +++ b/src/sage/combinat/rigged_configurations/bij_type_A.py @@ -21,7 +21,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011, 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -33,8 +33,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_abstract_class import KRTToRCBijectionAbstract from sage.combinat.rigged_configurations.bij_abstract_class import RCToKRTBijectionAbstract @@ -122,7 +122,7 @@ def next_state(self, height): sage: bijection.next_state(1) 5 """ - height -= 1 # indexing + height -= 1 # indexing n = self.n ell = [None] * n b = None @@ -158,4 +158,4 @@ def next_state(self, height): if row_num is not None: self.cur_partitions[n - 1].rigging[row_num] = self.cur_partitions[n - 1].vacancy_numbers[row_num] - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_A2_dual.py b/src/sage/combinat/rigged_configurations/bij_type_A2_dual.py index 934a92851a5..dee72713e12 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_A2_dual.py +++ b/src/sage/combinat/rigged_configurations/bij_type_A2_dual.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_C import KRTToRCBijectionTypeC from sage.combinat.rigged_configurations.bij_type_C import RCToKRTBijectionTypeC @@ -155,7 +155,7 @@ def next_state(self, val): else: j = i - 1 while j >= 0 and partition._list[j] <= max_width + 2: - partition.rigging[j+1] = partition.rigging[j] # Shuffle it along + partition.rigging[j+1] = partition.rigging[j] # Shuffle it along j -= 1 partition._list.pop(i) partition._list.insert(j+1, max_width + 2) @@ -219,7 +219,7 @@ def next_state(self, height): sage: bijection.next_state(2) -1 """ - height -= 1 # indexing + height -= 1 # indexing n = self.n ell = [None] * (2*n) case_S = [False] * n @@ -333,4 +333,4 @@ def next_state(self, height): else: self.cur_partitions[n-1].rigging[row_num_bar_next] = self.cur_partitions[n-1].vacancy_numbers[row_num_bar_next] - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_A2_even.py b/src/sage/combinat/rigged_configurations/bij_type_A2_even.py index 76dcca00f1f..1c0d587139a 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_A2_even.py +++ b/src/sage/combinat/rigged_configurations/bij_type_A2_even.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_C import KRTToRCBijectionTypeC @@ -139,7 +139,7 @@ def next_state(self, height): sage: bijection.next_state(2) -1 """ - height -= 1 # indexing + height -= 1 # indexing n = self.n ell = [None] * (2*n) case_S = [False] * n @@ -213,4 +213,4 @@ def next_state(self, height): if row_num_bar is not None: self.cur_partitions[n-1].rigging[row_num_bar] = self.cur_partitions[n-1].vacancy_numbers[row_num_bar] - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_A2_odd.py b/src/sage/combinat/rigged_configurations/bij_type_A2_odd.py index 477cbf6f9ab..42a8cf956fb 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_A2_odd.py +++ b/src/sage/combinat/rigged_configurations/bij_type_A2_odd.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_A import RCToKRTBijectionTypeA @@ -126,7 +126,7 @@ def next_state(self, height): sage: bijection.next_state(1) -2 """ - height -= 1 # indexing + height -= 1 # indexing n = self.n ell = [None] * (2*n) b = None @@ -194,4 +194,4 @@ def next_state(self, height): if ret_row_next is not None: self.cur_partitions[n-1].rigging[ret_row_next] = self.cur_partitions[n-1].vacancy_numbers[ret_row_next] - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_B.py b/src/sage/combinat/rigged_configurations/bij_type_B.py index 0f672e8fc2b..fd924150380 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_B.py +++ b/src/sage/combinat/rigged_configurations/bij_type_B.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_C import KRTToRCBijectionTypeC @@ -92,7 +92,7 @@ def run(self, verbose=False): """ if verbose: from sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element \ - import TensorProductOfKirillovReshetikhinTableauxElement + import TensorProductOfKirillovReshetikhinTableauxElement for cur_crystal in reversed(self.tp_krt): r = cur_crystal.parent().r() @@ -108,7 +108,7 @@ def run(self, verbose=False): if verbose: print("====================") if len(self.cur_path) == 0: - print(repr([])) # Special case for displaying when the rightmost factor is a spinor + print(repr([])) # Special case for displaying when the rightmost factor is a spinor else: print(repr(TensorProductOfKirillovReshetikhinTableauxElement(self.tp_krt.parent(), self.cur_path))) print("--------------------") @@ -143,14 +143,14 @@ def run(self, verbose=False): r = cur_crystal.parent().r() # Iterate through the columns for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))): - bij.cur_path.insert(0, []) # Prepend an empty list + bij.cur_path.insert(0, []) # Prepend an empty list bij.cur_dims.insert(0, [0, 1]) # Note that we do not need to worry about iterating over columns # (see previous note about the data structure). for letter in reversed(cur_column): bij.cur_dims[0][0] += 1 - val = letter.value # Convert from a CrystalOfLetter to an Integer + val = letter.value # Convert from a CrystalOfLetter to an Integer if verbose: print("====================") @@ -160,7 +160,7 @@ def run(self, verbose=False): print("--------------------\n") # Build the next state - bij.cur_path[0].insert(0, [letter]) # Prepend the value + bij.cur_path[0].insert(0, [letter]) # Prepend the value bij.next_state(val) # If we've split off a column, we need to merge the current column @@ -201,14 +201,14 @@ def run(self, verbose=False): # Perform the regular type B_n^{(1)} bijection # Iterate through the columns for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))): - self.cur_path.insert(0, []) # Prepend an empty list + self.cur_path.insert(0, []) # Prepend an empty list self.cur_dims.insert(0, [0, 1]) # Note that we do not need to worry about iterating over columns # (see previous note about the data structure). for letter in reversed(cur_column): self.cur_dims[0][0] += 1 - val = letter.value # Convert from a CrystalOfLetter to an Integer + val = letter.value # Convert from a CrystalOfLetter to an Integer if verbose: print("====================") @@ -218,7 +218,7 @@ def run(self, verbose=False): print("--------------------\n") # Build the next state - self.cur_path[0].insert(0, [letter]) # Prepend the value + self.cur_path[0].insert(0, [letter]) # Prepend the value self.next_state(val) # If we've split off a column, we need to merge the current column @@ -241,7 +241,7 @@ def run(self, verbose=False): # And perform the inverse column splitting map on the RC for a in range(self.n): self._update_vacancy_nums(a) - self.ret_rig_con.set_immutable() # Return it to immutable + self.ret_rig_con.set_immutable() # Return it to immutable return self.ret_rig_con def next_state(self, val): @@ -371,7 +371,7 @@ def next_state(self, val): # Add 2 boxes j = i - 1 while j >= 0 and p._list[j] <= max_width + 2: - p.rigging[j+1] = p.rigging[j] # Shuffle it along + p.rigging[j+1] = p.rigging[j] # Shuffle it along j -= 1 p._list.pop(i) p._list.insert(j+1, max_width + 2) @@ -379,7 +379,7 @@ def next_state(self, val): break if p._list[i] == max_width and not singular_max_width: - p._list[i] += 1 # We always at least add a box to the first singular value + p._list[i] += 1 # We always at least add a box to the first singular value p.rigging[i] = None if case_QS: width_n = p._list[i] @@ -402,7 +402,7 @@ def next_state(self, val): # to attempt both # Make a *deep* copy of the element cp = self.ret_rig_con.__copy__() - for i,rp in enumerate(cp): + for i, rp in enumerate(cp): cp[i] = rp._clone() # We attempt case (S) first self._insert_cell_case_S(p) @@ -493,7 +493,7 @@ def other_outcome(self, rc, pos_val, width_n): p.rigging[i] = None case_QS = True break - if not case_QS: # we have not added a box yet + if not case_QS: # we have not added a box yet p._list.append(1) p.rigging.append(None) p.vacancy_numbers.append(None) @@ -641,7 +641,7 @@ def run(self, verbose=False, build_graph=False): y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), 'ls']) - while bij.cur_dims[0][0]: # > 0: + while bij.cur_dims[0][0]: # > 0: if verbose: print("====================") print(repr(RC(*bij.cur_partitions, use_vacancy_numbers=True))) @@ -653,15 +653,15 @@ def run(self, verbose=False, build_graph=False): bij.cur_dims[0][0] = bij._next_index(ht) b = bij.next_state(ht) # Make sure we have a crystal letter - ret_crystal_path[-1].append(letters(b)) # Append the rank + ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) - bij.cur_dims.pop(0) # Pop off the leading column + bij.cur_dims.pop(0) # Pop off the leading column - self.cur_dims.pop(0) # Pop off the spin rectangle + self.cur_dims.pop(0) # Pop off the spin rectangle self.cur_partitions = bij.cur_partitions # Convert the n-th partition back into the special type B one @@ -712,7 +712,7 @@ def run(self, verbose=False, build_graph=False): y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), '2x']) - while self.cur_dims[0][0]: #> 0: + while self.cur_dims[0][0]: # > 0: if verbose: print("====================") print(repr(self.rigged_con.parent()(*self.cur_partitions, use_vacancy_numbers=True))) @@ -720,20 +720,20 @@ def run(self, verbose=False, build_graph=False): print(ret_crystal_path) print("--------------------\n") - self.cur_dims[0][0] -= 1 # This takes care of the indexing + self.cur_dims[0][0] -= 1 # This takes care of the indexing b = self.next_state(self.cur_dims[0][0]) # Make sure we have a crystal letter - ret_crystal_path[-1].append(letters(b)) # Append the rank + ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) - self.cur_dims.pop(0) # Pop off the leading column + self.cur_dims.pop(0) # Pop off the leading column if build_graph: - self._graph.pop(0) # Remove the dummy at the start + self._graph.pop(0) # Remove the dummy at the start from sage.graphs.digraph import DiGraph from sage.graphs.dot2tex_utils import have_dot2tex self._graph = DiGraph(self._graph) @@ -796,7 +796,7 @@ def next_state(self, height): last_size = partition[j] case_S = True break - if not case_Q: # We found a singular string above the quasi-singular one + if not case_Q: # We found a singular string above the quasi-singular one break ell[n-1] = i last_size = partition[i] @@ -882,7 +882,7 @@ def next_state(self, height): self._update_vacancy_numbers(n - 1) if row_num_next is not None: self.cur_partitions[n-1].rigging[row_num_next] = self.cur_partitions[n-1].vacancy_numbers[row_num_next] - if row_num_bar_next is not None: # If we enter here, it means case (Q, S) holds + if row_num_bar_next is not None: # If we enter here, it means case (Q, S) holds vac_num = self.cur_partitions[n-1].vacancy_numbers[row_num_bar_next] self.cur_partitions[n-1].rigging[row_num_bar_next] = vac_num if make_quasisingular: @@ -895,4 +895,4 @@ def next_state(self, height): j += 1 self.cur_partitions[n-1].rigging[j-1] = vac_num - 1 - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_C.py b/src/sage/combinat/rigged_configurations/bij_type_C.py index 0d18e575043..d04267b5569 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_C.py +++ b/src/sage/combinat/rigged_configurations/bij_type_C.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_A import RCToKRTBijectionTypeA @@ -151,7 +151,7 @@ def _insert_cell_case_S(self, partition): if partition.rigging[i] is None: j = i - 1 while j >= 0 and partition._list[j] == partition._list[i]: - partition.rigging[j+1] = partition.rigging[j] # Shuffle it along + partition.rigging[j+1] = partition.rigging[j] # Shuffle it along j -= 1 partition._list[j+1] += 1 partition.rigging[j+1] = None @@ -176,7 +176,7 @@ def next_state(self, height): sage: bijection.next_state(1) -1 """ - height -= 1 # indexing + height -= 1 # indexing n = self.n ell = [None] * (2*n) case_S = [False] * n @@ -214,7 +214,7 @@ def next_state(self, height): if a >= height and self.cur_partitions[a][ell[a]] == last_size: ell[n+a] = ell[a] case_S[a] = True - else: # note last_size > 1 + else: # note last_size > 1 ell[n+a] = self._find_singular_string(self.cur_partitions[a], last_size) if ell[n + a] is None: @@ -262,4 +262,4 @@ def next_state(self, height): if row_num_next is not None: self.cur_partitions[n-1].rigging[row_num_next] = self.cur_partitions[n-1].vacancy_numbers[row_num_next] - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_D.py b/src/sage/combinat/rigged_configurations/bij_type_D.py index a09c9383f1c..12fb6c6be2c 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011, 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_A import RCToKRTBijectionTypeA @@ -83,7 +83,7 @@ def run(self, verbose=False): r = cur_crystal.parent().r() # Iterate through the columns for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))): - self.cur_path.insert(0, []) # Prepend an empty list + self.cur_path.insert(0, []) # Prepend an empty list # Check to see if we are a spinor column if r >= self.n-1: @@ -102,7 +102,7 @@ def run(self, verbose=False): # This check is needed for the n-1 spin column if self.cur_dims[0][0] < r: self.cur_dims[0][0] += 1 - val = letter.value # Convert from a CrystalOfLetter to an Integer + val = letter.value # Convert from a CrystalOfLetter to an Integer if verbose: print("====================") @@ -112,7 +112,7 @@ def run(self, verbose=False): print("--------------------\n") # Build the next state - self.cur_path[0].insert(0, [letter]) # Prepend the value + self.cur_path[0].insert(0, [letter]) # Prepend the value self.next_state(val) # Check to see if we are a spinor column @@ -139,7 +139,7 @@ def run(self, verbose=False): for a in range(self.n): self._update_vacancy_nums(a) - self.ret_rig_con.set_immutable() # Return it to immutable + self.ret_rig_con.set_immutable() # Return it to immutable return self.ret_rig_con def next_state(self, val): @@ -495,7 +495,7 @@ def run(self, verbose=False, build_graph=False): b = self.next_state(self.n) if b == self.n: b = -self.n - ret_crystal_path[-1].append(letters(b)) # Append the rank + ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) @@ -509,7 +509,7 @@ def run(self, verbose=False, build_graph=False): print(ret_crystal_path) print("--------------------\n") - self.cur_dims[0][0] -= 1 # This takes care of the indexing + self.cur_dims[0][0] -= 1 # This takes care of the indexing b = self.next_state(self.cur_dims[0][0]) # Corrections for spinor @@ -518,13 +518,13 @@ def run(self, verbose=False, build_graph=False): b = -(self.n-1) # Make sure we have a crystal letter - ret_crystal_path[-1].append(letters(b)) # Append the rank + ret_crystal_path[-1].append(letters(b)) # Append the rank if build_graph: y = self.rigged_con.parent()(*[x._clone() for x in self.cur_partitions], use_vacancy_numbers=True) self._graph.append([self._graph[-1][1], (y, len(self._graph)), letters(b)]) - self.cur_dims.pop(0) # Pop off the leading column + self.cur_dims.pop(0) # Pop off the leading column # Check to see if we were a spinor if dim[0] >= self.n-1: @@ -677,7 +677,7 @@ def next_state(self, height): self.cur_partitions[n - 1].rigging[ret_row_bar_next] = \ self.cur_partitions[n - 1].vacancy_numbers[ret_row_bar_next] - return(b) + return b def doubling_map(self): r""" diff --git a/src/sage/combinat/rigged_configurations/bij_type_D_tri.py b/src/sage/combinat/rigged_configurations/bij_type_D_tri.py index e0796bf880d..f143b3ce38a 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D_tri.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D_tri.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2014 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_A import RCToKRTBijectionTypeA @@ -169,7 +169,7 @@ def next_state(self, val): else: j = i - 1 while j >= 0 and P._list[j] <= max_width + 2: - P.rigging[j+1] = P.rigging[j] # Shuffle it along + P.rigging[j+1] = P.rigging[j] # Shuffle it along j -= 1 P._list.pop(i) P._list.insert(j+1, max_width + 2) @@ -193,7 +193,7 @@ def next_state(self, val): if P.rigging[i] is None: j = i - 1 while j >= 0 and P._list[j] == P._list[i]: - P.rigging[j+1] = P.rigging[j] # Shuffle it along + P.rigging[j+1] = P.rigging[j] # Shuffle it along j -= 1 P._list[j+1] += 1 P.rigging[j+1] = None @@ -210,7 +210,7 @@ def next_state(self, val): if P.rigging[i] is None: j = i - 1 while j >= 0 and P._list[j] == P._list[i]: - P.rigging[j+1] = P.rigging[j] # Shuffle it along + P.rigging[j+1] = P.rigging[j] # Shuffle it along j -= 1 P._list[j+1] += 1 P.rigging[j+1] = None @@ -254,7 +254,7 @@ def next_state(self, height): sage: bijection.next_state(2) -3 """ - height -= 1 # indexing + height -= 1 # indexing ell = [None] * 6 case_S = [False] * 3 case_Q = False @@ -305,7 +305,7 @@ def next_state(self, height): else: b = 0 - if b is None: # Going back + if b is None: # Going back if self.cur_partitions[1][ell[1]] == last_size: ell[4] = ell[1] case_S[1] = True @@ -317,7 +317,7 @@ def next_state(self, height): else: last_size = self.cur_partitions[1][ell[4]] - if b is None: # Final partition + if b is None: # Final partition P = self.cur_partitions[0] if ell[0] is not None and P[ell[0]] == last_size: ell[5] = ell[0] @@ -346,7 +346,7 @@ def next_state(self, height): if case_S[0]: row0 = [self.cur_partitions[0].remove_cell(ell[5], 2)] - row0.append( self.cur_partitions[0].remove_cell(ell[3], 2) ) + row0.append(self.cur_partitions[0].remove_cell(ell[3], 2)) else: if case_Q: if ell[0] is None or ell[0] < ell[2]: @@ -360,9 +360,9 @@ def next_state(self, height): else: row0 = [self.cur_partitions[0].remove_cell(ell[0])] if case_S[2]: - row0.append( self.cur_partitions[0].remove_cell(ell[3], 2) ) + row0.append(self.cur_partitions[0].remove_cell(ell[3], 2)) - row0.append( self.cur_partitions[0].remove_cell(ell[5]) ) + row0.append(self.cur_partitions[0].remove_cell(ell[5])) self._update_vacancy_numbers(0) self._update_vacancy_numbers(1) @@ -387,4 +387,4 @@ def next_state(self, height): j += 1 P.rigging[j-1] = vac_num - 1 - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py index e9c13e4b54d..dbc049d6ae0 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011, 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_type_A import KRTToRCBijectionTypeA from sage.combinat.rigged_configurations.bij_type_A2_even import KRTToRCBijectionTypeA2Even @@ -84,7 +84,7 @@ def run(self, verbose=False): r = cur_crystal.parent().r() # Iterate through the columns for col_number, cur_column in enumerate(reversed(cur_crystal.to_array(False))): - self.cur_path.insert(0, []) # Prepend an empty list + self.cur_path.insert(0, []) # Prepend an empty list # Check to see if we are a spinor column if r == self.n: @@ -101,7 +101,7 @@ def run(self, verbose=False): for letter in reversed(cur_column): self.cur_dims[0][0] += 1 - val = letter.value # Convert from a CrystalOfLetter to an Integer + val = letter.value # Convert from a CrystalOfLetter to an Integer if verbose: print("====================") @@ -111,7 +111,7 @@ def run(self, verbose=False): print("--------------------\n") # Build the next state - self.cur_path[0].insert(0, [letter]) # Prepend the value + self.cur_path[0].insert(0, [letter]) # Prepend the value self.next_state(val) # Check to see if we are a spinor column @@ -138,7 +138,7 @@ def run(self, verbose=False): for a in range(self.n): self._update_vacancy_nums(a) - self.ret_rig_con.set_immutable() # Return it to immutable + self.ret_rig_con.set_immutable() # Return it to immutable return self.ret_rig_con def next_state(self, val): @@ -571,4 +571,4 @@ def next_state(self, height): else: self.cur_partitions[n-1].rigging[row_num_bar_next] = self.cur_partitions[n-1].vacancy_numbers[row_num_bar_next] - return(b) + return b diff --git a/src/sage/combinat/rigged_configurations/bij_type_E67.py b/src/sage/combinat/rigged_configurations/bij_type_E67.py index 6fedd39c5a0..3d258443276 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_E67.py +++ b/src/sage/combinat/rigged_configurations/bij_type_E67.py @@ -20,7 +20,7 @@ sage: TestSuite(bijection).run() """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2011, 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -32,8 +32,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.rigged_configurations.bij_abstract_class import KRTToRCBijectionAbstract from sage.combinat.rigged_configurations.bij_abstract_class import RCToKRTBijectionAbstract @@ -91,8 +91,8 @@ def find_singular_string(p, max_width): if not data: break - max_val = max(l for a,l in data) - for a,l in data: + max_val = max(l for a, l in data) + for a, l in data: if l == max_val: self.ret_rig_con[a-1].insert_cell(max_width) max_width = l @@ -153,7 +153,7 @@ def _next_index(self, r, target): return 2 if r == 2: return 5 - else: # rank == 7 + else: # rank == 7 # 1-2-3 # / # 0-7-6-5-4 @@ -240,12 +240,12 @@ def next_state(self, r): data = [(a, self._find_singular_string(self.cur_partitions[a-1], last_size)) for a in b.value if a > 0] data = [(val, a, self.cur_partitions[a-1][val]) - for a,val in data if val is not None] + for a, val in data if val is not None] if not data: break - min_val = min(l for i,a,l in data) - for i,a,l in data: + min_val = min(l for i, a, l in data) + for i, a, l in data: if l == min_val: found = True last_size = l @@ -253,13 +253,13 @@ def next_state(self, r): b = b.f(a) break - for a,p in enumerate(self.cur_partitions): + for a, p in enumerate(self.cur_partitions): self._update_vacancy_numbers(a) for i in range(len(p)): if p.rigging[i] is None: p.rigging[i] = p.vacancy_numbers[i] - return(b) + return b def _next_index(self, r): """ @@ -290,7 +290,7 @@ def _next_index(self, r): return 2 if r == 6: return 1 - else: # rank == 7 + else: # rank == 7 # 1-2-3 # / # 0-7-6-5-4 @@ -346,7 +346,7 @@ def endpoint6(r): sage: endpoint6(6) (-1, 6) """ - C = CrystalOfLetters(['E',6]) + C = CrystalOfLetters(['E', 6]) if r == 1: return C.module_generators[0] # C((1,)) elif r == 2: @@ -383,7 +383,7 @@ def endpoint7(r): sage: endpoint7(7) (7,) """ - C = CrystalOfLetters(['E',7]) + C = CrystalOfLetters(['E', 7]) if r == 1: return C((-7, 1)) elif r == 2: diff --git a/src/sage/combinat/rigged_configurations/kleber_tree.py b/src/sage/combinat/rigged_configurations/kleber_tree.py index 82c99e8ad73..7805d0b7f4b 100644 --- a/src/sage/combinat/rigged_configurations/kleber_tree.py +++ b/src/sage/combinat/rigged_configurations/kleber_tree.py @@ -170,7 +170,7 @@ def _draw_tree(tree_node, node_label=True, style_point=None, style_node='fill=wh else: lines_str += "\\draw%s (%s%s) -- (%s%s%s);\n"%(style_line_str, node_name, node_place_str, node_name, i, node_place_str) - #drawing root + # drawing root if style_node is None: style_node = '' else: @@ -429,8 +429,8 @@ def _repr_(self): sage: KT.root Kleber tree node with weight [0, 2, 0, 2, 0] and upwards edge root [0, 0, 0, 0, 0] """ - return "Kleber tree node with weight %s and upwards edge root %s"%( - list(self.weight.to_vector()), list(self.up_root.to_vector()) ) + return "Kleber tree node with weight %s and upwards edge root %s" % ( + list(self.weight.to_vector()), list(self.up_root.to_vector())) def _latex_(self): r""" diff --git a/src/sage/combinat/rigged_configurations/rc_crystal.py b/src/sage/combinat/rigged_configurations/rc_crystal.py index fbd149f6c0c..dbd7fd047fe 100644 --- a/src/sage/combinat/rigged_configurations/rc_crystal.py +++ b/src/sage/combinat/rigged_configurations/rc_crystal.py @@ -179,7 +179,7 @@ def __init__(self, wt, WLR): else: category = (RegularCrystals(), HighestWeightCrystals(), InfiniteEnumeratedSets()) Parent.__init__(self, category=category) - n = self._cartan_type.rank() #== len(self._cartan_type.index_set()) + n = self._cartan_type.rank() # == len(self._cartan_type.index_set()) self.module_generators = (self.element_class(self, partition_list=[[] for _ in repeat(None, n)]),) options = RiggedConfigurations.options @@ -444,7 +444,7 @@ def from_virtual(self, vrc): sage: elt == RC.from_virtual(RC.to_virtual(elt)) True """ - gamma = list(self._folded_ct.scaling_factors()) #map(int, self._folded_ct.scaling_factors()) + gamma = list(self._folded_ct.scaling_factors()) # map(int, self._folded_ct.scaling_factors()) sigma = self._folded_ct._orbit n = self._cartan_type.rank() partitions = [None] * n diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index 727322f0efd..542649cf9dd 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -232,8 +232,8 @@ def __init__(self, parent, rigged_partitions=[], **options): nu = [] for i in range(n): nu.append(RiggedPartition()) - #raise ValueError("Invalid input") - #raise ValueError("Incorrect number of rigged partitions") + # raise ValueError("Invalid input") + # raise ValueError("Incorrect number of rigged partitions") # Set the vacancy numbers for a, partition in enumerate(nu): @@ -330,7 +330,7 @@ def _repr_vertical(self): ret_str = "" for tableau in self: ret_str += "\n" + repr(tableau) - return(ret_str) + return ret_str def _repr_horizontal(self): """ @@ -1039,7 +1039,7 @@ def f(self, a): return self.parent().from_virtual(virtual_rc) ########################################################## -## Highest weight crystal rigged configuration elements ## +# Highest weight crystal rigged configuration elements # ########################################################## @@ -1229,7 +1229,7 @@ def weight(self): return self.parent()._wt - sum(sum(x) * alpha[i] for i,x in enumerate(self)) ############################################## -## KR crystal rigged configuration elements ## +# KR crystal rigged configuration elements # ############################################## @@ -2278,7 +2278,7 @@ def cocharge(self): sage: RC(partition_list=[[1,1],[2,1],[1,1]]).cocharge() 1 """ - #return self.to_virtual_configuration().cocharge() / self.parent()._folded_ct.gamma[0] + # return self.to_virtual_configuration().cocharge() / self.parent()._folded_ct.gamma[0] vct = self.parent()._folded_ct cc = ZZ.zero() rigging_sum = ZZ.zero() diff --git a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py index 74d923e0fd9..ce4c2ad2ab4 100644 --- a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py +++ b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux.py @@ -45,7 +45,7 @@ False """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010-2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -57,8 +57,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.misc.cachefunc import cached_method from sage.structure.unique_representation import UniqueRepresentation @@ -68,9 +68,9 @@ from sage.combinat.root_system.cartan_type import CartanType from sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element \ - import TensorProductOfKirillovReshetikhinTableauxElement + import TensorProductOfKirillovReshetikhinTableauxElement from sage.combinat.rigged_configurations.kr_tableaux import KirillovReshetikhinTableaux, \ - KirillovReshetikhinTableauxElement + KirillovReshetikhinTableauxElement from sage.rings.integer import Integer @@ -339,8 +339,8 @@ def __iter__(self): index_set = self._cartan_type.classical().index_set() from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet return RecursivelyEnumeratedSet(self.module_generators, - lambda x: [x.f(i) for i in index_set], - structure=None).naive_search_iterator() + lambda x: [x.f(i) for i in index_set], + structure=None).naive_search_iterator() def _test_bijection(self, **options): r""" @@ -360,7 +360,7 @@ def _test_bijection(self, **options): if z != x: rejects.append((x, z)) - tester.assertEqual(len(rejects), 0, "Bijection is not correct: %s"%rejects) + tester.assertEqual(len(rejects), 0, "Bijection is not correct: %s" % rejects) if rejects: return rejects @@ -415,7 +415,7 @@ def _module_generators_brute_force(self): """ index_set = self.cartan_type().classical().index_set() return tuple(x for x in FullTensorProductOfRegularCrystals.__iter__(self) - if x.is_highest_weight(index_set)) + if x.is_highest_weight(index_set)) @cached_method def rigged_configurations(self): diff --git a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py index fb43642a004..c816d2140a6 100644 --- a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +++ b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py @@ -9,7 +9,7 @@ - Travis Scrimshaw (2010-09-26): Initial version """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010, 2011, 2012 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) @@ -21,8 +21,8 @@ # # The full text of the GPL is available at: # -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.combinat.crystals.tensor_product import TensorProductOfRegularCrystalsElement @@ -158,7 +158,7 @@ def _repr_(self): ret_str = repr(self[0]) for i in range(1, len(self)): ret_str += " (X) " + repr(self[i]) - return(ret_str) + return ret_str def _repr_diagram(self): """ @@ -179,7 +179,7 @@ def _repr_diagram(self): sage: Partitions.options._reset() """ comp = [crys._repr_diagram().splitlines() for crys in self] - num_comp = len(comp) # number of components + num_comp = len(comp) # number of components col_len = [len(t) > 0 and len(t[0]) or 1 for t in comp] # columns per component num_rows = max(len(t) for t in comp) # number of rows @@ -190,11 +190,11 @@ def _repr_diagram(self): diag += '\n' for c in range(num_comp): if c > 0: - diag += ' ' # For the tensor symbol + diag += ' ' # For the tensor symbol if row < len(comp[c]): diag += comp[c][row] else: - diag += ' '*col_len[c] + diag += ' ' * col_len[c] return diag def pp(self): @@ -244,7 +244,7 @@ def lusztig_involution(self): Tensor product of Kirillov-Reshetikhin tableaux of type ['A', 3, 1] and factor(s) ((1, 3), (2, 2)) """ from sage.combinat.rigged_configurations.tensor_product_kr_tableaux \ - import TensorProductOfKirillovReshetikhinTableaux + import TensorProductOfKirillovReshetikhinTableaux P = self.parent() P = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, reversed(P.dims)) return P(*[x.lusztig_involution() for x in reversed(self)]) @@ -266,11 +266,11 @@ def left_split(self): P = self.parent() if P.dims[0][1] == 1: raise ValueError("cannot split a single column") - r,s = P.dims[0] - B = [[r,1], [r,s-1]] + r, s = P.dims[0] + B = [[r, 1], [r, s - 1]] B.extend(P.dims[1:]) from sage.combinat.rigged_configurations.tensor_product_kr_tableaux \ - import TensorProductOfKirillovReshetikhinTableaux + import TensorProductOfKirillovReshetikhinTableaux TP = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, B) x = self[0].left_split() return TP(*(list(x) + self[1:])) @@ -298,12 +298,12 @@ def right_split(self): P = self.parent() if P.dims[-1][1] == 1: raise ValueError("cannot split a single column") - r,s = P.dims[-1] + r, s = P.dims[-1] B = list(P.dims[:-1]) - B.append([r, s-1]) + B.append([r, s - 1]) B.append([r, 1]) from sage.combinat.rigged_configurations.tensor_product_kr_tableaux \ - import TensorProductOfKirillovReshetikhinTableaux + import TensorProductOfKirillovReshetikhinTableaux TP = TensorProductOfKirillovReshetikhinTableaux(P._cartan_type, B) x = self[-1].right_split() return TP(*(self[:-1] + list(x))) From 0552f7438b07498e0124e345ef0b693e86bed68a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 4 Jun 2023 09:10:16 +0200 Subject: [PATCH 44/56] fix the and add more checks --- src/sage/algebras/commutative_dga.py | 3 +-- src/sage/algebras/lie_algebras/affine_lie_algebra.py | 2 +- src/sage/knots/link.py | 9 +++------ src/sage/rings/polynomial/multi_polynomial_element.py | 4 ++-- src/tox.ini | 4 ++-- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/sage/algebras/commutative_dga.py b/src/sage/algebras/commutative_dga.py index d8127cc0585..3159fc608d8 100644 --- a/src/sage/algebras/commutative_dga.py +++ b/src/sage/algebras/commutative_dga.py @@ -3886,9 +3886,8 @@ class CohomologyClass(SageObject, CachedRepresentation): sage: CohomologyClass(x^2+2*y*z, A) [2*y*z + x^2] - TESTS: - + In order for the cache to not confuse objects with the same representation, we can pass the parent of the representative as a parameter:: diff --git a/src/sage/algebras/lie_algebras/affine_lie_algebra.py b/src/sage/algebras/lie_algebras/affine_lie_algebra.py index 5bde5399c3d..f94866cd1c6 100644 --- a/src/sage/algebras/lie_algebras/affine_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/affine_lie_algebra.py @@ -1211,4 +1211,4 @@ def __iter__(self): for r in self._roots: yield P((r, i)) for r in self._ac: - yield P((r, i)) \ No newline at end of file + yield P((r, i)) diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index 260022d05b7..a832f695eb1 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -3652,7 +3652,6 @@ def delta(u, v): ims += sum(line(a[0], **kwargs) for a in im) return image - def _markov_move_cmp(self, braid): r""" Return whether ``self`` can be transformed to the closure of ``braid`` @@ -4120,7 +4119,6 @@ def answer_list(l): raise NotImplementedError('this link cannot be uniquely determined%s' %non_unique_hint) - self_m = self.mirror_image() ls, proved_s = self._knotinfo_matching_list() lm, proved_m = self_m._knotinfo_matching_list() @@ -4147,18 +4145,18 @@ def answer_list(l): cr = len(self.pd_code()) if self.is_knot() and cr > 12: # we cannot not be sure if this link is recorded in the KnotInfo database - raise NotImplementedError('this knot having more than 12 crossings cannot be%s determined%s' %uniq_txt) + raise NotImplementedError('this knot having more than 12 crossings cannot be%s determined%s' % uniq_txt) if not self.is_knot() and cr > 11: # we cannot not be sure if this link is recorded in the KnotInfo database - raise NotImplementedError('this link having more than 11 crossings cannot be%s determined%s' %uniq_txt) + raise NotImplementedError('this link having more than 11 crossings cannot be%s determined%s' % uniq_txt) H = self.homfly_polynomial(normalization='vz') if sum(exp for f, exp in H.factor()) > 1: # we cannot be sure if this is a prime link (see the example for the connected # sum of K4_1 and K5_2 in the doctest of :meth:`_knotinfo_matching_list`) - raise NotImplementedError('this (possibly non prime) link cannot be%s determined%s' %uniq_txt) + raise NotImplementedError('this (possibly non prime) link cannot be%s determined%s' % uniq_txt) if not l: from sage.features.databases import DatabaseKnotInfo @@ -4167,7 +4165,6 @@ def answer_list(l): return answer_list(l) - def is_isotopic(self, other): r""" Check whether ``self`` is isotopic to ``other``. diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 2e007d4db5c..86d62c77bf9 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -2119,13 +2119,13 @@ def factor(self, proof=None): # try to use univariate factoring try: F = self.univariate_polynomial().factor() - return Factorization([(R(f),m) for f,m in F], unit=F.unit()) + return Factorization([(R(f), m) for f, m in F], unit=F.unit()) except TypeError: pass base_ring = self.base_ring() if base_ring.is_finite(): - if base_ring.characteristic() > 1<<29: + if base_ring.characteristic() > 1 << 29: raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") if proof is None: diff --git a/src/tox.ini b/src/tox.ini index 6c479f086df..7b99e519ff7 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -126,8 +126,8 @@ description = # W605: invalid escape sequence ‘x’ # See https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes deps = pycodestyle -commands = pycodestyle --select E111,E211,E271,E303,E306,E401,E502,E701,E702,E703,E714,W291,W293,W391,W605,E711,E712,E713,E721,E722 {posargs:{toxinidir}/sage/} - pycodestyle --select E111,E306,E401,E703,W293,W391,W605,E712,E713,E714,E721,E722 --filename *.pyx {posargs:{toxinidir}/sage/} +commands = pycodestyle --select E111,E21,E227,E271,E303,E306,E401,E502,E701,E702,E703,E71,E72,W291,W293,W391,W605 {posargs:{toxinidir}/sage/} + pycodestyle --select E111,E306,E401,E703,W29,W391,W605,E712,E713,E714,E721,E722 --filename *.pyx {posargs:{toxinidir}/sage/} [pycodestyle] max-line-length = 160 From b0763e9c493fe810742c404b53c253a6b2bb3265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 4 Jun 2023 14:07:26 +0200 Subject: [PATCH 45/56] fix --- src/sage/libs/mpmath/ext_libmp.pyx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sage/libs/mpmath/ext_libmp.pyx b/src/sage/libs/mpmath/ext_libmp.pyx index 2a5799e3513..6f4ab6b2914 100644 --- a/src/sage/libs/mpmath/ext_libmp.pyx +++ b/src/sage/libs/mpmath/ext_libmp.pyx @@ -4,6 +4,9 @@ Faster versions of some key functions in mpmath.libmp from .ext_impl cimport * from sage.libs.gmp.all cimport * +from sage.rings.integer cimport Integer + +from .ext_impl import exp_fixed, cos_sin_fixed, log_int_fixed # Note: not thread-safe cdef MPF tmp1 From 3eadc12d95580a39c953e18e29cd710428b613ce Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sun, 4 Jun 2023 14:40:52 +0100 Subject: [PATCH 46/56] a bit different error message due to the new class --- src/sage/modules/free_module_element.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 0532ea0c9bd..f4a1ec5c575 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -5080,7 +5080,7 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): This lack of bounds checking causes trouble later:: sage: v - ) failed: IndexError: list assignment index out of range> + ) failed: IndexError: list assignment index out of range> """ if value: self._entries[i] = value From f1546c0afc4a7c42c51ee39c131fb2f511e9d923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 4 Jun 2023 16:04:00 +0200 Subject: [PATCH 47/56] undo addition of sig_off --- src/sage/rings/finite_rings/element_ntl_gf2e.pyx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx index 55fcf329b6c..33db43010b9 100644 --- a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx @@ -26,7 +26,7 @@ AUTHORS: # **************************************************************************** from cysignals.memory cimport check_malloc, sig_free -from cysignals.signals cimport sig_on, sig_off +from cysignals.signals cimport sig_on from sage.ext.cplusplus cimport ccrepr, ccreadstr include "sage/libs/ntl/decl.pxi" @@ -372,7 +372,6 @@ cdef class Cache_ntl_gf2e(Cache_base): if isinstance(e, Gen): sig_on() t = (e).g - sig_off() if typ(t) == t_FFELT: t = FF_to_FpXQ(t) else: From 2891cd8841797ef8ddcd658fe6a0bfc38b6d9505 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 4 Jun 2023 09:37:28 -0700 Subject: [PATCH 48/56] sage.graphs: Fix alignment of # optional --- src/sage/graphs/connectivity.pyx | 4 +- src/sage/graphs/dot2tex_utils.py | 6 +-- src/sage/graphs/generic_graph.py | 52 ++++++++++--------- .../vertex_separation.pyx | 28 +++++----- 4 files changed, 46 insertions(+), 44 deletions(-) diff --git a/src/sage/graphs/connectivity.pyx b/src/sage/graphs/connectivity.pyx index 0f7b84d66da..0cbcb87dd8d 100644 --- a/src/sage/graphs/connectivity.pyx +++ b/src/sage/graphs/connectivity.pyx @@ -4246,8 +4246,8 @@ def is_triconnected(G): Comparing different methods on random graphs that are not always triconnected:: - sage: G = graphs.RandomBarabasiAlbert(50, 3) # optional - networkx - sage: G.is_triconnected() == G.vertex_connectivity(k=3) # optional - networkx + sage: G = graphs.RandomBarabasiAlbert(50, 3) # optional - networkx + sage: G.is_triconnected() == G.vertex_connectivity(k=3) # optional - networkx True .. SEEALSO:: diff --git a/src/sage/graphs/dot2tex_utils.py b/src/sage/graphs/dot2tex_utils.py index 710f3872b2a..95850012885 100644 --- a/src/sage/graphs/dot2tex_utils.py +++ b/src/sage/graphs/dot2tex_utils.py @@ -74,7 +74,7 @@ def quoted_latex(x): EXAMPLES:: - sage: sage.graphs.dot2tex_utils.quoted_latex(matrix([[1,1],[0,1],[0,0]])) # optional - sage.modules + sage: sage.graphs.dot2tex_utils.quoted_latex(matrix([[1,1],[0,1],[0,0]])) # optional - sage.modules '\\left(\\begin{array}{rr}1 & 1 \\\\0 & 1 \\\\0 & 0\\end{array}\\right)' """ return re.sub("\"|\r|(%[^\n]*)?\n", "", latex(x)) @@ -89,9 +89,9 @@ def quoted_str(x): EXAMPLES:: - sage: sage.graphs.dot2tex_utils.quoted_str(matrix([[1,1],[0,1],[0,0]])) # optional - sage.modules + sage: sage.graphs.dot2tex_utils.quoted_str(matrix([[1,1],[0,1],[0,0]])) # optional - sage.modules '[1 1]\\n\\\n[0 1]\\n\\\n[0 0]' - sage: print(sage.graphs.dot2tex_utils.quoted_str(matrix([[1,1],[0,1],[0,0]]))) # optional - sage.modules + sage: print(sage.graphs.dot2tex_utils.quoted_str(matrix([[1,1],[0,1],[0,0]]))) # optional - sage.modules [1 1]\n\ [0 1]\n\ [0 0] diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 440a0f4275f..1f8db82faed 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -19444,33 +19444,35 @@ def _color_by_label(self, format='hex', as_function=False, default_color="black" We consider the Cayley graph of the symmetric group, whose edges are labelled by the numbers 1,2, and 3:: - sage: G = SymmetricGroup(4).cayley_graph() # optional - sage.groups - sage: set(G.edge_labels()) # optional - sage.groups + sage: G = SymmetricGroup(4).cayley_graph() # optional - sage.groups + sage: set(G.edge_labels()) # optional - sage.groups {1, 2, 3} We first request the coloring as a function:: - sage: f = G._color_by_label(as_function=True) # optional - sage.groups - sage: [f(1), f(2), f(3)] # optional - sage.groups + sage: f = G._color_by_label(as_function=True) # optional - sage.groups + sage: [f(1), f(2), f(3)] # optional - sage.groups ['#0000ff', '#ff0000', '#00ff00'] - sage: f = G._color_by_label({1: "blue", 2: "red", 3: "green"}, as_function=True) # optional - sage.groups - sage: [f(1), f(2), f(3)] # optional - sage.groups + sage: f = G._color_by_label({1: "blue", 2: "red", 3: "green"}, # optional - sage.groups + ....: as_function=True) + sage: [f(1), f(2), f(3)] # optional - sage.groups ['blue', 'red', 'green'] - sage: f = G._color_by_label({1: "red"}, as_function=True) # optional - sage.groups - sage: [f(1), f(2), f(3)] # optional - sage.groups + sage: f = G._color_by_label({1: "red"}, as_function=True) # optional - sage.groups + sage: [f(1), f(2), f(3)] # optional - sage.groups ['red', 'black', 'black'] - sage: f = G._color_by_label({1: "red"}, as_function=True, default_color='blue') # optional - sage.groups - sage: [f(1), f(2), f(3)] # optional - sage.groups + sage: f = G._color_by_label({1: "red"}, as_function=True, # optional - sage.groups + ....: default_color='blue') + sage: [f(1), f(2), f(3)] # optional - sage.groups ['red', 'blue', 'blue'] The default output is a dictionary assigning edges to colors:: - sage: G._color_by_label() # optional - sage.groups + sage: G._color_by_label() # optional - sage.groups {'#0000ff': [((), (1,2), 1), ...], '#00ff00': [((), (3,4), 3), ...], '#ff0000': [((), (2,3), 2), ...]} - sage: G._color_by_label({1: "blue", 2: "red", 3: "green"}) # optional - sage.groups + sage: G._color_by_label({1: "blue", 2: "red", 3: "green"}) # optional - sage.groups {'blue': [((), (1,2), 1), ...], 'green': [((), (3,4), 3), ...], 'red': [((), (2,3), 2), ...]} @@ -19479,12 +19481,12 @@ def _color_by_label(self, format='hex', as_function=False, default_color="black" We check what happens when several labels have the same color:: - sage: result = G._color_by_label({1: "blue", 2: "blue", 3: "green"}) # optional - sage.groups - sage: sorted(result) # optional - sage.groups + sage: result = G._color_by_label({1: "blue", 2: "blue", 3: "green"}) # optional - sage.groups + sage: sorted(result) # optional - sage.groups ['blue', 'green'] - sage: len(result['blue']) # optional - sage.groups + sage: len(result['blue']) # optional - sage.groups 48 - sage: len(result['green']) # optional - sage.groups + sage: len(result['green']) # optional - sage.groups 24 """ if format is True: @@ -19538,8 +19540,8 @@ def latex_options(self): sage: opts = g.latex_options() sage: opts LaTeX options for Petersen graph: {} - sage: opts.set_option('tkz_style', 'Classic') # optional - sage.plot - sage: opts # optional - sage.plot + sage: opts.set_option('tkz_style', 'Classic') # optional - sage.plot + sage: opts # optional - sage.plot LaTeX options for Petersen graph: {'tkz_style': 'Classic'} """ if self._latex_opts is None: @@ -19567,9 +19569,9 @@ def set_latex_options(self, **kwds): EXAMPLES:: sage: g = graphs.PetersenGraph() - sage: g.set_latex_options(tkz_style='Welsh') # optional - sage.plot - sage: opts = g.latex_options() # optional - sage.plot - sage: opts.get_option('tkz_style') # optional - sage.plot + sage: g.set_latex_options(tkz_style='Welsh') # optional - sage.plot + sage: opts = g.latex_options() # optional - sage.plot + sage: opts.get_option('tkz_style') # optional - sage.plot 'Welsh' """ opts = self.latex_options() @@ -23284,13 +23286,13 @@ def is_vertex_transitive(self, partition=None, verbosity=0, sage: G.is_vertex_transitive() False sage: P = graphs.PetersenGraph() - sage: P.is_vertex_transitive() # optional - sage.groups + sage: P.is_vertex_transitive() # optional - sage.groups True sage: D = graphs.DodecahedralGraph() - sage: D.is_vertex_transitive() # optional - sage.groups + sage: D.is_vertex_transitive() # optional - sage.groups True - sage: R = graphs.RandomGNP(2000, .01) # optional - networkx - sage: R.is_vertex_transitive() # optional - networkx + sage: R = graphs.RandomGNP(2000, .01) # optional - networkx + sage: R.is_vertex_transitive() # optional - networkx False """ if partition is None: diff --git a/src/sage/graphs/graph_decompositions/vertex_separation.pyx b/src/sage/graphs/graph_decompositions/vertex_separation.pyx index 6773f1d6581..bf6070e9c8f 100644 --- a/src/sage/graphs/graph_decompositions/vertex_separation.pyx +++ b/src/sage/graphs/graph_decompositions/vertex_separation.pyx @@ -954,8 +954,8 @@ def vertex_separation_exp(G, verbose=False): Graphs with non-integer vertices:: sage: from sage.graphs.graph_decompositions.vertex_separation import vertex_separation_exp - sage: D = digraphs.DeBruijn(2,3) # optional - sage.combinat - sage: vertex_separation_exp(D) # optional - sage.combinat + sage: D = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: vertex_separation_exp(D) # optional - sage.combinat (2, ['000', '001', '100', '010', '101', '011', '110', '111']) Given a too large graph:: @@ -1211,12 +1211,12 @@ def width_of_path_decomposition(G, L): Path decomposition of a BalancedTree:: sage: from sage.graphs.graph_decompositions import vertex_separation - sage: G = graphs.BalancedTree(3,2) # optional - networkx - sage: pw, L = vertex_separation.path_decomposition(G) # optional - networkx - sage: pw == vertex_separation.width_of_path_decomposition(G, L) # optional - networkx + sage: G = graphs.BalancedTree(3,2) # optional - networkx + sage: pw, L = vertex_separation.path_decomposition(G) # optional - networkx + sage: pw == vertex_separation.width_of_path_decomposition(G, L) # optional - networkx True - sage: L.reverse() # optional - networkx - sage: pw == vertex_separation.width_of_path_decomposition(G, L) # optional - networkx + sage: L.reverse() # optional - networkx + sage: pw == vertex_separation.width_of_path_decomposition(G, L) # optional - networkx False Directed path decomposition of a circuit:: @@ -1305,9 +1305,9 @@ def _vertex_separation_MILP_formulation(G, integrality=False, solver=None): EXAMPLES:: sage: from sage.graphs.graph_decompositions.vertex_separation import _vertex_separation_MILP_formulation - sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat - sage: p, x, u, y, z = _vertex_separation_MILP_formulation(G) # optional - sage.combinat - sage: p # optional - sage.combinat + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: p, x, u, y, z = _vertex_separation_MILP_formulation(G) # optional - sage.combinat + sage: p # optional - sage.combinat Mixed Integer Program (minimization, 193 variables, 449 constraints) """ from sage.graphs.graph import Graph @@ -1420,12 +1420,12 @@ def vertex_separation_MILP(G, integrality=False, solver=None, verbose=0, Vertex separation of a De Bruijn digraph:: sage: from sage.graphs.graph_decompositions import vertex_separation - sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat - sage: vs, L = vertex_separation.vertex_separation_MILP(G); vs # optional - sage.combinat + sage: G = digraphs.DeBruijn(2,3) # optional - sage.combinat + sage: vs, L = vertex_separation.vertex_separation_MILP(G); vs # optional - sage.combinat 2 - sage: vs == vertex_separation.width_of_path_decomposition(G, L) # optional - sage.combinat + sage: vs == vertex_separation.width_of_path_decomposition(G, L) # optional - sage.combinat True - sage: vse, Le = vertex_separation.vertex_separation(G); vse # optional - sage.combinat + sage: vse, Le = vertex_separation.vertex_separation(G); vse # optional - sage.combinat 2 The vertex separation of a circuit is 1:: From cff047d72b6a3fc59c9d00b4169bcdbb330d37bb Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 31 May 2023 14:56:43 +0200 Subject: [PATCH 49/56] GAP: switch some code to use official libgap APIs --- src/sage/libs/gap/element.pyx | 36 ++++++++++++------------- src/sage/libs/gap/gap_includes.pxd | 42 +++++++++++++----------------- src/sage/libs/gap/libgap.pyx | 4 +-- src/sage/libs/gap/util.pyx | 4 +-- 4 files changed, 39 insertions(+), 47 deletions(-) diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index d9b47f19509..0543236cf30 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -195,7 +195,7 @@ cdef Obj make_gap_record(sage_dict) except NULL: try: GAP_Enter() - rec = NEW_PREC(len(data)) + rec = GAP_NewPrecord(len(data)) for d in data: key, val = d rnam = RNamName(str_to_bytes(key)) @@ -305,9 +305,9 @@ cdef GapElement make_any_gap_element(parent, Obj obj): if obj is NULL: return make_GapElement(parent, obj) num = TNUM_OBJ(obj) - if IS_INT(obj): + if GAP_IsInt(obj): return make_GapElement_Integer(parent, obj) - elif num == T_MACFLOAT: + elif GAP_IsMacFloat(obj): return make_GapElement_Float(parent, obj) elif num == T_CYC: return make_GapElement_Cyclotomic(parent, obj) @@ -321,15 +321,15 @@ cdef GapElement make_any_gap_element(parent, Obj obj): return make_GapElement_Function(parent, obj) elif num == T_PERM2 or num == T_PERM4: return make_GapElement_Permutation(parent, obj) - elif IS_REC(obj): + elif GAP_IsRecord(obj): return make_GapElement_Record(parent, obj) - elif IS_LIST(obj) and LEN_LIST(obj) == 0: + elif GAP_IsList(obj) and GAP_LenList(obj) == 0: # Empty lists are lists and not strings in Python return make_GapElement_List(parent, obj) elif IsStringConv(obj): # GAP strings are lists, too. Make sure this comes before non-empty make_GapElement_List return make_GapElement_String(parent, obj) - elif IS_LIST(obj): + elif GAP_IsList(obj): return make_GapElement_List(parent, obj) elif num == T_CHAR: ch = make_GapElement(parent, obj).IntChar().sage() @@ -1209,7 +1209,7 @@ cdef class GapElement(RingElement): sage: libgap.eval('3/2').is_list() False """ - return IS_LIST(self.value) + return GAP_IsList(self.value) def is_record(self): r""" @@ -1226,7 +1226,7 @@ cdef class GapElement(RingElement): sage: libgap.eval('rec(a:=1, b:=3)').is_record() True """ - return IS_REC(self.value) + return GAP_IsRecord(self.value) cpdef is_bool(self): r""" @@ -1456,7 +1456,7 @@ cdef class GapElement_Integer(GapElement): sage: N.IsInt() true """ - return IS_INTOBJ(self.value) + return GAP_IsSmallInt(self.value) def _rational_(self): r""" @@ -1607,7 +1607,7 @@ cdef class GapElement_Float(GapElement): """ if ring is None: ring = RDF - return ring(VAL_MACFLOAT(self.value)) + return ring(GAP_ValueMacFloat(self.value)) def __float__(self): r""" @@ -1616,7 +1616,7 @@ cdef class GapElement_Float(GapElement): sage: float(libgap.eval("Float(3.5)")) 3.5 """ - return VAL_MACFLOAT(self.value) + return GAP_ValueMacFloat(self.value) @@ -2750,7 +2750,7 @@ cdef class GapElement_List(GapElement): sage: len(lst) 4 """ - return LEN_LIST(self.value) + return GAP_LenList(self.value) def __getitem__(self, i): r""" @@ -2798,15 +2798,15 @@ cdef class GapElement_List(GapElement): if isinstance(i, tuple): for j in i: - if not IS_LIST(obj): + if not GAP_IsList(obj): raise ValueError('too many indices') - if j < 0 or j >= LEN_LIST(obj): + if j < 0 or j >= GAP_LenList(obj): raise IndexError('index out of range') obj = ELM_LIST(obj, j+1) else: j = i - if j < 0 or j >= LEN_LIST(obj): + if j < 0 or j >= GAP_LenList(obj): raise IndexError('index out of range.') obj = ELM_LIST(obj, j+1) @@ -2869,12 +2869,12 @@ cdef class GapElement_List(GapElement): if isinstance(i, tuple): for j in i[:-1]: - if not IS_LIST(obj): + if not GAP_IsList(obj): raise ValueError('too many indices') - if j < 0 or j >= LEN_LIST(obj): + if j < 0 or j >= GAP_LenList(obj): raise IndexError('index out of range') obj = ELM_LIST(obj, j+1) - if not IS_LIST(obj): + if not GAP_IsList(obj): raise ValueError('too many indices') j = i[-1] else: diff --git a/src/sage/libs/gap/gap_includes.pxd b/src/sage/libs/gap/gap_includes.pxd index 4a1ab942cbf..24cd3df21ed 100644 --- a/src/sage/libs/gap/gap_includes.pxd +++ b/src/sage/libs/gap/gap_includes.pxd @@ -33,11 +33,6 @@ cdef extern from "gap/ariths.h" nogil: bint LT(Obj opL, Obj opR) -cdef extern from "gap/bool.h" nogil: - cdef Obj GAP_True "True" - cdef Obj GAP_False "False" - - cdef extern from "gap/calls.h" nogil: bint IS_FUNC(Obj) Obj CALL_0ARGS(Obj f) # 0 arguments @@ -50,17 +45,7 @@ cdef extern from "gap/calls.h" nogil: Obj CALL_XARGS(Obj f, Obj args) # more than 6 arguments -cdef extern from "gap/gasman.h" nogil: - void MarkBag(Obj bag) - UInt CollectBags(UInt size, UInt full) - - -cdef extern from "gap/integer.h" nogil: - Int IS_INT(Obj) - - cdef extern from "gap/intobj.h" nogil: - bint IS_INTOBJ(Obj obj) Obj INTOBJ_INT(Int) Int INT_INTOBJ(Obj) @@ -90,10 +75,26 @@ cdef extern from "gap/libgap-api.h" nogil: cdef void GAP_Leave() cdef int GAP_Error_Setjmp() except 0 + void GAP_MarkBag(Obj bag) + void GAP_CollectBags(UInt full) + + cdef Obj GAP_True + cdef Obj GAP_False + + bint GAP_IsMacFloat(Obj obj) + double GAP_ValueMacFloat(Obj obj) + + bint GAP_IsInt(Obj) + bint GAP_IsSmallInt(Obj) + + bint GAP_IsList(Obj lst) + UInt GAP_LenList(Obj lst) + + bint GAP_IsRecord(Obj obj) + Obj GAP_NewPrecord(Int capacity) + cdef extern from "gap/lists.h" nogil: - bint IS_LIST(Obj lst) - int LEN_LIST(Obj lst) Obj ELM_LIST(Obj lst, int pos) Obj ELM0_LIST(Obj lst, int pos) void ASS_LIST(Obj lst, int pos, Obj elt) @@ -103,10 +104,6 @@ cdef extern from "gap/listfunc.h" nogil: void AddList(Obj list, Obj obj) -cdef extern from "gap/macfloat.h" nogil: - double VAL_MACFLOAT(Obj obj) - - cdef extern from "gap/objects.h" nogil: bint IS_MUTABLE_OBJ(Obj obj) Obj SHALLOW_COPY_OBJ(Obj obj) @@ -119,7 +116,6 @@ cdef extern from "gap/objects.h" nogil: T_RAT T_CYC T_FFE - T_MACFLOAT T_PERM2 T_PERM4 T_BOOL @@ -142,7 +138,6 @@ cdef extern from "gap/permutat.h" nogil: cdef extern from "gap/precord.h" nogil: - Obj NEW_PREC(int len) int LEN_PREC(Obj rec) int GET_RNAM_PREC(Obj rec, int i) Obj GET_ELM_PREC(Obj rec, int i) @@ -151,7 +146,6 @@ cdef extern from "gap/precord.h" nogil: cdef extern from "gap/records.h" nogil: char* NAME_RNAM(UInt rnam) - bint IS_REC(Obj obj) Obj ELM_REC(Obj rec, UInt rnam) UInt RNamName(Char* name) diff --git a/src/sage/libs/gap/libgap.pyx b/src/sage/libs/gap/libgap.pyx index 6a36613aa8c..4157fcb1873 100644 --- a/src/sage/libs/gap/libgap.pyx +++ b/src/sage/libs/gap/libgap.pyx @@ -782,9 +782,7 @@ class Gap(Parent): sage: libgap.collect() """ initialize() - rc = CollectBags(0, 1) - if rc != 1: - raise RuntimeError('Garbage collection failed.') + GAP_CollectBags(1) libgap = Gap() diff --git a/src/sage/libs/gap/util.pyx b/src/sage/libs/gap/util.pyx index 02ab44d2cec..c282a59cb96 100644 --- a/src/sage/libs/gap/util.pyx +++ b/src/sage/libs/gap/util.pyx @@ -157,7 +157,7 @@ cdef void gasman_callback() with gil: """ global owned_objects_refcount for obj in owned_objects_refcount: - MarkBag((obj).value) + GAP_MarkBag((obj).value) ############################################################################ @@ -368,7 +368,7 @@ cdef Obj gap_eval(str gap_string) except? NULL: # If an error occurred in GAP_EvalString we won't even get # here if the error handler was set; but in case it wasn't # let's still check the result... - nresults = LEN_LIST(result) + nresults = GAP_LenList(result) if nresults > 1: # to mimick the old libGAP # TODO: Get rid of this restriction eventually? raise GAPError("can only evaluate a single statement") From e4d25fb91ad92aa9a465b5786f48fa32a60693b7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 08:04:45 -0700 Subject: [PATCH 50/56] build/pkgs/pyflakes: Remove --- build/pkgs/pyflakes/SPKG.rst | 18 ------------------ build/pkgs/pyflakes/distros/conda.txt | 1 - build/pkgs/pyflakes/distros/macports.txt | 1 - build/pkgs/pyflakes/distros/opensuse.txt | 1 - build/pkgs/pyflakes/distros/repology.txt | 2 -- build/pkgs/pyflakes/distros/void.txt | 1 - build/pkgs/pyflakes/requirements.txt | 1 - build/pkgs/pyflakes/type | 1 - 8 files changed, 26 deletions(-) delete mode 100644 build/pkgs/pyflakes/SPKG.rst delete mode 100644 build/pkgs/pyflakes/distros/conda.txt delete mode 100644 build/pkgs/pyflakes/distros/macports.txt delete mode 100644 build/pkgs/pyflakes/distros/opensuse.txt delete mode 100644 build/pkgs/pyflakes/distros/repology.txt delete mode 100644 build/pkgs/pyflakes/distros/void.txt delete mode 100644 build/pkgs/pyflakes/requirements.txt delete mode 100644 build/pkgs/pyflakes/type diff --git a/build/pkgs/pyflakes/SPKG.rst b/build/pkgs/pyflakes/SPKG.rst deleted file mode 100644 index 88c3f07d2a7..00000000000 --- a/build/pkgs/pyflakes/SPKG.rst +++ /dev/null @@ -1,18 +0,0 @@ -pyflakes: Passive checker of Python programs -============================================ - -Description ------------ - -passive checker of Python programs - -License -------- - -MIT - -Upstream Contact ----------------- - -https://pypi.org/project/pyflakes/ - diff --git a/build/pkgs/pyflakes/distros/conda.txt b/build/pkgs/pyflakes/distros/conda.txt deleted file mode 100644 index 38675cb44a2..00000000000 --- a/build/pkgs/pyflakes/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -pyflakes diff --git a/build/pkgs/pyflakes/distros/macports.txt b/build/pkgs/pyflakes/distros/macports.txt deleted file mode 100644 index 399db8ac7bb..00000000000 --- a/build/pkgs/pyflakes/distros/macports.txt +++ /dev/null @@ -1 +0,0 @@ -py-pyflakes diff --git a/build/pkgs/pyflakes/distros/opensuse.txt b/build/pkgs/pyflakes/distros/opensuse.txt deleted file mode 100644 index a16ae878a72..00000000000 --- a/build/pkgs/pyflakes/distros/opensuse.txt +++ /dev/null @@ -1 +0,0 @@ -python3-pyflakes diff --git a/build/pkgs/pyflakes/distros/repology.txt b/build/pkgs/pyflakes/distros/repology.txt deleted file mode 100644 index 9990e60b2eb..00000000000 --- a/build/pkgs/pyflakes/distros/repology.txt +++ /dev/null @@ -1,2 +0,0 @@ -pyflakes -python:pyflakes diff --git a/build/pkgs/pyflakes/distros/void.txt b/build/pkgs/pyflakes/distros/void.txt deleted file mode 100644 index a16ae878a72..00000000000 --- a/build/pkgs/pyflakes/distros/void.txt +++ /dev/null @@ -1 +0,0 @@ -python3-pyflakes diff --git a/build/pkgs/pyflakes/requirements.txt b/build/pkgs/pyflakes/requirements.txt deleted file mode 100644 index 38675cb44a2..00000000000 --- a/build/pkgs/pyflakes/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -pyflakes diff --git a/build/pkgs/pyflakes/type b/build/pkgs/pyflakes/type deleted file mode 100644 index 134d9bc32d5..00000000000 --- a/build/pkgs/pyflakes/type +++ /dev/null @@ -1 +0,0 @@ -optional From bc543aac8970db211d97202489e9fae52a3e11f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 5 Jun 2023 20:57:24 +0200 Subject: [PATCH 51/56] more uses of yield from --- src/sage/combinat/interval_posets.py | 15 +++----- src/sage/combinat/necklace.py | 38 ++++++++----------- src/sage/combinat/posets/hasse_diagram.py | 6 +-- src/sage/combinat/tiling.py | 3 +- src/sage/combinat/words/finite_word.py | 9 ++--- src/sage/combinat/yang_baxter_graph.py | 3 +- src/sage/databases/oeis.py | 5 +-- src/sage/games/sudoku.py | 3 +- src/sage/graphs/bipartite_graph.py | 3 +- src/sage/graphs/pq_trees.py | 12 ++---- .../groups/abelian_gps/dual_abelian_group.py | 3 +- src/sage/groups/libgap_mixin.py | 3 +- src/sage/parallel/map_reduce.py | 3 +- src/sage/parallel/multiprocessing_sage.py | 3 +- .../asymptotic/growth_group_cartesian.py | 3 +- src/sage/rings/polynomial/pbori/blocks.py | 3 +- src/sage/rings/polynomial/polynomial_ring.py | 9 ++--- src/sage/rings/rational_field.py | 3 +- src/sage/rings/valuation/value_group.py | 3 +- .../elliptic_curves/ell_finite_field.py | 3 +- src/sage/sets/recursively_enumerated_set.pyx | 15 +++----- src/sage/symbolic/expression.pyx | 9 ++--- src/sage/tensor/modules/comp.py | 4 +- src/sage/tests/arxiv_0812_2725.py | 3 +- src/sage/typeset/character_art.py | 3 +- 25 files changed, 60 insertions(+), 107 deletions(-) diff --git a/src/sage/combinat/interval_posets.py b/src/sage/combinat/interval_posets.py index a2d4f6e607c..3466a57f255 100644 --- a/src/sage/combinat/interval_posets.py +++ b/src/sage/combinat/interval_posets.py @@ -2146,31 +2146,26 @@ def add_relations(poset, n, m): if poset.le(n, m): # there is already a link n->m, so we go to the next n - for pos in add_relations(poset, n - 1, m): - yield pos + yield from add_relations(poset, n - 1, m) elif poset.le(m, n): # there is an inverse link m->n, we know we won't be able # to create a link i->m with i<=n, so we go to the next m - for pos in add_relations(poset, m, m + 1): - yield pos + yield from add_relations(poset, m, m + 1) else: # there is no link n->m # first option : we don't create the link and go to the next m # (since the lack of a link n->m forbids any links i->m # with im already exist for all # n Integer: r""" diff --git a/src/sage/combinat/necklace.py b/src/sage/combinat/necklace.py index bcfb0d45185..32d345c7e11 100644 --- a/src/sage/combinat/necklace.py +++ b/src/sage/combinat/necklace.py @@ -295,8 +295,7 @@ def _ffc(content, equality=False): if not e[0]: # == 0 dll.hide(0) - for x in _fast_fixed_content(a, e, 2, 1, k, r, 2, dll, equality=equality): - yield x + yield from _fast_fixed_content(a, e, 2, 1, k, r, 2, dll, equality=equality) def _fast_fixed_content(a, content, t, p, k, r, s, dll, equality=False): @@ -347,13 +346,13 @@ def _fast_fixed_content(a, content, t, p, k, r, s, dll, equality=False): sp = t + 1 if j == a[t - p - 1]: - for x in _fast_fixed_content(a[:], content, t + 1, p, - k, r, sp, dll, equality=equality): - yield x + yield from _fast_fixed_content(a[:], content, t + 1, p, + k, r, sp, dll, + equality=equality) else: - for x in _fast_fixed_content(a[:], content, t + 1, t, - k, r, sp, dll, equality=equality): - yield x + yield from _fast_fixed_content(a[:], content, t + 1, t, + k, r, sp, dll, + equality=equality) if not content[j]: # == 0 dll.unhide(j) @@ -392,8 +391,7 @@ def _lfc(content, equality=False): if not content[0]: # == 0 dll.hide(0) - for z in _list_fixed_content(a, content, 2, 1, k, dll, equality=equality): - yield z + yield from _list_fixed_content(a, content, 2, 1, k, dll, equality=equality) def _list_fixed_content(a, content, t, p, k, dll, equality=False): @@ -434,13 +432,11 @@ def _list_fixed_content(a, content, t, p, k, dll, equality=False): dll.hide(j) if j == a[t - p - 1]: - for z in _list_fixed_content(a[:], content[:], t + 1, p, - k, dll, equality=equality): - yield z + yield from _list_fixed_content(a[:], content[:], t + 1, p, + k, dll, equality=equality) else: - for z in _list_fixed_content(a[:], content[:], t + 1, t, - k, dll, equality=equality): - yield z + yield from _list_fixed_content(a[:], content[:], t + 1, t, + k, dll, equality=equality) if not content[j]: # == 0 dll.unhide(j) @@ -519,13 +515,11 @@ def _simple_fixed_content(a, content, t, p, k, equality=False): a[t - 1] = j content[j] -= 1 if j == a[t - p - 1]: - for z in _simple_fixed_content(a[:], content, t + 1, p, - k, equality=equality): - yield z + yield from _simple_fixed_content(a[:], content, t + 1, p, + k, equality=equality) else: - for z in _simple_fixed_content(a[:], content, t + 1, t, - k, equality=equality): - yield z + yield from _simple_fixed_content(a[:], content, t + 1, t, + k, equality=equality) content[j] += 1 diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 7e1f1c6e4c6..7de90832e67 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -889,8 +889,7 @@ def upper_covers_iterator(self, element): sage: list(H.upper_covers_iterator(7)) [] """ - for x in self.neighbor_out_iterator(element): - yield x + yield from self.neighbor_out_iterator(element) def lower_covers_iterator(self, element): r""" @@ -905,8 +904,7 @@ def lower_covers_iterator(self, element): sage: list(H.lower_covers_iterator(4)) [1, 2] """ - for x in self.neighbor_in_iterator(element): - yield x + yield from self.neighbor_in_iterator(element) def cardinality(self): r""" diff --git a/src/sage/combinat/tiling.py b/src/sage/combinat/tiling.py index 640f1c6d096..d3e194956cb 100644 --- a/src/sage/combinat/tiling.py +++ b/src/sage/combinat/tiling.py @@ -1220,8 +1220,7 @@ def isometric_copies(self, box, orientation_preserving=True, all_distinct_cano = self.canonical_isometric_copies(orientation_preserving, mod_box_isometries) for cano in all_distinct_cano: - for t in cano.translated_copies(box=box): - yield t + yield from cano.translated_copies(box=box) def isometric_copies_intersection(self, box, orientation_preserving=True): r""" diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index d1aeb7c5b8a..b38241efc25 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -1731,8 +1731,7 @@ def left_special_factors_iterator(self, n=None): """ if n is None: for i in range(self.length()): - for w in self.left_special_factors_iterator(i): - yield w + yield from self.left_special_factors_iterator(i) else: left_extensions = defaultdict(set) for w in self.factor_iterator(n+1): @@ -1799,8 +1798,7 @@ def right_special_factors_iterator(self, n=None): """ if n is None: for i in range(self.length()): - for w in self.right_special_factors_iterator(i): - yield w + yield from self.right_special_factors_iterator(i) else: right_extensions = defaultdict(set) for w in self.factor_iterator(n+1): @@ -1890,8 +1888,7 @@ def bispecial_factors_iterator(self, n=None): """ if n is None: for i in range(self.length()): - for w in self.bispecial_factors_iterator(i): - yield w + yield from self.bispecial_factors_iterator(i) else: left_extensions = defaultdict(set) right_extensions = defaultdict(set) diff --git a/src/sage/combinat/yang_baxter_graph.py b/src/sage/combinat/yang_baxter_graph.py index 426095f6332..7b05bc68337 100644 --- a/src/sage/combinat/yang_baxter_graph.py +++ b/src/sage/combinat/yang_baxter_graph.py @@ -665,8 +665,7 @@ def __iter__(self): sage: list(Y.__iter__()) [(1, 0, 2, 1, 0), (1, 2, 0, 1, 0), (1, 2, 1, 0, 0), (2, 1, 0, 1, 0), (2, 1, 1, 0, 0)] """ - for v in self._vertex_ordering: - yield v + yield from self._vertex_ordering def _swap_operator(self, operator, u): r""" diff --git a/src/sage/databases/oeis.py b/src/sage/databases/oeis.py index 8dfe567a810..368ee80e120 100644 --- a/src/sage/databases/oeis.py +++ b/src/sage/databases/oeis.py @@ -1481,9 +1481,8 @@ def __iter__(self): sage: s = oeis._imaginary_sequence(ident='A999991', keywords='sign,full') sage: for i in s: pass """ - for x in self.first_terms(): - yield x - if not self.is_full() is True: + yield from self.first_terms() + if self.is_full() is not True: raise LookupError("future values not provided by OEIS") def references(self): diff --git a/src/sage/games/sudoku.py b/src/sage/games/sudoku.py index 2d2a2b36ab3..abcadd08ca3 100644 --- a/src/sage/games/sudoku.py +++ b/src/sage/games/sudoku.py @@ -719,8 +719,7 @@ def backtrack(self): """ from .sudoku_backtrack import backtrack_all solutions = backtrack_all(self.n, self.puzzle) - for soln in solutions: - yield soln + yield from solutions def dlx(self, count_only=False): r""" diff --git a/src/sage/graphs/bipartite_graph.py b/src/sage/graphs/bipartite_graph.py index 9b843ca965e..99bb96e637f 100644 --- a/src/sage/graphs/bipartite_graph.py +++ b/src/sage/graphs/bipartite_graph.py @@ -1701,8 +1701,7 @@ def rec(G): # For each unlabeled matching, we yield all its possible labelings for m in rec(G): - for pm in itertools.product(*[edges[frozenset(e)] for e in m]): - yield pm + yield from itertools.product(*[edges[frozenset(e)] for e in m]) def load_afile(self, fname): r""" diff --git a/src/sage/graphs/pq_trees.py b/src/sage/graphs/pq_trees.py index 4c3f25081bf..2ddd39691e8 100644 --- a/src/sage/graphs/pq_trees.py +++ b/src/sage/graphs/pq_trees.py @@ -365,8 +365,7 @@ def __iter__(self): {2, 3} ('P', [{2, 4}, {8, 2}, {9, 2}]) """ - for i in self._children: - yield i + yield from self._children def number_of_children(self): r""" @@ -795,13 +794,11 @@ def orderings(self): ({2, 4}, {0, 8}, {1, 2}, {0, 5}) ({2, 4}, {0, 8}, {0, 5}, {1, 2}) ... - """ from itertools import permutations, product for p in permutations(self._children): - for o in product(*[x.orderings() if isinstance(x, PQ) else [x] - for x in p]): - yield o + yield from product(*[x.orderings() if isinstance(x, PQ) else [x] + for x in p]) class Q(PQ): @@ -1124,8 +1121,7 @@ def orderings(self): """ if len(self._children) == 1: c = self._children[0] - for o in (c.orderings() if isinstance(c, PQ) else [c]): - yield o + yield from (c.orderings() if isinstance(c, PQ) else [c]) else: from itertools import product for o in product(*[x.orderings() if isinstance(x, PQ) else [x] diff --git a/src/sage/groups/abelian_gps/dual_abelian_group.py b/src/sage/groups/abelian_gps/dual_abelian_group.py index a1650f4eab0..2d5441daaca 100644 --- a/src/sage/groups/abelian_gps/dual_abelian_group.py +++ b/src/sage/groups/abelian_gps/dual_abelian_group.py @@ -405,5 +405,4 @@ def __iter__(self): sage: len([X for X in Gd if abs(X(x)-1)>0.01 and abs(X(y)-1)>0.01 and abs(X(z)-1)>0.01]) 880 """ - for g in self.list(): - yield g + yield from self.list() diff --git a/src/sage/groups/libgap_mixin.py b/src/sage/groups/libgap_mixin.py index fbf5ba3d349..6fb27280d8b 100644 --- a/src/sage/groups/libgap_mixin.py +++ b/src/sage/groups/libgap_mixin.py @@ -826,8 +826,7 @@ def __iter__(self): 60 """ if self.list.cache is not None: - for g in self.list(): - yield g + yield from self.list() return iterator = self.gap().Iterator() while not iterator.IsDoneIterator().sage(): diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index d46ef531add..47833d9f386 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -2010,8 +2010,7 @@ def __iter__(self): newres = self._results.get() if newres is not None: logger.debug("Got some results") - for r in newres: - yield r + yield from newres else: active_proc -= 1 if active_proc == 0: diff --git a/src/sage/parallel/multiprocessing_sage.py b/src/sage/parallel/multiprocessing_sage.py index be9b980aba9..2ccab49ac0f 100644 --- a/src/sage/parallel/multiprocessing_sage.py +++ b/src/sage/parallel/multiprocessing_sage.py @@ -74,7 +74,6 @@ def parallel_iter(processes, f, inputs): result = p.imap_unordered(call_pickled_function, [(fp, t) for t in inputs]) - for res in result: - yield res + yield from result p.close() p.join() diff --git a/src/sage/rings/asymptotic/growth_group_cartesian.py b/src/sage/rings/asymptotic/growth_group_cartesian.py index 155adb2398e..79510d42eca 100644 --- a/src/sage/rings/asymptotic/growth_group_cartesian.py +++ b/src/sage/rings/asymptotic/growth_group_cartesian.py @@ -775,8 +775,7 @@ def pushout_univariate_factors(self, other, var, Sfactors, Ofactors): def subfactors(F): for f in F: if isinstance(f, GenericProduct): - for g in subfactors(f.cartesian_factors()): - yield g + yield from subfactors(f.cartesian_factors()) else: yield f diff --git a/src/sage/rings/polynomial/pbori/blocks.py b/src/sage/rings/polynomial/pbori/blocks.py index 4115c35f832..752e0a14ee8 100644 --- a/src/sage/rings/polynomial/pbori/blocks.py +++ b/src/sage/rings/polynomial/pbori/blocks.py @@ -366,8 +366,7 @@ def canonicalize(blocks): if isinstance(elt, str): yield elt else: - for subelt in elt: - yield subelt + yield from elt blocks = list(blocks) n = 0 diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index ff1d3532124..b5a0a67c109 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -1444,7 +1444,7 @@ def random_element(self, degree=(-1,2), *args, **kwds): return p - def _monics_degree( self, of_degree ): + def _monics_degree(self, of_degree): """ Refer to monics() for full documentation. """ @@ -1455,15 +1455,14 @@ def _monics_degree( self, of_degree ): coeffs.reverse() yield self(coeffs) - def _monics_max( self, max_degree ): + def _monics_max(self, max_degree): """ Refer to monics() for full documentation. """ for degree in range(max_degree + 1): - for m in self._monics_degree( degree ): - yield m + yield from self._monics_degree(degree) - def _polys_degree( self, of_degree ): + def _polys_degree(self, of_degree): """ Refer to polynomials() for full documentation. """ diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index a82c5493545..6254f6b2494 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -540,8 +540,7 @@ def primes_of_bounded_norm_iter(self, B): return from sage.arith.misc import primes - for p in primes(B+1): - yield p + yield from primes(B + 1) def discriminant(self): """ diff --git a/src/sage/rings/valuation/value_group.py b/src/sage/rings/valuation/value_group.py index 159bb675664..816f142e0c7 100644 --- a/src/sage/rings/valuation/value_group.py +++ b/src/sage/rings/valuation/value_group.py @@ -676,8 +676,7 @@ def some_elements(self): yield self(0) if self.is_trivial(): return - for g in self._generators: - yield g + yield from self._generators from sage.rings.integer_ring import ZZ for x in (ZZ**len(self._generators)).some_elements(): yield QQ.coerce(sum([abs(c) * g diff --git a/src/sage/schemes/elliptic_curves/ell_finite_field.py b/src/sage/schemes/elliptic_curves/ell_finite_field.py index cd1e9c1733c..a46d722fb51 100644 --- a/src/sage/schemes/elliptic_curves/ell_finite_field.py +++ b/src/sage/schemes/elliptic_curves/ell_finite_field.py @@ -861,8 +861,7 @@ def __iter__(self): ... (10 : 0 : 1) 2 """ - for P in self.points(): - yield P + yield from self.points() def __getitem__(self, n): """ diff --git a/src/sage/sets/recursively_enumerated_set.pyx b/src/sage/sets/recursively_enumerated_set.pyx index 2ee74cbae1c..59f898ad830 100644 --- a/src/sage/sets/recursively_enumerated_set.pyx +++ b/src/sage/sets/recursively_enumerated_set.pyx @@ -827,8 +827,7 @@ cdef class RecursivelyEnumeratedSet_generic(Parent): current_level = self._seeds known = set(current_level) if max_depth >= 0: - for x in current_level: - yield x + yield from current_level depth = 0 while current_level and depth < max_depth: next_level = [] @@ -1078,8 +1077,7 @@ cdef class RecursivelyEnumeratedSet_symmetric(RecursivelyEnumeratedSet_generic): B = self._seeds set_B = set(B) if max_depth >= 0: - for x in B: - yield x + yield from B depth = 0 while B and depth < max_depth: C = list() @@ -1329,8 +1327,7 @@ cdef class RecursivelyEnumeratedSet_graded(RecursivelyEnumeratedSet_generic): max_depth = self._max_depth current_level = self._seeds if max_depth >= 0: - for x in current_level: - yield x + yield from current_level depth = 0 while current_level and depth < max_depth: next_level = list() @@ -1936,12 +1933,10 @@ class RecursivelyEnumeratedSet_forest(Parent): [] """ if depth == 0: - for node in self.roots(): - yield node + yield from self.roots() else: for father in self._elements_of_depth_iterator_rec(depth - 1): - for node in self.children(father): - yield node + yield from self.children(father) def elements_of_depth_iterator(self, depth=0): r""" diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 61d758f964d..bc72df269bc 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -3082,14 +3082,11 @@ cdef class Expression(Expression_abc): if op.is_numeric(): yield op else: - for opp in numelems_gen(op): - yield opp + yield from numelems_gen(op) # stop at the first inexact number in the subexpression tree of self, # and if there is no such element, then self is exact - for nelem in numelems_gen(self): - if not nelem.pyobject().base_ring().is_exact(): - return False - return True + return all(nelem.pyobject().base_ring().is_exact() + for nelem in numelems_gen(self)) cpdef bint is_infinity(self): """ diff --git a/src/sage/tensor/modules/comp.py b/src/sage/tensor/modules/comp.py index 653b65d529e..198fdc7479a 100644 --- a/src/sage/tensor/modules/comp.py +++ b/src/sage/tensor/modules/comp.py @@ -2518,10 +2518,8 @@ def non_redundant_index_generator(self): sage: list(c.non_redundant_index_generator()) [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)] - """ - for ind in self.index_generator(): - yield ind + yield from self.index_generator() def symmetrize(self, *pos): r""" diff --git a/src/sage/tests/arxiv_0812_2725.py b/src/sage/tests/arxiv_0812_2725.py index 093025373e1..3f304803c31 100644 --- a/src/sage/tests/arxiv_0812_2725.py +++ b/src/sage/tests/arxiv_0812_2725.py @@ -73,8 +73,7 @@ def CompleteMatchings(n): integer depends on what [1..n] returns, and also on what range(1, len([1..n])) is. """ - for m in matchingsset(list(range(1, n + 1))): - yield m + yield from matchingsset(list(range(1, n + 1))) def matchingsset(L): diff --git a/src/sage/typeset/character_art.py b/src/sage/typeset/character_art.py index dd1107db48d..a4de0e23964 100644 --- a/src/sage/typeset/character_art.py +++ b/src/sage/typeset/character_art.py @@ -133,8 +133,7 @@ def __iter__(self): * * ***** """ - for elem in self._matrix: - yield elem + yield from self._matrix def _repr_(self): r""" From 6b3eb6f5fd6ea71797692db8338a8660b5a9f34f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 5 Jun 2023 21:13:20 +0200 Subject: [PATCH 52/56] a few more yield from --- src/sage/combinat/non_decreasing_parking_function.py | 3 +-- src/sage/combinat/species/functorial_composition_species.py | 3 +-- src/sage/combinat/subset.py | 3 +-- src/sage/graphs/digraph_generators.py | 3 +-- src/sage/modular/multiple_zeta.py | 3 +-- src/sage/rings/polynomial/groebner_fan.py | 3 +-- src/sage/schemes/toric/points.py | 3 +-- 7 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/sage/combinat/non_decreasing_parking_function.py b/src/sage/combinat/non_decreasing_parking_function.py index 9b04286372c..532b4bf8762 100644 --- a/src/sage/combinat/non_decreasing_parking_function.py +++ b/src/sage/combinat/non_decreasing_parking_function.py @@ -419,8 +419,7 @@ def __iter__(self): [[], [1], [1, 1], [1, 2], [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 2]] """ for n in NN: - for pf in NonDecreasingParkingFunctions_n(n): - yield pf + yield from NonDecreasingParkingFunctions_n(n) def graded_component(self, n): """ diff --git a/src/sage/combinat/species/functorial_composition_species.py b/src/sage/combinat/species/functorial_composition_species.py index d97460e29e4..118e924d426 100644 --- a/src/sage/combinat/species/functorial_composition_species.py +++ b/src/sage/combinat/species/functorial_composition_species.py @@ -71,8 +71,7 @@ def _structures(self, structure_class, s): {{1, 2}*{3}, {1, 3}*{2}, {2, 3}*{1}}] """ gs = self._G.structures(s).list() - for f in self._F.structures(gs): - yield f + yield from self._F.structures(gs) def _isotypes(self, structure_class, s): """ diff --git a/src/sage/combinat/subset.py b/src/sage/combinat/subset.py index c27b1eb04ed..5a486b0f551 100644 --- a/src/sage/combinat/subset.py +++ b/src/sage/combinat/subset.py @@ -1130,8 +1130,7 @@ def __iter__(self): [1, 2, 2, 3]] """ for k in range(len(self._l) + 1): - for s in SubMultiset_sk(self._l, k): - yield s + yield from SubMultiset_sk(self._l, k) def __call__(self, el): r""" diff --git a/src/sage/graphs/digraph_generators.py b/src/sage/graphs/digraph_generators.py index 2b864b54284..b9a87601a47 100644 --- a/src/sage/graphs/digraph_generators.py +++ b/src/sage/graphs/digraph_generators.py @@ -1747,8 +1747,7 @@ def extra_property(x): if vertices is None: vertices = 0 while True: - for g in self(vertices, sparse=sparse, copy=copy): - yield g + yield from self(vertices, sparse=sparse, copy=copy) vertices += 1 from sage.graphs.graph_generators import canaug_traverse_edge diff --git a/src/sage/modular/multiple_zeta.py b/src/sage/modular/multiple_zeta.py index b6580211188..032a592ef36 100644 --- a/src/sage/modular/multiple_zeta.py +++ b/src/sage/modular/multiple_zeta.py @@ -575,8 +575,7 @@ def extend_multiplicative_basis(B, n) -> Iterator: [((7,),), ((5,), (2,)), ((3,), (2,), (2,))] """ for pi in Partitions(n, min_part=2): - for liste in cartesian_product([B[i] for i in pi]): - yield liste + yield from cartesian_product([B[i] for i in pi]) # several classes for the algebra of MZV diff --git a/src/sage/rings/polynomial/groebner_fan.py b/src/sage/rings/polynomial/groebner_fan.py index 6c6548d9e85..5177b2eaf27 100644 --- a/src/sage/rings/polynomial/groebner_fan.py +++ b/src/sage/rings/polynomial/groebner_fan.py @@ -1157,8 +1157,7 @@ def __iter__(self): sage: next(a) [y^9 - 3*y^6 + 3*y^3 - y - 1, -y^3 + x + 1] """ - for x in self.reduced_groebner_bases(): - yield x + yield from self.reduced_groebner_bases() def __getitem__(self, i): """ diff --git a/src/sage/schemes/toric/points.py b/src/sage/schemes/toric/points.py index f72bd2eb3ba..8a70350a30e 100644 --- a/src/sage/schemes/toric/points.py +++ b/src/sage/schemes/toric/points.py @@ -350,8 +350,7 @@ def cone_iter(self): """ fan = self.fan for d in range(fan.dim(), -1, -1): - for cone in fan.cones(d): - yield cone + yield from fan.cones(d) def coordinate_iter(self): """ From 29fce00171f368fb0d6b39399c0ca28726dfeed4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 15:58:52 -0700 Subject: [PATCH 53/56] build/pkgs/maxima/spkg-install.in: Patch out self-race --- build/pkgs/maxima/spkg-install.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/pkgs/maxima/spkg-install.in b/build/pkgs/maxima/spkg-install.in index cdb6fbf2069..ef044cbf010 100644 --- a/build/pkgs/maxima/spkg-install.in +++ b/build/pkgs/maxima/spkg-install.in @@ -20,6 +20,10 @@ cd src/ # Use newer version of config.guess and config.sub (see Trac #19734) cp "$SAGE_ROOT"/config/config.* . +# Patch out bad 'multiple targets' rule +# https://github.com/sagemath/sage/pull/35619#issuecomment-1567351409 +sed -i.bak 's/^maxima_singlepage.html //' doc/info/Makefile.in + # Note that maxima configure checks for git and, if it finds it, uses # versions information from the repo. See #15529. We disable this with # git_found=false From 05f6c84355b47d275481c30b20a064b70e5e0153 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 16:42:34 -0700 Subject: [PATCH 54/56] build/pkgs/info/spkg-configure.m4: Remove info file created in test --- build/pkgs/info/spkg-configure.m4 | 1 + 1 file changed, 1 insertion(+) diff --git a/build/pkgs/info/spkg-configure.m4 b/build/pkgs/info/spkg-configure.m4 index 85fe1ea4731..76ea2cc7565 100644 --- a/build/pkgs/info/spkg-configure.m4 +++ b/build/pkgs/info/spkg-configure.m4 @@ -9,6 +9,7 @@ SAGE_SPKG_CONFIGURE([info], [ AS_IF([makeinfo -c foo 2>&1 | grep -q invalid], [ dnl makeinfo found, but too old, and does not support all options that ecl likes to use sage_spkg_install_info=yes]) + rm -f stdin.info ]) ]) ]) From 41490d9e5af75d67735c09937f05c7adddd59cd2 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Wed, 7 Jun 2023 11:08:57 +0800 Subject: [PATCH 55/56] reviewer comments --- src/sage/schemes/elliptic_curves/hom.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 6f01468fa51..2a346d5e127 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -899,7 +899,7 @@ def compare_via_evaluation(left, right): 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')) + EE = E.base_extend(F.extension(e, 'U')) # named extension is faster Ps = EE.gens() return all(left._eval(P) == right._eval(P) for P in Ps) elif isinstance(F, number_field_base.NumberField): @@ -982,7 +982,7 @@ def find_post_isomorphism(phi, psi): if len(isos) <= 1: break else: - E = E.base_extend(E.base_field().extension(2,'U')) + E = E.base_extend(E.base_field().extension(2, 'U')) # named extension is faster elif isinstance(F, number_field_base.NumberField): for _ in range(100): From 443b7549ad36821e6e54829c8146cdae598ebd57 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sun, 11 Jun 2023 12:24:14 +0200 Subject: [PATCH 56/56] Updated SageMath version to 10.1.beta3 --- CITATION.cff | 4 ++-- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sage_conf/install-requires.txt | 2 +- build/pkgs/sage_docbuild/install-requires.txt | 2 +- build/pkgs/sage_setup/install-requires.txt | 2 +- build/pkgs/sage_sws2rst/install-requires.txt | 2 +- build/pkgs/sagelib/install-requires.txt | 2 +- build/pkgs/sagemath_categories/install-requires.txt | 2 +- build/pkgs/sagemath_environment/install-requires.txt | 2 +- build/pkgs/sagemath_objects/install-requires.txt | 2 +- build/pkgs/sagemath_repl/install-requires.txt | 2 +- pkgs/sage-conf/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-categories/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 25 files changed, 32 insertions(+), 32 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index c5d6e71ae60..29721b280a3 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.0 +version: 10.1.beta3 doi: 10.5281/zenodo.593563 -date-released: 2023-05-20 +date-released: 2023-06-11 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index c4c9b181ed8..22e57381881 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.1.beta2, Release Date: 2023-06-03 +SageMath version 10.1.beta3, Release Date: 2023-06-11 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 3f2e55cf907..7a9a8380e2c 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=efa52d2db3a67f4aba3f94cd83df9d0b9dd29f06 -md5=dedcc422a192b5d38a30940953f6c77a -cksum=3828425183 +sha1=c7c1743bdc3941301764422bef5694849cd1e265 +md5=610ce114c46a794ffd70346581012808 +cksum=2506747194 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 635824dbcda..d10b3c6b793 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -7fa8fbbef164382770f0f5e6611a75b6459a78eb +464d3d20aaa0a04237ebc98378cf1eec48505e17 diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index d50a8e7117e..89c7f89092e 100644 --- a/build/pkgs/sage_conf/install-requires.txt +++ b/build/pkgs/sage_conf/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-conf ~= 10.1b2 +sage-conf ~= 10.1b3 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index bd6be79c3ef..3853df189b7 100644 --- a/build/pkgs/sage_docbuild/install-requires.txt +++ b/build/pkgs/sage_docbuild/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-docbuild ~= 10.1b2 +sage-docbuild ~= 10.1b3 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index e2f10b4a6b5..cbe875cbadf 100644 --- a/build/pkgs/sage_setup/install-requires.txt +++ b/build/pkgs/sage_setup/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-setup ~= 10.1b2 +sage-setup ~= 10.1b3 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index cae34b0b6fe..15283c90e87 100644 --- a/build/pkgs/sage_sws2rst/install-requires.txt +++ b/build/pkgs/sage_sws2rst/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sage-sws2rst ~= 10.1b2 +sage-sws2rst ~= 10.1b3 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 35c2a8040ec..26f47a8cfe0 100644 --- a/build/pkgs/sagelib/install-requires.txt +++ b/build/pkgs/sagelib/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagelib ~= 10.1b2 +sagelib ~= 10.1b3 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index 1b18527c75d..5b009ccfdcb 100644 --- a/build/pkgs/sagemath_categories/install-requires.txt +++ b/build/pkgs/sagemath_categories/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-categories ~= 10.1b2 +sagemath-categories ~= 10.1b3 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index dddc4170942..0d2a87143f3 100644 --- a/build/pkgs/sagemath_environment/install-requires.txt +++ b/build/pkgs/sagemath_environment/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-environment ~= 10.1b2 +sagemath-environment ~= 10.1b3 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index 8254467164b..3f15a34d3aa 100644 --- a/build/pkgs/sagemath_objects/install-requires.txt +++ b/build/pkgs/sagemath_objects/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-objects ~= 10.1b2 +sagemath-objects ~= 10.1b3 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index 6b98d320073..bc8bda08722 100644 --- a/build/pkgs/sagemath_repl/install-requires.txt +++ b/build/pkgs/sagemath_repl/install-requires.txt @@ -1,2 +1,2 @@ # This file is updated on every release by the sage-update-version script -sagemath-repl ~= 10.1b2 +sagemath-repl ~= 10.1b3 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/src/VERSION.txt b/src/VERSION.txt index 05e26b17161..134573c319a 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.1.beta2 +10.1.beta3 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 1a398cd9676..00fd83ccd47 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.1.beta2' -SAGE_RELEASE_DATE='2023-06-03' -SAGE_VERSION_BANNER='SageMath version 10.1.beta2, Release Date: 2023-06-03' +SAGE_VERSION='10.1.beta3' +SAGE_RELEASE_DATE='2023-06-11' +SAGE_VERSION_BANNER='SageMath version 10.1.beta3, Release Date: 2023-06-11' diff --git a/src/sage/version.py b/src/sage/version.py index 0ac9bf873ed..5119b7def49 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.1.beta2' -date = '2023-06-03' -banner = 'SageMath version 10.1.beta2, Release Date: 2023-06-03' +version = '10.1.beta3' +date = '2023-06-11' +banner = 'SageMath version 10.1.beta3, Release Date: 2023-06-11'