From 28687752f6d593b5968020b2e061c6cd08c21c6a Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Fri, 25 Nov 2022 12:42:29 +0000 Subject: [PATCH 001/205] 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 002/205] 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 003/205] 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 004/205] 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 005/205] 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 006/205] 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 2e1d2c3f6d160d6d5152cdc6413873b9a28c6087 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 7 May 2023 00:14:20 -0700 Subject: [PATCH 007/205] doctester: Check for consistency of # optional annotations --- src/sage/doctest/forker.py | 29 ++++++++++++++++++++++------- src/sage/doctest/parsing.py | 1 + src/sage/doctest/sources.py | 1 + 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index fe58e2bde3e..e4ccec1234f 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -47,6 +47,7 @@ import doctest import traceback import tempfile +from collections import defaultdict from dis import findlinestarts from queue import Empty import gc @@ -527,7 +528,7 @@ def __init__(self, *args, **kwds): self.msgfile = self._fakeout.real_stdout self.history = [] self.references = [] - self.setters = {} + self.setters = defaultdict(dict) self.running_global_digest = hashlib.md5() self.total_walltime_skips = 0 self.total_performed_tests = 0 @@ -772,6 +773,9 @@ def compiler(example): if self.options.warn_long > 0 and example.walltime + check_duration > self.options.warn_long: self.report_overtime(out, test, example, got, check_duration=check_duration) + elif example.warnings: + for warning in example.warnings: + out(self._failure_header(test, example, f'Warning: {warning}')) elif not quiet: self.report_success(out, test, example, got, check_duration=check_duration) @@ -831,14 +835,15 @@ def run(self, test, compileflags=0, out=None, clear_globs=True): sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() sage: from sage.env import SAGE_SRC sage: import doctest, sys, os - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: filename = os.path.join(SAGE_SRC,'sage','doctest','forker.py') sage: FDS = FileDocTestSource(filename,DD) sage: doctests, extras = FDS.create_doctests(globals()) sage: DTR.run(doctests[0], clear_globs=False) TestResults(failed=0, attempted=4) """ - self.setters = {} + self.setters = defaultdict(dict) randstate.set_random_seed(self.options.random_seed) warnings.showwarning = showwarning_with_traceback self.running_doctest_digest = hashlib.md5() @@ -1085,6 +1090,7 @@ def compile_and_execute(self, example, compiler, globs): if isinstance(globs, RecordingDict): globs.start() example.sequence_number = len(self.history) + example.warnings = [] self.history.append(example) timer = Timer().start() try: @@ -1096,11 +1102,20 @@ def compile_and_execute(self, example, compiler, globs): if isinstance(globs, RecordingDict): example.predecessors = [] for name in globs.got: - ref = self.setters.get(name) - if ref is not None: - example.predecessors.append(ref) + setters_dict = self.setters.get(name) # setter_optional_tags -> setter + if setters_dict: + for setter_optional_tags, setter in setters_dict.items(): + if setter_optional_tags.issubset(example.optional_tags): + example.predecessors.append(setter) + if not example.predecessors: + f_setter_optional_tags = "; ".join("'# optional - " + + " ".join(sorted(setter_optional_tags)) + + "'" + for setter_optional_tags in setters_dict) + example.warnings.append(f"Variable '{name}' referenced here " + f"was set only in doctest marked {f_setter_optional_tags}") for name in globs.set: - self.setters[name] = example + self.setters[name][example.optional_tags] = example else: example.predecessors = None self.update_digests(example) diff --git a/src/sage/doctest/parsing.py b/src/sage/doctest/parsing.py index 2e39bee5704..5f733fa8e44 100644 --- a/src/sage/doctest/parsing.py +++ b/src/sage/doctest/parsing.py @@ -633,6 +633,7 @@ def parse(self, string, *args): for item in res: if isinstance(item, doctest.Example): optional_tags = parse_optional_tags(item.source) + item.optional_tags = frozenset(optional_tags) if optional_tags: for tag in optional_tags: self.optionals[tag] += 1 diff --git a/src/sage/doctest/sources.py b/src/sage/doctest/sources.py index 6321e73a5e8..461c0454795 100644 --- a/src/sage/doctest/sources.py +++ b/src/sage/doctest/sources.py @@ -224,6 +224,7 @@ def _process_doc(self, doctests, doc, namespace, start): # Line number refers to the end of the docstring sigon = doctest.Example(sig_on_count_doc_doctest, "0\n", lineno=docstring.count("\n")) sigon.sage_source = sig_on_count_doc_doctest + sigon.optional_tags = frozenset() dt.examples.append(sigon) doctests.append(dt) From b124f2a9451e7053b50b739a3ff6c686b007c949 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 7 May 2023 12:46:16 -0700 Subject: [PATCH 008/205] sage.doctest.parsing.unparse_optional_tags: New --- src/sage/doctest/forker.py | 6 +++--- src/sage/doctest/parsing.py | 40 ++++++++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index e4ccec1234f..9a39d3698bd 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -57,7 +57,7 @@ from sage.misc.misc import walltime from .util import Timer, RecordingDict, count_noun from .sources import DictAsObject -from .parsing import OriginalSource, reduce_hex +from .parsing import OriginalSource, reduce_hex, unparse_optional_tags from sage.structure.sage_object import SageObject from .parsing import SageOutputChecker, pre_hash, get_source from sage.repl.user_globals import set_globals @@ -1108,8 +1108,8 @@ def compile_and_execute(self, example, compiler, globs): if setter_optional_tags.issubset(example.optional_tags): example.predecessors.append(setter) if not example.predecessors: - f_setter_optional_tags = "; ".join("'# optional - " - + " ".join(sorted(setter_optional_tags)) + f_setter_optional_tags = "; ".join("'" + + unparse_optional_tags(setter_optional_tags) + "'" for setter_optional_tags in setters_dict) example.warnings.append(f"Variable '{name}' referenced here " diff --git a/src/sage/doctest/parsing.py b/src/sage/doctest/parsing.py index 5f733fa8e44..e585acf1e5d 100644 --- a/src/sage/doctest/parsing.py +++ b/src/sage/doctest/parsing.py @@ -79,6 +79,10 @@ def fake_RIFtol(*args): # This is the correct pattern to match ISO/IEC 6429 ANSI escape sequences: ansi_escape_sequence = re.compile(r'(\x1b[@-Z\\-~]|\x1b\[.*?[@-~]|\x9b.*?[@-~])') +special_optional_regex = 'arb216|arb218|py2|long time|not implemented|not tested|known bug' +optional_regex = re.compile(fr'({special_optional_regex})|([^ a-z]\s*optional\s*[:-]*((\s|\w|[.])*))') +special_optional_regex = re.compile(special_optional_regex) + def parse_optional_tags(string): """ @@ -137,8 +141,6 @@ def parse_optional_tags(string): # strip_string_literals replaces comments comment = "#" + (literals[comment]).lower() - optional_regex = re.compile(r'(arb216|arb218|py2|long time|not implemented|not tested|known bug)|([^ a-z]\s*optional\s*[:-]*((\s|\w|[.])*))') - tags = [] for m in optional_regex.finditer(comment): cmd = m.group(1) @@ -151,8 +153,40 @@ def parse_optional_tags(string): return set(tags) -def parse_tolerance(source, want): +def unparse_optional_tags(tags): + r""" + Return a comment string that sets ``tags``. + + INPUT: + + - ``tags`` -- iterable of tags, as output by :func:`parse_optional_tags` + + EXAMPLES:: + + sage: from sage.doctest.parsing import unparse_optional_tags + sage: unparse_optional_tags(set()) + '' + sage: unparse_optional_tags({'magma'}) + '# optional - magma' + sage: unparse_optional_tags(['zipp', 'sage.rings.number_field', 'foo']) + '# optional - foo zipp sage.rings.number_field' + sage: unparse_optional_tags(['long time', 'not tested', 'p4cka9e']) + '# long time, not tested, optional - p4cka9e' """ + tags = set(tags) + special_tags = set(tag for tag in tags if special_optional_regex.fullmatch(tag)) + optional_tags = sorted(tags - special_tags, + key=lambda tag: (tag.startswith('sage.'), tag)) + tags = sorted(special_tags) + if optional_tags: + tags.append('optional - ' + " ".join(optional_tags)) + if tags: + return '# ' + ', '.join(tags) + return '' + + +def parse_tolerance(source, want): + r""" Return a version of ``want`` marked up with the tolerance tags specified in ``source``. From 55f51970a74b38656c6f902a93aad53d4afef4e7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 7 May 2023 12:46:50 -0700 Subject: [PATCH 009/205] sage.doctest: Docstring/doctest cosmetics --- src/sage/doctest/forker.py | 19 +++++++++++++------ src/sage/doctest/parsing.py | 4 ++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index 9a39d3698bd..6a62fdccb83 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -1042,17 +1042,20 @@ def compile_and_execute(self, example, compiler, globs): sage: from sage.doctest.control import DocTestDefaults; DD = DocTestDefaults() sage: from sage.env import SAGE_SRC sage: import doctest, sys, os, hashlib - sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) + sage: DTR = SageDocTestRunner(SageOutputChecker(), verbose=False, sage_options=DD, + ....: optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS) sage: DTR.running_doctest_digest = hashlib.md5() - sage: filename = os.path.join(SAGE_SRC,'sage','doctest','forker.py') - sage: FDS = FileDocTestSource(filename,DD) + sage: filename = os.path.join(SAGE_SRC, 'sage', 'doctest', 'forker.py') + sage: FDS = FileDocTestSource(filename, DD) sage: globs = RecordingDict(globals()) sage: 'doctest_var' in globs False sage: doctests, extras = FDS.create_doctests(globs) sage: ex0 = doctests[0].examples[0] sage: flags = 32768 if sys.version_info.minor < 8 else 524288 - sage: compiler = lambda ex: compile(ex.source, '', 'single', flags, 1) + sage: def compiler(ex): + ....: return compile(ex.source, '', + ....: 'single', flags, 1) sage: DTR.compile_and_execute(ex0, compiler, globs) 1764 sage: globs['doctest_var'] @@ -1065,7 +1068,9 @@ def compile_and_execute(self, example, compiler, globs): Now we can execute some more doctests to see the dependencies. :: sage: ex1 = doctests[0].examples[1] - sage: compiler = lambda ex:compile(ex.source, '', 'single', flags, 1) + sage: def compiler(ex): + ....: return compile(ex.source, '', + ....: 'single', flags, 1) sage: DTR.compile_and_execute(ex1, compiler, globs) sage: sorted(list(globs.set)) ['R', 'a'] @@ -1077,7 +1082,9 @@ def compile_and_execute(self, example, compiler, globs): :: sage: ex2 = doctests[0].examples[2] - sage: compiler = lambda ex:compile(ex.source, '', 'single', flags, 1) + sage: def compiler(ex): + ....: return compile(ex.source, '', + ....: 'single', flags, 1) sage: DTR.compile_and_execute(ex2, compiler, globs) a + 42 sage: list(globs.set) diff --git a/src/sage/doctest/parsing.py b/src/sage/doctest/parsing.py index e585acf1e5d..579768d6a06 100644 --- a/src/sage/doctest/parsing.py +++ b/src/sage/doctest/parsing.py @@ -197,8 +197,8 @@ def parse_tolerance(source, want): OUTPUT: - - ``want`` if there are no tolerance tags specified; a - :class:`MarkedOutput` version otherwise. + ``want`` if there are no tolerance tags specified; a + :class:`MarkedOutput` version otherwise. EXAMPLES:: From 253491e97dbe6471299384441e7c2e1c6059a2b6 Mon Sep 17 00:00:00 2001 From: Christian Wuthrich Date: Tue, 9 May 2023 20:18:19 +0100 Subject: [PATCH 010/205] 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 011/205] 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 012/205] 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 013/205] 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 014/205] 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 015/205] 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 016/205] 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 445188664efb1224b5d8a510c9ef716b519558da Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 18 May 2023 17:37:13 -0700 Subject: [PATCH 017/205] .github/workflows/build.yml: First build really incrementally and test changed files --- .github/workflows/build.yml | 40 +++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ffc09d56ff2..b18b3ad5264 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,24 +29,38 @@ jobs: id: checkout uses: actions/checkout@v3 - - name: Prepare + - name: Update system packages id: prepare run: | - # Install test tools. - if apt-get update && apt-get install -y git python3-venv; then - # Debian-specific temporary code: - # Installation of python3-venv can be removed as soon as a - # base image with a release including #33822 is available - : - else - export PATH="build/bin:$PATH" - eval $(sage-print-system-package-command auto update) - eval $(sage-print-system-package-command auto --spkg --yes --no-install-recommends install git) - fi + export PATH="build/bin:$PATH" + eval $(sage-print-system-package-command auto update) + eval $(sage-print-system-package-command auto --spkg --yes --no-install-recommends install git) + + - name: Incremental build and test + if: always() && steps.prepare.outcome == 'success' + id: incremental + run: | + set -ex + git config --global user.email "ci-sage@example.com" + git config --global user.name "Build & Test workflow" + # If actions/checkout downloaded using the GitHub REST API: + if [ ! -d .git ]; then git config --global --add safe.directory $(pwd) && git init && git add -A && git commit --quiet -m "new"; fi + # Make the source tree from the container image a worktree: + git worktree add --detach worktree-image && git tag -f new + rm -rf /sage/.git && mv worktree-image/.git /sage/ + rm -rf worktree-image && ln -s /sage worktree-image + (cd /sage && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old && make build && ./sage -t --new -p2) + env: + MAKE: make -j2 + SAGE_NUM_THREADS: 2 + + - name: Configure new tree + if: always() && steps.prepare.outcome == 'success' + run: | # Reuse built SAGE_LOCAL contained in the Docker image ./bootstrap ./configure --enable-build-as-root --prefix=/sage/local --with-sage-venv --enable-editable --enable-download-from-upstream-url - + - name: Build and test modularized distributions if: always() && steps.prepare.outcome == 'success' run: make V=0 tox && make pypi-wheels From 2881586dd605cfb14be3f6c2860ae59e1b3abfcf Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 18 May 2023 19:30:24 -0700 Subject: [PATCH 018/205] src/sage/doctest/control.py: Make 'sage -t --new' work in git worktrees --- src/sage/doctest/control.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index 450d9b607da..c2e9f927e05 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -791,7 +791,7 @@ def add_files(self): # SAGE_ROOT_GIT can be None on distributions which typically # only have the SAGE_LOCAL install tree but not SAGE_ROOT if SAGE_ROOT_GIT is not None: - have_git = os.path.isdir(SAGE_ROOT_GIT) + have_git = os.path.exists(SAGE_ROOT_GIT) else: have_git = False From 43fcf4a93d03c6d9413d101369e795549407630c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 18 May 2023 19:43:06 -0700 Subject: [PATCH 019/205] .github/workflows/build.yml: Run non-incremental tests with --long --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b18b3ad5264..083e1f869b7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -105,7 +105,7 @@ jobs: if: always() && steps.build.outcome == 'success' run: | ../sage -python -m pip install coverage - ../sage -python -m coverage run ./bin/sage-runtests --all -p2 + ../sage -python -m coverage run ./bin/sage-runtests --all --long -p2 working-directory: ./src - name: Prepare coverage results From f9b4412d823b2c7964ded86c3e5afaba103c1430 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 25 May 2023 19:04:36 -0700 Subject: [PATCH 020/205] .github/workflows/build.yml: Explicitly run bootstrap before the incremental build --- .github/workflows/build.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 083e1f869b7..e287b5e52fd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,7 +49,7 @@ jobs: git worktree add --detach worktree-image && git tag -f new rm -rf /sage/.git && mv worktree-image/.git /sage/ rm -rf worktree-image && ln -s /sage worktree-image - (cd /sage && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old && make build && ./sage -t --new -p2) + (cd /sage && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old && ./bootstrap && make build && ./sage -t --new -p2) env: MAKE: make -j2 SAGE_NUM_THREADS: 2 @@ -58,7 +58,6 @@ jobs: if: always() && steps.prepare.outcome == 'success' run: | # Reuse built SAGE_LOCAL contained in the Docker image - ./bootstrap ./configure --enable-build-as-root --prefix=/sage/local --with-sage-venv --enable-editable --enable-download-from-upstream-url - name: Build and test modularized distributions From f93a4d68489383c0601ffa227245aca44916bafd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 27 May 2023 09:37:49 -0700 Subject: [PATCH 021/205] .github/workflows/build.yml: Explicitly run bootstrap before the incremental build (fixup) --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e287b5e52fd..3f61126b8a8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -58,6 +58,7 @@ jobs: if: always() && steps.prepare.outcome == 'success' run: | # Reuse built SAGE_LOCAL contained in the Docker image + ./bootstrap ./configure --enable-build-as-root --prefix=/sage/local --with-sage-venv --enable-editable --enable-download-from-upstream-url - name: Build and test modularized distributions From 3cf43946f40307a9e06e2e0a20e1d68dc8c26461 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 27 May 2023 13:02:55 -0700 Subject: [PATCH 022/205] src/sage/doctest/sources.py: Fix doctest output --- src/sage/doctest/sources.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/doctest/sources.py b/src/sage/doctest/sources.py index 461c0454795..15115a245b3 100644 --- a/src/sage/doctest/sources.py +++ b/src/sage/doctest/sources.py @@ -788,7 +788,7 @@ def _test_enough_doctests(self, check_extras=True, verbose=True): ....: filename = os.path.join(path, F) ....: FDS = FileDocTestSource(filename, DocTestDefaults(long=True, optional=True, force_lib=True)) ....: FDS._test_enough_doctests(verbose=False) - There are 3 unexpected tests being run in sage/doctest/parsing.py + There are 4 unexpected tests being run in sage/doctest/parsing.py There are 1 unexpected tests being run in sage/doctest/reporting.py sage: os.chdir(cwd) """ From f46d247a303306ddafeb352f733fac09035500a6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 27 May 2023 18:43:48 -0700 Subject: [PATCH 023/205] .github/workflows/build.yml: Add comments --- .github/workflows/build.yml | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3f61126b8a8..edc0cf1337b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,13 +43,27 @@ jobs: set -ex git config --global user.email "ci-sage@example.com" git config --global user.name "Build & Test workflow" - # If actions/checkout downloaded using the GitHub REST API: + # If actions/checkout downloaded our source tree using the GitHub REST API + # instead of with git (because do not have git installed in our image), + # we first make the source tree a repo. if [ ! -d .git ]; then git config --global --add safe.directory $(pwd) && git init && git add -A && git commit --quiet -m "new"; fi - # Make the source tree from the container image a worktree: - git worktree add --detach worktree-image && git tag -f new + # Tag this state of the source tree "new". This is what we want to build and test. + git tag -f new + # Our container image contains a source tree in /sage with a full build of Sage. + # But /sage is not a git repository. + # We make /sage a worktree whose index is at tag "new". + # We then commit the current sources and set the tag "old". (This keeps all mtimes unchanged.) + # Then we update worktree and index with "git reset --hard". + # (This keeps mtimes of unchanged files unchanged and mtimes of changed files newer than unchanged files.) + # Finally we reset the index to "old". (This keeps all mtimes unchanged.) + # The changed files now show up as uncommitted changes. + git worktree add --detach worktree-image rm -rf /sage/.git && mv worktree-image/.git /sage/ rm -rf worktree-image && ln -s /sage worktree-image - (cd /sage && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old && ./bootstrap && make build && ./sage -t --new -p2) + (cd worktree-image && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) + # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. + # We run tests with "sage -t --new"; this only tests the uncommitted changes. + (cd worktree-image && ./bootstrap && make build && ./sage -t --new -p2) env: MAKE: make -j2 SAGE_NUM_THREADS: 2 From cbc0198be05923dc230021749bcd59cb4cb3cf99 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 27 May 2023 19:32:26 -0700 Subject: [PATCH 024/205] .github/workflows/build.yml: Add comments (fixup) --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index edc0cf1337b..1977b2d27f3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,7 +53,7 @@ jobs: # But /sage is not a git repository. # We make /sage a worktree whose index is at tag "new". # We then commit the current sources and set the tag "old". (This keeps all mtimes unchanged.) - # Then we update worktree and index with "git reset --hard". + # Then we update worktree and index with "git reset --hard new". # (This keeps mtimes of unchanged files unchanged and mtimes of changed files newer than unchanged files.) # Finally we reset the index to "old". (This keeps all mtimes unchanged.) # The changed files now show up as uncommitted changes. 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 025/205] :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 026/205] 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 027/205] 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 028/205] 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 029/205] 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 030/205] 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 031/205] 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 032/205] 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 033/205] 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 034/205] 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 035/205] 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 036/205] 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 037/205] 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 038/205] 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 039/205] 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 040/205] 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 041/205] 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 042/205] 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 cf2d370ba5d8b62c6e1ec5bf2e5e03041521fc3a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 12 Mar 2023 00:22:41 -0800 Subject: [PATCH 043/205] sage.matroids: More # optional --- src/sage/matroids/basis_exchange_matroid.pyx | 170 +++++++-------- src/sage/matroids/basis_matroid.pyx | 120 +++++------ src/sage/matroids/catalog.py | 198 +++++++++--------- .../matroids/circuit_closures_matroid.pyx | 16 +- src/sage/matroids/constructor.py | 10 +- src/sage/matroids/dual_matroid.py | 34 +-- src/sage/matroids/extension.pyx | 2 +- src/sage/matroids/graphic_matroid.py | 2 + src/sage/matroids/minor_matroid.py | 48 ++--- src/sage/matroids/set_system.pyx | 12 +- src/sage/matroids/unpickling.pyx | 60 +++--- src/sage/matroids/utilities.py | 44 ++-- 12 files changed, 359 insertions(+), 357 deletions(-) diff --git a/src/sage/matroids/basis_exchange_matroid.pyx b/src/sage/matroids/basis_exchange_matroid.pyx index 8555ff67152..89dbb8e5e56 100644 --- a/src/sage/matroids/basis_exchange_matroid.pyx +++ b/src/sage/matroids/basis_exchange_matroid.pyx @@ -473,8 +473,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted(M.groundset()) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted(M.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g'] """ return self._groundset @@ -495,17 +495,17 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: type(M.groundset()) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: type(M.groundset()) # optional - sage.libs.pari <... 'frozenset'> - sage: type(M.groundset_list()) + sage: type(M.groundset_list()) # optional - sage.libs.pari <... 'list'> - sage: sorted(M.groundset_list()) + sage: sorted(M.groundset_list()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - sage: E = M.groundset_list() - sage: E.remove('a') - sage: sorted(M.groundset_list()) + sage: E = M.groundset_list() # optional - sage.libs.pari + sage: E.remove('a') # optional - sage.libs.pari + sage: sorted(M.groundset_list()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g'] """ return list(self._E) @@ -538,10 +538,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.full_rank() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.full_rank() # optional - sage.libs.pari 3 - sage: M.dual().full_rank() + sage: M.dual().full_rank() # optional - sage.libs.pari 4 """ return self._matroid_rank @@ -564,10 +564,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.full_corank() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.full_corank() # optional - sage.libs.pari 4 - sage: M.dual().full_corank() + sage: M.dual().full_corank() # optional - sage.libs.pari 3 """ return self._groundset_size - self._matroid_rank @@ -592,12 +592,12 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted(M.basis()) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted(M.basis()) # optional - sage.libs.pari ['a', 'b', 'c'] - sage: M.rank('cd') + sage: M.rank('cd') # optional - sage.libs.pari 2 - sage: sorted(M.basis()) + sage: sorted(M.basis()) # optional - sage.libs.pari ['a', 'c', 'd'] """ @@ -750,8 +750,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.P8() - sage: sorted(M._fundamental_circuit('abcd', 'e')) + sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari + sage: sorted(M._fundamental_circuit('abcd', 'e')) # optional - sage.libs.pari ['a', 'b', 'c', 'e'] """ self.__pack(self._input, B) @@ -906,8 +906,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.P8() - sage: sorted(M._fundamental_cocircuit('efgh', 'e')) + sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari + sage: sorted(M._fundamental_cocircuit('efgh', 'e')) # optional - sage.libs.pari ['b', 'c', 'd', 'e'] """ self.__pack(self._input, B) @@ -1255,8 +1255,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.S8() - sage: M.f_vector() + sage: M = matroids.named_matroids.S8() # optional - sage.libs.pari + sage: M.f_vector() # optional - sage.libs.pari [1, 8, 22, 14, 1] """ @@ -1321,14 +1321,14 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.S8() - sage: M.f_vector() + sage: M = matroids.named_matroids.S8() # optional - sage.libs.pari + sage: M.f_vector() # optional - sage.libs.pari [1, 8, 22, 14, 1] - sage: len(M.flats(2)) + sage: len(M.flats(2)) # optional - sage.libs.pari 22 - sage: len(M.flats(8)) + sage: len(M.flats(8)) # optional - sage.libs.pari 0 - sage: len(M.flats(4)) + sage: len(M.flats(4)) # optional - sage.libs.pari 1 """ cdef bitset_t *flats @@ -1396,14 +1396,14 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.S8().dual() - sage: M.f_vector() + sage: M = matroids.named_matroids.S8().dual() # optional - sage.libs.pari + sage: M.f_vector() # optional - sage.libs.pari [1, 8, 22, 14, 1] - sage: len(M.coflats(2)) + sage: len(M.coflats(2)) # optional - sage.libs.pari 22 - sage: len(M.coflats(8)) + sage: len(M.coflats(8)) # optional - sage.libs.pari 0 - sage: len(M.coflats(4)) + sage: len(M.coflats(4)) # optional - sage.libs.pari 1 """ cdef bitset_t *coflats @@ -1529,8 +1529,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: M.bases_count() + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: M.bases_count() # optional - sage.libs.pari 184 """ if self._bcount is not None: @@ -1556,9 +1556,9 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: I = M.independent_sets() - sage: len(I) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: I = M.independent_sets() # optional - sage.libs.pari + sage: len(I) # optional - sage.libs.pari 57 """ cdef bitset_t *I @@ -1617,10 +1617,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: M.bases_count() + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: M.bases_count() # optional - sage.libs.pari 184 - sage: [len(M.independent_r_sets(r)) for r in range(M.full_rank() + 1)] + sage: [len(M.independent_r_sets(r)) for r in range(M.full_rank() + 1)] # optional - sage.libs.pari [1, 10, 45, 120, 201, 184] """ @@ -1649,10 +1649,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: M.bases_count() + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: M.bases_count() # optional - sage.libs.pari 184 - sage: len([B for B in M.bases()]) + sage: len([B for B in M.bases()]) # optional - sage.libs.pari 184 """ return self.independent_r_sets(self.full_rank()) @@ -1671,10 +1671,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: len(M.nonbases()) + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: len(M.nonbases()) # optional - sage.libs.pari 68 - sage: [len(M.dependent_r_sets(r)) for r in range(M.full_rank() + 1)] + sage: [len(M.dependent_r_sets(r)) for r in range(M.full_rank() + 1)] # optional - sage.libs.pari [0, 0, 0, 0, 9, 68] """ @@ -1714,10 +1714,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: binomial(M.size(), M.full_rank())-M.bases_count() + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: binomial(M.size(), M.full_rank())-M.bases_count() # optional - sage.libs.pari 68 - sage: len([B for B in M.nonbases()]) + sage: len([B for B in M.nonbases()]) # optional - sage.libs.pari 68 """ return self.dependent_r_sets(self.full_rank()) @@ -1740,8 +1740,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: len(M.nonspanning_circuits()) + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: len(M.nonspanning_circuits()) # optional - sage.libs.pari 23 """ cdef SetSystem NSC @@ -1789,8 +1789,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: len(M.noncospanning_cocircuits()) + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: len(M.noncospanning_cocircuits()) # optional - sage.libs.pari 23 """ cdef SetSystem NSC @@ -1835,8 +1835,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.NonFano().bases()) - sage: sorted([sorted(C) for C in M.cocircuits()]) + sage: M = Matroid(bases=matroids.named_matroids.NonFano().bases()) # optional - sage.libs.pari + sage: sorted([sorted(C) for C in M.cocircuits()]) # optional - sage.libs.pari [['a', 'b', 'c', 'd', 'g'], ['a', 'b', 'c', 'e', 'g'], ['a', 'b', 'c', 'f', 'g'], ['a', 'b', 'd', 'e'], ['a', 'c', 'd', 'f'], ['a', 'e', 'f', 'g'], ['b', 'c', 'e', 'f'], @@ -1883,8 +1883,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = Matroid(matroids.named_matroids.NonFano().bases()) - sage: sorted([sorted(C) for C in M.circuits()]) + sage: M = Matroid(matroids.named_matroids.NonFano().bases()) # optional - sage.libs.pari + sage: sorted([sorted(C) for C in M.circuits()]) # optional - sage.libs.pari [['a', 'b', 'c', 'g'], ['a', 'b', 'd', 'e'], ['a', 'b', 'f'], ['a', 'c', 'd', 'f'], ['a', 'c', 'e'], ['a', 'd', 'e', 'f'], ['a', 'd', 'g'], ['a', 'e', 'f', 'g'], ['b', 'c', 'd'], @@ -1932,10 +1932,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: M._characteristic_setsystem() + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: M._characteristic_setsystem() # optional - sage.libs.pari Iterator over a system of subsets - sage: len(M._characteristic_setsystem()) + sage: len(M._characteristic_setsystem()) # optional - sage.libs.pari 23 """ if 2 * self._matroid_rank > self._groundset_size: @@ -1958,9 +1958,9 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) - sage: N = Matroid(matroids.named_matroids.NonFano().bases()) - sage: M._weak_invariant() == N._weak_invariant() + sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari + sage: N = Matroid(matroids.named_matroids.NonFano().bases()) # optional - sage.libs.pari + sage: M._weak_invariant() == N._weak_invariant() # optional - sage.libs.pari False """ if self._weak_invariant_var is None: @@ -2003,9 +2003,9 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = Matroid(matroids.named_matroids.Fano().bases()) - sage: N = Matroid(matroids.named_matroids.NonFano().bases()) - sage: M._strong_invariant() == N._strong_invariant() + sage: M = Matroid(matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari + sage: N = Matroid(matroids.named_matroids.NonFano().bases()) # optional - sage.libs.pari + sage: M._strong_invariant() == N._strong_invariant() # optional - sage.libs.pari False """ if self._strong_invariant_var is None: @@ -2132,10 +2132,10 @@ cdef class BasisExchangeMatroid(Matroid): sage: N._is_isomorphism(M, {e:e for e in M.groundset()}) False - sage: M = matroids.named_matroids.Fano() \ ['g'] - sage: N = matroids.Wheel(3) - sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} - sage: M._is_isomorphism(N, morphism) + sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.libs.pari + sage: N = matroids.Wheel(3) # optional - sage.libs.pari + sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} # optional - sage.libs.pari + sage: M._is_isomorphism(N, morphism) # optional - sage.libs.pari True TESTS: @@ -2199,9 +2199,9 @@ cdef class BasisExchangeMatroid(Matroid): sage: morphism = M1._isomorphism(M2) sage: M1._is_isomorphism(M2, morphism) True - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = matroids.named_matroids.NonFano() - sage: M1._isomorphism(M2) is None + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M1._isomorphism(M2) is None # optional - sage.libs.pari True TESTS: @@ -2212,8 +2212,8 @@ cdef class BasisExchangeMatroid(Matroid): ....: return min(len(X), 2) ....: sage: M = Matroid(groundset='abcd', rank_function=f) - sage: N = Matroid(field=GF(3), reduced_matrix=[[1,1],[1,-1]]) - sage: N._isomorphism(M) is not None + sage: N = Matroid(field=GF(3), reduced_matrix=[[1,1],[1,-1]]) # optional - sage.libs.pari + sage: N._isomorphism(M) is not None # optional - sage.libs.pari True """ if not isinstance(other, BasisExchangeMatroid): @@ -2294,11 +2294,11 @@ cdef class BasisExchangeMatroid(Matroid): True sage: M1._is_isomorphic(M2, certificate=True) (True, {0: 0, 1: 1, 2: 2, 3: 3, 4: 5, 5: 4}) - sage: M1 = BasisMatroid(matroids.named_matroids.Fano()) - sage: M2 = matroids.named_matroids.NonFano() - sage: M1._is_isomorphic(M2) + sage: M1 = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M1._is_isomorphic(M2) # optional - sage.libs.pari False - sage: M1._is_isomorphic(M2, certificate=True) + sage: M1._is_isomorphic(M2, certificate=True) # optional - sage.libs.pari (False, None) """ @@ -2370,8 +2370,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: M.is_valid() + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.libs.pari True sage: M = Matroid(groundset='abcd', bases=['ab', 'cd']) sage: M.is_valid() @@ -2381,7 +2381,7 @@ cdef class BasisExchangeMatroid(Matroid): Verify that :trac:`20172` was fixed:: - sage: M=Matroid(groundset='1234',bases=['12','13','23','34']) + sage: M = Matroid(groundset='1234', bases=['12','13','23','34']) sage: M.is_valid() False """ diff --git a/src/sage/matroids/basis_matroid.pyx b/src/sage/matroids/basis_matroid.pyx index 85f09fd8f97..4c9ccf70db5 100644 --- a/src/sage/matroids/basis_matroid.pyx +++ b/src/sage/matroids/basis_matroid.pyx @@ -110,11 +110,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): Create a BasisMatroid instance out of any other matroid:: sage: from sage.matroids.advanced import * - sage: F = matroids.named_matroids.Fano() - sage: M = BasisMatroid(F) - sage: F.groundset() == M.groundset() + sage: F = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M = BasisMatroid(F) # optional - sage.libs.pari + sage: F.groundset() == M.groundset() # optional - sage.libs.pari True - sage: len(set(F.bases()).difference(M.bases())) + sage: len(set(F.bases()).difference(M.bases())) # optional - sage.libs.pari 0 It is possible to provide either bases or nonbases:: @@ -150,11 +150,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: F = matroids.named_matroids.Fano() - sage: M = BasisMatroid(F) - sage: F.groundset() == M.groundset() + sage: F = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M = BasisMatroid(F) # optional - sage.libs.pari + sage: F.groundset() == M.groundset() # optional - sage.libs.pari True - sage: len(set(F.bases()).difference(M.bases())) + sage: len(set(F.bases()).difference(M.bases())) # optional - sage.libs.pari 0 """ cdef SetSystem NB @@ -254,8 +254,8 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: repr(M) # indirect doctest + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: repr(M) # indirect doctest # optional - sage.libs.pari 'Matroid of rank 3 on 7 elements with 28 bases' """ @@ -429,12 +429,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.N2().bases()) - sage: M.truncation() + sage: M = Matroid(bases=matroids.named_matroids.N2().bases()) # optional - sage.libs.pari + sage: M.truncation() # optional - sage.libs.pari Matroid of rank 5 on 12 elements with 702 bases - sage: M.f_vector() + sage: M.f_vector() # optional - sage.libs.pari [1, 12, 66, 190, 258, 99, 1] - sage: M.truncation().f_vector() + sage: M.truncation().f_vector() # optional - sage.libs.pari [1, 12, 66, 190, 258, 1] """ @@ -511,10 +511,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: M + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Matroid of rank 3 on 7 elements with 28 bases - sage: M._with_coloop('x') + sage: M._with_coloop('x') # optional - sage.libs.pari Matroid of rank 4 on 8 elements with 28 bases """ @@ -548,11 +548,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: sorted(M.groundset()) + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: sorted(M.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - sage: N = M.relabel({'g':'x'}) - sage: sorted(N.groundset()) + sage: N = M.relabel({'g':'x'}) # optional - sage.libs.pari + sage: sorted(N.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'x'] """ @@ -572,10 +572,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) - sage: M + sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Matroid of rank 3 on 7 elements with 28 bases - sage: M.bases_count() + sage: M.bases_count() # optional - sage.libs.pari 28 """ if self._bcount is None: @@ -594,10 +594,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) - sage: M + sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Matroid of rank 3 on 7 elements with 28 bases - sage: len(M.bases()) + sage: len(M.bases()) # optional - sage.libs.pari 28 """ cdef long r, n @@ -630,10 +630,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) - sage: M + sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Matroid of rank 3 on 7 elements with 28 bases - sage: len(M.nonbases()) + sage: len(M.nonbases()) # optional - sage.libs.pari 7 """ if self._nonbases is not None: @@ -674,9 +674,9 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: N = BasisMatroid(matroids.named_matroids.Fano()) - sage: M._bases_invariant() == N._bases_invariant() + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M._bases_invariant() == N._bases_invariant() # optional - sage.libs.pari True """ if self._bases_invariant_var is not None: @@ -733,9 +733,9 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: N = BasisMatroid(matroids.named_matroids.NonFano()) - sage: M._bases_invariant2() == N._bases_invariant2() + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari + sage: M._bases_invariant2() == N._bases_invariant2() # optional - sage.libs.pari False """ if self._bases_invariant2_var is None: @@ -844,8 +844,8 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.N1()) - sage: sorted([e for e in M.groundset() if M.is_distinguished(e)]) + sage: M = BasisMatroid(matroids.named_matroids.N1()) # optional - sage.libs.pari + sage: sorted([e for e in M.groundset() if M.is_distinguished(e)]) # optional - sage.libs.pari ['c', 'g', 'h', 'j'] """ @@ -886,12 +886,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.NonFano()) - sage: N = BasisMatroid(matroids.named_matroids.Fano()) - sage: m = {e:e for e in M.groundset()} - sage: M._is_relaxation(N, m) + sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: m = {e:e for e in M.groundset()} # optional - sage.libs.pari + sage: M._is_relaxation(N, m) # optional - sage.libs.pari True - sage: N._is_relaxation(M, m) + sage: N._is_relaxation(M, m) # optional - sage.libs.pari False """ cdef long i, j @@ -941,12 +941,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.NonFano()) - sage: N = BasisMatroid(matroids.named_matroids.Fano()) - sage: m = {e:e for e in M.groundset()} - sage: M._is_relaxation(N, m) + sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: m = {e:e for e in M.groundset()} # optional - sage.libs.pari + sage: M._is_relaxation(N, m) # optional - sage.libs.pari True - sage: M._is_isomorphism(N, m) + sage: M._is_isomorphism(N, m) # optional - sage.libs.pari False """ if not isinstance(other, BasisMatroid): @@ -979,9 +979,9 @@ cdef class BasisMatroid(BasisExchangeMatroid): sage: morphism = M._isomorphism(N) sage: M._is_isomorphism(N, morphism) True - sage: M = BasisMatroid(matroids.named_matroids.NonFano()) - sage: N = BasisMatroid(matroids.named_matroids.Fano()) - sage: M._isomorphism(N) is not None + sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M._isomorphism(N) is not None # optional - sage.libs.pari False """ if not isinstance(other, BasisMatroid): @@ -1055,11 +1055,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.NonFano()) - sage: N = BasisMatroid(matroids.named_matroids.Fano()) - sage: M._is_isomorphic(N) + sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M._is_isomorphic(N) # optional - sage.libs.pari False - sage: M._is_isomorphic(N, certificate=True) + sage: M._is_isomorphic(N, certificate=True) # optional - sage.libs.pari (False, None) """ if certificate: @@ -1127,12 +1127,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) - sage: N = BasisMatroid(matroids.named_matroids.Fano().dual()).dual() - sage: O = BasisMatroid(matroids.named_matroids.NonFano()) - sage: hash(M) == hash(N) + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: N = BasisMatroid(matroids.named_matroids.Fano().dual()).dual() # optional - sage.libs.pari + sage: O = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari + sage: hash(M) == hash(N) # optional - sage.libs.pari True - sage: hash(M) == hash(O) + sage: hash(M) == hash(O) # optional - sage.libs.pari False """ return hash((self.groundset(), self.bases_count(), self._weak_invariant())) diff --git a/src/sage/matroids/catalog.py b/src/sage/matroids/catalog.py index 769ef123923..c82ae02d063 100644 --- a/src/sage/matroids/catalog.py +++ b/src/sage/matroids/catalog.py @@ -67,13 +67,13 @@ def Q6(): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Q6(); M + sage: M = matroids.named_matroids.Q6(); M # optional - sage.libs.pari Q6: Quaternary matroid of rank 3 on 6 elements - sage: setprint(M.hyperplanes()) + sage: setprint(M.hyperplanes()) # optional - sage.libs.pari [{'a', 'b', 'd'}, {'a', 'c'}, {'a', 'e'}, {'a', 'f'}, {'b', 'c', 'e'}, {'b', 'f'}, {'c', 'd'}, {'c', 'f'}, {'d', 'e'}, {'d', 'f'}, {'e', 'f'}] - sage: M.nonspanning_circuits() == M.noncospanning_cocircuits() + sage: M.nonspanning_circuits() == M.noncospanning_cocircuits() # optional - sage.libs.pari False """ F = GF(4, 'x') @@ -106,10 +106,10 @@ def P6(): {2: {{'a', 'b', 'c'}}, 3: {{'a', 'b', 'c', 'd', 'e', 'f'}}} sage: len(set(M.nonspanning_circuits()).difference(M.nonbases())) == 0 True - sage: Matroid(matrix=random_matrix(GF(4, 'a'), ncols=5, + sage: Matroid(matrix=random_matrix(GF(4, 'a'), ncols=5, # optional - sage.libs.pari ....: nrows=5)).has_minor(M) False - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ E = 'abcdef' @@ -134,13 +134,13 @@ def R6(): EXAMPLES:: - sage: M = matroids.named_matroids.R6(); M + sage: M = matroids.named_matroids.R6(); M # optional - sage.libs.pari R6: Ternary matroid of rank 3 on 6 elements, type 2+ - sage: M.equals(M.dual()) + sage: M.equals(M.dual()) # optional - sage.libs.pari True - sage: M.is_connected() + sage: M.is_connected() # optional - sage.libs.pari True - sage: M.is_3connected() + sage: M.is_3connected() # optional - sage.libs.pari False """ A = Matrix(GF(3), [ @@ -167,12 +167,12 @@ def Fano(): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano(); M + sage: M = matroids.named_matroids.Fano(); M # optional - sage.libs.pari Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) - sage: setprint(sorted(M.nonspanning_circuits())) + sage: setprint(sorted(M.nonspanning_circuits())) # optional - sage.libs.pari [{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}, {'d', 'e', 'f'}] - sage: M.delete(M.groundset_list()[randrange(0, + sage: M.delete(M.groundset_list()[randrange(0, # optional - sage.libs.pari ....: 7)]).is_isomorphic(matroids.CompleteGraphic(4)) True """ @@ -198,14 +198,14 @@ def NonFano(): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.NonFano(); M + sage: M = matroids.named_matroids.NonFano(); M # optional - sage.libs.pari NonFano: Ternary matroid of rank 3 on 7 elements, type 0- - sage: setprint(M.nonbases()) + sage: setprint(M.nonbases()) # optional - sage.libs.pari [{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}] - sage: M.delete('f').is_isomorphic(matroids.CompleteGraphic(4)) + sage: M.delete('f').is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.libs.pari True - sage: M.delete('g').is_isomorphic(matroids.CompleteGraphic(4)) + sage: M.delete('g').is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.libs.pari False """ A = Matrix(GF(3), [ @@ -230,11 +230,11 @@ def O7(): EXAMPLES:: - sage: M = matroids.named_matroids.O7(); M + sage: M = matroids.named_matroids.O7(); M # optional - sage.libs.pari O7: Ternary matroid of rank 3 on 7 elements, type 0+ - sage: M.delete('e').is_isomorphic(matroids.CompleteGraphic(4)) + sage: M.delete('e').is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.libs.pari True - sage: M.tutte_polynomial() + sage: M.tutte_polynomial() # optional - sage.libs.pari y^4 + x^3 + x*y^2 + 3*y^3 + 4*x^2 + 5*x*y + 5*y^2 + 4*x + 4*y """ A = Matrix(GF(3), [ @@ -259,13 +259,13 @@ def P7(): EXAMPLES:: - sage: M = matroids.named_matroids.P7(); M + sage: M = matroids.named_matroids.P7(); M # optional - sage.libs.pari P7: Ternary matroid of rank 3 on 7 elements, type 1+ - sage: M.f_vector() + sage: M.f_vector() # optional - sage.libs.pari [1, 7, 11, 1] - sage: M.has_minor(matroids.CompleteGraphic(4)) + sage: M.has_minor(matroids.CompleteGraphic(4)) # optional - sage.libs.pari False - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(3), [ @@ -332,14 +332,14 @@ def R8(): EXAMPLES:: - sage: M = matroids.named_matroids.R8(); M + sage: M = matroids.named_matroids.R8(); M # optional - sage.libs.pari R8: Ternary matroid of rank 4 on 8 elements, type 0+ - sage: M.contract(M.groundset_list()[randrange(0, + sage: M.contract(M.groundset_list()[randrange(0, # optional - sage.libs.pari ....: 8)]).is_isomorphic(matroids.named_matroids.NonFano()) True - sage: M.equals(M.dual()) + sage: M.equals(M.dual()) # optional - sage.libs.pari True - sage: M.has_minor(matroids.named_matroids.Fano()) + sage: M.has_minor(matroids.named_matroids.Fano()) # optional - sage.libs.pari False """ A = Matrix(GF(3), [ @@ -477,21 +477,21 @@ def S8(): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.S8(); M + sage: M = matroids.named_matroids.S8(); M # optional - sage.libs.pari S8: Binary matroid of rank 4 on 8 elements, type (2, 0) - sage: M.contract('d').is_isomorphic(matroids.named_matroids.Fano()) + sage: M.contract('d').is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.libs.pari True - sage: M.delete('d').is_isomorphic( + sage: M.delete('d').is_isomorphic( # optional - sage.libs.pari ....: matroids.named_matroids.Fano().dual()) False - sage: M.is_graphic() + sage: M.is_graphic() # optional - sage.libs.pari False - sage: D = get_nonisomorphic_matroids( + sage: D = get_nonisomorphic_matroids( # optional - sage.libs.pari ....: list(matroids.named_matroids.Fano().linear_coextensions( ....: cosimple=True))) - sage: len(D) + sage: len(D) # optional - sage.libs.pari 2 - sage: [N.is_isomorphic(M) for N in D] + sage: [N.is_isomorphic(M) for N in D] # optional - sage.libs.pari [...True...] """ @@ -553,13 +553,13 @@ def T8(): EXAMPLES:: - sage: M = matroids.named_matroids.T8(); M + sage: M = matroids.named_matroids.T8(); M # optional - sage.libs.pari T8: Ternary matroid of rank 4 on 8 elements, type 0- - sage: M.truncation().is_isomorphic(matroids.Uniform(3, 8)) + sage: M.truncation().is_isomorphic(matroids.Uniform(3, 8)) # optional - sage.libs.pari True - sage: M.contract('e').is_isomorphic(matroids.named_matroids.P7()) + sage: M.contract('e').is_isomorphic(matroids.named_matroids.P7()) # optional - sage.libs.pari True - sage: M.has_minor(matroids.Uniform(3, 8)) + sage: M.has_minor(matroids.Uniform(3, 8)) # optional - sage.libs.pari False """ @@ -585,15 +585,15 @@ def J(): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.J(); M + sage: M = matroids.named_matroids.J(); M # optional - sage.libs.pari J: Ternary matroid of rank 4 on 8 elements, type 0- - sage: setprint(M.truncation().nonbases()) + sage: setprint(M.truncation().nonbases()) # optional - sage.libs.pari [{'a', 'b', 'f'}, {'a', 'c', 'g'}, {'a', 'd', 'h'}] - sage: M.is_isomorphic(M.dual()) + sage: M.is_isomorphic(M.dual()) # optional - sage.libs.pari True - sage: M.has_minor(matroids.CompleteGraphic(4)) + sage: M.has_minor(matroids.CompleteGraphic(4)) # optional - sage.libs.pari False - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(3), [ @@ -619,14 +619,14 @@ def P8(): EXAMPLES:: - sage: M = matroids.named_matroids.P8(); M + sage: M = matroids.named_matroids.P8(); M # optional - sage.libs.pari P8: Ternary matroid of rank 4 on 8 elements, type 2+ - sage: M.is_isomorphic(M.dual()) + sage: M.is_isomorphic(M.dual()) # optional - sage.libs.pari True - sage: Matroid(matrix=random_matrix(GF(4, 'a'), ncols=5, + sage: Matroid(matrix=random_matrix(GF(4, 'a'), ncols=5, # optional - sage.libs.pari ....: nrows=5)).has_minor(M) False - sage: M.bicycle_dimension() + sage: M.bicycle_dimension() # optional - sage.libs.pari 2 """ @@ -719,11 +719,11 @@ def TernaryDowling3(): EXAMPLES:: - sage: M = matroids.named_matroids.TernaryDowling3(); M + sage: M = matroids.named_matroids.TernaryDowling3(); M # optional - sage.libs.pari Q3(GF(3)x): Ternary matroid of rank 3 on 9 elements, type 0- - sage: len(list(M.linear_subclasses())) + sage: len(list(M.linear_subclasses())) # optional - sage.libs.pari 72 - sage: M.fundamental_cycle('abc', 'd') + sage: M.fundamental_cycle('abc', 'd') # optional - sage.libs.pari {'a': 2, 'b': 1, 'd': 1} """ @@ -853,17 +853,17 @@ def Whirl(n): EXAMPLES:: - sage: M = matroids.Whirl(5); M + sage: M = matroids.Whirl(5); M # optional - sage.libs.pari Whirl(5): Ternary matroid of rank 5 on 10 elements, type 0- - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True - sage: M.tutte_polynomial() + sage: M.tutte_polynomial() # optional - sage.libs.pari x^5 + y^5 + 5*x^4 + 5*x^3*y + 5*x^2*y^2 + 5*x*y^3 + 5*y^4 + 10*x^3 + 15*x^2*y + 15*x*y^2 + 10*y^3 + 10*x^2 + 15*x*y + 10*y^2 + 5*x + 5*y - sage: M.is_isomorphic(matroids.Wheel(5)) + sage: M.is_isomorphic(matroids.Wheel(5)) # optional - sage.libs.pari False - sage: M = matroids.Whirl(3) - sage: M.is_isomorphic(matroids.CompleteGraphic(4)) + sage: M = matroids.Whirl(3) # optional - sage.libs.pari + sage: M.is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.libs.pari False .. TODO:: @@ -960,12 +960,12 @@ def PG(n, q, x=None): EXAMPLES:: - sage: M = matroids.PG(2, 2) - sage: M.is_isomorphic(matroids.named_matroids.Fano()) + sage: M = matroids.PG(2, 2) # optional - sage.libs.pari + sage: M.is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.libs.pari True - sage: matroids.PG(5, 4, 'z').size() == (4^6 - 1) / (4 - 1) + sage: matroids.PG(5, 4, 'z').size() == (4^6 - 1) / (4 - 1) # optional - sage.libs.pari True - sage: M = matroids.PG(4, 7); M + sage: M = matroids.PG(4, 7); M # optional - sage.libs.pari PG(4, 7): Linear matroid of rank 5 on 2801 elements represented over the Finite Field of size 7 """ @@ -1003,13 +1003,13 @@ def AG(n, q, x=None): EXAMPLES:: - sage: M = matroids.AG(2, 3) \ 8 - sage: M.is_isomorphic(matroids.named_matroids.AG23minus()) + sage: M = matroids.AG(2, 3) \ 8 # optional - sage.libs.pari + sage: M.is_isomorphic(matroids.named_matroids.AG23minus()) # optional - sage.libs.pari True - sage: matroids.AG(5, 4, 'z').size() == ((4 ^ 6 - 1) / (4 - 1) - + sage: matroids.AG(5, 4, 'z').size() == ((4 ^ 6 - 1) / (4 - 1) - # optional - sage.libs.pari ....: (4 ^ 5 - 1)/(4 - 1)) True - sage: M = matroids.AG(4, 2); M + sage: M = matroids.AG(4, 2); M # optional - sage.libs.pari AG(4, 2): Binary matroid of rank 5 on 16 elements, type (5, 0) """ @@ -1243,10 +1243,10 @@ def Q10(): EXAMPLES:: - sage: M = matroids.named_matroids.Q10() - sage: M.is_isomorphic(M.dual()) + sage: M = matroids.named_matroids.Q10() # optional - sage.libs.pari + sage: M.is_isomorphic(M.dual()) # optional - sage.libs.pari True - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True Check the splitter property. By Seymour's Theorem, and using self-duality, @@ -1255,8 +1255,8 @@ def Q10(): are quaternary are `U_{2, 5}, U_{3, 5}, F_7, F_7^*`. As it happens, it suffices to check for `U_{2, 5}`: - sage: S = matroids.named_matroids.Q10().linear_extensions(simple=True) - sage: [M for M in S if not M.has_line_minor(5)] # long time + sage: S = matroids.named_matroids.Q10().linear_extensions(simple=True) # optional - sage.libs.pari + sage: [M for M in S if not M.has_line_minor(5)] # long time # optional - sage.libs.pari [] """ F = GF(4, 'x') @@ -1281,10 +1281,10 @@ def N1(): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: M.is_field_isomorphic(M.dual()) + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: M.is_field_isomorphic(M.dual()) # optional - sage.libs.pari True - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ @@ -1308,10 +1308,10 @@ def N2(): EXAMPLES:: - sage: M = matroids.named_matroids.N2() - sage: M.is_field_isomorphic(M.dual()) + sage: M = matroids.named_matroids.N2() # optional - sage.libs.pari + sage: M.is_field_isomorphic(M.dual()) # optional - sage.libs.pari True - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ @@ -1422,11 +1422,11 @@ def ExtendedBinaryGolayCode(): EXAMPLES:: - sage: M = matroids.named_matroids.ExtendedBinaryGolayCode() - sage: C = LinearCode(M.representation()) - sage: C.is_permutation_equivalent(codes.GolayCode(GF(2))) # long time + sage: M = matroids.named_matroids.ExtendedBinaryGolayCode() # optional - sage.libs.pari + sage: C = LinearCode(M.representation()) # optional - sage.libs.pari + sage: C.is_permutation_equivalent(codes.GolayCode(GF(2))) # long time # optional - sage.libs.pari True - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(2), [ @@ -1457,11 +1457,11 @@ def ExtendedTernaryGolayCode(): EXAMPLES:: - sage: M = matroids.named_matroids.ExtendedTernaryGolayCode() - sage: C = LinearCode(M.representation()) - sage: C.is_permutation_equivalent(codes.GolayCode(GF(3))) # long time + sage: M = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari + sage: C = LinearCode(M.representation()) # optional - sage.libs.pari + sage: C.is_permutation_equivalent(codes.GolayCode(GF(3))) # long time # optional - sage.libs.pari True - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(3), [ @@ -1509,11 +1509,11 @@ def NotP8(): EXAMPLES:: - sage: M = matroids.named_matroids.P8() - sage: N = matroids.named_matroids.NotP8() - sage: M.is_isomorphic(N) + sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari + sage: N = matroids.named_matroids.NotP8() # optional - sage.libs.pari + sage: M.is_isomorphic(N) # optional - sage.libs.pari False - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(3), [ @@ -1538,10 +1538,10 @@ def D16(): # A.K.A. the Carolyn Chun Matroid EXAMPLES:: - sage: M = matroids.named_matroids.D16() - sage: M + sage: M = matroids.named_matroids.D16() # optional - sage.libs.pari + sage: M # optional - sage.libs.pari D16: Binary matroid of rank 8 on 16 elements, type (0, 0) - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ @@ -1569,10 +1569,10 @@ def Terrahawk(): # A.K.A. the Dillon Mayhew Matroid EXAMPLES:: - sage: M = matroids.named_matroids.Terrahawk() - sage: M + sage: M = matroids.named_matroids.Terrahawk() # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Terrahawk: Binary matroid of rank 8 on 16 elements, type (0, 4) - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ @@ -1653,10 +1653,10 @@ def T12(): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: M + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: M # optional - sage.libs.pari T12: Binary matroid of rank 6 on 12 elements, type (2, None) - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(2), [ @@ -1681,10 +1681,10 @@ def P9(): EXAMPLES:: - sage: M = matroids.named_matroids.P9() - sage: M + sage: M = matroids.named_matroids.P9() # optional - sage.libs.pari + sage: M # optional - sage.libs.pari P9: Binary matroid of rank 4 on 9 elements, type (1, 1) - sage: M.is_valid() + sage: M.is_valid() # optional - sage.libs.pari True """ A = Matrix(GF(2), [ diff --git a/src/sage/matroids/circuit_closures_matroid.pyx b/src/sage/matroids/circuit_closures_matroid.pyx index 679445a6a62..351f62c94c7 100644 --- a/src/sage/matroids/circuit_closures_matroid.pyx +++ b/src/sage/matroids/circuit_closures_matroid.pyx @@ -50,8 +50,8 @@ AUTHORS: TESTS:: sage: from sage.matroids.advanced import * - sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) - sage: TestSuite(M).run() + sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: TestSuite(M).run() # optional - sage.libs.pari Methods ======= @@ -117,8 +117,8 @@ cdef class CircuitClosuresMatroid(Matroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) - sage: M + sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Matroid of rank 3 on 7 elements with circuit-closures {2: {{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}, @@ -127,7 +127,7 @@ cdef class CircuitClosuresMatroid(Matroid): ....: circuit_closures={3: ['edfg', 'acdg', 'bcfg', 'cefh', ....: 'afgh', 'abce', 'abdf', 'begh', 'bcdh', 'adeh'], ....: 4: ['abcdefgh']}) - sage: M.equals(matroids.named_matroids.P8()) + sage: M.equals(matroids.named_matroids.P8()) # optional - sage.libs.pari True """ @@ -140,8 +140,8 @@ cdef class CircuitClosuresMatroid(Matroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) - sage: M + sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Matroid of rank 3 on 7 elements with circuit-closures {2: {{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}, @@ -152,7 +152,7 @@ cdef class CircuitClosuresMatroid(Matroid): ....: circuit_closures={3: ['edfg', 'acdg', 'bcfg', 'cefh', ....: 'afgh', 'abce', 'abdf', 'begh', 'bcdh', 'adeh'], ....: 4: ['abcdefgh']}) - sage: M.equals(matroids.named_matroids.P8()) + sage: M.equals(matroids.named_matroids.P8()) # optional - sage.libs.pari True """ if M is not None: diff --git a/src/sage/matroids/constructor.py b/src/sage/matroids/constructor.py index 99580562e96..6ab2f4917ef 100644 --- a/src/sage/matroids/constructor.py +++ b/src/sage/matroids/constructor.py @@ -53,8 +53,8 @@ A number of special matroids are collected under a ``named_matroids`` submenu. To see which, type ``matroids.named_matroids.`` as above:: - sage: F7 = matroids.named_matroids.Fano() - sage: len(F7.nonspanning_circuits()) + sage: F7 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: len(F7.nonspanning_circuits()) # optional - sage.libs.pari 7 Constructing matroids @@ -68,11 +68,11 @@ EXAMPLES:: - sage: A = Matrix(GF(2), [[1, 0, 0, 0, 1, 1, 1], + sage: A = Matrix(GF(2), [[1, 0, 0, 0, 1, 1, 1], # optional - sage.libs.pari ....: [0, 1, 0, 1, 0, 1, 1], ....: [0, 0, 1, 1, 1, 0, 1]]) - sage: M = Matroid(A) - sage: M.is_isomorphic(matroids.named_matroids.Fano()) + sage: M = Matroid(A) # optional - sage.libs.pari + sage: M.is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.libs.pari True sage: M = Matroid(graphs.PetersenGraph()) diff --git a/src/sage/matroids/dual_matroid.py b/src/sage/matroids/dual_matroid.py index 804e43f035b..73ad305e1d6 100644 --- a/src/sage/matroids/dual_matroid.py +++ b/src/sage/matroids/dual_matroid.py @@ -10,13 +10,13 @@ EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: N = M.dual() - sage: M.is_basis('abc') + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N = M.dual() # optional - sage.libs.pari + sage: M.is_basis('abc') # optional - sage.libs.pari True - sage: N.is_basis('defg') + sage: N.is_basis('defg') # optional - sage.libs.pari True - sage: M.dual().dual() == M + sage: M.dual().dual() == M # optional - sage.libs.pari True Implementation @@ -455,17 +455,17 @@ def __eq__(self, other): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = CircuitClosuresMatroid(M1.dual()) - sage: M3 = CircuitClosuresMatroid(M1).dual() + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = CircuitClosuresMatroid(M1.dual()) # optional - sage.libs.pari + sage: M3 = CircuitClosuresMatroid(M1).dual() # optional - sage.libs.pari sage: M4 = CircuitClosuresMatroid(groundset='abcdefg', ....: circuit_closures={3: ['abcdefg'], 2: ['beg', 'cdb', 'cfg', ....: 'ace', 'fed', 'gad', 'fab']}).dual() - sage: M1.dual() == M2 # indirect doctest + sage: M1.dual() == M2 # indirect doctest # optional - sage.libs.pari False - sage: M2 == M3 + sage: M2 == M3 # optional - sage.libs.pari False - sage: M3 == M4 + sage: M3 == M4 # optional - sage.libs.pari True """ if not isinstance(other, DualMatroid): @@ -487,17 +487,17 @@ def __ne__(self, other): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = CircuitClosuresMatroid(M1.dual()) - sage: M3 = CircuitClosuresMatroid(M1).dual() + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = CircuitClosuresMatroid(M1.dual()) # optional - sage.libs.pari + sage: M3 = CircuitClosuresMatroid(M1).dual() # optional - sage.libs.pari sage: M4 = CircuitClosuresMatroid(groundset='abcdefg', ....: circuit_closures={3: ['abcdefg'], 2: ['beg', 'cdb', 'cfg', ....: 'ace', 'fed', 'gad', 'fab']}).dual() - sage: M1.dual() != M2 # indirect doctest + sage: M1.dual() != M2 # indirect doctest # optional - sage.libs.pari True - sage: M2 != M3 + sage: M2 != M3 # optional - sage.libs.pari True - sage: M3 != M4 + sage: M3 != M4 # optional - sage.libs.pari False """ return not self == other diff --git a/src/sage/matroids/extension.pyx b/src/sage/matroids/extension.pyx index d762526d2fa..608d9363496 100644 --- a/src/sage/matroids/extension.pyx +++ b/src/sage/matroids/extension.pyx @@ -59,7 +59,7 @@ cdef class CutNode: EXAMPLES:: - sage: len(list(matroids.named_matroids.Fano().linear_subclasses())) # indirect doctest + sage: len(list(matroids.named_matroids.Fano().linear_subclasses())) # indirect doctest # optional - sage.libs.pari 16 """ cdef CutNode node diff --git a/src/sage/matroids/graphic_matroid.py b/src/sage/matroids/graphic_matroid.py index 9bafa6dc0c7..f91ad67ddcc 100644 --- a/src/sage/matroids/graphic_matroid.py +++ b/src/sage/matroids/graphic_matroid.py @@ -1,3 +1,5 @@ +# sage.doctest: optional - sage.graphs +# sage.doctest: optional - sage.groups (for DisjointSet) r""" Graphic Matroids diff --git a/src/sage/matroids/minor_matroid.py b/src/sage/matroids/minor_matroid.py index 907bb54356f..7c5cbbc55ba 100644 --- a/src/sage/matroids/minor_matroid.py +++ b/src/sage/matroids/minor_matroid.py @@ -13,23 +13,23 @@ EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M \ ['a', 'c' ] == M.delete(['a', 'c']) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M \ ['a', 'c' ] == M.delete(['a', 'c']) # optional - sage.libs.pari True - sage: M / 'a' == M.contract('a') + sage: M / 'a' == M.contract('a') # optional - sage.libs.pari True - sage: M / 'c' \ 'ab' == M.minor(contractions='c', deletions='ab') + sage: M / 'c' \ 'ab' == M.minor(contractions='c', deletions='ab') # optional - sage.libs.pari True If a contraction set is not independent (or a deletion set not coindependent), this is taken care of:: - sage: M = matroids.named_matroids.Fano() - sage: M.rank('abf') + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.rank('abf') # optional - sage.libs.pari 2 - sage: M / 'abf' == M / 'ab' \ 'f' + sage: M / 'abf' == M / 'ab' \ 'f' # optional - sage.libs.pari True - sage: M / 'abf' == M / 'af' \ 'b' + sage: M / 'abf' == M / 'af' \ 'b' # optional - sage.libs.pari True .. SEEALSO:: @@ -132,9 +132,9 @@ def __init__(self, matroid, contractions=None, deletions=None): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = MinorMatroid(matroids.named_matroids.Fano(), # indirect doctest + sage: M = MinorMatroid(matroids.named_matroids.Fano(), # indirect doctest # optional - sage.libs.pari ....: contractions=set(), deletions=set(['g'])) - sage: M.is_isomorphic(matroids.Wheel(3)) + sage: M.is_isomorphic(matroids.Wheel(3)) # optional - sage.libs.pari True """ if not isinstance(matroid, Matroid): @@ -423,15 +423,15 @@ def __eq__(self, other): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() - sage: M1 = MinorMatroid(M, set('ab'), set('f')) - sage: M2 = MinorMatroid(M, set('af'), set('b')) - sage: M3 = MinorMatroid(M, set('a'), set('f'))._minor(set('b'), set()) - sage: M1 == M2 # indirect doctest + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M1 = MinorMatroid(M, set('ab'), set('f')) # optional - sage.libs.pari + sage: M2 = MinorMatroid(M, set('af'), set('b')) # optional - sage.libs.pari + sage: M3 = MinorMatroid(M, set('a'), set('f'))._minor(set('b'), set()) # optional - sage.libs.pari + sage: M1 == M2 # indirect doctest # optional - sage.libs.pari False - sage: M1.equals(M2) + sage: M1.equals(M2) # optional - sage.libs.pari True - sage: M1 == M3 + sage: M1 == M3 # optional - sage.libs.pari True """ if not isinstance(other, MinorMatroid): @@ -455,15 +455,15 @@ def __ne__(self, other): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() - sage: M1 = MinorMatroid(M, set('ab'), set('f')) - sage: M2 = MinorMatroid(M, set('af'), set('b')) - sage: M3 = MinorMatroid(M, set('a'), set('f'))._minor(set('b'), set()) - sage: M1 != M2 # indirect doctest + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M1 = MinorMatroid(M, set('ab'), set('f')) # optional - sage.libs.pari + sage: M2 = MinorMatroid(M, set('af'), set('b')) # optional - sage.libs.pari + sage: M3 = MinorMatroid(M, set('a'), set('f'))._minor(set('b'), set()) # optional - sage.libs.pari + sage: M1 != M2 # indirect doctest # optional - sage.libs.pari True - sage: M1.equals(M2) + sage: M1.equals(M2) # optional - sage.libs.pari True - sage: M1 != M3 + sage: M1 != M3 # optional - sage.libs.pari False """ return not self == other diff --git a/src/sage/matroids/set_system.pyx b/src/sage/matroids/set_system.pyx index d183f6ed5d1..9b68cfe342d 100644 --- a/src/sage/matroids/set_system.pyx +++ b/src/sage/matroids/set_system.pyx @@ -38,8 +38,8 @@ cdef class SetSystem: contents. One is most likely to encounter these as output from some Matroid methods:: - sage: M = matroids.named_matroids.Fano() - sage: M.circuits() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.circuits() # optional - sage.libs.pari Iterator over a system of subsets To access the sets in this structure, simply iterate over them. The @@ -729,11 +729,11 @@ cdef class SetSystem: Check that :trac:`15189` is fixed:: - sage: M = Matroid(ring=GF(5), reduced_matrix=[[1,0,3],[0,1,1],[1,1,0]]) - sage: N = Matroid(ring=GF(5), reduced_matrix=[[1,0,1],[0,1,1],[1,1,0]]) - sage: M.is_field_isomorphic(N) + sage: M = Matroid(ring=GF(5), reduced_matrix=[[1,0,3],[0,1,1],[1,1,0]]) # optional - sage.libs.pari + sage: N = Matroid(ring=GF(5), reduced_matrix=[[1,0,1],[0,1,1],[1,1,0]]) # optional - sage.libs.pari + sage: M.is_field_isomorphic(N) # optional - sage.libs.pari False - sage: any(M.is_field_isomorphism(N, p) for p in Permutations(range(6))) + sage: any(M.is_field_isomorphism(N, p) for p in Permutations(range(6))) # optional - sage.combinat sage.libs.pari False """ cdef long v diff --git a/src/sage/matroids/unpickling.pyx b/src/sage/matroids/unpickling.pyx index b37ae49a37f..8916067025c 100644 --- a/src/sage/matroids/unpickling.pyx +++ b/src/sage/matroids/unpickling.pyx @@ -211,11 +211,11 @@ def unpickle_binary_matrix(version, data): EXAMPLES:: sage: from sage.matroids.lean_matrix import * - sage: A = BinaryMatrix(2, 5) - sage: A == loads(dumps(A)) # indirect doctest + sage: A = BinaryMatrix(2, 5) # optional - sage.libs.pari + sage: A == loads(dumps(A)) # indirect doctest # optional - sage.libs.pari True - sage: C = BinaryMatrix(2, 2, Matrix(GF(2), [[1, 1], [0, 1]])) - sage: C == loads(dumps(C)) + sage: C = BinaryMatrix(2, 2, Matrix(GF(2), [[1, 1], [0, 1]])) # optional - sage.libs.pari + sage: C == loads(dumps(C)) # optional - sage.libs.pari True """ cdef BinaryMatrix A @@ -240,11 +240,11 @@ def unpickle_ternary_matrix(version, data): EXAMPLES:: sage: from sage.matroids.lean_matrix import * - sage: A = TernaryMatrix(2, 5) - sage: A == loads(dumps(A)) # indirect doctest + sage: A = TernaryMatrix(2, 5) # optional - sage.libs.pari + sage: A == loads(dumps(A)) # indirect doctest # optional - sage.libs.pari True - sage: C = TernaryMatrix(2, 2, Matrix(GF(3), [[1, 1], [0, 1]])) - sage: C == loads(dumps(C)) + sage: C = TernaryMatrix(2, 2, Matrix(GF(3), [[1, 1], [0, 1]])) # optional - sage.libs.pari + sage: C == loads(dumps(C)) # optional - sage.libs.pari True """ cdef TernaryMatrix A @@ -270,11 +270,11 @@ def unpickle_quaternary_matrix(version, data): EXAMPLES:: sage: from sage.matroids.lean_matrix import * - sage: A = QuaternaryMatrix(2, 5, ring=GF(4, 'x')) - sage: A == loads(dumps(A)) # indirect doctest + sage: A = QuaternaryMatrix(2, 5, ring=GF(4, 'x')) # optional - sage.libs.pari + sage: A == loads(dumps(A)) # indirect doctest # optional - sage.libs.pari True - sage: C = QuaternaryMatrix(2, 2, Matrix(GF(4, 'x'), [[1, 1], [0, 1]])) - sage: C == loads(dumps(C)) + sage: C = QuaternaryMatrix(2, 2, Matrix(GF(4, 'x'), [[1, 1], [0, 1]])) # optional - sage.libs.pari + sage: C == loads(dumps(C)) # optional - sage.libs.pari True """ cdef QuaternaryMatrix A @@ -388,12 +388,12 @@ def unpickle_linear_matroid(version, data): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], + sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], # optional - sage.libs.pari ....: [0, 1, 1, 1, 3]])) - sage: M == loads(dumps(M)) # indirect doctest + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.libs.pari True - sage: M.rename("U35") - sage: loads(dumps(M)) + sage: M.rename("U35") # optional - sage.libs.pari + sage: loads(dumps(M)) # optional - sage.libs.pari U35 """ if version != 0: @@ -434,12 +434,12 @@ def unpickle_binary_matroid(version, data): EXAMPLES:: - sage: M = Matroid(Matrix(GF(2), [[1, 0, 0, 1], [0, 1, 0, 1], + sage: M = Matroid(Matrix(GF(2), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.libs.pari ....: [0, 0, 1, 1]])) - sage: M == loads(dumps(M)) # indirect doctest + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.libs.pari True - sage: M.rename("U34") - sage: loads(dumps(M)) + sage: M.rename("U34") # optional - sage.libs.pari + sage: loads(dumps(M)) # optional - sage.libs.pari U34 """ if version != 0: @@ -481,12 +481,12 @@ def unpickle_ternary_matroid(version, data): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = TernaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], [0, 1, 0, 1], + sage: M = TernaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.libs.pari ....: [0, 0, 1, 1]])) - sage: M == loads(dumps(M)) # indirect doctest + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.libs.pari True - sage: M.rename("U34") - sage: loads(dumps(M)) + sage: M.rename("U34") # optional - sage.libs.pari + sage: loads(dumps(M)) # optional - sage.libs.pari U34 """ if version != 0: @@ -528,16 +528,16 @@ def unpickle_quaternary_matroid(version, data): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = QuaternaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], [0, 1, 0, 1], + sage: M = QuaternaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.libs.pari ....: [0, 0, 1, 1]])) - sage: M == loads(dumps(M)) # indirect doctest + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.libs.pari True - sage: M.rename("U34") - sage: loads(dumps(M)) + sage: M.rename("U34") # optional - sage.libs.pari + sage: loads(dumps(M)) # optional - sage.libs.pari U34 - sage: M = QuaternaryMatroid(Matrix(GF(4, 'x'), [[1, 0, 1], + sage: M = QuaternaryMatroid(Matrix(GF(4, 'x'), [[1, 0, 1], # optional - sage.libs.pari ....: [1, 0, 1]])) - sage: loads(dumps(M)).representation() + sage: loads(dumps(M)).representation() # optional - sage.libs.pari [1 0 1] [1 0 1] """ diff --git a/src/sage/matroids/utilities.py b/src/sage/matroids/utilities.py index eb2999ea07b..a9764c86891 100644 --- a/src/sage/matroids/utilities.py +++ b/src/sage/matroids/utilities.py @@ -74,10 +74,10 @@ def setprint(X): Note that for iterables, the effect can be undesirable:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano().delete('efg') - sage: M.bases() + sage: M = matroids.named_matroids.Fano().delete('efg') # optional - sage.libs.pari + sage: M.bases() # optional - sage.libs.pari Iterator over a system of subsets - sage: setprint(M.bases()) + sage: setprint(M.bases()) # optional - sage.libs.pari [{'a', 'b', 'c'}, {'a', 'b', 'd'}, {'a', 'c', 'd'}] An exception was made for subclasses of SageObject:: @@ -215,20 +215,20 @@ def sanitize_contractions_deletions(matroid, contractions, deletions): sage: from sage.matroids.utilities import setprint sage: from sage.matroids.utilities import sanitize_contractions_deletions - sage: M = matroids.named_matroids.Fano() - sage: setprint(sanitize_contractions_deletions(M, 'abc', 'defg')) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: setprint(sanitize_contractions_deletions(M, 'abc', 'defg')) # optional - sage.libs.pari [{'a', 'b', 'c'}, {'d', 'e', 'f', 'g'}] - sage: setprint(sanitize_contractions_deletions(M, 'defg', 'abc')) + sage: setprint(sanitize_contractions_deletions(M, 'defg', 'abc')) # optional - sage.libs.pari [{'a', 'b', 'c', 'f'}, {'d', 'e', 'g'}] - sage: setprint(sanitize_contractions_deletions(M, [1, 2, 3], 'efg')) + sage: setprint(sanitize_contractions_deletions(M, [1, 2, 3], 'efg')) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: [1, 2, 3] is not a subset of the groundset - sage: setprint(sanitize_contractions_deletions(M, 'efg', [1, 2, 3])) + sage: setprint(sanitize_contractions_deletions(M, 'efg', [1, 2, 3])) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: [1, 2, 3] is not a subset of the groundset - sage: setprint(sanitize_contractions_deletions(M, 'ade', 'efg')) + sage: setprint(sanitize_contractions_deletions(M, 'ade', 'efg')) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: contraction and deletion sets are not disjoint. @@ -532,25 +532,25 @@ def lift_cross_ratios(A, lift_map=None): EXAMPLES:: sage: from sage.matroids.advanced import lift_cross_ratios, lift_map, LinearMatroid - sage: R = GF(7) - sage: to_sixth_root_of_unity = lift_map('sru') - sage: A = Matrix(R, [[1, 0, 6, 1, 2],[6, 1, 0, 0, 1],[0, 6, 3, 6, 0]]) - sage: A + sage: R = GF(7) # optional - sage.libs.pari + sage: to_sixth_root_of_unity = lift_map('sru') # optional - sage.rings.number_field + sage: A = Matrix(R, [[1, 0, 6, 1, 2],[6, 1, 0, 0, 1],[0, 6, 3, 6, 0]]) # optional - sage.libs.pari + sage: A # optional - sage.libs.pari [1 0 6 1 2] [6 1 0 0 1] [0 6 3 6 0] - sage: Z = lift_cross_ratios(A, to_sixth_root_of_unity) - sage: Z + sage: Z = lift_cross_ratios(A, to_sixth_root_of_unity) # optional - sage.libs.pari sage.rings.number_field + sage: Z # optional - sage.libs.pari sage.rings.number_field [ 1 0 1 1 1] [ 1 1 0 0 z] [ 0 -1 z 1 0] - sage: M = LinearMatroid(reduced_matrix = A) - sage: sorted(M.cross_ratios()) + sage: M = LinearMatroid(reduced_matrix=A) # optional - sage.libs.pari + sage: sorted(M.cross_ratios()) # optional - sage.libs.pari [3, 5] - sage: N = LinearMatroid(reduced_matrix = Z) - sage: sorted(N.cross_ratios()) + sage: N = LinearMatroid(reduced_matrix=Z) # optional - sage.libs.pari sage.rings.number_field + sage: sorted(N.cross_ratios()) # optional - sage.libs.pari sage.rings.number_field [-z + 1, z] - sage: M.is_isomorphism(N, {e:e for e in M.groundset()}) + sage: M.is_isomorphism(N, {e:e for e in M.groundset()}) # optional - sage.libs.pari sage.rings.number_field True """ @@ -690,8 +690,8 @@ def lift_map(target): EXAMPLES:: sage: from sage.matroids.utilities import lift_map - sage: lm = lift_map('gm') - sage: for x in lm: + sage: lm = lift_map('gm') # optional - sage.libs.pari sage.rings.number_field + sage: for x in lm: # optional - sage.libs.pari sage.rings.number_field ....: if (x == 1) is not (lm[x] == 1): ....: print('not a proper lift map') ....: for y in lm: From 9364d7218687925f24421efbb593a224868c7b5a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 12 Mar 2023 13:23:05 -0700 Subject: [PATCH 044/205] sage.matroids: More # optional --- src/sage/matroids/matroid.pyx | 597 +++++++++++++++++----------------- 1 file changed, 299 insertions(+), 298 deletions(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 8d641737a8f..e693cbfb17d 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -216,7 +216,7 @@ in which the partition is specified as a list of lists:: sage: M = PartitionMatroid([[1, 2], [3, 4, 5], [6, 7]]) sage: M.full_rank() 3 - sage: M.tutte_polynomial(var('x'), var('y')) + sage: M.tutte_polynomial(var('x'), var('y')) # optional - sage.symbolic x^2*y^2 + 2*x*y^3 + y^4 + x^3 + 3*x^2*y + 3*x*y^2 + y^3 .. NOTE:: @@ -394,7 +394,7 @@ cdef class Matroid(SageObject): sage: M = PartitionMatroid([[1, 2], [3, 4, 5], [6, 7]]) sage: M.full_rank() 3 - sage: M.tutte_polynomial(var('x'), var('y')) + sage: M.tutte_polynomial(var('x'), var('y')) # optional - sage.symbolic x^2*y^2 + 2*x*y^3 + y^4 + x^3 + 3*x^2*y + 3*x*y^2 + y^3 .. NOTE:: @@ -1133,7 +1133,7 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.named_matroids.Vamos() - sage: M._has_minor(matroids.Whirl(3)) + sage: M._has_minor(matroids.Whirl(3)) # optional - sage.libs.pari False sage: M._has_minor(matroids.Uniform(2, 4)) True @@ -1361,12 +1361,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.rank() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.rank() # optional - sage.libs.pari 3 - sage: M.rank(['a', 'b', 'f']) + sage: M.rank(['a', 'b', 'f']) # optional - sage.libs.pari 2 - sage: M.rank(['a', 'b', 'x']) + sage: M.rank(['a', 'b', 'x']) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: ['a', 'b', 'x'] is not a subset of the groundset @@ -1672,12 +1672,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.corank() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.corank() # optional - sage.libs.pari 4 - sage: M.corank('cdeg') + sage: M.corank('cdeg') # optional - sage.libs.pari 3 - sage: M.rank(['a', 'b', 'x']) + sage: M.rank(['a', 'b', 'x']) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: ['a', 'b', 'x'] is not a subset of the groundset @@ -1914,10 +1914,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.loops() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.loops() # optional - sage.libs.pari frozenset() - sage: (M / ['a', 'b']).loops() + sage: (M / ['a', 'b']).loops() # optional - sage.libs.pari frozenset({'f'}) """ return self._closure(set()) @@ -2138,10 +2138,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().dual() - sage: M.coloops() + sage: M = matroids.named_matroids.Fano().dual() # optional - sage.libs.pari + sage: M.coloops() # optional - sage.libs.pari frozenset() - sage: (M \ ['a', 'b']).coloops() + sage: (M \ ['a', 'b']).coloops() # optional - sage.libs.pari frozenset({'f'}) """ return self._coclosure(set()) @@ -2384,8 +2384,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted([sorted(C) for C in M.circuits()]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted([sorted(C) for C in M.circuits()]) # optional - sage.libs.pari [['a', 'b', 'c', 'g'], ['a', 'b', 'd', 'e'], ['a', 'b', 'f'], ['a', 'c', 'd', 'f'], ['a', 'c', 'e'], ['a', 'd', 'g'], ['a', 'e', 'f', 'g'], ['b', 'c', 'd'], ['b', 'c', 'e', 'f'], @@ -2416,8 +2416,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted([sorted(C) for C in M.nonspanning_circuits()]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted([sorted(C) for C in M.nonspanning_circuits()]) # optional - sage.libs.pari [['a', 'b', 'f'], ['a', 'c', 'e'], ['a', 'd', 'g'], ['b', 'c', 'd'], ['b', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] @@ -2442,8 +2442,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted([sorted(C) for C in M.cocircuits()]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted([sorted(C) for C in M.cocircuits()]) # optional - sage.libs.pari [['a', 'b', 'c', 'g'], ['a', 'b', 'd', 'e'], ['a', 'c', 'd', 'f'], ['a', 'e', 'f', 'g'], ['b', 'c', 'e', 'f'], ['b', 'd', 'f', 'g'], ['c', 'd', 'e', 'g']] @@ -2471,8 +2471,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().dual() - sage: sorted([sorted(C) for C in M.noncospanning_cocircuits()]) + sage: M = matroids.named_matroids.Fano().dual() # optional - sage.libs.pari + sage: sorted([sorted(C) for C in M.noncospanning_cocircuits()]) # optional - sage.libs.pari [['a', 'b', 'f'], ['a', 'c', 'e'], ['a', 'd', 'g'], ['b', 'c', 'd'], ['b', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] @@ -2497,17 +2497,17 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: CC = M.circuit_closures() - sage: len(CC[2]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: CC = M.circuit_closures() # optional - sage.libs.pari + sage: len(CC[2]) # optional - sage.libs.pari 7 - sage: len(CC[3]) + sage: len(CC[3]) # optional - sage.libs.pari 1 - sage: len(CC[1]) + sage: len(CC[1]) # optional - sage.libs.pari Traceback (most recent call last): ... KeyError: 1 - sage: [sorted(X) for X in CC[3]] + sage: [sorted(X) for X in CC[3]] # optional - sage.libs.pari [['a', 'b', 'c', 'd', 'e', 'f', 'g']] """ CC = [set([]) for r in xrange(self.rank() + 1)] @@ -2534,11 +2534,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: CC = M.nonspanning_circuit_closures() - sage: len(CC[2]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: CC = M.nonspanning_circuit_closures() # optional - sage.libs.pari + sage: len(CC[2]) # optional - sage.libs.pari 7 - sage: len(CC[3]) + sage: len(CC[3]) # optional - sage.libs.pari Traceback (most recent call last): ... KeyError: 3 @@ -2737,9 +2737,9 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: F = M._flags(1) - sage: sorted(M._extend_flags(F)) == sorted(M._flags(2)) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: F = M._flags(1) # optional - sage.libs.pari + sage: sorted(M._extend_flags(F)) == sorted(M._flags(2)) # optional - sage.libs.pari True """ newflags = [] @@ -2777,8 +2777,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted([M._flags(1)]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted([M._flags(1)]) # optional - sage.libs.pari [[[frozenset({'a'}), {'a'}, frozenset({'b', 'c', 'd', 'e', 'f', 'g'})], [frozenset({'b'}), {'b'}, frozenset({'c', 'd', 'e', 'f', 'g'})], [frozenset({'c'}), {'c'}, frozenset({'d', 'e', 'f', 'g'})], @@ -2815,8 +2815,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted([sorted(F) for F in M.flats(2)]) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted([sorted(F) for F in M.flats(2)]) # optional - sage.libs.pari [['a', 'b', 'f'], ['a', 'c', 'e'], ['a', 'd', 'g'], ['b', 'c', 'd'], ['b', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] @@ -2844,8 +2844,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Q6() - sage: sorted([sorted(F) for F in M.coflats(2)]) + sage: M = matroids.named_matroids.Q6() # optional - sage.libs.pari + sage: sorted([sorted(F) for F in M.coflats(2)]) # optional - sage.libs.pari [['a', 'b'], ['a', 'c'], ['a', 'd', 'f'], ['a', 'e'], ['b', 'c'], ['b', 'd'], ['b', 'e'], ['b', 'f'], ['c', 'd'], ['c', 'e', 'f'], ['d', 'e']] @@ -2858,8 +2858,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.lattice_of_flats() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.lattice_of_flats() # optional - sage.libs.pari Finite lattice containing 16 elements """ from sage.combinat.posets.lattices import LatticePoset @@ -3125,13 +3125,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.Whirl(4) - sage: P = M.matroid_polytope(); P + sage: M = matroids.Whirl(4) # optional - sage.libs.pari + sage: P = M.matroid_polytope(); P # optional - sage.geometry.polyhedron sage.libs.pari A 7-dimensional polyhedron in ZZ^8 defined as the convex hull of 46 vertices - sage: M = matroids.named_matroids.NonFano() - sage: M.matroid_polytope() + sage: M = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M.matroid_polytope() # optional - sage.geometry.polyhedron sage.libs.pari A 6-dimensional polyhedron in ZZ^7 defined as the convex hull of 29 vertices @@ -3168,13 +3168,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.Whirl(4) - sage: M.independence_matroid_polytope() + sage: M = matroids.Whirl(4) # optional - sage.libs.pari + sage: M.independence_matroid_polytope() # optional - sage.geometry.polyhedron sage.libs.pari A 8-dimensional polyhedron in ZZ^8 defined as the convex hull of 135 vertices - sage: M = matroids.named_matroids.NonFano() - sage: M.independence_matroid_polytope() + sage: M = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M.independence_matroid_polytope() # optional - sage.geometry.polyhedron sage.libs.pari A 7-dimensional polyhedron in ZZ^7 defined as the convex hull of 58 vertices @@ -3227,11 +3227,11 @@ cdef class Matroid(SageObject): TypeError: can only test for isomorphism between matroids. - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = matroids.named_matroids.NonFano() - sage: M1.is_isomorphic(M2) + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M1.is_isomorphic(M2) # optional - sage.libs.pari False - sage: M1.is_isomorphic(M2, certificate=True) + sage: M1.is_isomorphic(M2, certificate=True) # optional - sage.libs.pari (False, None) """ if not isinstance(other, Matroid): @@ -3267,9 +3267,9 @@ cdef class Matroid(SageObject): sage: M1._is_isomorphic(M2, certificate=True) (True, {0: 0, 1: 1, 2: 2, 3: 3, 4: 5, 5: 4}) - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = matroids.named_matroids.NonFano() - sage: M1._is_isomorphic(M2) + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M1._is_isomorphic(M2) # optional - sage.libs.pari False """ @@ -3309,9 +3309,9 @@ cdef class Matroid(SageObject): ... TypeError: can only give isomorphism between matroids. - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = matroids.named_matroids.NonFano() - sage: M1.isomorphism(M2) is not None + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M1.isomorphism(M2) is not None # optional - sage.libs.pari False """ if not isinstance(other, Matroid): @@ -3339,9 +3339,9 @@ cdef class Matroid(SageObject): sage: morphism=M1.isomorphism(M2) sage: M1.is_isomorphism(M2, morphism) True - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = matroids.named_matroids.NonFano() - sage: M1.isomorphism(M2) is not None + sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M1.isomorphism(M2) is not None # optional - sage.libs.pari False """ if self is other: @@ -3385,38 +3385,38 @@ cdef class Matroid(SageObject): yields ``False``, even if the matroids are equal:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() - sage: M + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M # optional - sage.libs.pari Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) - sage: M1 = BasisMatroid(M) - sage: M2 = Matroid(groundset='abcdefg', reduced_matrix=[ + sage: M1 = BasisMatroid(M) # optional - sage.libs.pari + sage: M2 = Matroid(groundset='abcdefg', reduced_matrix=[ # optional - sage.libs.pari ....: [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 0, 1]], field=GF(2)) - sage: M.equals(M1) + sage: M.equals(M1) # optional - sage.libs.pari True - sage: M.equals(M2) + sage: M.equals(M2) # optional - sage.libs.pari True - sage: M == M1 + sage: M == M1 # optional - sage.libs.pari False - sage: M == M2 + sage: M == M2 # optional - sage.libs.pari True :class:`LinearMatroid ` instances ``M`` and ``N`` satisfy ``M == N`` if the representations are equivalent up to row operations and column scaling:: - sage: M1 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M1 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari ....: [[1, 0, 1, 1], [0, 1, 1, 2]])) - sage: M2 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M2 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari ....: [[1, 0, 1, 1], [0, 1, 1, 3]])) - sage: M3 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M3 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari ....: [[2, 6, 1, 0], [6, 1, 0, 1]])) - sage: M1.equals(M2) + sage: M1.equals(M2) # optional - sage.libs.pari True - sage: M1.equals(M3) + sage: M1.equals(M3) # optional - sage.libs.pari True - sage: M1 == M2 + sage: M1 == M2 # optional - sage.libs.pari False - sage: M1 == M3 + sage: M1 == M3 # optional - sage.libs.pari True """ if self is other: @@ -3463,19 +3463,19 @@ cdef class Matroid(SageObject): sage: N.is_isomorphism(M, {e:e for e in M.groundset()}) False - sage: M = matroids.named_matroids.Fano() \ ['g'] - sage: N = matroids.Wheel(3) - sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} - sage: M.is_isomorphism(N, morphism) + sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.libs.pari + sage: N = matroids.Wheel(3) # optional - sage.libs.pari + sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} # optional - sage.libs.pari + sage: M.is_isomorphism(N, morphism) # optional - sage.libs.pari True A morphism can be specified as a dictionary (above), a permutation, a function, and many other types of maps:: - sage: M = matroids.named_matroids.Fano() - sage: P = PermutationGroup([[('a', 'b', 'c'), + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: P = PermutationGroup([[('a', 'b', 'c'), # optional - sage.libs.pari ....: ('d', 'e', 'f'), ('g')]]).gen() - sage: M.is_isomorphism(M, P) + sage: M.is_isomorphism(M, P) # optional - sage.libs.pari True sage: M = matroids.named_matroids.Pappus() @@ -3572,10 +3572,10 @@ cdef class Matroid(SageObject): sage: N._is_isomorphism(M, {e:e for e in M.groundset()}) False - sage: M = matroids.named_matroids.Fano() \ ['g'] + sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.libs.pari sage: N = matroids.Wheel(3) sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} - sage: M._is_isomorphism(N, morphism) + sage: M._is_isomorphism(N, morphism) # optional - sage.libs.pari True """ from . import basis_exchange_matroid @@ -3639,19 +3639,19 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M1 = Matroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M1 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari ....: [[1, 0, 1, 1], [0, 1, 1, 2]])) - sage: M2 = Matroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M2 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari ....: [[1, 0, 1, 1], [0, 1, 1, 3]])) - sage: M3 = Matroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M3 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari ....: [[2, 6, 1, 0], [6, 1, 0, 1]])) - sage: M1.equals(M2) + sage: M1.equals(M2) # optional - sage.libs.pari True - sage: M1.equals(M3) + sage: M1.equals(M3) # optional - sage.libs.pari True - sage: M1 != M2 # indirect doctest + sage: M1 != M2 # indirect doctest # optional - sage.libs.pari True - sage: M1 == M3 # indirect doctest + sage: M1 == M3 # indirect doctest # optional - sage.libs.pari True """ if op not in [Py_EQ, Py_NE]: @@ -3713,10 +3713,10 @@ cdef class Matroid(SageObject): The sets of contractions and deletions need not be independent, respectively coindependent:: - sage: M = matroids.named_matroids.Fano() - sage: M.rank('abf') + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.rank('abf') # optional - sage.libs.pari 2 - sage: M.minor(contractions='abf') + sage: M.minor(contractions='abf') # optional - sage.libs.pari Binary matroid of rank 1 on 4 elements, type (1, 0) However, they need to be subsets of the groundset, and disjoint:: @@ -3819,12 +3819,12 @@ cdef class Matroid(SageObject): :: - sage: M = matroids.named_matroids.Fano() - sage: sorted(M.groundset()) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted(M.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - sage: M.contract(['a', 'c']) + sage: M.contract(['a', 'c']) # optional - sage.libs.pari Binary matroid of rank 1 on 5 elements, type (1, 0) - sage: M.contract(['a']) == M / ['a'] + sage: M.contract(['a']) == M / ['a'] # optional - sage.libs.pari True One can use a single element, rather than a set:: @@ -3837,8 +3837,8 @@ cdef class Matroid(SageObject): Note that one can iterate over strings:: - sage: M = matroids.named_matroids.Fano() - sage: M / 'abc' + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M / 'abc' # optional - sage.libs.pari Binary matroid of rank 0 on 4 elements, type (0, 0) The following is therefore ambiguous. Sage will contract the single @@ -3896,12 +3896,12 @@ cdef class Matroid(SageObject): :: - sage: M = matroids.named_matroids.Fano() - sage: sorted(M.groundset()) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted(M.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - sage: M.delete(['a', 'c']) + sage: M.delete(['a', 'c']) # optional - sage.libs.pari Binary matroid of rank 3 on 5 elements, type (1, 6) - sage: M.delete(['a']) == M \ ['a'] + sage: M.delete(['a']) == M \ ['a'] # optional - sage.libs.pari True One can use a single element, rather than a set:: @@ -3914,8 +3914,8 @@ cdef class Matroid(SageObject): Note that one can iterate over strings:: - sage: M = matroids.named_matroids.Fano() - sage: M \ 'abc' + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M \ 'abc' # optional - sage.libs.pari Binary matroid of rank 3 on 4 elements, type (0, 5) The following is therefore ambiguous. Sage will delete the single @@ -3994,9 +3994,9 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: N = M.truncation() - sage: N.is_isomorphic(matroids.Uniform(2, 7)) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N = M.truncation() # optional - sage.libs.pari + sage: N.is_isomorphic(matroids.Uniform(2, 7)) # optional - sage.libs.pari True """ if self.full_rank() == 0: @@ -4034,15 +4034,15 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.Whirl(3) - sage: matroids.named_matroids.Fano().has_minor(M) + sage: matroids.named_matroids.Fano().has_minor(M) # optional - sage.libs.pari False - sage: matroids.named_matroids.NonFano().has_minor(M) + sage: matroids.named_matroids.NonFano().has_minor(M) # optional - sage.libs.pari True - sage: matroids.named_matroids.NonFano().has_minor(M, certificate=True) + sage: matroids.named_matroids.NonFano().has_minor(M, certificate=True) # optional - sage.libs.pari (True, (frozenset(), frozenset({'g'}), {0: 'b', 1: 'c', 2: 'a', 3: 'd', 4: 'e', 5: 'f'})) - sage: M = matroids.named_matroids.Fano() - sage: M.has_minor(M, True) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.has_minor(M, True) # optional - sage.libs.pari (True, (frozenset(), frozenset(), @@ -4083,21 +4083,21 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: M.has_line_minor(4) + sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari + sage: M.has_line_minor(4) # optional - sage.libs.pari True - sage: M.has_line_minor(5) + sage: M.has_line_minor(5) # optional - sage.libs.pari False - sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c']]) + sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c']]) # optional - sage.libs.pari False - sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], + sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], # optional - sage.libs.pari ....: ['a', 'b', 'd' ]]) True - sage: M.has_line_minor(4, certificate=True) + sage: M.has_line_minor(4, certificate=True) # optional - sage.libs.pari (True, frozenset({'a', 'b', 'd'})) - sage: M.has_line_minor(5, certificate=True) + sage: M.has_line_minor(5, certificate=True) # optional - sage.libs.pari (False, None) - sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], + sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], # optional - sage.libs.pari ....: ['a', 'b', 'd' ]], certificate=True) (True, frozenset({'a', 'b', 'd'})) @@ -4231,9 +4231,9 @@ cdef class Matroid(SageObject): Putting an element in parallel with another:: - sage: M = matroids.named_matroids.Fano() - sage: N = M.extension('z', ['c']) - sage: N.rank('cz') + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N = M.extension('z', ['c']) # optional - sage.libs.pari + sage: N.rank('cz') # optional - sage.libs.pari 1 """ r = self.full_rank() - 1 @@ -4304,9 +4304,9 @@ cdef class Matroid(SageObject): Put an element in series with another:: - sage: M = matroids.named_matroids.Fano() - sage: N = M.coextension('z', ['c']) - sage: N.corank('cz') + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N = M.coextension('z', ['c']) # optional - sage.libs.pari + sage: N.corank('cz') # optional - sage.libs.pari 1 """ return self.dual().extension(element, subsets).dual() @@ -4374,8 +4374,8 @@ cdef class Matroid(SageObject): The modular cut of the full groundset is equal to just the groundset:: - sage: M = matroids.named_matroids.Fano() - sage: M.modular_cut([M.groundset()]).difference( + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.modular_cut([M.groundset()]).difference( # optional - sage.libs.pari ....: [frozenset(M.groundset())]) set() """ @@ -4446,12 +4446,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: len(list(M.linear_subclasses())) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: len(list(M.linear_subclasses())) # optional - sage.libs.pari 16 - sage: len(list(M.linear_subclasses(line_length=3))) + sage: len(list(M.linear_subclasses(line_length=3))) # optional - sage.libs.pari 8 - sage: len(list(M.linear_subclasses(subsets=[{'a', 'b'}]))) + sage: len(list(M.linear_subclasses(subsets=[{'a', 'b'}]))) # optional - sage.libs.pari 5 The following matroid has an extension by element `e` such that @@ -4515,14 +4515,14 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.P8() - sage: len(list(M.extensions())) + sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari + sage: len(list(M.extensions())) # optional - sage.libs.pari 1705 - sage: len(list(M.extensions(line_length=4))) + sage: len(list(M.extensions(line_length=4))) # optional - sage.libs.pari 41 - sage: sorted(M.groundset()) + sage: sorted(M.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] - sage: len(list(M.extensions(subsets=[{'a', 'b'}], line_length=4))) + sage: len(list(M.extensions(subsets=[{'a', 'b'}], line_length=4))) # optional - sage.libs.pari 5 """ @@ -4583,14 +4583,14 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.P8() - sage: len(list(M.coextensions())) + sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari + sage: len(list(M.coextensions())) # optional - sage.libs.pari 1705 - sage: len(list(M.coextensions(coline_length=4))) + sage: len(list(M.coextensions(coline_length=4))) # optional - sage.libs.pari 41 - sage: sorted(M.groundset()) + sage: sorted(M.groundset()) # optional - sage.libs.pari ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] - sage: len(list(M.coextensions(subsets=[{'a', 'b'}], coline_length=4))) + sage: len(list(M.coextensions(subsets=[{'a', 'b'}], coline_length=4))) # optional - sage.libs.pari 5 """ @@ -4624,8 +4624,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().contract('a') - sage: M.size() - M.simplify().size() + sage: M = matroids.named_matroids.Fano().contract('a') # optional - sage.libs.pari + sage: M.size() - M.simplify().size() # optional - sage.libs.pari 3 """ @@ -4663,8 +4663,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().dual().delete('a') - sage: M.cosimplify().size() + sage: M = matroids.named_matroids.Fano().dual().delete('a') # optional - sage.libs.pari + sage: M.cosimplify().size() # optional - sage.libs.pari 3 """ @@ -4698,11 +4698,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.is_simple() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.is_simple() # optional - sage.libs.pari True - sage: N = M / 'a' - sage: N.is_simple() + sage: N = M / 'a' # optional - sage.libs.pari + sage: N.is_simple() # optional - sage.libs.pari False """ if self._closure(frozenset()): @@ -4734,11 +4734,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().dual() - sage: M.is_cosimple() + sage: M = matroids.named_matroids.Fano().dual() # optional - sage.libs.pari + sage: M.is_cosimple() # optional - sage.libs.pari True - sage: N = M \ 'a' - sage: N.is_cosimple() + sage: N = M \ 'a' # optional - sage.libs.pari + sage: N.is_cosimple() # optional - sage.libs.pari False """ if self._coclosure(frozenset()): @@ -5281,14 +5281,14 @@ cdef class Matroid(SageObject): (False, True) sage: matroids.Uniform(4, 8).is_4connected() True - sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], + sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.libs.pari ....: [0,1,0,1,0,1,0,1,0,0,0,1], ....: [0,0,1,1,0,0,1,1,0,1,0,1], ....: [0,0,0,0,1,1,1,1,0,0,1,1], ....: [0,0,0,0,0,0,0,0,1,1,1,1]]) - sage: M.is_4connected() == M.is_4connected(algorithm="shifting") + sage: M.is_4connected() == M.is_4connected(algorithm="shifting") # optional - sage.libs.pari True - sage: M.is_4connected() == M.is_4connected(algorithm="intersection") + sage: M.is_4connected() == M.is_4connected(algorithm="intersection") # optional - sage.libs.pari True """ if algorithm is None or algorithm == "intersection": @@ -5636,18 +5636,18 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], + sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.libs.pari ....: [0,1,0,1,0,1,0,1,0,0,0,1], ....: [0,0,1,1,0,0,1,1,0,1,0,1], ....: [0,0,0,0,1,1,1,1,0,0,1,1], ....: [0,0,0,0,0,0,0,0,1,1,1,1]]) - sage: M._shifting_all(M.basis(),set([0,1]),set([0,1]),set([]),set([]),3) + sage: M._shifting_all(M.basis(),set([0,1]),set([0,1]),set([]),set([]),3) # optional - sage.libs.pari (False, None) - sage: M = Matroid(field=GF(2), reduced_matrix=[[1,0,1,1,1], + sage: M = Matroid(field=GF(2), reduced_matrix=[[1,0,1,1,1], # optional - sage.libs.pari ....: [1,1,1,1,0], ....: [0,1,1,1,0], ....: [0,0,0,1,1]]) - sage: M._shifting_all(M.basis(), set([0,1]), set([5,8]), set([]), set([]), 3)[0] + sage: M._shifting_all(M.basis(), set([0,1]), set([5,8]), set([]), set([]), 3)[0] # optional - sage.libs.pari True """ @@ -5696,18 +5696,18 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], + sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.libs.pari ....: [0,1,0,1,0,1,0,1,0,0,0,1], ....: [0,0,1,1,0,0,1,1,0,1,0,1], ....: [0,0,0,0,1,1,1,1,0,0,1,1], ....: [0,0,0,0,0,0,0,0,1,1,1,1]]) - sage: M._shifting(M.basis(),set([0,1]),set([0,1]),set([]),set([]),3) + sage: M._shifting(M.basis(),set([0,1]),set([0,1]),set([]),set([]),3) # optional - sage.libs.pari (False, None) - sage: M = Matroid(field=GF(2), reduced_matrix=[[1,0,1,1,1], + sage: M = Matroid(field=GF(2), reduced_matrix=[[1,0,1,1,1], # optional - sage.libs.pari ....: [1,1,1,1,0], ....: [0,1,1,1,0], ....: [0,0,0,1,1]]) - sage: M._shifting(M.basis(), set([0,1]), set([5,8]), set([]), set([4]), 3)[0] + sage: M._shifting(M.basis(), set([0,1]), set([5,8]), set([]), set([4]), 3)[0] # optional - sage.libs.pari True """ @@ -5791,8 +5791,8 @@ cdef class Matroid(SageObject): False sage: matroids.named_matroids.BetsyRoss()._is_3connected_BC() True - sage: M = matroids.named_matroids.R6() - sage: M._is_3connected_BC() + sage: M = matroids.named_matroids.R6() # optional - sage.libs.pari + sage: M._is_3connected_BC() # optional - sage.libs.pari False """ # The 5 stages of the algorithm @@ -5837,9 +5837,9 @@ cdef class Matroid(SageObject): sage: M._is_3connected_BC_recursion(B, ....: [M.fundamental_cocircuit(B, e) for e in B]) True - sage: M = matroids.named_matroids.R6() - sage: B = M.basis() - sage: M._is_3connected_BC_recursion(B, + sage: M = matroids.named_matroids.R6() # optional - sage.libs.pari + sage: B = M.basis() # optional - sage.libs.pari + sage: M._is_3connected_BC_recursion(B, # optional - sage.libs.pari ....: [M.fundamental_cocircuit(B, e) for e in B]) False @@ -5929,13 +5929,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() - sage: M = N._local_binary_matroid() - sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) + sage: N = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M = N._local_binary_matroid() # optional - sage.libs.pari + sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.libs.pari True - sage: N = matroids.named_matroids.NonFano() - sage: M = N._local_binary_matroid() - sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) + sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M = N._local_binary_matroid() # optional - sage.libs.pari + sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.libs.pari False """ if basis is None: @@ -5987,11 +5987,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.binary_matroid() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.binary_matroid() # optional - sage.libs.pari Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) - sage: N = matroids.named_matroids.NonFano() - sage: N.binary_matroid() is None + sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: N.binary_matroid() is None # optional - sage.libs.pari True """ @@ -6039,11 +6039,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() - sage: N.is_binary() + sage: N = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N.is_binary() # optional - sage.libs.pari True - sage: N = matroids.named_matroids.NonFano() - sage: N.is_binary() + sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: N.is_binary() # optional - sage.libs.pari False """ @@ -6080,13 +6080,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() - sage: M = N._local_ternary_matroid() - sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) + sage: N = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M = N._local_ternary_matroid() # optional - sage.libs.pari + sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.libs.pari False - sage: N = matroids.named_matroids.NonFano() - sage: M = N._local_ternary_matroid() - sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) + sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M = N._local_ternary_matroid() # optional - sage.libs.pari + sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.libs.pari True """ if basis is None: @@ -6172,11 +6172,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.ternary_matroid() is None + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.ternary_matroid() is None # optional - sage.libs.pari True - sage: N = matroids.named_matroids.NonFano() - sage: N.ternary_matroid() + sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: N.ternary_matroid() # optional - sage.libs.pari NonFano: Ternary matroid of rank 3 on 7 elements, type 0- """ @@ -6224,11 +6224,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() - sage: N.is_ternary() + sage: N = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N.is_ternary() # optional - sage.libs.pari False - sage: N = matroids.named_matroids.NonFano() - sage: N.is_ternary() + sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: N.is_ternary() # optional - sage.libs.pari True """ @@ -6392,15 +6392,15 @@ cdef class Matroid(SageObject): sage: M = matroids.Uniform(2,4) sage: [M.is_chordal(i) for i in range(4, 8)] [True, True, True, True] - sage: M = matroids.named_matroids.NonFano() - sage: [M.is_chordal(i) for i in range(4, 8)] + sage: M = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: [M.is_chordal(i) for i in range(4, 8)] # optional - sage.libs.pari [False, True, True, True] - sage: M = matroids.named_matroids.N2() - sage: [M.is_chordal(i) for i in range(4, 10)] + sage: M = matroids.named_matroids.N2() # optional - sage.libs.pari + sage: [M.is_chordal(i) for i in range(4, 10)] # optional - sage.libs.pari [False, False, False, False, True, True] - sage: M.is_chordal(4, 5) + sage: M.is_chordal(4, 5) # optional - sage.libs.pari False - sage: M.is_chordal(4, 5, certificate=True) + sage: M.is_chordal(4, 5, certificate=True) # optional - sage.libs.pari (False, frozenset({'a', 'b', 'e', 'f', 'g'})) """ cdef frozenset C @@ -6428,11 +6428,11 @@ cdef class Matroid(SageObject): sage: M = matroids.Uniform(2,4) sage: M.chordality() 4 - sage: M = matroids.named_matroids.NonFano() - sage: M.chordality() + sage: M = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M.chordality() # optional - sage.libs.pari 5 - sage: M = matroids.named_matroids.Fano() - sage: M.chordality() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.chordality() # optional - sage.libs.pari 4 """ cdef frozenset C @@ -6474,14 +6474,14 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() - sage: X = M.max_weight_independent() - sage: M.is_basis(X) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: X = M.max_weight_independent() # optional - sage.libs.pari + sage: M.is_basis(X) # optional - sage.libs.pari True sage: wt = {'a': 1, 'b': 2, 'c': 2, 'd': 1/2, 'e': 1, ....: 'f': 2, 'g': 2} - sage: setprint(M.max_weight_independent(weights=wt)) + sage: setprint(M.max_weight_independent(weights=wt)) # optional - sage.libs.pari {'b', 'f', 'g'} sage: def wt(x): ....: return x @@ -6561,18 +6561,18 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() - sage: X = M.max_weight_coindependent() - sage: M.is_cobasis(X) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: X = M.max_weight_coindependent() # optional - sage.libs.pari + sage: M.is_cobasis(X) # optional - sage.libs.pari True sage: wt = {'a': 1, 'b': 2, 'c': 2, 'd': 1/2, 'e': 1, 'f': 2, ....: 'g': 2} - sage: setprint(M.max_weight_coindependent(weights=wt)) + sage: setprint(M.max_weight_coindependent(weights=wt)) # optional - sage.libs.pari {'b', 'c', 'f', 'g'} sage: wt = {'a': 1, 'b': -10, 'c': 2, 'd': 1/2, 'e': 1, 'f': 2, ....: 'g': 2} - sage: setprint(M.max_weight_coindependent(weights=wt)) + sage: setprint(M.max_weight_coindependent(weights=wt)) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: nonnegative weights were expected. @@ -6660,8 +6660,8 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() - sage: M.is_max_weight_independent_generic() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.is_max_weight_independent_generic() # optional - sage.libs.pari False sage: def wt(x): @@ -6810,8 +6810,8 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() - sage: M.is_max_weight_coindependent_generic() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.is_max_weight_coindependent_generic() # optional - sage.libs.pari False sage: def wt(x): @@ -6958,18 +6958,18 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari sage: w = {'a':30, 'b':10, 'c':11, 'd':20, 'e':70, 'f':21, 'g':90, ....: 'h':12, 'i':80, 'j':13, 'k':40, 'l':21} - sage: Y = M.intersection(N, w) - sage: sorted(Y) + sage: Y = M.intersection(N, w) # optional - sage.libs.pari + sage: sorted(Y) # optional - sage.libs.pari ['a', 'd', 'e', 'g', 'i', 'k'] - sage: sum([w[y] for y in Y]) + sage: sum([w[y] for y in Y]) # optional - sage.libs.pari 330 - sage: M = matroids.named_matroids.Fano() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari sage: N = matroids.Uniform(4, 7) - sage: M.intersection(N) + sage: M.intersection(N) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: matroid intersection requires equal groundsets. @@ -7017,14 +7017,14 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari sage: w = {'a':30, 'b':10, 'c':11, 'd':20, 'e':70, 'f':21, 'g':90, ....: 'h':12, 'i':80, 'j':13, 'k':40, 'l':21} - sage: Y = M._intersection(N, w) - sage: sorted(Y) + sage: Y = M._intersection(N, w) # optional - sage.libs.pari + sage: sorted(Y) # optional - sage.libs.pari ['a', 'd', 'e', 'g', 'i', 'k'] - sage: sum([w[y] for y in Y]) + sage: sum([w[y] for y in Y]) # optional - sage.libs.pari 330 """ Y = set() @@ -7063,14 +7063,14 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari sage: w = {'a':30, 'b':10, 'c':11, 'd':20, 'e':70, 'f':21, 'g':90, ....: 'h':12, 'i':80, 'j':13, 'k':40, 'l':21} - sage: Y = M.intersection(N, w) - sage: sorted(Y) + sage: Y = M.intersection(N, w) # optional - sage.libs.pari + sage: sorted(Y) # optional - sage.libs.pari ['a', 'd', 'e', 'g', 'i', 'k'] - sage: M._intersection_augmentation(N, w, Y)[0] + sage: M._intersection_augmentation(N, w, Y)[0] # optional - sage.libs.pari False """ X = self.groundset() - Y @@ -7144,13 +7144,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() - sage: len(M.intersection_unweighted(N)) + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari + sage: len(M.intersection_unweighted(N)) # optional - sage.libs.pari 6 - sage: M = matroids.named_matroids.Fano() - sage: N = matroids.Uniform(4, 7) - sage: M.intersection_unweighted(N) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: N = matroids.Uniform(4, 7) # optional - sage.libs.pari + sage: M.intersection_unweighted(N) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: matroid intersection requires equal groundsets. @@ -7185,9 +7185,9 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() - sage: len(M._intersection_unweighted(N)) + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari + sage: len(M._intersection_unweighted(N)) # optional - sage.libs.pari 6 """ Y = set() @@ -7219,15 +7219,15 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() - sage: Y = M.intersection(N) - sage: M._intersection_augmentation_unweighted(N, Y)[0] + sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari + sage: Y = M.intersection(N) # optional - sage.libs.pari + sage: M._intersection_augmentation_unweighted(N, Y)[0] # optional - sage.libs.pari False - sage: Y = M._intersection_augmentation_unweighted(N,set()) - sage: Y[0] + sage: Y = M._intersection_augmentation_unweighted(N,set()) # optional - sage.libs.pari + sage: Y[0] # optional - sage.libs.pari True - sage: len(Y[1])>0 + sage: len(Y[1])>0 # optional - sage.libs.pari True """ E = self.groundset() @@ -7425,10 +7425,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted(M._internal({'a', 'b', 'c'})) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted(M._internal({'a', 'b', 'c'})) # optional - sage.libs.pari ['a', 'b', 'c'] - sage: sorted(M._internal({'e', 'f', 'g'})) + sage: sorted(M._internal({'e', 'f', 'g'})) # optional - sage.libs.pari [] """ N = self.groundset() - B @@ -7464,10 +7464,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: sorted(M._external({'a', 'b', 'c'})) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: sorted(M._external({'a', 'b', 'c'})) # optional - sage.libs.pari [] - sage: sorted(M._external({'e', 'f', 'g'})) + sage: sorted(M._external({'e', 'f', 'g'})) # optional - sage.libs.pari ['a', 'b', 'c', 'd'] """ @@ -7517,10 +7517,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.tutte_polynomial() + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M.tutte_polynomial() # optional - sage.libs.pari y^4 + x^3 + 3*y^3 + 4*x^2 + 7*x*y + 6*y^2 + 3*x + 3*y - sage: M.tutte_polynomial(1, 1) == M.bases_count() + sage: M.tutte_polynomial(1, 1) == M.bases_count() # optional - sage.libs.pari True ALGORITHM: @@ -7565,8 +7565,8 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() - sage: setprint(M.flat_cover()) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: setprint(M.flat_cover()) # optional - sage.libs.pari [{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}, {'d', 'e', 'f'}] @@ -7634,21 +7634,21 @@ cdef class Matroid(SageObject): We construct a more interesting example using the Fano matroid:: - sage: M = matroids.named_matroids.Fano() - sage: A = M.chow_ring(QQ) - sage: A + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: A = M.chow_ring(QQ) # optional - sage.libs.pari + sage: A # optional - sage.libs.pari Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) over Rational Field Next we get the non-trivial generators and do some computations:: - sage: G = A.gens()[6:] - sage: Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef = G - sage: Ag * Ag + sage: G = A.gens()[6:] # optional - sage.libs.pari + sage: Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef = G # optional - sage.libs.pari + sage: Ag * Ag # optional - sage.libs.pari 2*Adef^2 - sage: Ag * Abeg + sage: Ag * Abeg # optional - sage.libs.pari -Adef^2 - sage: matrix([[x * y for x in G] for y in G]) + sage: matrix([[x * y for x in G] for y in G]) # optional - sage.libs.pari [2*Adef^2 0 0 -Adef^2 0 -Adef^2 -Adef^2 0] [ 0 Adef^2 0 0 0 0 0 0] [ 0 0 Adef^2 0 0 0 0 0] @@ -7723,11 +7723,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M=matroids.named_matroids.Fano() - sage: G=M.plot() - sage: type(G) + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: G = M.plot() # optional - sage.libs.pari sage.plot + sage: type(G) # optional - sage.libs.pari sage.plot - sage: G.show() + sage: G.show() # optional - sage.libs.pari sage.plot """ from . import matroids_plot_helpers @@ -7780,11 +7780,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M=matroids.named_matroids.TernaryDowling3() - sage: M.show(B=['a','b','c']) - sage: M.show(B=['a','b','c'],lineorders=[['f','e','i']]) - sage: pos = {'a':(0,0), 'b': (0,1), 'c':(1,0), 'd':(1,1), 'e':(1,-1), 'f':(-1,1), 'g':(-1,-1),'h':(2,0), 'i':(0,2)} - sage: M.show(pos_method=1, pos_dict=pos,lims=[-3,3,-3,3]) + sage: M = matroids.named_matroids.TernaryDowling3() # optional - sage.libs.pari + sage: M.show(B=['a','b','c']) # optional - sage.libs.pari sage.plot + sage: M.show(B=['a','b','c'], lineorders=[['f','e','i']]) # optional - sage.libs.pari sage.plot + sage: pos = {'a':(0,0), 'b': (0,1), 'c':(1,0), 'd':(1,1), # optional - sage.libs.pari sage.plot + ....: 'e':(1,-1), 'f':(-1,1), 'g':(-1,-1),'h':(2,0), 'i':(0,2)} + sage: M.show(pos_method=1, pos_dict=pos, lims=[-3,3,-3,3]) # optional - sage.libs.pari sage.plot """ if self.rank() > 3: raise NotImplementedError @@ -7886,8 +7887,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: B = M.bergman_complex(); B + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: B = M.bergman_complex(); B # optional - sage.libs.pari Simplicial complex with 14 vertices and 21 facets .. SEEALSO:: @@ -7925,8 +7926,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: A = M.augmented_bergman_complex(); A + sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: A = M.augmented_bergman_complex(); A # optional - sage.libs.pari Simplicial complex with 22 vertices and 91 facets sage: M = matroids.Uniform(2,3) @@ -8059,7 +8060,7 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.named_matroids.Pappus() - sage: N = matroids.named_matroids.Fano().direct_sum(M); N + sage: N = matroids.named_matroids.Fano().direct_sum(M); N # optional - sage.libs.pari Matroid of rank 6 on 16 elements as matroid sum of Binary matroid of rank 3 on 7 elements, type (3, 0) Matroid of rank 3 on 9 elements with circuit-closures @@ -8067,9 +8068,9 @@ cdef class Matroid(SageObject): {'b', 'd', 'i'}, {'b', 'f', 'g'}, {'c', 'd', 'h'}, {'c', 'e', 'g'}, {'d', 'e', 'f'}, {'g', 'h', 'i'}}, 3: {{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}}} - sage: len(N.independent_sets()) + sage: len(N.independent_sets()) # optional - sage.libs.pari 6897 - sage: len(N.bases()) + sage: len(N.bases()) # optional - sage.libs.pari 2100 """ from . import union_matroid From 931deebf67071af8fcc182fabd6e6f5aac5b9d20 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 30 Apr 2023 18:41:19 -0700 Subject: [PATCH 045/205] Doctest cosmetics --- src/sage/matroids/basis_exchange_matroid.pyx | 168 ++-- src/sage/matroids/basis_matroid.pyx | 120 +-- src/sage/matroids/catalog.py | 198 ++-- .../matroids/circuit_closures_matroid.pyx | 16 +- src/sage/matroids/constructor.py | 10 +- src/sage/matroids/dual_matroid.py | 34 +- src/sage/matroids/extension.pyx | 2 +- src/sage/matroids/linear_matroid.pyx | 863 +++++++++--------- src/sage/matroids/matroid.pyx | 619 +++++++------ src/sage/matroids/minor_matroid.py | 48 +- src/sage/matroids/set_system.pyx | 10 +- src/sage/matroids/unpickling.pyx | 60 +- src/sage/matroids/utilities.py | 42 +- src/sage/structure/sage_object.pyx | 40 +- 14 files changed, 1115 insertions(+), 1115 deletions(-) diff --git a/src/sage/matroids/basis_exchange_matroid.pyx b/src/sage/matroids/basis_exchange_matroid.pyx index 89dbb8e5e56..360ec9538aa 100644 --- a/src/sage/matroids/basis_exchange_matroid.pyx +++ b/src/sage/matroids/basis_exchange_matroid.pyx @@ -473,8 +473,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: sorted(M.groundset()) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd', 'e', 'f', 'g'] """ return self._groundset @@ -495,17 +495,17 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: type(M.groundset()) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: type(M.groundset()) # optional - sage.rings.finite_rings <... 'frozenset'> - sage: type(M.groundset_list()) # optional - sage.libs.pari + sage: type(M.groundset_list()) # optional - sage.rings.finite_rings <... 'list'> - sage: sorted(M.groundset_list()) # optional - sage.libs.pari + sage: sorted(M.groundset_list()) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - sage: E = M.groundset_list() # optional - sage.libs.pari - sage: E.remove('a') # optional - sage.libs.pari - sage: sorted(M.groundset_list()) # optional - sage.libs.pari + sage: E = M.groundset_list() # optional - sage.rings.finite_rings + sage: E.remove('a') # optional - sage.rings.finite_rings + sage: sorted(M.groundset_list()) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd', 'e', 'f', 'g'] """ return list(self._E) @@ -538,10 +538,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.full_rank() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.full_rank() # optional - sage.rings.finite_rings 3 - sage: M.dual().full_rank() # optional - sage.libs.pari + sage: M.dual().full_rank() # optional - sage.rings.finite_rings 4 """ return self._matroid_rank @@ -564,10 +564,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.full_corank() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.full_corank() # optional - sage.rings.finite_rings 4 - sage: M.dual().full_corank() # optional - sage.libs.pari + sage: M.dual().full_corank() # optional - sage.rings.finite_rings 3 """ return self._groundset_size - self._matroid_rank @@ -592,12 +592,12 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: sorted(M.basis()) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: sorted(M.basis()) # optional - sage.rings.finite_rings ['a', 'b', 'c'] - sage: M.rank('cd') # optional - sage.libs.pari + sage: M.rank('cd') # optional - sage.rings.finite_rings 2 - sage: sorted(M.basis()) # optional - sage.libs.pari + sage: sorted(M.basis()) # optional - sage.rings.finite_rings ['a', 'c', 'd'] """ @@ -750,8 +750,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari - sage: sorted(M._fundamental_circuit('abcd', 'e')) # optional - sage.libs.pari + sage: M = matroids.named_matroids.P8() # optional - sage.rings.finite_rings + sage: sorted(M._fundamental_circuit('abcd', 'e')) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'e'] """ self.__pack(self._input, B) @@ -906,8 +906,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari - sage: sorted(M._fundamental_cocircuit('efgh', 'e')) # optional - sage.libs.pari + sage: M = matroids.named_matroids.P8() # optional - sage.rings.finite_rings + sage: sorted(M._fundamental_cocircuit('efgh', 'e')) # optional - sage.rings.finite_rings ['b', 'c', 'd', 'e'] """ self.__pack(self._input, B) @@ -1255,8 +1255,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.S8() # optional - sage.libs.pari - sage: M.f_vector() # optional - sage.libs.pari + sage: M = matroids.named_matroids.S8() # optional - sage.rings.finite_rings + sage: M.f_vector() # optional - sage.rings.finite_rings [1, 8, 22, 14, 1] """ @@ -1321,14 +1321,14 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.S8() # optional - sage.libs.pari - sage: M.f_vector() # optional - sage.libs.pari + sage: M = matroids.named_matroids.S8() # optional - sage.rings.finite_rings + sage: M.f_vector() # optional - sage.rings.finite_rings [1, 8, 22, 14, 1] - sage: len(M.flats(2)) # optional - sage.libs.pari + sage: len(M.flats(2)) # optional - sage.rings.finite_rings 22 - sage: len(M.flats(8)) # optional - sage.libs.pari + sage: len(M.flats(8)) # optional - sage.rings.finite_rings 0 - sage: len(M.flats(4)) # optional - sage.libs.pari + sage: len(M.flats(4)) # optional - sage.rings.finite_rings 1 """ cdef bitset_t *flats @@ -1396,14 +1396,14 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.S8().dual() # optional - sage.libs.pari - sage: M.f_vector() # optional - sage.libs.pari + sage: M = matroids.named_matroids.S8().dual() # optional - sage.rings.finite_rings + sage: M.f_vector() # optional - sage.rings.finite_rings [1, 8, 22, 14, 1] - sage: len(M.coflats(2)) # optional - sage.libs.pari + sage: len(M.coflats(2)) # optional - sage.rings.finite_rings 22 - sage: len(M.coflats(8)) # optional - sage.libs.pari + sage: len(M.coflats(8)) # optional - sage.rings.finite_rings 0 - sage: len(M.coflats(4)) # optional - sage.libs.pari + sage: len(M.coflats(4)) # optional - sage.rings.finite_rings 1 """ cdef bitset_t *coflats @@ -1529,8 +1529,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari - sage: M.bases_count() # optional - sage.libs.pari + sage: M = matroids.named_matroids.N1() # optional - sage.rings.finite_rings + sage: M.bases_count() # optional - sage.rings.finite_rings 184 """ if self._bcount is not None: @@ -1556,9 +1556,9 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: I = M.independent_sets() # optional - sage.libs.pari - sage: len(I) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: I = M.independent_sets() # optional - sage.rings.finite_rings + sage: len(I) # optional - sage.rings.finite_rings 57 """ cdef bitset_t *I @@ -1617,10 +1617,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari - sage: M.bases_count() # optional - sage.libs.pari + sage: M = matroids.named_matroids.N1() # optional - sage.rings.finite_rings + sage: M.bases_count() # optional - sage.rings.finite_rings 184 - sage: [len(M.independent_r_sets(r)) for r in range(M.full_rank() + 1)] # optional - sage.libs.pari + sage: [len(M.independent_r_sets(r)) for r in range(M.full_rank() + 1)] # optional - sage.rings.finite_rings [1, 10, 45, 120, 201, 184] """ @@ -1649,10 +1649,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari - sage: M.bases_count() # optional - sage.libs.pari + sage: M = matroids.named_matroids.N1() # optional - sage.rings.finite_rings + sage: M.bases_count() # optional - sage.rings.finite_rings 184 - sage: len([B for B in M.bases()]) # optional - sage.libs.pari + sage: len([B for B in M.bases()]) # optional - sage.rings.finite_rings 184 """ return self.independent_r_sets(self.full_rank()) @@ -1671,10 +1671,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari - sage: len(M.nonbases()) # optional - sage.libs.pari + sage: M = matroids.named_matroids.N1() # optional - sage.rings.finite_rings + sage: len(M.nonbases()) # optional - sage.rings.finite_rings 68 - sage: [len(M.dependent_r_sets(r)) for r in range(M.full_rank() + 1)] # optional - sage.libs.pari + sage: [len(M.dependent_r_sets(r)) for r in range(M.full_rank() + 1)] # optional - sage.rings.finite_rings [0, 0, 0, 0, 9, 68] """ @@ -1714,10 +1714,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari - sage: binomial(M.size(), M.full_rank())-M.bases_count() # optional - sage.libs.pari + sage: M = matroids.named_matroids.N1() # optional - sage.rings.finite_rings + sage: binomial(M.size(), M.full_rank())-M.bases_count() # optional - sage.rings.finite_rings 68 - sage: len([B for B in M.nonbases()]) # optional - sage.libs.pari + sage: len([B for B in M.nonbases()]) # optional - sage.rings.finite_rings 68 """ return self.dependent_r_sets(self.full_rank()) @@ -1740,8 +1740,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari - sage: len(M.nonspanning_circuits()) # optional - sage.libs.pari + sage: M = matroids.named_matroids.N1() # optional - sage.rings.finite_rings + sage: len(M.nonspanning_circuits()) # optional - sage.rings.finite_rings 23 """ cdef SetSystem NSC @@ -1789,8 +1789,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari - sage: len(M.noncospanning_cocircuits()) # optional - sage.libs.pari + sage: M = matroids.named_matroids.N1() # optional - sage.rings.finite_rings + sage: len(M.noncospanning_cocircuits()) # optional - sage.rings.finite_rings 23 """ cdef SetSystem NSC @@ -1835,8 +1835,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.NonFano().bases()) # optional - sage.libs.pari - sage: sorted([sorted(C) for C in M.cocircuits()]) # optional - sage.libs.pari + sage: M = Matroid(bases=matroids.named_matroids.NonFano().bases()) # optional - sage.rings.finite_rings + sage: sorted([sorted(C) for C in M.cocircuits()]) # optional - sage.rings.finite_rings [['a', 'b', 'c', 'd', 'g'], ['a', 'b', 'c', 'e', 'g'], ['a', 'b', 'c', 'f', 'g'], ['a', 'b', 'd', 'e'], ['a', 'c', 'd', 'f'], ['a', 'e', 'f', 'g'], ['b', 'c', 'e', 'f'], @@ -1883,8 +1883,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = Matroid(matroids.named_matroids.NonFano().bases()) # optional - sage.libs.pari - sage: sorted([sorted(C) for C in M.circuits()]) # optional - sage.libs.pari + sage: M = Matroid(matroids.named_matroids.NonFano().bases()) # optional - sage.rings.finite_rings + sage: sorted([sorted(C) for C in M.circuits()]) # optional - sage.rings.finite_rings [['a', 'b', 'c', 'g'], ['a', 'b', 'd', 'e'], ['a', 'b', 'f'], ['a', 'c', 'd', 'f'], ['a', 'c', 'e'], ['a', 'd', 'e', 'f'], ['a', 'd', 'g'], ['a', 'e', 'f', 'g'], ['b', 'c', 'd'], @@ -1932,10 +1932,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari - sage: M._characteristic_setsystem() # optional - sage.libs.pari + sage: M = matroids.named_matroids.N1() # optional - sage.rings.finite_rings + sage: M._characteristic_setsystem() # optional - sage.rings.finite_rings Iterator over a system of subsets - sage: len(M._characteristic_setsystem()) # optional - sage.libs.pari + sage: len(M._characteristic_setsystem()) # optional - sage.rings.finite_rings 23 """ if 2 * self._matroid_rank > self._groundset_size: @@ -1958,9 +1958,9 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari - sage: N = Matroid(matroids.named_matroids.NonFano().bases()) # optional - sage.libs.pari - sage: M._weak_invariant() == N._weak_invariant() # optional - sage.libs.pari + sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.rings.finite_rings + sage: N = Matroid(matroids.named_matroids.NonFano().bases()) # optional - sage.rings.finite_rings + sage: M._weak_invariant() == N._weak_invariant() # optional - sage.rings.finite_rings False """ if self._weak_invariant_var is None: @@ -2003,9 +2003,9 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = Matroid(matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari - sage: N = Matroid(matroids.named_matroids.NonFano().bases()) # optional - sage.libs.pari - sage: M._strong_invariant() == N._strong_invariant() # optional - sage.libs.pari + sage: M = Matroid(matroids.named_matroids.Fano().bases()) # optional - sage.rings.finite_rings + sage: N = Matroid(matroids.named_matroids.NonFano().bases()) # optional - sage.rings.finite_rings + sage: M._strong_invariant() == N._strong_invariant() # optional - sage.rings.finite_rings False """ if self._strong_invariant_var is None: @@ -2132,10 +2132,10 @@ cdef class BasisExchangeMatroid(Matroid): sage: N._is_isomorphism(M, {e:e for e in M.groundset()}) False - sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.libs.pari - sage: N = matroids.Wheel(3) # optional - sage.libs.pari - sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} # optional - sage.libs.pari - sage: M._is_isomorphism(N, morphism) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.rings.finite_rings + sage: N = matroids.Wheel(3) # optional - sage.rings.finite_rings + sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} # optional - sage.rings.finite_rings + sage: M._is_isomorphism(N, morphism) # optional - sage.rings.finite_rings True TESTS: @@ -2199,9 +2199,9 @@ cdef class BasisExchangeMatroid(Matroid): sage: morphism = M1._isomorphism(M2) sage: M1._is_isomorphism(M2, morphism) True - sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: M1._isomorphism(M2) is None # optional - sage.libs.pari + sage: M1 = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M1._isomorphism(M2) is None # optional - sage.rings.finite_rings True TESTS: @@ -2212,8 +2212,8 @@ cdef class BasisExchangeMatroid(Matroid): ....: return min(len(X), 2) ....: sage: M = Matroid(groundset='abcd', rank_function=f) - sage: N = Matroid(field=GF(3), reduced_matrix=[[1,1],[1,-1]]) # optional - sage.libs.pari - sage: N._isomorphism(M) is not None # optional - sage.libs.pari + sage: N = Matroid(field=GF(3), reduced_matrix=[[1,1],[1,-1]]) # optional - sage.rings.finite_rings + sage: N._isomorphism(M) is not None # optional - sage.rings.finite_rings True """ if not isinstance(other, BasisExchangeMatroid): @@ -2294,11 +2294,11 @@ cdef class BasisExchangeMatroid(Matroid): True sage: M1._is_isomorphic(M2, certificate=True) (True, {0: 0, 1: 1, 2: 2, 3: 3, 4: 5, 5: 4}) - sage: M1 = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: M1._is_isomorphic(M2) # optional - sage.libs.pari + sage: M1 = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M1._is_isomorphic(M2) # optional - sage.rings.finite_rings False - sage: M1._is_isomorphic(M2, certificate=True) # optional - sage.libs.pari + sage: M1._is_isomorphic(M2, certificate=True) # optional - sage.rings.finite_rings (False, None) """ @@ -2370,8 +2370,8 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: M.is_valid() # optional - sage.libs.pari + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: M.is_valid() # optional - sage.rings.finite_rings True sage: M = Matroid(groundset='abcd', bases=['ab', 'cd']) sage: M.is_valid() diff --git a/src/sage/matroids/basis_matroid.pyx b/src/sage/matroids/basis_matroid.pyx index 4c9ccf70db5..b7007314b1b 100644 --- a/src/sage/matroids/basis_matroid.pyx +++ b/src/sage/matroids/basis_matroid.pyx @@ -110,11 +110,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): Create a BasisMatroid instance out of any other matroid:: sage: from sage.matroids.advanced import * - sage: F = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M = BasisMatroid(F) # optional - sage.libs.pari - sage: F.groundset() == M.groundset() # optional - sage.libs.pari + sage: F = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M = BasisMatroid(F) # optional - sage.rings.finite_rings + sage: F.groundset() == M.groundset() # optional - sage.rings.finite_rings True - sage: len(set(F.bases()).difference(M.bases())) # optional - sage.libs.pari + sage: len(set(F.bases()).difference(M.bases())) # optional - sage.rings.finite_rings 0 It is possible to provide either bases or nonbases:: @@ -150,11 +150,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: F = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M = BasisMatroid(F) # optional - sage.libs.pari - sage: F.groundset() == M.groundset() # optional - sage.libs.pari + sage: F = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M = BasisMatroid(F) # optional - sage.rings.finite_rings + sage: F.groundset() == M.groundset() # optional - sage.rings.finite_rings True - sage: len(set(F.bases()).difference(M.bases())) # optional - sage.libs.pari + sage: len(set(F.bases()).difference(M.bases())) # optional - sage.rings.finite_rings 0 """ cdef SetSystem NB @@ -254,8 +254,8 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: repr(M) # indirect doctest # optional - sage.libs.pari + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: repr(M) # indirect doctest # optional - sage.rings.finite_rings 'Matroid of rank 3 on 7 elements with 28 bases' """ @@ -429,12 +429,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.N2().bases()) # optional - sage.libs.pari - sage: M.truncation() # optional - sage.libs.pari + sage: M = Matroid(bases=matroids.named_matroids.N2().bases()) # optional - sage.rings.finite_rings + sage: M.truncation() # optional - sage.rings.finite_rings Matroid of rank 5 on 12 elements with 702 bases - sage: M.f_vector() # optional - sage.libs.pari + sage: M.f_vector() # optional - sage.rings.finite_rings [1, 12, 66, 190, 258, 99, 1] - sage: M.truncation().f_vector() # optional - sage.libs.pari + sage: M.truncation().f_vector() # optional - sage.rings.finite_rings [1, 12, 66, 190, 258, 1] """ @@ -511,10 +511,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: M # optional - sage.libs.pari + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings Matroid of rank 3 on 7 elements with 28 bases - sage: M._with_coloop('x') # optional - sage.libs.pari + sage: M._with_coloop('x') # optional - sage.rings.finite_rings Matroid of rank 4 on 8 elements with 28 bases """ @@ -548,11 +548,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: sorted(M.groundset()) # optional - sage.libs.pari + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - sage: N = M.relabel({'g':'x'}) # optional - sage.libs.pari - sage: sorted(N.groundset()) # optional - sage.libs.pari + sage: N = M.relabel({'g':'x'}) # optional - sage.rings.finite_rings + sage: sorted(N.groundset()) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd', 'e', 'f', 'x'] """ @@ -572,10 +572,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari - sage: M # optional - sage.libs.pari + sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings Matroid of rank 3 on 7 elements with 28 bases - sage: M.bases_count() # optional - sage.libs.pari + sage: M.bases_count() # optional - sage.rings.finite_rings 28 """ if self._bcount is None: @@ -594,10 +594,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari - sage: M # optional - sage.libs.pari + sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings Matroid of rank 3 on 7 elements with 28 bases - sage: len(M.bases()) # optional - sage.libs.pari + sage: len(M.bases()) # optional - sage.rings.finite_rings 28 """ cdef long r, n @@ -630,10 +630,10 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.libs.pari - sage: M # optional - sage.libs.pari + sage: M = Matroid(bases=matroids.named_matroids.Fano().bases()) # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings Matroid of rank 3 on 7 elements with 28 bases - sage: len(M.nonbases()) # optional - sage.libs.pari + sage: len(M.nonbases()) # optional - sage.rings.finite_rings 7 """ if self._nonbases is not None: @@ -674,9 +674,9 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: M._bases_invariant() == N._bases_invariant() # optional - sage.libs.pari + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: M._bases_invariant() == N._bases_invariant() # optional - sage.rings.finite_rings True """ if self._bases_invariant_var is not None: @@ -733,9 +733,9 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: N = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari - sage: M._bases_invariant2() == N._bases_invariant2() # optional - sage.libs.pari + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: N = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.rings.finite_rings + sage: M._bases_invariant2() == N._bases_invariant2() # optional - sage.rings.finite_rings False """ if self._bases_invariant2_var is None: @@ -844,8 +844,8 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.N1()) # optional - sage.libs.pari - sage: sorted([e for e in M.groundset() if M.is_distinguished(e)]) # optional - sage.libs.pari + sage: M = BasisMatroid(matroids.named_matroids.N1()) # optional - sage.rings.finite_rings + sage: sorted([e for e in M.groundset() if M.is_distinguished(e)]) # optional - sage.rings.finite_rings ['c', 'g', 'h', 'j'] """ @@ -886,12 +886,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari - sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: m = {e:e for e in M.groundset()} # optional - sage.libs.pari - sage: M._is_relaxation(N, m) # optional - sage.libs.pari + sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.rings.finite_rings + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: m = {e:e for e in M.groundset()} # optional - sage.rings.finite_rings + sage: M._is_relaxation(N, m) # optional - sage.rings.finite_rings True - sage: N._is_relaxation(M, m) # optional - sage.libs.pari + sage: N._is_relaxation(M, m) # optional - sage.rings.finite_rings False """ cdef long i, j @@ -941,12 +941,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari - sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: m = {e:e for e in M.groundset()} # optional - sage.libs.pari - sage: M._is_relaxation(N, m) # optional - sage.libs.pari + sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.rings.finite_rings + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: m = {e:e for e in M.groundset()} # optional - sage.rings.finite_rings + sage: M._is_relaxation(N, m) # optional - sage.rings.finite_rings True - sage: M._is_isomorphism(N, m) # optional - sage.libs.pari + sage: M._is_isomorphism(N, m) # optional - sage.rings.finite_rings False """ if not isinstance(other, BasisMatroid): @@ -979,9 +979,9 @@ cdef class BasisMatroid(BasisExchangeMatroid): sage: morphism = M._isomorphism(N) sage: M._is_isomorphism(N, morphism) True - sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari - sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: M._isomorphism(N) is not None # optional - sage.libs.pari + sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.rings.finite_rings + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: M._isomorphism(N) is not None # optional - sage.rings.finite_rings False """ if not isinstance(other, BasisMatroid): @@ -1055,11 +1055,11 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari - sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: M._is_isomorphic(N) # optional - sage.libs.pari + sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.rings.finite_rings + sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: M._is_isomorphic(N) # optional - sage.rings.finite_rings False - sage: M._is_isomorphic(N, certificate=True) # optional - sage.libs.pari + sage: M._is_isomorphic(N, certificate=True) # optional - sage.rings.finite_rings (False, None) """ if certificate: @@ -1127,12 +1127,12 @@ cdef class BasisMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: N = BasisMatroid(matroids.named_matroids.Fano().dual()).dual() # optional - sage.libs.pari - sage: O = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.libs.pari - sage: hash(M) == hash(N) # optional - sage.libs.pari + sage: M = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: N = BasisMatroid(matroids.named_matroids.Fano().dual()).dual() # optional - sage.rings.finite_rings + sage: O = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.rings.finite_rings + sage: hash(M) == hash(N) # optional - sage.rings.finite_rings True - sage: hash(M) == hash(O) # optional - sage.libs.pari + sage: hash(M) == hash(O) # optional - sage.rings.finite_rings False """ return hash((self.groundset(), self.bases_count(), self._weak_invariant())) diff --git a/src/sage/matroids/catalog.py b/src/sage/matroids/catalog.py index c82ae02d063..01b1ad09a1f 100644 --- a/src/sage/matroids/catalog.py +++ b/src/sage/matroids/catalog.py @@ -67,13 +67,13 @@ def Q6(): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Q6(); M # optional - sage.libs.pari + sage: M = matroids.named_matroids.Q6(); M # optional - sage.rings.finite_rings Q6: Quaternary matroid of rank 3 on 6 elements - sage: setprint(M.hyperplanes()) # optional - sage.libs.pari + sage: setprint(M.hyperplanes()) # optional - sage.rings.finite_rings [{'a', 'b', 'd'}, {'a', 'c'}, {'a', 'e'}, {'a', 'f'}, {'b', 'c', 'e'}, {'b', 'f'}, {'c', 'd'}, {'c', 'f'}, {'d', 'e'}, {'d', 'f'}, {'e', 'f'}] - sage: M.nonspanning_circuits() == M.noncospanning_cocircuits() # optional - sage.libs.pari + sage: M.nonspanning_circuits() == M.noncospanning_cocircuits() # optional - sage.rings.finite_rings False """ F = GF(4, 'x') @@ -106,10 +106,10 @@ def P6(): {2: {{'a', 'b', 'c'}}, 3: {{'a', 'b', 'c', 'd', 'e', 'f'}}} sage: len(set(M.nonspanning_circuits()).difference(M.nonbases())) == 0 True - sage: Matroid(matrix=random_matrix(GF(4, 'a'), ncols=5, # optional - sage.libs.pari + sage: Matroid(matrix=random_matrix(GF(4, 'a'), ncols=5, # optional - sage.rings.finite_rings ....: nrows=5)).has_minor(M) False - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True """ E = 'abcdef' @@ -134,13 +134,13 @@ def R6(): EXAMPLES:: - sage: M = matroids.named_matroids.R6(); M # optional - sage.libs.pari + sage: M = matroids.named_matroids.R6(); M # optional - sage.rings.finite_rings R6: Ternary matroid of rank 3 on 6 elements, type 2+ - sage: M.equals(M.dual()) # optional - sage.libs.pari + sage: M.equals(M.dual()) # optional - sage.rings.finite_rings True - sage: M.is_connected() # optional - sage.libs.pari + sage: M.is_connected() # optional - sage.rings.finite_rings True - sage: M.is_3connected() # optional - sage.libs.pari + sage: M.is_3connected() # optional - sage.rings.finite_rings False """ A = Matrix(GF(3), [ @@ -167,12 +167,12 @@ def Fano(): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano(); M # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano(); M # optional - sage.rings.finite_rings Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) - sage: setprint(sorted(M.nonspanning_circuits())) # optional - sage.libs.pari + sage: setprint(sorted(M.nonspanning_circuits())) # optional - sage.rings.finite_rings [{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}, {'d', 'e', 'f'}] - sage: M.delete(M.groundset_list()[randrange(0, # optional - sage.libs.pari + sage: M.delete(M.groundset_list()[randrange(0, # optional - sage.rings.finite_rings ....: 7)]).is_isomorphic(matroids.CompleteGraphic(4)) True """ @@ -198,14 +198,14 @@ def NonFano(): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.NonFano(); M # optional - sage.libs.pari + sage: M = matroids.named_matroids.NonFano(); M # optional - sage.rings.finite_rings NonFano: Ternary matroid of rank 3 on 7 elements, type 0- - sage: setprint(M.nonbases()) # optional - sage.libs.pari + sage: setprint(M.nonbases()) # optional - sage.rings.finite_rings [{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}] - sage: M.delete('f').is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.libs.pari + sage: M.delete('f').is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.rings.finite_rings True - sage: M.delete('g').is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.libs.pari + sage: M.delete('g').is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.rings.finite_rings False """ A = Matrix(GF(3), [ @@ -230,11 +230,11 @@ def O7(): EXAMPLES:: - sage: M = matroids.named_matroids.O7(); M # optional - sage.libs.pari + sage: M = matroids.named_matroids.O7(); M # optional - sage.rings.finite_rings O7: Ternary matroid of rank 3 on 7 elements, type 0+ - sage: M.delete('e').is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.libs.pari + sage: M.delete('e').is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.rings.finite_rings True - sage: M.tutte_polynomial() # optional - sage.libs.pari + sage: M.tutte_polynomial() # optional - sage.rings.finite_rings y^4 + x^3 + x*y^2 + 3*y^3 + 4*x^2 + 5*x*y + 5*y^2 + 4*x + 4*y """ A = Matrix(GF(3), [ @@ -259,13 +259,13 @@ def P7(): EXAMPLES:: - sage: M = matroids.named_matroids.P7(); M # optional - sage.libs.pari + sage: M = matroids.named_matroids.P7(); M # optional - sage.rings.finite_rings P7: Ternary matroid of rank 3 on 7 elements, type 1+ - sage: M.f_vector() # optional - sage.libs.pari + sage: M.f_vector() # optional - sage.rings.finite_rings [1, 7, 11, 1] - sage: M.has_minor(matroids.CompleteGraphic(4)) # optional - sage.libs.pari + sage: M.has_minor(matroids.CompleteGraphic(4)) # optional - sage.rings.finite_rings False - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True """ A = Matrix(GF(3), [ @@ -332,14 +332,14 @@ def R8(): EXAMPLES:: - sage: M = matroids.named_matroids.R8(); M # optional - sage.libs.pari + sage: M = matroids.named_matroids.R8(); M # optional - sage.rings.finite_rings R8: Ternary matroid of rank 4 on 8 elements, type 0+ - sage: M.contract(M.groundset_list()[randrange(0, # optional - sage.libs.pari + sage: M.contract(M.groundset_list()[randrange(0, # optional - sage.rings.finite_rings ....: 8)]).is_isomorphic(matroids.named_matroids.NonFano()) True - sage: M.equals(M.dual()) # optional - sage.libs.pari + sage: M.equals(M.dual()) # optional - sage.rings.finite_rings True - sage: M.has_minor(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M.has_minor(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings False """ A = Matrix(GF(3), [ @@ -477,21 +477,21 @@ def S8(): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.S8(); M # optional - sage.libs.pari + sage: M = matroids.named_matroids.S8(); M # optional - sage.rings.finite_rings S8: Binary matroid of rank 4 on 8 elements, type (2, 0) - sage: M.contract('d').is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M.contract('d').is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings True - sage: M.delete('d').is_isomorphic( # optional - sage.libs.pari + sage: M.delete('d').is_isomorphic( # optional - sage.rings.finite_rings ....: matroids.named_matroids.Fano().dual()) False - sage: M.is_graphic() # optional - sage.libs.pari + sage: M.is_graphic() # optional - sage.rings.finite_rings False - sage: D = get_nonisomorphic_matroids( # optional - sage.libs.pari + sage: D = get_nonisomorphic_matroids( # optional - sage.rings.finite_rings ....: list(matroids.named_matroids.Fano().linear_coextensions( ....: cosimple=True))) - sage: len(D) # optional - sage.libs.pari + sage: len(D) # optional - sage.rings.finite_rings 2 - sage: [N.is_isomorphic(M) for N in D] # optional - sage.libs.pari + sage: [N.is_isomorphic(M) for N in D] # optional - sage.rings.finite_rings [...True...] """ @@ -553,13 +553,13 @@ def T8(): EXAMPLES:: - sage: M = matroids.named_matroids.T8(); M # optional - sage.libs.pari + sage: M = matroids.named_matroids.T8(); M # optional - sage.rings.finite_rings T8: Ternary matroid of rank 4 on 8 elements, type 0- - sage: M.truncation().is_isomorphic(matroids.Uniform(3, 8)) # optional - sage.libs.pari + sage: M.truncation().is_isomorphic(matroids.Uniform(3, 8)) # optional - sage.rings.finite_rings True - sage: M.contract('e').is_isomorphic(matroids.named_matroids.P7()) # optional - sage.libs.pari + sage: M.contract('e').is_isomorphic(matroids.named_matroids.P7()) # optional - sage.rings.finite_rings True - sage: M.has_minor(matroids.Uniform(3, 8)) # optional - sage.libs.pari + sage: M.has_minor(matroids.Uniform(3, 8)) # optional - sage.rings.finite_rings False """ @@ -585,15 +585,15 @@ def J(): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.J(); M # optional - sage.libs.pari + sage: M = matroids.named_matroids.J(); M # optional - sage.rings.finite_rings J: Ternary matroid of rank 4 on 8 elements, type 0- - sage: setprint(M.truncation().nonbases()) # optional - sage.libs.pari + sage: setprint(M.truncation().nonbases()) # optional - sage.rings.finite_rings [{'a', 'b', 'f'}, {'a', 'c', 'g'}, {'a', 'd', 'h'}] - sage: M.is_isomorphic(M.dual()) # optional - sage.libs.pari + sage: M.is_isomorphic(M.dual()) # optional - sage.rings.finite_rings True - sage: M.has_minor(matroids.CompleteGraphic(4)) # optional - sage.libs.pari + sage: M.has_minor(matroids.CompleteGraphic(4)) # optional - sage.rings.finite_rings False - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True """ A = Matrix(GF(3), [ @@ -619,14 +619,14 @@ def P8(): EXAMPLES:: - sage: M = matroids.named_matroids.P8(); M # optional - sage.libs.pari + sage: M = matroids.named_matroids.P8(); M # optional - sage.rings.finite_rings P8: Ternary matroid of rank 4 on 8 elements, type 2+ - sage: M.is_isomorphic(M.dual()) # optional - sage.libs.pari + sage: M.is_isomorphic(M.dual()) # optional - sage.rings.finite_rings True - sage: Matroid(matrix=random_matrix(GF(4, 'a'), ncols=5, # optional - sage.libs.pari + sage: Matroid(matrix=random_matrix(GF(4, 'a'), ncols=5, # optional - sage.rings.finite_rings ....: nrows=5)).has_minor(M) False - sage: M.bicycle_dimension() # optional - sage.libs.pari + sage: M.bicycle_dimension() # optional - sage.rings.finite_rings 2 """ @@ -719,11 +719,11 @@ def TernaryDowling3(): EXAMPLES:: - sage: M = matroids.named_matroids.TernaryDowling3(); M # optional - sage.libs.pari + sage: M = matroids.named_matroids.TernaryDowling3(); M # optional - sage.rings.finite_rings Q3(GF(3)x): Ternary matroid of rank 3 on 9 elements, type 0- - sage: len(list(M.linear_subclasses())) # optional - sage.libs.pari + sage: len(list(M.linear_subclasses())) # optional - sage.rings.finite_rings 72 - sage: M.fundamental_cycle('abc', 'd') # optional - sage.libs.pari + sage: M.fundamental_cycle('abc', 'd') # optional - sage.rings.finite_rings {'a': 2, 'b': 1, 'd': 1} """ @@ -853,17 +853,17 @@ def Whirl(n): EXAMPLES:: - sage: M = matroids.Whirl(5); M # optional - sage.libs.pari + sage: M = matroids.Whirl(5); M # optional - sage.rings.finite_rings Whirl(5): Ternary matroid of rank 5 on 10 elements, type 0- - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True - sage: M.tutte_polynomial() # optional - sage.libs.pari + sage: M.tutte_polynomial() # optional - sage.rings.finite_rings x^5 + y^5 + 5*x^4 + 5*x^3*y + 5*x^2*y^2 + 5*x*y^3 + 5*y^4 + 10*x^3 + 15*x^2*y + 15*x*y^2 + 10*y^3 + 10*x^2 + 15*x*y + 10*y^2 + 5*x + 5*y - sage: M.is_isomorphic(matroids.Wheel(5)) # optional - sage.libs.pari + sage: M.is_isomorphic(matroids.Wheel(5)) # optional - sage.rings.finite_rings False - sage: M = matroids.Whirl(3) # optional - sage.libs.pari - sage: M.is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.libs.pari + sage: M = matroids.Whirl(3) # optional - sage.rings.finite_rings + sage: M.is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.rings.finite_rings False .. TODO:: @@ -960,12 +960,12 @@ def PG(n, q, x=None): EXAMPLES:: - sage: M = matroids.PG(2, 2) # optional - sage.libs.pari - sage: M.is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M = matroids.PG(2, 2) # optional - sage.rings.finite_rings + sage: M.is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings True - sage: matroids.PG(5, 4, 'z').size() == (4^6 - 1) / (4 - 1) # optional - sage.libs.pari + sage: matroids.PG(5, 4, 'z').size() == (4^6 - 1) / (4 - 1) # optional - sage.rings.finite_rings True - sage: M = matroids.PG(4, 7); M # optional - sage.libs.pari + sage: M = matroids.PG(4, 7); M # optional - sage.rings.finite_rings PG(4, 7): Linear matroid of rank 5 on 2801 elements represented over the Finite Field of size 7 """ @@ -1003,13 +1003,13 @@ def AG(n, q, x=None): EXAMPLES:: - sage: M = matroids.AG(2, 3) \ 8 # optional - sage.libs.pari - sage: M.is_isomorphic(matroids.named_matroids.AG23minus()) # optional - sage.libs.pari + sage: M = matroids.AG(2, 3) \ 8 # optional - sage.rings.finite_rings + sage: M.is_isomorphic(matroids.named_matroids.AG23minus()) # optional - sage.rings.finite_rings True - sage: matroids.AG(5, 4, 'z').size() == ((4 ^ 6 - 1) / (4 - 1) - # optional - sage.libs.pari + sage: matroids.AG(5, 4, 'z').size() == ((4 ^ 6 - 1) / (4 - 1) - # optional - sage.rings.finite_rings ....: (4 ^ 5 - 1)/(4 - 1)) True - sage: M = matroids.AG(4, 2); M # optional - sage.libs.pari + sage: M = matroids.AG(4, 2); M # optional - sage.rings.finite_rings AG(4, 2): Binary matroid of rank 5 on 16 elements, type (5, 0) """ @@ -1243,10 +1243,10 @@ def Q10(): EXAMPLES:: - sage: M = matroids.named_matroids.Q10() # optional - sage.libs.pari - sage: M.is_isomorphic(M.dual()) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Q10() # optional - sage.rings.finite_rings + sage: M.is_isomorphic(M.dual()) # optional - sage.rings.finite_rings True - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True Check the splitter property. By Seymour's Theorem, and using self-duality, @@ -1255,8 +1255,8 @@ def Q10(): are quaternary are `U_{2, 5}, U_{3, 5}, F_7, F_7^*`. As it happens, it suffices to check for `U_{2, 5}`: - sage: S = matroids.named_matroids.Q10().linear_extensions(simple=True) # optional - sage.libs.pari - sage: [M for M in S if not M.has_line_minor(5)] # long time # optional - sage.libs.pari + sage: S = matroids.named_matroids.Q10().linear_extensions(simple=True) # optional - sage.rings.finite_rings + sage: [M for M in S if not M.has_line_minor(5)] # long time # optional - sage.rings.finite_rings [] """ F = GF(4, 'x') @@ -1281,10 +1281,10 @@ def N1(): EXAMPLES:: - sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari - sage: M.is_field_isomorphic(M.dual()) # optional - sage.libs.pari + sage: M = matroids.named_matroids.N1() # optional - sage.rings.finite_rings + sage: M.is_field_isomorphic(M.dual()) # optional - sage.rings.finite_rings True - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True """ @@ -1308,10 +1308,10 @@ def N2(): EXAMPLES:: - sage: M = matroids.named_matroids.N2() # optional - sage.libs.pari - sage: M.is_field_isomorphic(M.dual()) # optional - sage.libs.pari + sage: M = matroids.named_matroids.N2() # optional - sage.rings.finite_rings + sage: M.is_field_isomorphic(M.dual()) # optional - sage.rings.finite_rings True - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True """ @@ -1422,11 +1422,11 @@ def ExtendedBinaryGolayCode(): EXAMPLES:: - sage: M = matroids.named_matroids.ExtendedBinaryGolayCode() # optional - sage.libs.pari - sage: C = LinearCode(M.representation()) # optional - sage.libs.pari - sage: C.is_permutation_equivalent(codes.GolayCode(GF(2))) # long time # optional - sage.libs.pari + sage: M = matroids.named_matroids.ExtendedBinaryGolayCode() # optional - sage.rings.finite_rings + sage: C = LinearCode(M.representation()) # optional - sage.rings.finite_rings + sage: C.is_permutation_equivalent(codes.GolayCode(GF(2))) # long time # optional - sage.rings.finite_rings True - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True """ A = Matrix(GF(2), [ @@ -1457,11 +1457,11 @@ def ExtendedTernaryGolayCode(): EXAMPLES:: - sage: M = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari - sage: C = LinearCode(M.representation()) # optional - sage.libs.pari - sage: C.is_permutation_equivalent(codes.GolayCode(GF(3))) # long time # optional - sage.libs.pari + sage: M = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.rings.finite_rings + sage: C = LinearCode(M.representation()) # optional - sage.rings.finite_rings + sage: C.is_permutation_equivalent(codes.GolayCode(GF(3))) # long time # optional - sage.rings.finite_rings True - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True """ A = Matrix(GF(3), [ @@ -1509,11 +1509,11 @@ def NotP8(): EXAMPLES:: - sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari - sage: N = matroids.named_matroids.NotP8() # optional - sage.libs.pari - sage: M.is_isomorphic(N) # optional - sage.libs.pari + sage: M = matroids.named_matroids.P8() # optional - sage.rings.finite_rings + sage: N = matroids.named_matroids.NotP8() # optional - sage.rings.finite_rings + sage: M.is_isomorphic(N) # optional - sage.rings.finite_rings False - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True """ A = Matrix(GF(3), [ @@ -1538,10 +1538,10 @@ def D16(): # A.K.A. the Carolyn Chun Matroid EXAMPLES:: - sage: M = matroids.named_matroids.D16() # optional - sage.libs.pari - sage: M # optional - sage.libs.pari + sage: M = matroids.named_matroids.D16() # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings D16: Binary matroid of rank 8 on 16 elements, type (0, 0) - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True """ @@ -1569,10 +1569,10 @@ def Terrahawk(): # A.K.A. the Dillon Mayhew Matroid EXAMPLES:: - sage: M = matroids.named_matroids.Terrahawk() # optional - sage.libs.pari - sage: M # optional - sage.libs.pari + sage: M = matroids.named_matroids.Terrahawk() # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings Terrahawk: Binary matroid of rank 8 on 16 elements, type (0, 4) - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True """ @@ -1653,10 +1653,10 @@ def T12(): EXAMPLES:: - sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari - sage: M # optional - sage.libs.pari + sage: M = matroids.named_matroids.T12() # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings T12: Binary matroid of rank 6 on 12 elements, type (2, None) - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True """ A = Matrix(GF(2), [ @@ -1681,10 +1681,10 @@ def P9(): EXAMPLES:: - sage: M = matroids.named_matroids.P9() # optional - sage.libs.pari - sage: M # optional - sage.libs.pari + sage: M = matroids.named_matroids.P9() # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings P9: Binary matroid of rank 4 on 9 elements, type (1, 1) - sage: M.is_valid() # optional - sage.libs.pari + sage: M.is_valid() # optional - sage.rings.finite_rings True """ A = Matrix(GF(2), [ diff --git a/src/sage/matroids/circuit_closures_matroid.pyx b/src/sage/matroids/circuit_closures_matroid.pyx index 351f62c94c7..ebbea7c26cd 100644 --- a/src/sage/matroids/circuit_closures_matroid.pyx +++ b/src/sage/matroids/circuit_closures_matroid.pyx @@ -50,8 +50,8 @@ AUTHORS: TESTS:: sage: from sage.matroids.advanced import * - sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: TestSuite(M).run() # optional - sage.libs.pari + sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: TestSuite(M).run() # optional - sage.rings.finite_rings Methods ======= @@ -117,8 +117,8 @@ cdef class CircuitClosuresMatroid(Matroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: M # optional - sage.libs.pari + sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings Matroid of rank 3 on 7 elements with circuit-closures {2: {{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}, @@ -127,7 +127,7 @@ cdef class CircuitClosuresMatroid(Matroid): ....: circuit_closures={3: ['edfg', 'acdg', 'bcfg', 'cefh', ....: 'afgh', 'abce', 'abdf', 'begh', 'bcdh', 'adeh'], ....: 4: ['abcdefgh']}) - sage: M.equals(matroids.named_matroids.P8()) # optional - sage.libs.pari + sage: M.equals(matroids.named_matroids.P8()) # optional - sage.rings.finite_rings True """ @@ -140,8 +140,8 @@ cdef class CircuitClosuresMatroid(Matroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.libs.pari - sage: M # optional - sage.libs.pari + sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings Matroid of rank 3 on 7 elements with circuit-closures {2: {{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}, @@ -152,7 +152,7 @@ cdef class CircuitClosuresMatroid(Matroid): ....: circuit_closures={3: ['edfg', 'acdg', 'bcfg', 'cefh', ....: 'afgh', 'abce', 'abdf', 'begh', 'bcdh', 'adeh'], ....: 4: ['abcdefgh']}) - sage: M.equals(matroids.named_matroids.P8()) # optional - sage.libs.pari + sage: M.equals(matroids.named_matroids.P8()) # optional - sage.rings.finite_rings True """ if M is not None: diff --git a/src/sage/matroids/constructor.py b/src/sage/matroids/constructor.py index 6ab2f4917ef..8d3abb1df0d 100644 --- a/src/sage/matroids/constructor.py +++ b/src/sage/matroids/constructor.py @@ -53,8 +53,8 @@ A number of special matroids are collected under a ``named_matroids`` submenu. To see which, type ``matroids.named_matroids.`` as above:: - sage: F7 = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: len(F7.nonspanning_circuits()) # optional - sage.libs.pari + sage: F7 = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: len(F7.nonspanning_circuits()) # optional - sage.rings.finite_rings 7 Constructing matroids @@ -68,11 +68,11 @@ EXAMPLES:: - sage: A = Matrix(GF(2), [[1, 0, 0, 0, 1, 1, 1], # optional - sage.libs.pari + sage: A = Matrix(GF(2), [[1, 0, 0, 0, 1, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 0, 1, 0, 1, 1], ....: [0, 0, 1, 1, 1, 0, 1]]) - sage: M = Matroid(A) # optional - sage.libs.pari - sage: M.is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.libs.pari + sage: M = Matroid(A) # optional - sage.rings.finite_rings + sage: M.is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings True sage: M = Matroid(graphs.PetersenGraph()) diff --git a/src/sage/matroids/dual_matroid.py b/src/sage/matroids/dual_matroid.py index 73ad305e1d6..87dfdda88d0 100644 --- a/src/sage/matroids/dual_matroid.py +++ b/src/sage/matroids/dual_matroid.py @@ -10,13 +10,13 @@ EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: N = M.dual() # optional - sage.libs.pari - sage: M.is_basis('abc') # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: N = M.dual() # optional - sage.rings.finite_rings + sage: M.is_basis('abc') # optional - sage.rings.finite_rings True - sage: N.is_basis('defg') # optional - sage.libs.pari + sage: N.is_basis('defg') # optional - sage.rings.finite_rings True - sage: M.dual().dual() == M # optional - sage.libs.pari + sage: M.dual().dual() == M # optional - sage.rings.finite_rings True Implementation @@ -455,17 +455,17 @@ def __eq__(self, other): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M2 = CircuitClosuresMatroid(M1.dual()) # optional - sage.libs.pari - sage: M3 = CircuitClosuresMatroid(M1).dual() # optional - sage.libs.pari + sage: M1 = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M2 = CircuitClosuresMatroid(M1.dual()) # optional - sage.rings.finite_rings + sage: M3 = CircuitClosuresMatroid(M1).dual() # optional - sage.rings.finite_rings sage: M4 = CircuitClosuresMatroid(groundset='abcdefg', ....: circuit_closures={3: ['abcdefg'], 2: ['beg', 'cdb', 'cfg', ....: 'ace', 'fed', 'gad', 'fab']}).dual() - sage: M1.dual() == M2 # indirect doctest # optional - sage.libs.pari + sage: M1.dual() == M2 # indirect doctest # optional - sage.rings.finite_rings False - sage: M2 == M3 # optional - sage.libs.pari + sage: M2 == M3 # optional - sage.rings.finite_rings False - sage: M3 == M4 # optional - sage.libs.pari + sage: M3 == M4 # optional - sage.rings.finite_rings True """ if not isinstance(other, DualMatroid): @@ -487,17 +487,17 @@ def __ne__(self, other): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M2 = CircuitClosuresMatroid(M1.dual()) # optional - sage.libs.pari - sage: M3 = CircuitClosuresMatroid(M1).dual() # optional - sage.libs.pari + sage: M1 = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M2 = CircuitClosuresMatroid(M1.dual()) # optional - sage.rings.finite_rings + sage: M3 = CircuitClosuresMatroid(M1).dual() # optional - sage.rings.finite_rings sage: M4 = CircuitClosuresMatroid(groundset='abcdefg', ....: circuit_closures={3: ['abcdefg'], 2: ['beg', 'cdb', 'cfg', ....: 'ace', 'fed', 'gad', 'fab']}).dual() - sage: M1.dual() != M2 # indirect doctest # optional - sage.libs.pari + sage: M1.dual() != M2 # indirect doctest # optional - sage.rings.finite_rings True - sage: M2 != M3 # optional - sage.libs.pari + sage: M2 != M3 # optional - sage.rings.finite_rings True - sage: M3 != M4 # optional - sage.libs.pari + sage: M3 != M4 # optional - sage.rings.finite_rings False """ return not self == other diff --git a/src/sage/matroids/extension.pyx b/src/sage/matroids/extension.pyx index 608d9363496..dae24e2be8b 100644 --- a/src/sage/matroids/extension.pyx +++ b/src/sage/matroids/extension.pyx @@ -59,7 +59,7 @@ cdef class CutNode: EXAMPLES:: - sage: len(list(matroids.named_matroids.Fano().linear_subclasses())) # indirect doctest # optional - sage.libs.pari + sage: len(list(matroids.named_matroids.Fano().linear_subclasses())) # indirect doctest # optional - sage.rings.finite_rings 16 """ cdef CutNode node diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index cd7416c986e..100f5c3e74f 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -21,25 +21,25 @@ See also :mod:`sage.matroids.advanced`. In both cases, it is possible to provide a reduced matrix `B`, to create the matroid induced by `A = [ I B ]`:: sage: from sage.matroids.advanced import * - sage: A = Matrix(GF(2), [[1, 0, 0, 1, 1, 0, 1], [0, 1, 0, 1, 0, 1, 1], + sage: A = Matrix(GF(2), [[1, 0, 0, 1, 1, 0, 1], [0, 1, 0, 1, 0, 1, 1], # optional - sage.rings.finite_rings ....: [0, 0, 1, 0, 1, 1, 1]]) - sage: B = Matrix(GF(2), [[1, 1, 0, 1], [1, 0, 1, 1], [0, 1, 1, 1]]) - sage: M1 = Matroid(A) - sage: M2 = LinearMatroid(A) - sage: M3 = BinaryMatroid(A) - sage: M4 = Matroid(reduced_matrix=B) - sage: M5 = LinearMatroid(reduced_matrix=B) - sage: isinstance(M1, BinaryMatroid) + sage: B = Matrix(GF(2), [[1, 1, 0, 1], [1, 0, 1, 1], [0, 1, 1, 1]]) # optional - sage.rings.finite_rings + sage: M1 = Matroid(A) # optional - sage.rings.finite_rings + sage: M2 = LinearMatroid(A) # optional - sage.rings.finite_rings + sage: M3 = BinaryMatroid(A) # optional - sage.rings.finite_rings + sage: M4 = Matroid(reduced_matrix=B) # optional - sage.rings.finite_rings + sage: M5 = LinearMatroid(reduced_matrix=B) # optional - sage.rings.finite_rings + sage: isinstance(M1, BinaryMatroid) # optional - sage.rings.finite_rings True - sage: M1.equals(M2) + sage: M1.equals(M2) # optional - sage.rings.finite_rings True - sage: M1.equals(M3) + sage: M1.equals(M3) # optional - sage.rings.finite_rings True - sage: M1 == M4 + sage: M1 == M4 # optional - sage.rings.finite_rings True - sage: M1.is_field_isomorphic(M5) + sage: M1.is_field_isomorphic(M5) # optional - sage.rings.finite_rings True - sage: M2 == M3 # comparing LinearMatroid and BinaryMatroid always yields False + sage: M2 == M3 # comparing LinearMatroid and BinaryMatroid always yields False # optional - sage.rings.finite_rings False Class methods @@ -241,22 +241,22 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: A = Matrix(GF(3), 2, 4, [[1, 0, 1, 1], [0, 1, 1, 2]]) - sage: M = LinearMatroid(A) - sage: M + sage: A = Matrix(GF(3), 2, 4, [[1, 0, 1, 1], [0, 1, 1, 2]]) # optional - sage.rings.finite_rings + sage: M = LinearMatroid(A) # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings Linear matroid of rank 2 on 4 elements represented over the Finite Field of size 3 - sage: sorted(M.groundset()) + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings [0, 1, 2, 3] - sage: Matrix(M) + sage: Matrix(M) # optional - sage.rings.finite_rings [1 0 1 1] [0 1 1 2] - sage: M = LinearMatroid(A, 'abcd') - sage: sorted(M.groundset()) + sage: M = LinearMatroid(A, 'abcd') # optional - sage.rings.finite_rings + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd'] - sage: B = Matrix(GF(3), 2, 2, [[1, 1], [1, 2]]) - sage: N = LinearMatroid(reduced_matrix=B, groundset='abcd') - sage: M == N + sage: B = Matrix(GF(3), 2, 2, [[1, 1], [1, 2]]) # optional - sage.rings.finite_rings + sage: N = LinearMatroid(reduced_matrix=B, groundset='abcd') # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings True """ def __init__(self, matrix=None, groundset=None, reduced_matrix=None, ring=None, keep_initial_representation=True): @@ -355,11 +355,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = LinearMatroid(matrix=Matrix(GF(5), [[1, 1, 0, 1, 1], + sage: M = LinearMatroid(matrix=Matrix(GF(5), [[1, 1, 0, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 1, 2, 3]])) - sage: A = Matrix(M) - sage: M._forget() - sage: A == Matrix(M) + sage: A = Matrix(M) # optional - sage.rings.finite_rings + sage: M._forget() # optional - sage.rings.finite_rings + sage: A == Matrix(M) # optional - sage.rings.finite_rings False """ self._representation = None @@ -370,9 +370,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1], + sage: M = Matroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 1, 2, 3]])) - sage: M.base_ring() + sage: M.base_ring() # optional - sage.rings.finite_rings Finite Field of size 5 """ return self._A.base_ring() @@ -384,9 +384,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1], + sage: M = Matroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 1, 2, 3]])) - sage: M.characteristic() + sage: M.characteristic() # optional - sage.rings.finite_rings 5 """ return characteristic(self._A) @@ -442,13 +442,13 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(matrix=Matrix(GF(5), [[1, 1, 0, 1, 1], + sage: M = Matroid(matrix=Matrix(GF(5), [[1, 1, 0, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 1, 2, 3]])) - sage: M._matrix_() + sage: M._matrix_() # optional - sage.rings.finite_rings [1 1 0 1 1] [0 1 1 2 3] - sage: M._forget() - sage: M._matrix_() + sage: M._forget() # optional - sage.rings.finite_rings + sage: M._matrix_() # optional - sage.rings.finite_rings [1 0 4 4 3] [0 1 1 2 3] """ @@ -460,9 +460,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(matrix=Matrix(GF(5), [[1, 1, 0, 1, 1], + sage: M = Matroid(matrix=Matrix(GF(5), [[1, 1, 0, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 1, 2, 3]])) - sage: repr(M) # indirect doctest + sage: repr(M) # indirect doctest # optional - sage.rings.finite_rings 'Linear matroid of rank 2 on 5 elements represented over the Finite Field of size 5' """ @@ -538,44 +538,44 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.representation() + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.representation() # optional - sage.rings.finite_rings [1 0 0 0 1 1 1] [0 1 0 1 0 1 1] [0 0 1 1 1 0 1] - sage: Matrix(M) == M.representation() + sage: Matrix(M) == M.representation() # optional - sage.rings.finite_rings True - sage: M.representation(labels=True) + sage: M.representation(labels=True) # optional - sage.rings.finite_rings ( [1 0 0 0 1 1 1] [0 1 0 1 0 1 1] [0 0 1 1 1 0 1], ['a', 'b', 'c', 'd', 'e', 'f', 'g'] ) - sage: M.representation(B='efg') + sage: M.representation(B='efg') # optional - sage.rings.finite_rings [1 1 0 1 1 0 0] [1 0 1 1 0 1 0] [1 1 1 0 0 0 1] - sage: M.representation(B='efg', order='efgabcd') + sage: M.representation(B='efg', order='efgabcd') # optional - sage.rings.finite_rings [1 0 0 1 1 0 1] [0 1 0 1 0 1 1] [0 0 1 1 1 1 0] - sage: M.representation(B='abc', reduced=True) + sage: M.representation(B='abc', reduced=True) # optional - sage.rings.finite_rings ( [0 1 1 1] [1 0 1 1] [1 1 0 1], ['a', 'b', 'c'], ['d', 'e', 'f', 'g'] ) - sage: M.representation(B='efg', reduced=True, labels=False, + sage: M.representation(B='efg', reduced=True, labels=False, # optional - sage.rings.finite_rings ....: order='gfeabcd') [1 1 1 0] [1 0 1 1] [1 1 0 1] sage: from sage.matroids.advanced import lift_cross_ratios, lift_map, LinearMatroid - sage: R = GF(7) - sage: A = Matrix(R, [[1, 0, 6, 1, 2],[6, 1, 0, 0, 1],[0, 6, 3, 6, 0]]) - sage: M = LinearMatroid(reduced_matrix = A) - sage: M.representation(lift_map=lift_map('sru')) + sage: R = GF(7) # optional - sage.rings.finite_rings + sage: A = Matrix(R, [[1, 0, 6, 1, 2],[6, 1, 0, 0, 1],[0, 6, 3, 6, 0]]) # optional - sage.rings.finite_rings + sage: M = LinearMatroid(reduced_matrix=A) # optional - sage.rings.finite_rings + sage: M.representation(lift_map=lift_map('sru')) # optional - sage.rings.finite_rings [ 1 0 0 1 0 1 1 1] [ 0 1 0 -z + 1 1 0 0 1] [ 0 0 1 0 -z z 1 0] @@ -667,13 +667,13 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: A = M._reduced_representation('efg') - sage: R, C = M._current_rows_cols() - sage: (sorted(R), sorted(C)) + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: A = M._reduced_representation('efg') # optional - sage.rings.finite_rings + sage: R, C = M._current_rows_cols() # optional - sage.rings.finite_rings + sage: (sorted(R), sorted(C)) # optional - sage.rings.finite_rings (['e', 'f', 'g'], ['a', 'b', 'c', 'd']) - sage: R, C = M._current_rows_cols(B='abg') - sage: (sorted(R), sorted(C)) + sage: R, C = M._current_rows_cols(B='abg') # optional - sage.rings.finite_rings + sage: (sorted(R), sorted(C)) # optional - sage.rings.finite_rings (['a', 'b', 'g'], ['c', 'd', 'e', 'f']) """ @@ -712,12 +712,12 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(reduced_matrix=Matrix(GF(7), [[1, 1, 1], + sage: M = Matroid(reduced_matrix=Matrix(GF(7), [[1, 1, 1], # optional - sage.rings.finite_rings ....: [1, 2, 3]])) - sage: M._basic_representation() + sage: M._basic_representation() # optional - sage.rings.finite_rings LeanMatrix instance with 2 rows and 5 columns over Finite Field of size 7 - sage: matrix(M._basic_representation([3, 4])) + sage: matrix(M._basic_representation([3, 4])) # optional - sage.rings.finite_rings [3 6 2 1 0] [5 1 6 0 1] @@ -748,9 +748,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: E = M.groundset_list() - sage: [M.representation_vectors()[e] for e in E] + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: E = M.groundset_list() # optional - sage.rings.finite_rings + sage: [M.representation_vectors()[e] for e in E] # optional - sage.rings.finite_rings [(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 1, 1), (1, 0, 1), (1, 1, 0), (1, 1, 1)] """ @@ -781,12 +781,12 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(reduced_matrix=Matrix(GF(7), [[1, 1, 1], + sage: M = Matroid(reduced_matrix=Matrix(GF(7), [[1, 1, 1], # optional - sage.rings.finite_rings ....: [1, 2, 3]])) - sage: M._reduced_representation() + sage: M._reduced_representation() # optional - sage.rings.finite_rings LeanMatrix instance with 2 rows and 3 columns over Finite Field of size 7 - sage: matrix(M._reduced_representation([3, 4])) + sage: matrix(M._reduced_representation([3, 4])) # optional - sage.rings.finite_rings [2 3 6] [6 5 1] """ @@ -819,10 +819,10 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() \ ['g'] - sage: N = BinaryMatroid(Matrix(matroids.Wheel(3))) - sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} - sage: M._is_field_isomorphism(N, morphism) + sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.rings.finite_rings + sage: N = BinaryMatroid(Matrix(matroids.Wheel(3))) # optional - sage.rings.finite_rings + sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} # optional - sage.rings.finite_rings + sage: M._is_field_isomorphism(N, morphism) # optional - sage.rings.finite_rings True """ # TODO: ensure this is safe for noncommutative rings @@ -907,48 +907,48 @@ cdef class LinearMatroid(BasisExchangeMatroid): yields ``False``, even if the matroids are equal:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() - sage: M1 = LinearMatroid(Matrix(M), groundset=M.groundset_list()) - sage: M2 = Matroid(groundset='abcdefg', + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M1 = LinearMatroid(Matrix(M), groundset=M.groundset_list()) # optional - sage.rings.finite_rings + sage: M2 = Matroid(groundset='abcdefg', # optional - sage.rings.finite_rings ....: reduced_matrix=[[0, 1, 1, 1], ....: [1, 0, 1, 1], ....: [1, 1, 0, 1]], field=GF(2)) - sage: M.equals(M1) + sage: M.equals(M1) # optional - sage.rings.finite_rings True - sage: M.equals(M2) + sage: M.equals(M2) # optional - sage.rings.finite_rings True - sage: M.is_field_equivalent(M1) + sage: M.is_field_equivalent(M1) # optional - sage.rings.finite_rings True - sage: M.is_field_equivalent(M2) + sage: M.is_field_equivalent(M2) # optional - sage.rings.finite_rings True - sage: M == M1 + sage: M == M1 # optional - sage.rings.finite_rings False - sage: M == M2 + sage: M == M2 # optional - sage.rings.finite_rings True ``LinearMatroid`` instances ``M`` and ``N`` satisfy ``M == N`` if the representations are equivalent up to row operations and column scaling:: - sage: M1 = Matroid(groundset='abcd', + sage: M1 = Matroid(groundset='abcd', # optional - sage.rings.finite_rings ....: matrix=Matrix(GF(7), [[1, 0, 1, 1], [0, 1, 1, 2]])) - sage: M2 = Matroid(groundset='abcd', + sage: M2 = Matroid(groundset='abcd', # optional - sage.rings.finite_rings ....: matrix=Matrix(GF(7), [[1, 0, 1, 1], [0, 1, 1, 3]])) - sage: M3 = Matroid(groundset='abcd', + sage: M3 = Matroid(groundset='abcd', # optional - sage.rings.finite_rings ....: matrix=Matrix(GF(7), [[2, 6, 1, 0], [6, 1, 0, 1]])) - sage: M1.equals(M2) + sage: M1.equals(M2) # optional - sage.rings.finite_rings True - sage: M1.equals(M3) + sage: M1.equals(M3) # optional - sage.rings.finite_rings True - sage: M1 == M2 + sage: M1 == M2 # optional - sage.rings.finite_rings False - sage: M1 == M3 + sage: M1 == M3 # optional - sage.rings.finite_rings True - sage: M1.is_field_equivalent(M2) + sage: M1.is_field_equivalent(M2) # optional - sage.rings.finite_rings False - sage: M1.is_field_equivalent(M3) + sage: M1.is_field_equivalent(M3) # optional - sage.rings.finite_rings True - sage: M1.is_field_equivalent(M1) + sage: M1.is_field_equivalent(M1) # optional - sage.rings.finite_rings True """ if self is other: @@ -994,28 +994,28 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: N = matroids.named_matroids.NonFano() - sage: N.is_field_isomorphism(M, {e:e for e in M.groundset()}) + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: N = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: N.is_field_isomorphism(M, {e:e for e in M.groundset()}) # optional - sage.rings.finite_rings False - sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() \ ['g'] - sage: N = LinearMatroid(reduced_matrix=Matrix(GF(2), + sage: from sage.matroids.advanced import * # optional - sage.rings.finite_rings + sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.rings.finite_rings + sage: N = LinearMatroid(reduced_matrix=Matrix(GF(2), # optional - sage.rings.finite_rings ....: [[-1, 0, 1], [1, -1, 0], [0, 1, -1]])) - sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} - sage: M.is_field_isomorphism(N, morphism) + sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} # optional - sage.rings.finite_rings + sage: M.is_field_isomorphism(N, morphism) # optional - sage.rings.finite_rings True - sage: M1 = Matroid(groundset=[0, 1, 2, 3], matrix=Matrix(GF(7), + sage: M1 = Matroid(groundset=[0, 1, 2, 3], matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[1, 0, 1, 1], [0, 1, 1, 2]])) - sage: M2 = Matroid(groundset=[0, 1, 2, 3], matrix=Matrix(GF(7), + sage: M2 = Matroid(groundset=[0, 1, 2, 3], matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[1, 0, 1, 1], [0, 1, 2, 1]])) - sage: mf1 = {0:0, 1:1, 2:2, 3:3} - sage: mf2 = {0:0, 1:1, 2:3, 3:2} - sage: M1.is_field_isomorphism(M2, mf1) + sage: mf1 = {0:0, 1:1, 2:2, 3:3} # optional - sage.rings.finite_rings + sage: mf2 = {0:0, 1:1, 2:3, 3:2} # optional - sage.rings.finite_rings + sage: M1.is_field_isomorphism(M2, mf1) # optional - sage.rings.finite_rings False - sage: M1.is_field_isomorphism(M2, mf2) + sage: M1.is_field_isomorphism(M2, mf2) # optional - sage.rings.finite_rings True """ from copy import copy @@ -1072,20 +1072,20 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M1 = BinaryMatroid(reduced_matrix=Matrix(GF(2), + sage: M1 = BinaryMatroid(reduced_matrix=Matrix(GF(2), # optional - sage.rings.finite_rings ....: [[1, 1, 0, 1], [1, 0, 1, 1], [0, 1, 1, 1]])) - sage: M2 = LinearMatroid(reduced_matrix=Matrix(GF(2), + sage: M2 = LinearMatroid(reduced_matrix=Matrix(GF(2), # optional - sage.rings.finite_rings ....: [[1, 1, 0, 1], [1, 0, 1, 1], [1, 1, 0, 1]])) - sage: M3 = BinaryMatroid(reduced_matrix=Matrix(GF(2), + sage: M3 = BinaryMatroid(reduced_matrix=Matrix(GF(2), # optional - sage.rings.finite_rings ....: [[1, 1, 0, 1], [1, 0, 1, 1], [1, 1, 1, 0]])) - sage: M2._fast_isom_test(M1) is None + sage: M2._fast_isom_test(M1) is None # optional - sage.rings.finite_rings True - sage: M1._fast_isom_test(M2) + sage: M1._fast_isom_test(M2) # optional - sage.rings.finite_rings Traceback (most recent call last): ... AttributeError: 'sage.matroids.linear_matroid.LinearMatroid' object has no attribute '_invariant' - sage: M1._fast_isom_test(M3) is None + sage: M1._fast_isom_test(M3) is None # optional - sage.rings.finite_rings True sage: Matroid(graphs.WheelGraph(6), regular = True)._fast_isom_test( ....: matroids.Wheel(5)) @@ -1132,19 +1132,19 @@ cdef class LinearMatroid(BasisExchangeMatroid): AttributeError: 'sage.matroids.basis_matroid.BasisMatroid' object has no attribute 'base_ring' sage: from sage.matroids.advanced import * - sage: M4 = BinaryMatroid(Matrix(M1)) - sage: M5 = LinearMatroid(reduced_matrix=Matrix(GF(2), [[-1, 0, 1], + sage: M4 = BinaryMatroid(Matrix(M1)) # optional - sage.rings.finite_rings + sage: M5 = LinearMatroid(reduced_matrix=Matrix(GF(2), [[-1, 0, 1], # optional - sage.rings.finite_rings ....: [1, -1, 0], [0, 1, -1]])) - sage: M4.is_field_isomorphic(M5) + sage: M4.is_field_isomorphic(M5) # optional - sage.rings.finite_rings True - sage: M1 = Matroid(groundset=[0, 1, 2, 3], matrix=Matrix(GF(7), + sage: M1 = Matroid(groundset=[0, 1, 2, 3], matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[1, 0, 1, 1], [0, 1, 1, 2]])) - sage: M2 = Matroid(groundset=[0, 1, 2, 3], matrix=Matrix(GF(7), + sage: M2 = Matroid(groundset=[0, 1, 2, 3], matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[1, 0, 1, 1], [0, 1, 2, 1]])) - sage: M1.is_field_isomorphic(M2) + sage: M1.is_field_isomorphic(M2) # optional - sage.rings.finite_rings True - sage: M1.is_field_equivalent(M2) + sage: M1.is_field_equivalent(M2) # optional - sage.rings.finite_rings False """ @@ -1220,19 +1220,19 @@ cdef class LinearMatroid(BasisExchangeMatroid): See docstring for :meth:`LinearMatroid.equals>` for more:: - sage: M1 = Matroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M1 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[1, 0, 1, 1], [0, 1, 1, 2]])) - sage: M2 = Matroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M2 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[1, 0, 1, 1], [0, 1, 1, 3]])) - sage: M3 = Matroid(groundset='abcd', matrix=Matrix(GF(7), + sage: M3 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[2, 6, 1, 0], [6, 1, 0, 1]])) - sage: M1.equals(M2) + sage: M1.equals(M2) # optional - sage.rings.finite_rings True - sage: M1.equals(M3) + sage: M1.equals(M3) # optional - sage.rings.finite_rings True - sage: M1 != M2 # indirect doctest + sage: M1 != M2 # indirect doctest # optional - sage.rings.finite_rings True - sage: M1 == M3 # indirect doctest + sage: M1 == M3 # indirect doctest # optional - sage.rings.finite_rings True """ if op not in [Py_EQ, Py_NE]: @@ -1260,14 +1260,14 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M1 = Matroid(groundset='abcde', matrix=Matrix(GF(7), + sage: M1 = Matroid(groundset='abcde', matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[1, 0, 1, 1, 1], [0, 1, 1, 2, 3]])) - sage: M2 = Matroid(groundset='abcde', matrix=Matrix(GF(7), + sage: M2 = Matroid(groundset='abcde', matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[0, 1, 1, 2, 3], [1, 0, 1, 1, 1]])) - sage: hash(M1) == hash(M2) + sage: hash(M1) == hash(M2) # optional - sage.rings.finite_rings True - sage: M2 = M1.dual() - sage: hash(M1) == hash(M2) + sage: M2 = M1.dual() # optional - sage.rings.finite_rings + sage: hash(M1) == hash(M2) # optional - sage.rings.finite_rings False """ return hash((self.groundset(), self.full_rank(), self._weak_invariant())) @@ -1300,11 +1300,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(groundset='abcdefgh', ring=GF(5), + sage: M = Matroid(groundset='abcdefgh', ring=GF(5), # optional - sage.rings.finite_rings ....: reduced_matrix=[[2, 1, 1, 0], ....: [1, 1, 0, 1], [1, 0, 1, 1], [0, 1, 1, 2]]) - sage: N = M._minor(contractions=set(['a']), deletions=set([])) - sage: N._minor(contractions=set([]), deletions=set(['b', 'c'])) + sage: N = M._minor(contractions=set(['a']), deletions=set([])) # optional - sage.rings.finite_rings + sage: N._minor(contractions=set([]), deletions=set(['b', 'c'])) # optional - sage.rings.finite_rings Linear matroid of rank 3 on 5 elements represented over the Finite Field of size 5 """ @@ -1336,11 +1336,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: A = Matrix(GF(7), [[1, 1, 0, 1], + sage: A = Matrix(GF(7), [[1, 1, 0, 1], # optional - sage.rings.finite_rings ....: [1, 0, 1, 1], ....: [0, 1, 1, 1]]) - sage: B = - A.transpose() - sage: Matroid(reduced_matrix=A).dual() == Matroid( + sage: B = - A.transpose() # optional - sage.rings.finite_rings + sage: Matroid(reduced_matrix=A).dual() == Matroid( # optional - sage.rings.finite_rings ....: reduced_matrix=B, ....: groundset=[3, 4, 5, 6, 0, 1, 2]) True @@ -1377,21 +1377,21 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: M.has_line_minor(4) + sage: M = matroids.named_matroids.N1() # optional - sage.rings.finite_rings + sage: M.has_line_minor(4) # optional - sage.rings.finite_rings True - sage: M.has_line_minor(5) + sage: M.has_line_minor(5) # optional - sage.rings.finite_rings False - sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c']]) + sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c']]) # optional - sage.rings.finite_rings False - sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], + sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], # optional - sage.rings.finite_rings ....: ['a', 'b', 'd' ]]) True - sage: M.has_line_minor(4, certificate=True) + sage: M.has_line_minor(4, certificate=True) # optional - sage.rings.finite_rings (True, frozenset({'a', 'b', 'd'})) - sage: M.has_line_minor(5, certificate=True) + sage: M.has_line_minor(5, certificate=True) # optional - sage.rings.finite_rings (False, None) - sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], + sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], # optional - sage.rings.finite_rings ....: ['a', 'b', 'd' ]], certificate=True) (True, frozenset({'a', 'b', 'd'})) @@ -1429,10 +1429,10 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = matroids.Whirl(3) - sage: matroids.named_matroids.Fano().has_field_minor(M) + sage: M = matroids.Whirl(3) # optional - sage.rings.finite_rings + sage: matroids.named_matroids.Fano().has_field_minor(M) # optional - sage.rings.finite_rings False - sage: matroids.named_matroids.NonFano().has_field_minor(M) + sage: matroids.named_matroids.NonFano().has_field_minor(M) # optional - sage.rings.finite_rings True """ if self is N: @@ -1485,8 +1485,8 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 1, 1], [0, 1, 1, 4]])) - sage: M._exchange_value(1, 3) + sage: M = Matroid(Matrix(GF(7), [[1, 0, 1, 1], [0, 1, 1, 4]])) # optional - sage.rings.finite_rings + sage: M._exchange_value(1, 3) # optional - sage.rings.finite_rings 4 """ return self.__exchange_value(self._idx[e], self._idx[f]) @@ -1518,11 +1518,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 1, 1], [0, 1, 1, 4]])) - sage: v = M.fundamental_cycle([0, 1], 3) - sage: [v[0], v[1], v[3]] + sage: M = Matroid(Matrix(GF(7), [[1, 0, 1, 1], [0, 1, 1, 4]])) # optional - sage.rings.finite_rings + sage: v = M.fundamental_cycle([0, 1], 3) # optional - sage.rings.finite_rings + sage: [v[0], v[1], v[3]] # optional - sage.rings.finite_rings [6, 3, 1] - sage: frozenset(v.keys()) == M.fundamental_circuit([0, 1], 3) + sage: frozenset(v.keys()) == M.fundamental_circuit([0, 1], 3) # optional - sage.rings.finite_rings True """ if e in B or not self._is_basis(B): @@ -1564,11 +1564,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 1, 1], [0, 1, 1, 4]])) - sage: v = M.fundamental_cocycle([0, 1], 0) - sage: [v[0], v[2], v[3]] + sage: M = Matroid(Matrix(GF(7), [[1, 0, 1, 1], [0, 1, 1, 4]])) # optional - sage.rings.finite_rings + sage: v = M.fundamental_cocycle([0, 1], 0) # optional - sage.rings.finite_rings + sage: [v[0], v[2], v[3]] # optional - sage.rings.finite_rings [1, 1, 1] - sage: frozenset(v.keys()) == M.fundamental_cocircuit([0, 1], 0) + sage: frozenset(v.keys()) == M.fundamental_cocircuit([0, 1], 0) # optional - sage.rings.finite_rings True """ if e not in B or not self._is_basis(B): @@ -1593,11 +1593,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1, 1], + sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 0, 1, 2, 4], [0, 0, 1, 3, 2, 5]])) - sage: sorted(M._line_ratios(set([2]))) + sage: sorted(M._line_ratios(set([2]))) # optional - sage.rings.finite_rings [1, 2, 4] - sage: sorted(M._line_ratios([0])) + sage: sorted(M._line_ratios([0])) # optional - sage.rings.finite_rings [1, 5] """ self._move_current_basis(F, set()) @@ -1624,11 +1624,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1, 1], + sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 0, 1, 2, 4], [0, 0, 1, 3, 2, 5]])) - sage: M._line_length([2]) + sage: M._line_length([2]) # optional - sage.rings.finite_rings 5 - sage: M._line_length([0]) + sage: M._line_length([0]) # optional - sage.rings.finite_rings 4 """ return 2 + len(self._line_ratios(F)) @@ -1646,11 +1646,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1, 1], + sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 0, 1, 2, 4], [0, 0, 1, 3, 2, 5]])) - sage: sorted(M._line_cross_ratios(set([2]))) + sage: sorted(M._line_cross_ratios(set([2]))) # optional - sage.rings.finite_rings [2, 4] - sage: sorted(M._line_cross_ratios([0])) + sage: sorted(M._line_cross_ratios([0])) # optional - sage.rings.finite_rings [5] """ cr = set() @@ -1697,10 +1697,10 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1, 1], + sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 0, 1, 2, 4], ....: [0, 0, 1, 3, 2, 5]])) - sage: sorted(M.cross_ratios()) + sage: sorted(M.cross_ratios()) # optional - sage.rings.finite_rings [2, 3, 4, 5, 6] sage: M = Matroid(graphs.CompleteGraph(5), regular = True) sage: M.cross_ratios() @@ -1750,14 +1750,14 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1, 1], + sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 0, 1, 2, 4], ....: [0, 0, 1, 3, 2, 6]])) - sage: M.cross_ratio([0], 1, 2, 3, 5) + sage: M.cross_ratio([0], 1, 2, 3, 5) # optional - sage.rings.finite_rings 4 - sage: M = Matroid(ring=GF(7), matrix=[[1, 0, 1, 1], [0, 1, 1, 1]]) - sage: M.cross_ratio(set(), 0, 1, 2, 3) + sage: M = Matroid(ring=GF(7), matrix=[[1, 0, 1, 1], [0, 1, 1, 1]]) # optional - sage.rings.finite_rings + sage: M.cross_ratio(set(), 0, 1, 2, 3) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: points a, b, c, d do not form a 4-point line in M/F @@ -1915,16 +1915,16 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(ring=GF(2), matrix=[[1, 1, 0, 1, 0, 0], + sage: M = Matroid(ring=GF(2), matrix=[[1, 1, 0, 1, 0, 0], # optional - sage.rings.finite_rings ....: [1, 0, 1, 0, 1, 0], ....: [0, 1, 1, 0, 0, 1], ....: [0, 0, 0, 1, 1, 1]]) - sage: M.linear_extension(6, {0:1, 5: 1}).representation() + sage: M.linear_extension(6, {0:1, 5: 1}).representation() # optional - sage.rings.finite_rings [1 1 0 1 0 0 1] [1 0 1 0 1 0 1] [0 1 1 0 0 1 1] [0 0 0 1 1 1 1] - sage: M.linear_extension(6, col=[0, 1, 1, 1]).representation() + sage: M.linear_extension(6, col=[0, 1, 1, 1]).representation() # optional - sage.rings.finite_rings [1 1 0 1 0 0 0] [1 0 1 0 1 0 1] [0 1 1 0 0 1 1] @@ -2003,17 +2003,17 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(ring=GF(2), matrix=[[1, 1, 0, 1, 0, 0], + sage: M = Matroid(ring=GF(2), matrix=[[1, 1, 0, 1, 0, 0], # optional - sage.rings.finite_rings ....: [1, 0, 1, 0, 1, 0], ....: [0, 1, 1, 0, 0, 1], ....: [0, 0, 0, 1, 1, 1]]) - sage: M.linear_coextension(6, {0:1, 5: 1}).representation() + sage: M.linear_coextension(6, {0:1, 5: 1}).representation() # optional - sage.rings.finite_rings [1 1 0 1 0 0 0] [1 0 1 0 1 0 0] [0 1 1 0 0 1 0] [0 0 0 1 1 1 0] [1 0 0 0 0 1 1] - sage: M.linear_coextension(6, row=[0,1,1,1,0,1]).representation() + sage: M.linear_coextension(6, row=[0,1,1,1,0,1]).representation() # optional - sage.rings.finite_rings [1 1 0 1 0 0 0] [1 0 1 0 1 0 0] [0 1 1 0 0 1 0] @@ -2022,11 +2022,11 @@ cdef class LinearMatroid(BasisExchangeMatroid): Coextending commutes with dualizing:: - sage: M = matroids.named_matroids.NonFano() - sage: chain = {'a': 1, 'b': -1, 'f': 1} - sage: M1 = M.linear_coextension('x', chain) - sage: M2 = M.dual().linear_extension('x', chain) - sage: M1 == M2.dual() + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: chain = {'a': 1, 'b': -1, 'f': 1} # optional - sage.rings.finite_rings + sage: M1 = M.linear_coextension('x', chain) # optional - sage.rings.finite_rings + sage: M2 = M.dual().linear_extension('x', chain) # optional - sage.rings.finite_rings + sage: M1 == M2.dual() # optional - sage.rings.finite_rings True """ cdef LeanMatrix col @@ -2078,9 +2078,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(ring=GF(2), matrix=[[1, 1, 0, 1, 0, 0], + sage: M = Matroid(ring=GF(2), matrix=[[1, 1, 0, 1, 0, 0], # optional - sage.rings.finite_rings ....: [1, 0, 1, 0, 1, 0], [0, 1, 1, 0, 0, 1], [0, 0, 0, 1, 1, 1]]) - sage: M._linear_extensions(6, [{0:1, 5: 1}])[0].representation() + sage: M._linear_extensions(6, [{0:1, 5: 1}])[0].representation() # optional - sage.rings.finite_rings [1 1 0 1 0 0 1] [1 0 1 0 1 0 1] [0 1 1 0 0 1 1] @@ -2127,9 +2127,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(ring=GF(2), matrix=[[1, 1, 0, 1, 0, 0], + sage: M = Matroid(ring=GF(2), matrix=[[1, 1, 0, 1, 0, 0], # optional - sage.rings.finite_rings ....: [1, 0, 1, 0, 1, 0], [0, 1, 1, 0, 0, 1], [0, 0, 0, 1, 1, 1]]) - sage: M._linear_coextensions(6, [{0:1, 5: 1}])[0].representation() + sage: M._linear_coextensions(6, [{0:1, 5: 1}])[0].representation() # optional - sage.rings.finite_rings [1 1 0 1 0 0 0] [1 0 1 0 1 0 0] [0 1 1 0 0 1 0] @@ -2241,15 +2241,15 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(reduced_matrix=Matrix(GF(2), [[1, 1, 0], + sage: M = Matroid(reduced_matrix=Matrix(GF(2), [[1, 1, 0], # optional - sage.rings.finite_rings ....: [1, 0, 1], [0, 1, 1]])) - sage: len(M._linear_extension_chains(F=set([0, 1, 2]))) + sage: len(M._linear_extension_chains(F=set([0, 1, 2]))) # optional - sage.rings.finite_rings 8 - sage: M._linear_extension_chains(F=set()) + sage: M._linear_extension_chains(F=set()) # optional - sage.rings.finite_rings [{}] - sage: M._linear_extension_chains(F=set([1])) + sage: M._linear_extension_chains(F=set([1])) # optional - sage.rings.finite_rings [{}, {1: 1}] - sage: len(M._linear_extension_chains(F=set([0, 1]))) + sage: len(M._linear_extension_chains(F=set([0, 1]))) # optional - sage.rings.finite_rings 4 sage: N = Matroid(ring=QQ, reduced_matrix=[[1, 1, 0], ....: [1, 0, 1], [0, 1, 1]]) @@ -2333,15 +2333,15 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(reduced_matrix=Matrix(GF(2), + sage: M = Matroid(reduced_matrix=Matrix(GF(2), # optional - sage.rings.finite_rings ....: [[1, 1, 0], [1, 0, 1], [0, 1, 1]])) - sage: len(M.linear_extension_chains()) + sage: len(M.linear_extension_chains()) # optional - sage.rings.finite_rings 8 - sage: len(M.linear_extension_chains(F=[0, 1])) + sage: len(M.linear_extension_chains(F=[0, 1])) # optional - sage.rings.finite_rings 4 - sage: len(M.linear_extension_chains(F=[0, 1], simple=True)) + sage: len(M.linear_extension_chains(F=[0, 1], simple=True)) # optional - sage.rings.finite_rings 0 - sage: M.linear_extension_chains(F=[0, 1, 2], simple=True) + sage: M.linear_extension_chains(F=[0, 1, 2], simple=True) # optional - sage.rings.finite_rings [{0: 1, 1: 1, 2: 1}] sage: N = Matroid(ring=QQ, ....: reduced_matrix=[[-1, -1, 0], [1, 0, -1], [0, 1, 1]]) @@ -2433,15 +2433,15 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(reduced_matrix=Matrix(GF(2), + sage: M = Matroid(reduced_matrix=Matrix(GF(2), # optional - sage.rings.finite_rings ....: [[1, 1, 0], [1, 0, 1], [0, 1, 1]])) - sage: len(M.linear_coextension_cochains()) + sage: len(M.linear_coextension_cochains()) # optional - sage.rings.finite_rings 8 - sage: len(M.linear_coextension_cochains(F=[0, 1])) + sage: len(M.linear_coextension_cochains(F=[0, 1])) # optional - sage.rings.finite_rings 4 - sage: len(M.linear_coextension_cochains(F=[0, 1], cosimple=True)) + sage: len(M.linear_coextension_cochains(F=[0, 1], cosimple=True)) # optional - sage.rings.finite_rings 0 - sage: M.linear_coextension_cochains(F=[3, 4, 5], cosimple=True) + sage: M.linear_coextension_cochains(F=[3, 4, 5], cosimple=True) # optional - sage.rings.finite_rings [{3: 1, 4: 1, 5: 1}] sage: N = Matroid(ring=QQ, ....: reduced_matrix=[[-1, -1, 0], [1, 0, -1], [0, 1, 1]]) @@ -2490,14 +2490,14 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(ring=GF(2), + sage: M = Matroid(ring=GF(2), # optional - sage.rings.finite_rings ....: reduced_matrix=[[-1, 0, 1], [1, -1, 0], [0, 1, -1]]) - sage: len(M.linear_extensions()) + sage: len(M.linear_extensions()) # optional - sage.rings.finite_rings 8 - sage: S = M.linear_extensions(simple=True) - sage: S + sage: S = M.linear_extensions(simple=True) # optional - sage.rings.finite_rings + sage: S # optional - sage.rings.finite_rings [Binary matroid of rank 3 on 7 elements, type (3, 0)] - sage: S[0].is_field_isomorphic(matroids.named_matroids.Fano()) + sage: S[0].is_field_isomorphic(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings True sage: M = Matroid(ring=QQ, ....: reduced_matrix=[[1, 0, 1], [1, 1, 0], [0, 1, 1]]) @@ -2559,15 +2559,15 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(ring=GF(2), + sage: M = Matroid(ring=GF(2), # optional - sage.rings.finite_rings ....: reduced_matrix=[[-1, 0, 1], [1, -1, 0], [0, 1, -1]]) - sage: len(M.linear_coextensions()) + sage: len(M.linear_coextensions()) # optional - sage.rings.finite_rings 8 - sage: S = M.linear_coextensions(cosimple=True) - sage: S + sage: S = M.linear_coextensions(cosimple=True) # optional - sage.rings.finite_rings + sage: S # optional - sage.rings.finite_rings [Binary matroid of rank 4 on 7 elements, type (3, 7)] - sage: F7 = matroids.named_matroids.Fano() - sage: S[0].is_field_isomorphic(F7.dual()) + sage: F7 = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: S[0].is_field_isomorphic(F7.dual()) # optional - sage.rings.finite_rings True sage: M = Matroid(ring=QQ, ....: reduced_matrix=[[1, 0, 1], [1, 1, 0], [0, 1, 1]]) @@ -2575,10 +2575,10 @@ cdef class LinearMatroid(BasisExchangeMatroid): ....: fundamentals=[1, -1, 1/2, 2]) sage: len(S) 7 - sage: NF7 = matroids.named_matroids.NonFano() - sage: any(N.is_isomorphic(NF7.dual()) for N in S) + sage: NF7 = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: any(N.is_isomorphic(NF7.dual()) for N in S) # optional - sage.rings.finite_rings True - sage: len(M.linear_coextensions(cosimple=True, + sage: len(M.linear_coextensions(cosimple=True, # optional - sage.rings.finite_rings ....: fundamentals=[1, -1, 1/2, 2], ....: F=[3, 4])) 1 @@ -2747,12 +2747,12 @@ cdef class LinearMatroid(BasisExchangeMatroid): (False, True) sage: matroids.Uniform(4, 8)._is_4connected_shifting() True - sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], + sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.rings.finite_rings ....: [0,1,0,1,0,1,0,1,0,0,0,1], ....: [0,0,1,1,0,0,1,1,0,1,0,1], ....: [0,0,0,0,1,1,1,1,0,0,1,1], ....: [0,0,0,0,0,0,0,0,1,1,1,1]]) - sage: M._is_4connected_shifting() + sage: M._is_4connected_shifting() # optional - sage.rings.finite_rings True """ if self.rank()>self.size()-self.rank(): @@ -2919,10 +2919,10 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], + sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], # optional - sage.rings.finite_rings ....: [0, 0, 1, 1, 3]])) - sage: N = deepcopy(M) # indirect doctest - sage: M == N + sage: N = deepcopy(M) # indirect doctest # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings True """ cdef LinearMatroid N @@ -2955,16 +2955,16 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], + sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], # optional - sage.rings.finite_rings ....: [0, 0, 1, 1, 3]])) - sage: M == loads(dumps(M)) # indirect doctest + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.rings.finite_rings True - sage: M.rename("U35") - sage: loads(dumps(M)) + sage: M.rename("U35") # optional - sage.rings.finite_rings + sage: loads(dumps(M)) # optional - sage.rings.finite_rings U35 - sage: M = Matroid(Matrix(GF(7), [[1, 0, 1], [1, 0, 1]])) - sage: N = loads(dumps(M)) - sage: N.representation() + sage: M = Matroid(Matrix(GF(7), [[1, 0, 1], [1, 0, 1]])) # optional - sage.rings.finite_rings + sage: N = loads(dumps(M)) # optional - sage.rings.finite_rings + sage: N.representation() # optional - sage.rings.finite_rings [1 0 1] [1 0 1] """ @@ -3038,21 +3038,21 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: A = Matrix(GF(2), 2, 4, [[1, 0, 1, 1], [0, 1, 1, 1]]) - sage: M = Matroid(A) - sage: M + sage: A = Matrix(GF(2), 2, 4, [[1, 0, 1, 1], [0, 1, 1, 1]]) # optional - sage.rings.finite_rings + sage: M = Matroid(A) # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings Binary matroid of rank 2 on 4 elements, type (0, 6) - sage: sorted(M.groundset()) + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings [0, 1, 2, 3] - sage: Matrix(M) + sage: Matrix(M) # optional - sage.rings.finite_rings [1 0 1 1] [0 1 1 1] - sage: M = Matroid(matrix=A, groundset='abcd') - sage: sorted(M.groundset()) + sage: M = Matroid(matrix=A, groundset='abcd') # optional - sage.rings.finite_rings + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd'] - sage: B = Matrix(GF(2), 2, 2, [[1, 1], [1, 1]]) - sage: N = Matroid(reduced_matrix=B, groundset='abcd') - sage: M == N + sage: B = Matrix(GF(2), 2, 2, [[1, 1], [1, 1]]) # optional - sage.rings.finite_rings + sage: N = Matroid(reduced_matrix=B, groundset='abcd') # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings True """ def __init__(self, matrix=None, groundset=None, reduced_matrix=None, ring=None, keep_initial_representation=True, basis=None): @@ -3133,8 +3133,8 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.base_ring() + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.base_ring() # optional - sage.rings.finite_rings Finite Field of size 2 """ global GF2 @@ -3147,8 +3147,8 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.characteristic() + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.characteristic() # optional - sage.rings.finite_rings 2 """ return 2 @@ -3215,9 +3215,9 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.rename() - sage: repr(M) # indirect doctest + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.rename() # optional - sage.rings.finite_rings + sage: repr(M) # indirect doctest # optional - sage.rings.finite_rings 'Binary matroid of rank 3 on 7 elements, type (3, 0)' """ S = "Binary matroid of rank " + str(self.rank()) + " on " + str(self.size()) + " elements, type (" + str(self.bicycle_dimension()) + ', ' + str(self.brown_invariant()) + ')' @@ -3241,13 +3241,13 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: A = M._reduced_representation('efg') - sage: R, C = M._current_rows_cols() - sage: (sorted(R), sorted(C)) + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: A = M._reduced_representation('efg') # optional - sage.rings.finite_rings + sage: R, C = M._current_rows_cols() # optional - sage.rings.finite_rings + sage: (sorted(R), sorted(C)) # optional - sage.rings.finite_rings (['e', 'f', 'g'], ['a', 'b', 'c', 'd']) - sage: R, C = M._current_rows_cols(B='abg') - sage: (sorted(R), sorted(C)) + sage: R, C = M._current_rows_cols(B='abg') # optional - sage.rings.finite_rings + sage: (sorted(R), sorted(C)) # optional - sage.rings.finite_rings (['a', 'b', 'g'], ['c', 'd', 'e', 'f']) """ @@ -3289,13 +3289,13 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M._basic_representation() + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M._basic_representation() # optional - sage.rings.finite_rings 3 x 7 BinaryMatrix [1000111] [0101011] [0011101] - sage: matrix(M._basic_representation('efg')) + sage: matrix(M._basic_representation('efg')) # optional - sage.rings.finite_rings [1 1 0 1 1 0 0] [1 0 1 1 0 1 0] [1 1 1 0 0 0 1] @@ -3328,13 +3328,13 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M._reduced_representation() + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M._reduced_representation() # optional - sage.rings.finite_rings 3 x 4 BinaryMatrix [0111] [1011] [1101] - sage: matrix(M._reduced_representation('efg')) + sage: matrix(M._reduced_representation('efg')) # optional - sage.rings.finite_rings [1 1 0 1] [1 0 1 1] [1 1 1 0] @@ -3368,23 +3368,23 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M1 = matroids.named_matroids.Fano() - sage: M2 = Matroid(ring=GF(2), + sage: M1 = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M2 = Matroid(ring=GF(2), # optional - sage.rings.finite_rings ....: reduced_matrix=[[1, 0, 1, 1], [0, 1, 1, 1], [1, 1, 0, 1]]) - sage: M1._is_isomorphic(M2) + sage: M1._is_isomorphic(M2) # optional - sage.rings.finite_rings True - sage: M1._is_isomorphic(M2, certificate=True) + sage: M1._is_isomorphic(M2, certificate=True) # optional - sage.rings.finite_rings (True, {'a': 0, 'b': 1, 'c': 2, 'd': 4, 'e': 3, 'f': 5, 'g': 6}) - sage: M1 = matroids.named_matroids.Fano().delete('a') - sage: M2 = matroids.Whirl(3) - sage: M1._is_isomorphic(M2) + sage: M1 = matroids.named_matroids.Fano().delete('a') # optional - sage.rings.finite_rings + sage: M2 = matroids.Whirl(3) # optional - sage.rings.finite_rings + sage: M1._is_isomorphic(M2) # optional - sage.rings.finite_rings False - sage: M1._is_isomorphic(M2, certificate=True) + sage: M1._is_isomorphic(M2, certificate=True) # optional - sage.rings.finite_rings (False, None) - sage: M1._is_isomorphic(matroids.Wheel(3)) + sage: M1._is_isomorphic(matroids.Wheel(3)) # optional - sage.rings.finite_rings True - sage: M1._is_isomorphic(matroids.Wheel(3), certificate=True) + sage: M1._is_isomorphic(matroids.Wheel(3), certificate=True) # optional - sage.rings.finite_rings (True, {'b': 1, 'c': 2, 'd': 4, 'e': 3, 'f': 5, 'g': 0}) """ @@ -3414,10 +3414,10 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() \ ['a'] - sage: N = matroids.named_matroids.Fano() \ ['b'] - sage: morphism = {'b':'a', 'c':'c', 'd':'e', 'e':'d', 'f':'f', 'g':'g'} - sage: M._is_isomorphism(N, morphism) + sage: M = matroids.named_matroids.Fano() \ ['a'] # optional - sage.rings.finite_rings + sage: N = matroids.named_matroids.Fano() \ ['b'] # optional - sage.rings.finite_rings + sage: morphism = {'b':'a', 'c':'c', 'd':'e', 'e':'d', 'f':'f', 'g':'g'} # optional - sage.rings.finite_rings + sage: M._is_isomorphism(N, morphism) # optional - sage.rings.finite_rings True """ if isinstance(other, BinaryMatroid): @@ -3434,8 +3434,8 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M._invariant() # indirect doctest + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M._invariant() # indirect doctest # optional - sage.rings.finite_rings (3, 0, 7, 0, 0, 0, 0, 0) """ cdef BinaryMatrix B @@ -3537,8 +3537,8 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BinaryMatroid(matroids.AG(2, 5).representation()) - sage: M._invariant() + sage: M = BinaryMatroid(matroids.AG(2, 5).representation()) # optional - sage.rings.finite_rings + sage: M._invariant() # optional - sage.rings.finite_rings (2, 1, 24, 0, 1, 0, 0, 1) """ if self._b_invariant is None: @@ -3560,8 +3560,8 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.bicycle_dimension() + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.bicycle_dimension() # optional - sage.rings.finite_rings 3 """ if self._b_invariant is None: @@ -3592,13 +3592,13 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: M.brown_invariant() + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.brown_invariant() # optional - sage.rings.finite_rings 0 - sage: M = Matroid(Matrix(GF(2), 3, 8, [[1, 0, 0, 1, 1, 1, 1, 1], + sage: M = Matroid(Matrix(GF(2), 3, 8, [[1, 0, 0, 1, 1, 1, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 0, 1, 1, 0, 0, 0], ....: [0, 0, 1, 0, 0, 1, 1, 0]])) - sage: M.brown_invariant() is None + sage: M.brown_invariant() is None # optional - sage.rings.finite_rings True """ if self._b_invariant is None: @@ -3624,14 +3624,16 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.S8() - sage: for F in M._principal_tripartition(): print(sorted(F)) + sage: M = matroids.named_matroids.S8() # optional - sage.rings.finite_rings + sage: for F in M._principal_tripartition(): print(sorted(F)) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'e', 'f', 'g'] ['d'] ['h'] - sage: M.bicycle_dimension() + sage: M.bicycle_dimension() # optional - sage.rings.finite_rings 2 - sage: for i in [-1, 0, 1]: print(sorted([e for e in M.groundset() if (M\e).bicycle_dimension() == 2 + i])) + sage: for i in [-1, 0, 1]: # optional - sage.rings.finite_rings + ....: print(sorted(e for e in M.groundset() + ....: if (M\e).bicycle_dimension() == 2 + i])) ['a', 'b', 'c', 'e', 'f', 'g'] ['d'] ['h'] @@ -3662,8 +3664,8 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = BinaryMatroid(matrix(matroids.named_matroids.R12())) - sage: M._projection() + sage: M = BinaryMatroid(matrix(matroids.named_matroids.R12())) # optional - sage.rings.finite_rings + sage: M._projection() # optional - sage.rings.finite_rings 12 x 12 BinaryMatrix [001110111000] [001101110100] @@ -3699,14 +3701,14 @@ cdef class BinaryMatroid(LinearMatroid): An ordered partition. sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.R12() - sage: N = BinaryMatroid(reduced_matrix=M.representation(reduced=True, + sage: M = matroids.named_matroids.R12() # optional - sage.rings.finite_rings + sage: N = BinaryMatroid(reduced_matrix=M.representation(reduced=True, # optional - sage.rings.finite_rings ....: labels=False), groundset='abcdefghijkl') - sage: Npp = N._projection_partition(); Npp # random + sage: Npp = N._projection_partition(); Npp # random # optional - sage.rings.finite_rings 2 x 12 BinaryMatrix [110011001100] [001100110011] - sage: sorted(Npp._matrix_().rows()) + sage: sorted(Npp._matrix_().rows()) # optional - sage.rings.finite_rings [(1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0), (0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1)] """ if self._eq_part is None: @@ -3734,9 +3736,9 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.S8() - sage: N = matroids.named_matroids.S8() - sage: M._fast_isom_test(N) is None + sage: M = matroids.named_matroids.S8() # optional - sage.rings.finite_rings + sage: N = matroids.named_matroids.S8() # optional - sage.rings.finite_rings + sage: M._fast_isom_test(N) is None # optional - sage.rings.finite_rings True """ if self._invariant() != other._invariant(): @@ -3775,9 +3777,9 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: N = M._minor(contractions=set(['a']), deletions=set([])) - sage: N._minor(contractions=set([]), deletions=set(['b', 'c'])) + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: N = M._minor(contractions=set(['a']), deletions=set([])) # optional - sage.rings.finite_rings + sage: N._minor(contractions=set([]), deletions=set(['b', 'c'])) # optional - sage.rings.finite_rings Binary matroid of rank 2 on 4 elements, type (0, 6) """ self._move_current_basis(contractions, deletions) @@ -3808,16 +3810,16 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: sage: R10 = matroids.named_matroids.R10() - sage: M = Matroid(ring=GF(2), reduced_matrix=R10.representation( + sage: M = Matroid(ring=GF(2), reduced_matrix=R10.representation( # optional - sage.rings.finite_rings ....: reduced=True, labels=False)) - sage: M.is_graphic() + sage: M.is_graphic() # optional - sage.rings.finite_rings False sage: K5 = Matroid(graphs.CompleteGraph(5), regular = True) - sage: M = Matroid(ring=GF(2), reduced_matrix=K5.representation( + sage: M = Matroid(ring=GF(2), reduced_matrix=K5.representation( # optional - sage.rings.finite_rings ....: reduced=True, labels=False)) - sage: M.is_graphic() + sage: M.is_graphic() # optional - sage.rings.finite_rings True - sage: M.dual().is_graphic() + sage: M.dual().is_graphic() # optional - sage.rings.finite_rings False ALGORITHM: @@ -3876,8 +3878,8 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(2), [[]])) - sage: M.is_valid() + sage: M = Matroid(Matrix(GF(2), [[]])) # optional - sage.rings.finite_rings + sage: M.is_valid() # optional - sage.rings.finite_rings True """ return True @@ -3908,8 +3910,8 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() - sage: N.binary_matroid() is N + sage: N = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: N.binary_matroid() is N # optional - sage.rings.finite_rings True """ return self @@ -3936,8 +3938,8 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() - sage: N.is_binary() + sage: N = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: N.is_binary() # optional - sage.rings.finite_rings True """ return True @@ -3948,10 +3950,10 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(2), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], + sage: M = Matroid(Matrix(GF(2), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], # optional - sage.rings.finite_rings ....: [0, 0, 1, 1, 3]])) - sage: N = copy(M) # indirect doctest - sage: M == N + sage: N = copy(M) # indirect doctest # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings True """ cdef BinaryMatroid N @@ -3972,10 +3974,10 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(2), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], + sage: M = Matroid(Matrix(GF(2), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], # optional - sage.rings.finite_rings ....: [0, 0, 1, 1, 3]])) - sage: N = deepcopy(M) # indirect doctest - sage: M == N + sage: N = deepcopy(M) # indirect doctest # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings True """ from copy import deepcopy @@ -4011,15 +4013,15 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(2), [[1, 0, 0, 1], [0, 1, 0, 1], + sage: M = Matroid(Matrix(GF(2), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.rings.finite_rings ....: [0, 0, 1, 1]])) - sage: M == loads(dumps(M)) # indirect doctest + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.rings.finite_rings True - sage: M.rename("U34") - sage: loads(dumps(M)) + sage: M.rename("U34") # optional - sage.rings.finite_rings + sage: loads(dumps(M)) # optional - sage.rings.finite_rings U34 - sage: M = Matroid(Matrix(GF(2), [[1, 0, 1], [1, 0, 1]])) - sage: loads(dumps(M)).representation() + sage: M = Matroid(Matrix(GF(2), [[1, 0, 1], [1, 0, 1]])) # optional - sage.rings.finite_rings + sage: loads(dumps(M)).representation() # optional - sage.rings.finite_rings [1 0 1] [1 0 1] @@ -4027,12 +4029,12 @@ cdef class BinaryMatroid(LinearMatroid): Check that :trac:`23437` is fixed:: - sage: M = matroids.named_matroids.Fano().dual() - sage: B = list(M.bases()) - sage: N = loads(dumps(M)) - sage: N.closure(frozenset({'d'})) + sage: M = matroids.named_matroids.Fano().dual() # optional - sage.rings.finite_rings + sage: B = list(M.bases()) # optional - sage.rings.finite_rings + sage: N = loads(dumps(M)) # optional - sage.rings.finite_rings + sage: N.closure(frozenset({'d'})) # optional - sage.rings.finite_rings frozenset({'d'}) - sage: N.is_isomorphic(M) + sage: N.is_isomorphic(M) # optional - sage.rings.finite_rings True """ import sage.matroids.unpickling @@ -4103,21 +4105,20 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: A = Matrix(GF(3), 2, 4, [[1, 0, 1, 1], [0, 1, 1, 1]]) - sage: M = Matroid(A) - sage: M + sage: A = Matrix(GF(3), 2, 4, [[1, 0, 1, 1], [0, 1, 1, 1]]) # optional - sage.rings.finite_rings + sage: M = Matroid(A); M # optional - sage.rings.finite_rings Ternary matroid of rank 2 on 4 elements, type 0- - sage: sorted(M.groundset()) + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings [0, 1, 2, 3] - sage: Matrix(M) + sage: Matrix(M) # optional - sage.rings.finite_rings [1 0 1 1] [0 1 1 1] - sage: M = Matroid(matrix=A, groundset='abcd') - sage: sorted(M.groundset()) + sage: M = Matroid(matrix=A, groundset='abcd') # optional - sage.rings.finite_rings + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd'] - sage: B = Matrix(GF(2), 2, 2, [[1, 1], [1, 1]]) - sage: N = Matroid(ring=GF(3), reduced_matrix=B, groundset='abcd') - sage: M == N + sage: B = Matrix(GF(2), 2, 2, [[1, 1], [1, 1]]) # optional - sage.rings.finite_rings + sage: N = Matroid(ring=GF(3), reduced_matrix=B, groundset='abcd') # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings True """ def __init__(self, matrix=None, groundset=None, reduced_matrix=None, ring=None, keep_initial_representation=True, basis=None): @@ -4200,8 +4201,8 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.NonFano() - sage: M.base_ring() + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M.base_ring() # optional - sage.rings.finite_rings Finite Field of size 3 """ global GF3 @@ -4214,8 +4215,8 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.NonFano() - sage: M.characteristic() + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M.characteristic() # optional - sage.rings.finite_rings 3 """ return 3 @@ -4284,9 +4285,9 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.NonFano() - sage: M.rename() - sage: repr(M) # indirect doctest + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M.rename() # optional - sage.rings.finite_rings + sage: repr(M) # indirect doctest # optional - sage.rings.finite_rings 'Ternary matroid of rank 3 on 7 elements, type 0-' """ S = "Ternary matroid of rank " + str(self.rank()) + " on " + str(self.size()) + " elements, type " + str(self.bicycle_dimension()) @@ -4314,13 +4315,13 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.NonFano() - sage: A = M._reduced_representation('efg') - sage: R, C = M._current_rows_cols() - sage: (sorted(R), sorted(C)) + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: A = M._reduced_representation('efg') # optional - sage.rings.finite_rings + sage: R, C = M._current_rows_cols() # optional - sage.rings.finite_rings + sage: (sorted(R), sorted(C)) # optional - sage.rings.finite_rings (['e', 'f', 'g'], ['a', 'b', 'c', 'd']) - sage: R, C = M._current_rows_cols(B='abg') - sage: (sorted(R), sorted(C)) + sage: R, C = M._current_rows_cols(B='abg') # optional - sage.rings.finite_rings + sage: (sorted(R), sorted(C)) # optional - sage.rings.finite_rings (['a', 'b', 'g'], ['c', 'd', 'e', 'f']) """ @@ -4362,13 +4363,13 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.NonFano() - sage: M._basic_representation() + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M._basic_representation() # optional - sage.rings.finite_rings 3 x 7 TernaryMatrix [+000+++] [0+0+0++] [00+++0+] - sage: matrix(M._basic_representation('efg')) + sage: matrix(M._basic_representation('efg')) # optional - sage.rings.finite_rings [1 2 0 2 1 0 0] [1 0 2 2 0 1 0] [2 1 1 2 0 0 1] @@ -4401,13 +4402,13 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.NonFano() - sage: M._reduced_representation() + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M._reduced_representation() # optional - sage.rings.finite_rings 3 x 4 TernaryMatrix [0+++] [+0++] [++0+] - sage: matrix(M._reduced_representation('efg')) + sage: matrix(M._reduced_representation('efg')) # optional - sage.rings.finite_rings [1 2 0 2] [1 0 2 2] [2 1 1 2] @@ -4440,13 +4441,13 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M1 = matroids.named_matroids.NonFano().delete('a') - sage: M2 = matroids.Whirl(3) - sage: M1._is_isomorphic(M2) + sage: M1 = matroids.named_matroids.NonFano().delete('a') # optional - sage.rings.finite_rings + sage: M2 = matroids.Whirl(3) # optional - sage.rings.finite_rings + sage: M1._is_isomorphic(M2) # optional - sage.rings.finite_rings True - sage: M2 = matroids.Wheel(3) - sage: M1._is_isomorphic(M2) + sage: M2 = matroids.Wheel(3) # optional - sage.rings.finite_rings + sage: M1._is_isomorphic(M2) # optional - sage.rings.finite_rings False """ if certificate: @@ -4466,8 +4467,8 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.NonFano() - sage: M._invariant() # indirect doctest + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M._invariant() # indirect doctest # optional - sage.rings.finite_rings (0, 2, 0, 4, 3, 0, 12, 12, 3, 0, 0, 0) """ cdef TernaryMatrix T @@ -4551,8 +4552,8 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.NonFano() - sage: M._invariant() + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M._invariant() # optional - sage.rings.finite_rings (0, 2, 0, 4, 3, 0, 12, 12, 3, 0, 0, 0) """ if self._t_invariant is None: @@ -4574,8 +4575,8 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.NonFano() - sage: M.bicycle_dimension() + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M.bicycle_dimension() # optional - sage.rings.finite_rings 0 """ if self._t_invariant is None: @@ -4600,8 +4601,8 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.NonFano() - sage: M.character() + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M.character() # optional - sage.rings.finite_rings 2 """ if self._t_invariant is None: @@ -4618,20 +4619,20 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.N1() - sage: print(M) + sage: M = matroids.named_matroids.N1() # optional - sage.rings.finite_rings + sage: print(M) # optional - sage.rings.finite_rings N1: Ternary matroid of rank 5 on 10 elements, type 0+ - sage: P = M._principal_quadripartition() - sage: for e in sorted(P[0]): print("{} {}".format(e, M/e)) - sage: for e in sorted(P[1]): print("{} {}".format(e, M/e)) + sage: P = M._principal_quadripartition() # optional - sage.rings.finite_rings + sage: for e in sorted(P[0]): print("{} {}".format(e, M/e)) # optional - sage.rings.finite_rings + sage: for e in sorted(P[1]): print("{} {}".format(e, M/e)) # optional - sage.rings.finite_rings a Ternary matroid of rank 4 on 9 elements, type 1- b Ternary matroid of rank 4 on 9 elements, type 1- e Ternary matroid of rank 4 on 9 elements, type 1- f Ternary matroid of rank 4 on 9 elements, type 1- - sage: for e in sorted(P[2]): print("{} {}".format(e, M/e)) + sage: for e in sorted(P[2]): print("{} {}".format(e, M/e)) # optional - sage.rings.finite_rings d Ternary matroid of rank 4 on 9 elements, type 0- i Ternary matroid of rank 4 on 9 elements, type 0- - sage: for e in sorted(P[3]): print("{} {}".format(e, M/e)) + sage: for e in sorted(P[3]): print("{} {}".format(e, M/e)) # optional - sage.rings.finite_rings c Ternary matroid of rank 4 on 9 elements, type 0+ g Ternary matroid of rank 4 on 9 elements, type 0+ h Ternary matroid of rank 4 on 9 elements, type 0+ @@ -4663,9 +4664,9 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: from sage.matroids.advanced import * - sage: M = TernaryMatroid(matrix(matroids.named_matroids.R12())) - sage: M._projection() + sage: from sage.matroids.advanced import * # optional - sage.rings.finite_rings + sage: M = TernaryMatroid(matrix(matroids.named_matroids.R12())) # optional - sage.rings.finite_rings + sage: M._projection() # optional - sage.rings.finite_rings 12 x 12 TernaryMatrix [++00-0--0+++] [+-+000+0+-+0] @@ -4705,9 +4706,9 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.T8() - sage: N = matroids.named_matroids.P8() - sage: M._fast_isom_test(N) + sage: M = matroids.named_matroids.T8() # optional - sage.rings.finite_rings + sage: N = matroids.named_matroids.P8() # optional - sage.rings.finite_rings + sage: M._fast_isom_test(N) # optional - sage.rings.finite_rings False """ if self._invariant() != other._invariant(): @@ -4742,9 +4743,9 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.P8() - sage: N = M._minor(contractions=set(['a']), deletions=set([])) - sage: N._minor(contractions=set([]), deletions=set(['b', 'c'])) + sage: M = matroids.named_matroids.P8() # optional - sage.rings.finite_rings + sage: N = M._minor(contractions=set(['a']), deletions=set([])) # optional - sage.rings.finite_rings + sage: N._minor(contractions=set([]), deletions=set(['b', 'c'])) # optional - sage.rings.finite_rings Ternary matroid of rank 3 on 5 elements, type 0- """ self._move_current_basis(contractions, deletions) @@ -4771,8 +4772,8 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(3), [[]])) - sage: M.is_valid() + sage: M = Matroid(Matrix(GF(3), [[]])) # optional - sage.rings.finite_rings + sage: M.is_valid() # optional - sage.rings.finite_rings True """ return True @@ -4803,8 +4804,8 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: N = matroids.named_matroids.NonFano() - sage: N.ternary_matroid() is N + sage: N = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: N.ternary_matroid() is N # optional - sage.rings.finite_rings True """ return self @@ -4831,8 +4832,8 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: N = matroids.named_matroids.NonFano() - sage: N.is_ternary() + sage: N = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: N.is_ternary() # optional - sage.rings.finite_rings True """ return True @@ -4843,10 +4844,10 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(3), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], + sage: M = Matroid(Matrix(GF(3), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], # optional - sage.rings.finite_rings ....: [0, 0, 1, 1, 3]])) - sage: N = copy(M) # indirect doctest - sage: M == N + sage: N = copy(M) # indirect doctest # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings True """ cdef TernaryMatroid N @@ -4867,10 +4868,10 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(3), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], + sage: M = Matroid(Matrix(GF(3), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], # optional - sage.rings.finite_rings ....: [0, 0, 1, 1, -1]])) - sage: N = deepcopy(M) # indirect doctest - sage: M == N + sage: N = deepcopy(M) # indirect doctest # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings True """ from copy import deepcopy @@ -4907,15 +4908,15 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = TernaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], + sage: M = TernaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], # optional - sage.rings.finite_rings ....: [0, 1, 0, 1], [0, 0, 1, 1]])) - sage: M == loads(dumps(M)) # indirect doctest + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.rings.finite_rings True - sage: M.rename("U34") - sage: loads(dumps(M)) + sage: M.rename("U34") # optional - sage.rings.finite_rings + sage: loads(dumps(M)) # optional - sage.rings.finite_rings U34 - sage: M = TernaryMatroid(Matrix(GF(3), [[1, 0, 1], [1, 0, 1]])) - sage: loads(dumps(M)).representation() + sage: M = TernaryMatroid(Matrix(GF(3), [[1, 0, 1], [1, 0, 1]])) # optional - sage.rings.finite_rings + sage: loads(dumps(M)).representation() # optional - sage.rings.finite_rings [1 0 1] [1 0 1] @@ -4923,15 +4924,15 @@ cdef class TernaryMatroid(LinearMatroid): Check that :trac:`23437` is fixed:: - sage: from sage.matroids.advanced import * - sage: X_bin = matroids.named_matroids.Fano().representation() - sage: X = Matrix(GF(3), X_bin) - sage: M = TernaryMatroid(matrix=X).dual() - sage: B = list(M.bases()) - sage: N = loads(dumps(M)) - sage: N.closure(frozenset({3})) + sage: from sage.matroids.advanced import * # optional - sage.rings.finite_rings + sage: X_bin = matroids.named_matroids.Fano().representation() # optional - sage.rings.finite_rings + sage: X = Matrix(GF(3), X_bin) # optional - sage.rings.finite_rings + sage: M = TernaryMatroid(matrix=X).dual() # optional - sage.rings.finite_rings + sage: B = list(M.bases()) # optional - sage.rings.finite_rings + sage: N = loads(dumps(M)) # optional - sage.rings.finite_rings + sage: N.closure(frozenset({3})) # optional - sage.rings.finite_rings frozenset({3}) - sage: N.is_isomorphic(M) + sage: N.is_isomorphic(M) # optional - sage.rings.finite_rings True """ import sage.matroids.unpickling @@ -5004,25 +5005,25 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: GF4 = GF(4, 'x') - sage: x = GF4.gens()[0] - sage: A = Matrix(GF4, 2, 4, [[1, 0, 1, 1], [0, 1, 1, x]]) - sage: M = Matroid(A) - sage: M + sage: GF4 = GF(4, 'x') # optional - sage.rings.finite_rings + sage: x = GF4.gens()[0] # optional - sage.rings.finite_rings + sage: A = Matrix(GF4, 2, 4, [[1, 0, 1, 1], [0, 1, 1, x]]) # optional - sage.rings.finite_rings + sage: M = Matroid(A) # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings Quaternary matroid of rank 2 on 4 elements - sage: sorted(M.groundset()) + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings [0, 1, 2, 3] - sage: Matrix(M) + sage: Matrix(M) # optional - sage.rings.finite_rings [1 0 1 1] [0 1 1 x] - sage: M = Matroid(matrix=A, groundset='abcd') - sage: sorted(M.groundset()) + sage: M = Matroid(matrix=A, groundset='abcd') # optional - sage.rings.finite_rings + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd'] - sage: GF4p = GF(4, 'y') - sage: y = GF4p.gens()[0] - sage: B = Matrix(GF4p, 2, 2, [[1, 1], [1, y]]) - sage: N = Matroid(reduced_matrix=B, groundset='abcd') - sage: M == N + sage: GF4p = GF(4, 'y') # optional - sage.rings.finite_rings + sage: y = GF4p.gens()[0] # optional - sage.rings.finite_rings + sage: B = Matrix(GF4p, 2, 2, [[1, 1], [1, y]]) # optional - sage.rings.finite_rings + sage: N = Matroid(reduced_matrix=B, groundset='abcd') # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings False """ def __init__(self, matrix=None, groundset=None, reduced_matrix=None, ring=None, keep_initial_representation=True, basis=None): @@ -5038,7 +5039,7 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: QuaternaryMatroid(matrix=Matrix(GF(4, 'x'), # indirect doctest + sage: QuaternaryMatroid(matrix=Matrix(GF(4, 'x'), # indirect doctest # optional - sage.rings.finite_rings ....: [[1, 0, 1, 1, 1], ....: [0, 1, 1, 1, 1]])) Quaternary matroid of rank 2 on 5 elements @@ -5632,12 +5633,12 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(4, 'x'), [[1, 0, 0, 1], [0, 1, 0, 1], + sage: M = Matroid(Matrix(GF(4, 'x'), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.rings.finite_rings ....: [0, 0, 1, 1]])) - sage: M == loads(dumps(M)) # indirect doctest + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.rings.finite_rings True - sage: M.rename("U34") - sage: loads(dumps(M)) + sage: M.rename("U34") # optional - sage.rings.finite_rings + sage: loads(dumps(M)) # optional - sage.rings.finite_rings U34 TESTS: @@ -5645,14 +5646,14 @@ cdef class QuaternaryMatroid(LinearMatroid): Check that :trac:`23437` is fixed:: sage: from sage.matroids.advanced import QuaternaryMatroid - sage: X_bin = matroids.named_matroids.Fano().representation() - sage: X = Matrix(GF(4), X_bin) - sage: M = QuaternaryMatroid(matrix=X).dual() - sage: B = list(M.bases()) - sage: N = loads(dumps(M)) - sage: N.closure(frozenset({3})) + sage: X_bin = matroids.named_matroids.Fano().representation() # optional - sage.rings.finite_rings + sage: X = Matrix(GF(4), X_bin) # optional - sage.rings.finite_rings + sage: M = QuaternaryMatroid(matrix=X).dual() # optional - sage.rings.finite_rings + sage: B = list(M.bases()) # optional - sage.rings.finite_rings + sage: N = loads(dumps(M)) # optional - sage.rings.finite_rings + sage: N.closure(frozenset({3})) # optional - sage.rings.finite_rings frozenset({3}) - sage: N.is_isomorphic(M) + sage: N.is_isomorphic(M) # optional - sage.rings.finite_rings True """ import sage.matroids.unpickling diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index e693cbfb17d..0a49ae27cb9 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -1133,7 +1133,7 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.named_matroids.Vamos() - sage: M._has_minor(matroids.Whirl(3)) # optional - sage.libs.pari + sage: M._has_minor(matroids.Whirl(3)) # optional - sage.rings.finite_rings False sage: M._has_minor(matroids.Uniform(2, 4)) True @@ -1361,12 +1361,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.rank() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.rank() # optional - sage.rings.finite_rings 3 - sage: M.rank(['a', 'b', 'f']) # optional - sage.libs.pari + sage: M.rank(['a', 'b', 'f']) # optional - sage.rings.finite_rings 2 - sage: M.rank(['a', 'b', 'x']) # optional - sage.libs.pari + sage: M.rank(['a', 'b', 'x']) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: ['a', 'b', 'x'] is not a subset of the groundset @@ -1489,7 +1489,7 @@ cdef class Matroid(SageObject): ... ValueError: ['x'] is not a subset of the groundset sage: C = M.circuit() - sage: sorted(C) # random + sage: sorted(C) # random ['a', 'b', 'c', 'd'] sage: M.is_circuit(C) True @@ -1672,12 +1672,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.corank() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.corank() # optional - sage.rings.finite_rings 4 - sage: M.corank('cdeg') # optional - sage.libs.pari + sage: M.corank('cdeg') # optional - sage.rings.finite_rings 3 - sage: M.rank(['a', 'b', 'x']) # optional - sage.libs.pari + sage: M.rank(['a', 'b', 'x']) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: ['a', 'b', 'x'] is not a subset of the groundset @@ -1769,7 +1769,7 @@ cdef class Matroid(SageObject): sage: M = matroids.named_matroids.Vamos() sage: X = M.max_coindependent(['a', 'c', 'd', 'e', 'f']) - sage: sorted(X) # random + sage: sorted(X) # random ['a', 'c', 'd', 'f'] sage: M.is_coindependent(X) True @@ -1855,7 +1855,7 @@ cdef class Matroid(SageObject): ... ValueError: ['x'] is not a subset of the groundset sage: C = M.cocircuit() - sage: sorted(C) # random + sage: sorted(C) # random ['e', 'f', 'g', 'h'] sage: M.is_cocircuit(C) True @@ -1914,10 +1914,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.loops() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.loops() # optional - sage.rings.finite_rings frozenset() - sage: (M / ['a', 'b']).loops() # optional - sage.libs.pari + sage: (M / ['a', 'b']).loops() # optional - sage.rings.finite_rings frozenset({'f'}) """ return self._closure(set()) @@ -2138,10 +2138,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().dual() # optional - sage.libs.pari - sage: M.coloops() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano().dual() # optional - sage.rings.finite_rings + sage: M.coloops() # optional - sage.rings.finite_rings frozenset() - sage: (M \ ['a', 'b']).coloops() # optional - sage.libs.pari + sage: (M \ ['a', 'b']).coloops() # optional - sage.rings.finite_rings frozenset({'f'}) """ return self._coclosure(set()) @@ -2384,8 +2384,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: sorted([sorted(C) for C in M.circuits()]) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: sorted([sorted(C) for C in M.circuits()]) # optional - sage.rings.finite_rings [['a', 'b', 'c', 'g'], ['a', 'b', 'd', 'e'], ['a', 'b', 'f'], ['a', 'c', 'd', 'f'], ['a', 'c', 'e'], ['a', 'd', 'g'], ['a', 'e', 'f', 'g'], ['b', 'c', 'd'], ['b', 'c', 'e', 'f'], @@ -2416,8 +2416,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: sorted([sorted(C) for C in M.nonspanning_circuits()]) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: sorted([sorted(C) for C in M.nonspanning_circuits()]) # optional - sage.rings.finite_rings [['a', 'b', 'f'], ['a', 'c', 'e'], ['a', 'd', 'g'], ['b', 'c', 'd'], ['b', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] @@ -2442,8 +2442,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: sorted([sorted(C) for C in M.cocircuits()]) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: sorted([sorted(C) for C in M.cocircuits()]) # optional - sage.rings.finite_rings [['a', 'b', 'c', 'g'], ['a', 'b', 'd', 'e'], ['a', 'c', 'd', 'f'], ['a', 'e', 'f', 'g'], ['b', 'c', 'e', 'f'], ['b', 'd', 'f', 'g'], ['c', 'd', 'e', 'g']] @@ -2471,8 +2471,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().dual() # optional - sage.libs.pari - sage: sorted([sorted(C) for C in M.noncospanning_cocircuits()]) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano().dual() # optional - sage.rings.finite_rings + sage: sorted([sorted(C) for C in M.noncospanning_cocircuits()]) # optional - sage.rings.finite_rings [['a', 'b', 'f'], ['a', 'c', 'e'], ['a', 'd', 'g'], ['b', 'c', 'd'], ['b', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] @@ -2497,17 +2497,17 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: CC = M.circuit_closures() # optional - sage.libs.pari - sage: len(CC[2]) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: CC = M.circuit_closures() # optional - sage.rings.finite_rings + sage: len(CC[2]) # optional - sage.rings.finite_rings 7 - sage: len(CC[3]) # optional - sage.libs.pari + sage: len(CC[3]) # optional - sage.rings.finite_rings 1 - sage: len(CC[1]) # optional - sage.libs.pari + sage: len(CC[1]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... KeyError: 1 - sage: [sorted(X) for X in CC[3]] # optional - sage.libs.pari + sage: [sorted(X) for X in CC[3]] # optional - sage.rings.finite_rings [['a', 'b', 'c', 'd', 'e', 'f', 'g']] """ CC = [set([]) for r in xrange(self.rank() + 1)] @@ -2534,11 +2534,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: CC = M.nonspanning_circuit_closures() # optional - sage.libs.pari - sage: len(CC[2]) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: CC = M.nonspanning_circuit_closures() # optional - sage.rings.finite_rings + sage: len(CC[2]) # optional - sage.rings.finite_rings 7 - sage: len(CC[3]) # optional - sage.libs.pari + sage: len(CC[3]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... KeyError: 3 @@ -2737,9 +2737,9 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: F = M._flags(1) # optional - sage.libs.pari - sage: sorted(M._extend_flags(F)) == sorted(M._flags(2)) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: F = M._flags(1) # optional - sage.rings.finite_rings + sage: sorted(M._extend_flags(F)) == sorted(M._flags(2)) # optional - sage.rings.finite_rings True """ newflags = [] @@ -2777,8 +2777,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: sorted([M._flags(1)]) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: sorted([M._flags(1)]) # optional - sage.rings.finite_rings [[[frozenset({'a'}), {'a'}, frozenset({'b', 'c', 'd', 'e', 'f', 'g'})], [frozenset({'b'}), {'b'}, frozenset({'c', 'd', 'e', 'f', 'g'})], [frozenset({'c'}), {'c'}, frozenset({'d', 'e', 'f', 'g'})], @@ -2815,8 +2815,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: sorted([sorted(F) for F in M.flats(2)]) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: sorted([sorted(F) for F in M.flats(2)]) # optional - sage.rings.finite_rings [['a', 'b', 'f'], ['a', 'c', 'e'], ['a', 'd', 'g'], ['b', 'c', 'd'], ['b', 'e', 'g'], ['c', 'f', 'g'], ['d', 'e', 'f']] @@ -2844,8 +2844,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Q6() # optional - sage.libs.pari - sage: sorted([sorted(F) for F in M.coflats(2)]) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Q6() # optional - sage.rings.finite_rings + sage: sorted([sorted(F) for F in M.coflats(2)]) # optional - sage.rings.finite_rings [['a', 'b'], ['a', 'c'], ['a', 'd', 'f'], ['a', 'e'], ['b', 'c'], ['b', 'd'], ['b', 'e'], ['b', 'f'], ['c', 'd'], ['c', 'e', 'f'], ['d', 'e']] @@ -2858,8 +2858,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.lattice_of_flats() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.lattice_of_flats() # optional - sage.rings.finite_rings Finite lattice containing 16 elements """ from sage.combinat.posets.lattices import LatticePoset @@ -3125,12 +3125,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.Whirl(4) # optional - sage.libs.pari + sage: M = matroids.Whirl(4) # optional - sage.rings.finite_rings sage: P = M.matroid_polytope(); P # optional - sage.geometry.polyhedron sage.libs.pari A 7-dimensional polyhedron in ZZ^8 defined as the convex hull of 46 vertices - sage: M = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings sage: M.matroid_polytope() # optional - sage.geometry.polyhedron sage.libs.pari A 6-dimensional polyhedron in ZZ^7 defined as the convex hull of 29 vertices @@ -3168,12 +3168,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.Whirl(4) # optional - sage.libs.pari + sage: M = matroids.Whirl(4) # optional - sage.rings.finite_rings sage: M.independence_matroid_polytope() # optional - sage.geometry.polyhedron sage.libs.pari A 8-dimensional polyhedron in ZZ^8 defined as the convex hull of 135 vertices - sage: M = matroids.named_matroids.NonFano() # optional - sage.libs.pari + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings sage: M.independence_matroid_polytope() # optional - sage.geometry.polyhedron sage.libs.pari A 7-dimensional polyhedron in ZZ^7 defined as the convex hull of 58 vertices @@ -3227,11 +3227,11 @@ cdef class Matroid(SageObject): TypeError: can only test for isomorphism between matroids. - sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: M1.is_isomorphic(M2) # optional - sage.libs.pari + sage: M1 = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M1.is_isomorphic(M2) # optional - sage.rings.finite_rings False - sage: M1.is_isomorphic(M2, certificate=True) # optional - sage.libs.pari + sage: M1.is_isomorphic(M2, certificate=True) # optional - sage.rings.finite_rings (False, None) """ if not isinstance(other, Matroid): @@ -3267,9 +3267,9 @@ cdef class Matroid(SageObject): sage: M1._is_isomorphic(M2, certificate=True) (True, {0: 0, 1: 1, 2: 2, 3: 3, 4: 5, 5: 4}) - sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: M1._is_isomorphic(M2) # optional - sage.libs.pari + sage: M1 = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M1._is_isomorphic(M2) # optional - sage.rings.finite_rings False """ @@ -3309,9 +3309,9 @@ cdef class Matroid(SageObject): ... TypeError: can only give isomorphism between matroids. - sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: M1.isomorphism(M2) is not None # optional - sage.libs.pari + sage: M1 = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M1.isomorphism(M2) is not None # optional - sage.rings.finite_rings False """ if not isinstance(other, Matroid): @@ -3339,9 +3339,9 @@ cdef class Matroid(SageObject): sage: morphism=M1.isomorphism(M2) sage: M1.is_isomorphism(M2, morphism) True - sage: M1 = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M2 = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: M1.isomorphism(M2) is not None # optional - sage.libs.pari + sage: M1 = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M1.isomorphism(M2) is not None # optional - sage.rings.finite_rings False """ if self is other: @@ -3385,38 +3385,38 @@ cdef class Matroid(SageObject): yields ``False``, even if the matroids are equal:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M # optional - sage.rings.finite_rings Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) - sage: M1 = BasisMatroid(M) # optional - sage.libs.pari - sage: M2 = Matroid(groundset='abcdefg', reduced_matrix=[ # optional - sage.libs.pari + sage: M1 = BasisMatroid(M) # optional - sage.rings.finite_rings + sage: M2 = Matroid(groundset='abcdefg', reduced_matrix=[ # optional - sage.rings.finite_rings ....: [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 0, 1]], field=GF(2)) - sage: M.equals(M1) # optional - sage.libs.pari + sage: M.equals(M1) # optional - sage.rings.finite_rings True - sage: M.equals(M2) # optional - sage.libs.pari + sage: M.equals(M2) # optional - sage.rings.finite_rings True - sage: M == M1 # optional - sage.libs.pari + sage: M == M1 # optional - sage.rings.finite_rings False - sage: M == M2 # optional - sage.libs.pari + sage: M == M2 # optional - sage.rings.finite_rings True :class:`LinearMatroid ` instances ``M`` and ``N`` satisfy ``M == N`` if the representations are equivalent up to row operations and column scaling:: - sage: M1 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari + sage: M1 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[1, 0, 1, 1], [0, 1, 1, 2]])) - sage: M2 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari + sage: M2 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[1, 0, 1, 1], [0, 1, 1, 3]])) - sage: M3 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari + sage: M3 = LinearMatroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[2, 6, 1, 0], [6, 1, 0, 1]])) - sage: M1.equals(M2) # optional - sage.libs.pari + sage: M1.equals(M2) # optional - sage.rings.finite_rings True - sage: M1.equals(M3) # optional - sage.libs.pari + sage: M1.equals(M3) # optional - sage.rings.finite_rings True - sage: M1 == M2 # optional - sage.libs.pari + sage: M1 == M2 # optional - sage.rings.finite_rings False - sage: M1 == M3 # optional - sage.libs.pari + sage: M1 == M3 # optional - sage.rings.finite_rings True """ if self is other: @@ -3463,19 +3463,19 @@ cdef class Matroid(SageObject): sage: N.is_isomorphism(M, {e:e for e in M.groundset()}) False - sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.libs.pari - sage: N = matroids.Wheel(3) # optional - sage.libs.pari - sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} # optional - sage.libs.pari - sage: M.is_isomorphism(N, morphism) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.rings.finite_rings + sage: N = matroids.Wheel(3) # optional - sage.rings.finite_rings + sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} # optional - sage.rings.finite_rings + sage: M.is_isomorphism(N, morphism) # optional - sage.rings.finite_rings True A morphism can be specified as a dictionary (above), a permutation, a function, and many other types of maps:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: P = PermutationGroup([[('a', 'b', 'c'), # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: P = PermutationGroup([[('a', 'b', 'c'), # optional - sage.rings.finite_rings ....: ('d', 'e', 'f'), ('g')]]).gen() - sage: M.is_isomorphism(M, P) # optional - sage.libs.pari + sage: M.is_isomorphism(M, P) # optional - sage.rings.finite_rings True sage: M = matroids.named_matroids.Pappus() @@ -3572,10 +3572,10 @@ cdef class Matroid(SageObject): sage: N._is_isomorphism(M, {e:e for e in M.groundset()}) False - sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() \ ['g'] # optional - sage.rings.finite_rings sage: N = matroids.Wheel(3) sage: morphism = {'a':0, 'b':1, 'c': 2, 'd':4, 'e':5, 'f':3} - sage: M._is_isomorphism(N, morphism) # optional - sage.libs.pari + sage: M._is_isomorphism(N, morphism) # optional - sage.rings.finite_rings True """ from . import basis_exchange_matroid @@ -3639,19 +3639,19 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M1 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari + sage: M1 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[1, 0, 1, 1], [0, 1, 1, 2]])) - sage: M2 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari + sage: M2 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[1, 0, 1, 1], [0, 1, 1, 3]])) - sage: M3 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.libs.pari + sage: M3 = Matroid(groundset='abcd', matrix=Matrix(GF(7), # optional - sage.rings.finite_rings ....: [[2, 6, 1, 0], [6, 1, 0, 1]])) - sage: M1.equals(M2) # optional - sage.libs.pari + sage: M1.equals(M2) # optional - sage.rings.finite_rings True - sage: M1.equals(M3) # optional - sage.libs.pari + sage: M1.equals(M3) # optional - sage.rings.finite_rings True - sage: M1 != M2 # indirect doctest # optional - sage.libs.pari + sage: M1 != M2 # indirect doctest # optional - sage.rings.finite_rings True - sage: M1 == M3 # indirect doctest # optional - sage.libs.pari + sage: M1 == M3 # indirect doctest # optional - sage.rings.finite_rings True """ if op not in [Py_EQ, Py_NE]: @@ -3713,10 +3713,10 @@ cdef class Matroid(SageObject): The sets of contractions and deletions need not be independent, respectively coindependent:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.rank('abf') # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.rank('abf') # optional - sage.rings.finite_rings 2 - sage: M.minor(contractions='abf') # optional - sage.libs.pari + sage: M.minor(contractions='abf') # optional - sage.rings.finite_rings Binary matroid of rank 1 on 4 elements, type (1, 0) However, they need to be subsets of the groundset, and disjoint:: @@ -3819,12 +3819,12 @@ cdef class Matroid(SageObject): :: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: sorted(M.groundset()) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - sage: M.contract(['a', 'c']) # optional - sage.libs.pari + sage: M.contract(['a', 'c']) # optional - sage.rings.finite_rings Binary matroid of rank 1 on 5 elements, type (1, 0) - sage: M.contract(['a']) == M / ['a'] # optional - sage.libs.pari + sage: M.contract(['a']) == M / ['a'] # optional - sage.rings.finite_rings True One can use a single element, rather than a set:: @@ -3837,8 +3837,8 @@ cdef class Matroid(SageObject): Note that one can iterate over strings:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M / 'abc' # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M / 'abc' # optional - sage.rings.finite_rings Binary matroid of rank 0 on 4 elements, type (0, 0) The following is therefore ambiguous. Sage will contract the single @@ -3896,12 +3896,12 @@ cdef class Matroid(SageObject): :: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: sorted(M.groundset()) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - sage: M.delete(['a', 'c']) # optional - sage.libs.pari + sage: M.delete(['a', 'c']) # optional - sage.rings.finite_rings Binary matroid of rank 3 on 5 elements, type (1, 6) - sage: M.delete(['a']) == M \ ['a'] # optional - sage.libs.pari + sage: M.delete(['a']) == M \ ['a'] # optional - sage.rings.finite_rings True One can use a single element, rather than a set:: @@ -3914,8 +3914,8 @@ cdef class Matroid(SageObject): Note that one can iterate over strings:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M \ 'abc' # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M \ 'abc' # optional - sage.rings.finite_rings Binary matroid of rank 3 on 4 elements, type (0, 5) The following is therefore ambiguous. Sage will delete the single @@ -3994,9 +3994,9 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: N = M.truncation() # optional - sage.libs.pari - sage: N.is_isomorphic(matroids.Uniform(2, 7)) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: N = M.truncation() # optional - sage.rings.finite_rings + sage: N.is_isomorphic(matroids.Uniform(2, 7)) # optional - sage.rings.finite_rings True """ if self.full_rank() == 0: @@ -4034,15 +4034,15 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.Whirl(3) - sage: matroids.named_matroids.Fano().has_minor(M) # optional - sage.libs.pari + sage: matroids.named_matroids.Fano().has_minor(M) # optional - sage.rings.finite_rings False - sage: matroids.named_matroids.NonFano().has_minor(M) # optional - sage.libs.pari + sage: matroids.named_matroids.NonFano().has_minor(M) # optional - sage.rings.finite_rings True - sage: matroids.named_matroids.NonFano().has_minor(M, certificate=True) # optional - sage.libs.pari + sage: matroids.named_matroids.NonFano().has_minor(M, certificate=True) # optional - sage.rings.finite_rings (True, (frozenset(), frozenset({'g'}), {0: 'b', 1: 'c', 2: 'a', 3: 'd', 4: 'e', 5: 'f'})) - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.has_minor(M, True) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.has_minor(M, True) # optional - sage.rings.finite_rings (True, (frozenset(), frozenset(), @@ -4083,21 +4083,21 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.N1() # optional - sage.libs.pari - sage: M.has_line_minor(4) # optional - sage.libs.pari + sage: M = matroids.named_matroids.N1() # optional - sage.rings.finite_rings + sage: M.has_line_minor(4) # optional - sage.rings.finite_rings True - sage: M.has_line_minor(5) # optional - sage.libs.pari + sage: M.has_line_minor(5) # optional - sage.rings.finite_rings False - sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c']]) # optional - sage.libs.pari + sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c']]) # optional - sage.rings.finite_rings False - sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], # optional - sage.libs.pari + sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], # optional - sage.rings.finite_rings ....: ['a', 'b', 'd' ]]) True - sage: M.has_line_minor(4, certificate=True) # optional - sage.libs.pari + sage: M.has_line_minor(4, certificate=True) # optional - sage.rings.finite_rings (True, frozenset({'a', 'b', 'd'})) - sage: M.has_line_minor(5, certificate=True) # optional - sage.libs.pari + sage: M.has_line_minor(5, certificate=True) # optional - sage.rings.finite_rings (False, None) - sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], # optional - sage.libs.pari + sage: M.has_line_minor(k=4, hyperlines=[['a', 'b', 'c'], # optional - sage.rings.finite_rings ....: ['a', 'b', 'd' ]], certificate=True) (True, frozenset({'a', 'b', 'd'})) @@ -4231,9 +4231,9 @@ cdef class Matroid(SageObject): Putting an element in parallel with another:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: N = M.extension('z', ['c']) # optional - sage.libs.pari - sage: N.rank('cz') # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: N = M.extension('z', ['c']) # optional - sage.rings.finite_rings + sage: N.rank('cz') # optional - sage.rings.finite_rings 1 """ r = self.full_rank() - 1 @@ -4304,9 +4304,9 @@ cdef class Matroid(SageObject): Put an element in series with another:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: N = M.coextension('z', ['c']) # optional - sage.libs.pari - sage: N.corank('cz') # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: N = M.coextension('z', ['c']) # optional - sage.rings.finite_rings + sage: N.corank('cz') # optional - sage.rings.finite_rings 1 """ return self.dual().extension(element, subsets).dual() @@ -4374,8 +4374,8 @@ cdef class Matroid(SageObject): The modular cut of the full groundset is equal to just the groundset:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.modular_cut([M.groundset()]).difference( # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.modular_cut([M.groundset()]).difference( # optional - sage.rings.finite_rings ....: [frozenset(M.groundset())]) set() """ @@ -4446,12 +4446,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: len(list(M.linear_subclasses())) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: len(list(M.linear_subclasses())) # optional - sage.rings.finite_rings 16 - sage: len(list(M.linear_subclasses(line_length=3))) # optional - sage.libs.pari + sage: len(list(M.linear_subclasses(line_length=3))) # optional - sage.rings.finite_rings 8 - sage: len(list(M.linear_subclasses(subsets=[{'a', 'b'}]))) # optional - sage.libs.pari + sage: len(list(M.linear_subclasses(subsets=[{'a', 'b'}]))) # optional - sage.rings.finite_rings 5 The following matroid has an extension by element `e` such that @@ -4515,14 +4515,14 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari - sage: len(list(M.extensions())) # optional - sage.libs.pari + sage: M = matroids.named_matroids.P8() # optional - sage.rings.finite_rings + sage: len(list(M.extensions())) # optional - sage.rings.finite_rings 1705 - sage: len(list(M.extensions(line_length=4))) # optional - sage.libs.pari + sage: len(list(M.extensions(line_length=4))) # optional - sage.rings.finite_rings 41 - sage: sorted(M.groundset()) # optional - sage.libs.pari + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] - sage: len(list(M.extensions(subsets=[{'a', 'b'}], line_length=4))) # optional - sage.libs.pari + sage: len(list(M.extensions(subsets=[{'a', 'b'}], line_length=4))) # optional - sage.rings.finite_rings 5 """ @@ -4583,14 +4583,14 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.P8() # optional - sage.libs.pari - sage: len(list(M.coextensions())) # optional - sage.libs.pari + sage: M = matroids.named_matroids.P8() # optional - sage.rings.finite_rings + sage: len(list(M.coextensions())) # optional - sage.rings.finite_rings 1705 - sage: len(list(M.coextensions(coline_length=4))) # optional - sage.libs.pari + sage: len(list(M.coextensions(coline_length=4))) # optional - sage.rings.finite_rings 41 - sage: sorted(M.groundset()) # optional - sage.libs.pari + sage: sorted(M.groundset()) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] - sage: len(list(M.coextensions(subsets=[{'a', 'b'}], coline_length=4))) # optional - sage.libs.pari + sage: len(list(M.coextensions(subsets=[{'a', 'b'}], coline_length=4))) # optional - sage.rings.finite_rings 5 """ @@ -4624,8 +4624,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().contract('a') # optional - sage.libs.pari - sage: M.size() - M.simplify().size() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano().contract('a') # optional - sage.rings.finite_rings + sage: M.size() - M.simplify().size() # optional - sage.rings.finite_rings 3 """ @@ -4663,8 +4663,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().dual().delete('a') # optional - sage.libs.pari - sage: M.cosimplify().size() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano().dual().delete('a') # optional - sage.rings.finite_rings + sage: M.cosimplify().size() # optional - sage.rings.finite_rings 3 """ @@ -4698,11 +4698,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.is_simple() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.is_simple() # optional - sage.rings.finite_rings True - sage: N = M / 'a' # optional - sage.libs.pari - sage: N.is_simple() # optional - sage.libs.pari + sage: N = M / 'a' # optional - sage.rings.finite_rings + sage: N.is_simple() # optional - sage.rings.finite_rings False """ if self._closure(frozenset()): @@ -4734,11 +4734,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano().dual() # optional - sage.libs.pari - sage: M.is_cosimple() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano().dual() # optional - sage.rings.finite_rings + sage: M.is_cosimple() # optional - sage.rings.finite_rings True - sage: N = M \ 'a' # optional - sage.libs.pari - sage: N.is_cosimple() # optional - sage.libs.pari + sage: N = M \ 'a' # optional - sage.rings.finite_rings + sage: N.is_cosimple() # optional - sage.rings.finite_rings False """ if self._coclosure(frozenset()): @@ -5281,14 +5281,14 @@ cdef class Matroid(SageObject): (False, True) sage: matroids.Uniform(4, 8).is_4connected() True - sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.libs.pari + sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.rings.finite_rings ....: [0,1,0,1,0,1,0,1,0,0,0,1], ....: [0,0,1,1,0,0,1,1,0,1,0,1], ....: [0,0,0,0,1,1,1,1,0,0,1,1], ....: [0,0,0,0,0,0,0,0,1,1,1,1]]) - sage: M.is_4connected() == M.is_4connected(algorithm="shifting") # optional - sage.libs.pari + sage: M.is_4connected() == M.is_4connected(algorithm="shifting") # optional - sage.rings.finite_rings True - sage: M.is_4connected() == M.is_4connected(algorithm="intersection") # optional - sage.libs.pari + sage: M.is_4connected() == M.is_4connected(algorithm="intersection") # optional - sage.rings.finite_rings True """ if algorithm is None or algorithm == "intersection": @@ -5530,12 +5530,12 @@ cdef class Matroid(SageObject): (False, True) sage: matroids.Uniform(4, 8)._is_4connected_shifting() True - sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], + sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.rings.finite_rings ....: [0,1,0,1,0,1,0,1,0,0,0,1], ....: [0,0,1,1,0,0,1,1,0,1,0,1], ....: [0,0,0,0,1,1,1,1,0,0,1,1], ....: [0,0,0,0,0,0,0,0,1,1,1,1]]) - sage: M._is_4connected_shifting() + sage: M._is_4connected_shifting() # optional - sage.rings.finite_rings True """ if self.rank()>self.size()-self.rank(): @@ -5636,18 +5636,20 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.libs.pari + sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.rings.finite_rings ....: [0,1,0,1,0,1,0,1,0,0,0,1], ....: [0,0,1,1,0,0,1,1,0,1,0,1], ....: [0,0,0,0,1,1,1,1,0,0,1,1], ....: [0,0,0,0,0,0,0,0,1,1,1,1]]) - sage: M._shifting_all(M.basis(),set([0,1]),set([0,1]),set([]),set([]),3) # optional - sage.libs.pari + sage: M._shifting_all(M.basis(), # optional - sage.rings.finite_rings + ....: set([0,1]), set([0,1]), set([]), set([]), 3) (False, None) - sage: M = Matroid(field=GF(2), reduced_matrix=[[1,0,1,1,1], # optional - sage.libs.pari + sage: M = Matroid(field=GF(2), reduced_matrix=[[1,0,1,1,1], # optional - sage.rings.finite_rings ....: [1,1,1,1,0], ....: [0,1,1,1,0], ....: [0,0,0,1,1]]) - sage: M._shifting_all(M.basis(), set([0,1]), set([5,8]), set([]), set([]), 3)[0] # optional - sage.libs.pari + sage: M._shifting_all(M.basis(), # optional - sage.rings.finite_rings + ....: set([0,1]), set([5,8]), set([]), set([]), 3)[0] True """ @@ -5672,8 +5674,8 @@ cdef class Matroid(SageObject): Given a basis ``X``. If the submatrix of the partial matrix using rows `X_1` columns `Y_2` and submatrix using rows `X_2` columns `Y_1` can be extended to a ``m``-separator, then it returns - `True, E`, where `E` is a ``m``-separator. Otherwise it returns - `False, None` + ``True, E``, where `E` is a ``m``-separator. Otherwise it returns + ``False, None`` `X_1` and `X_2` must be disjoint subsets of `X`. `Y_1` and `Y_2` must be disjoint subsets of `Y`. @@ -5691,23 +5693,25 @@ cdef class Matroid(SageObject): OUTPUT: - - `False, None` -- if there is no ``m``-separator. - - `True, E` -- if there exist a ``m``-separator ``E``. + - ``False, None`` -- if there is no ``m``-separator. + - ``True, E`` -- if there exist a ``m``-separator ``E``. EXAMPLES:: - sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.libs.pari + sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.rings.finite_rings ....: [0,1,0,1,0,1,0,1,0,0,0,1], ....: [0,0,1,1,0,0,1,1,0,1,0,1], ....: [0,0,0,0,1,1,1,1,0,0,1,1], ....: [0,0,0,0,0,0,0,0,1,1,1,1]]) - sage: M._shifting(M.basis(),set([0,1]),set([0,1]),set([]),set([]),3) # optional - sage.libs.pari + sage: M._shifting(M.basis(), # optional - sage.rings.finite_rings + ....: set([0,1]), set([0,1]), set([]), set([]), 3) (False, None) - sage: M = Matroid(field=GF(2), reduced_matrix=[[1,0,1,1,1], # optional - sage.libs.pari + sage: M = Matroid(field=GF(2), reduced_matrix=[[1,0,1,1,1], # optional - sage.rings.finite_rings ....: [1,1,1,1,0], ....: [0,1,1,1,0], ....: [0,0,0,1,1]]) - sage: M._shifting(M.basis(), set([0,1]), set([5,8]), set([]), set([4]), 3)[0] # optional - sage.libs.pari + sage: M._shifting(M.basis(), # optional - sage.rings.finite_rings + ....: set([0,1]), set([5,8]), set([]), set([4]), 3)[0] True """ @@ -5784,15 +5788,14 @@ cdef class Matroid(SageObject): ....: [0, 0, 1, 0, 0, 1]]) sage: M._is_3connected_BC() False - sage: N = Matroid(circuit_closures={2: ['abc', 'cdef'], - ....: 3: ['abcdef']}, + sage: N = Matroid(circuit_closures={2: ['abc', 'cdef'], 3: ['abcdef']}, ....: groundset='abcdef') sage: N._is_3connected_BC() False sage: matroids.named_matroids.BetsyRoss()._is_3connected_BC() True - sage: M = matroids.named_matroids.R6() # optional - sage.libs.pari - sage: M._is_3connected_BC() # optional - sage.libs.pari + sage: M = matroids.named_matroids.R6() # optional - sage.rings.finite_rings + sage: M._is_3connected_BC() # optional - sage.rings.finite_rings False """ # The 5 stages of the algorithm @@ -5837,9 +5840,9 @@ cdef class Matroid(SageObject): sage: M._is_3connected_BC_recursion(B, ....: [M.fundamental_cocircuit(B, e) for e in B]) True - sage: M = matroids.named_matroids.R6() # optional - sage.libs.pari - sage: B = M.basis() # optional - sage.libs.pari - sage: M._is_3connected_BC_recursion(B, # optional - sage.libs.pari + sage: M = matroids.named_matroids.R6() # optional - sage.rings.finite_rings + sage: B = M.basis() # optional - sage.rings.finite_rings + sage: M._is_3connected_BC_recursion(B, # optional - sage.rings.finite_rings ....: [M.fundamental_cocircuit(B, e) for e in B]) False @@ -5929,13 +5932,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M = N._local_binary_matroid() # optional - sage.libs.pari - sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.libs.pari + sage: N = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M = N._local_binary_matroid() # optional - sage.rings.finite_rings + sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.rings.finite_rings True - sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: M = N._local_binary_matroid() # optional - sage.libs.pari - sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.libs.pari + sage: N = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M = N._local_binary_matroid() # optional - sage.rings.finite_rings + sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.rings.finite_rings False """ if basis is None: @@ -5987,11 +5990,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.binary_matroid() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.binary_matroid() # optional - sage.rings.finite_rings Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) - sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: N.binary_matroid() is None # optional - sage.libs.pari + sage: N = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: N.binary_matroid() is None # optional - sage.rings.finite_rings True """ @@ -6039,11 +6042,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: N.is_binary() # optional - sage.libs.pari + sage: N = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: N.is_binary() # optional - sage.rings.finite_rings True - sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: N.is_binary() # optional - sage.libs.pari + sage: N = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: N.is_binary() # optional - sage.rings.finite_rings False """ @@ -6080,13 +6083,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M = N._local_ternary_matroid() # optional - sage.libs.pari - sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.libs.pari + sage: N = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M = N._local_ternary_matroid() # optional - sage.rings.finite_rings + sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.rings.finite_rings False - sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: M = N._local_ternary_matroid() # optional - sage.libs.pari - sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.libs.pari + sage: N = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M = N._local_ternary_matroid() # optional - sage.rings.finite_rings + sage: N.is_isomorphism(M, {e:e for e in N.groundset()}) # optional - sage.rings.finite_rings True """ if basis is None: @@ -6172,11 +6175,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.ternary_matroid() is None # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.ternary_matroid() is None # optional - sage.rings.finite_rings True - sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: N.ternary_matroid() # optional - sage.libs.pari + sage: N = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: N.ternary_matroid() # optional - sage.rings.finite_rings NonFano: Ternary matroid of rank 3 on 7 elements, type 0- """ @@ -6224,11 +6227,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: N = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: N.is_ternary() # optional - sage.libs.pari + sage: N = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: N.is_ternary() # optional - sage.rings.finite_rings False - sage: N = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: N.is_ternary() # optional - sage.libs.pari + sage: N = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: N.is_ternary() # optional - sage.rings.finite_rings True """ @@ -6392,15 +6395,15 @@ cdef class Matroid(SageObject): sage: M = matroids.Uniform(2,4) sage: [M.is_chordal(i) for i in range(4, 8)] [True, True, True, True] - sage: M = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: [M.is_chordal(i) for i in range(4, 8)] # optional - sage.libs.pari + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: [M.is_chordal(i) for i in range(4, 8)] # optional - sage.rings.finite_rings [False, True, True, True] - sage: M = matroids.named_matroids.N2() # optional - sage.libs.pari - sage: [M.is_chordal(i) for i in range(4, 10)] # optional - sage.libs.pari + sage: M = matroids.named_matroids.N2() # optional - sage.rings.finite_rings + sage: [M.is_chordal(i) for i in range(4, 10)] # optional - sage.rings.finite_rings [False, False, False, False, True, True] - sage: M.is_chordal(4, 5) # optional - sage.libs.pari + sage: M.is_chordal(4, 5) # optional - sage.rings.finite_rings False - sage: M.is_chordal(4, 5, certificate=True) # optional - sage.libs.pari + sage: M.is_chordal(4, 5, certificate=True) # optional - sage.rings.finite_rings (False, frozenset({'a', 'b', 'e', 'f', 'g'})) """ cdef frozenset C @@ -6428,11 +6431,11 @@ cdef class Matroid(SageObject): sage: M = matroids.Uniform(2,4) sage: M.chordality() 4 - sage: M = matroids.named_matroids.NonFano() # optional - sage.libs.pari - sage: M.chordality() # optional - sage.libs.pari + sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M.chordality() # optional - sage.rings.finite_rings 5 - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.chordality() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.chordality() # optional - sage.rings.finite_rings 4 """ cdef frozenset C @@ -6474,14 +6477,14 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: X = M.max_weight_independent() # optional - sage.libs.pari - sage: M.is_basis(X) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: X = M.max_weight_independent() # optional - sage.rings.finite_rings + sage: M.is_basis(X) # optional - sage.rings.finite_rings True sage: wt = {'a': 1, 'b': 2, 'c': 2, 'd': 1/2, 'e': 1, ....: 'f': 2, 'g': 2} - sage: setprint(M.max_weight_independent(weights=wt)) # optional - sage.libs.pari + sage: setprint(M.max_weight_independent(weights=wt)) # optional - sage.rings.finite_rings {'b', 'f', 'g'} sage: def wt(x): ....: return x @@ -6561,18 +6564,16 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: X = M.max_weight_coindependent() # optional - sage.libs.pari - sage: M.is_cobasis(X) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: X = M.max_weight_coindependent() # optional - sage.rings.finite_rings + sage: M.is_cobasis(X) # optional - sage.rings.finite_rings True - sage: wt = {'a': 1, 'b': 2, 'c': 2, 'd': 1/2, 'e': 1, 'f': 2, - ....: 'g': 2} - sage: setprint(M.max_weight_coindependent(weights=wt)) # optional - sage.libs.pari + sage: wt = {'a': 1, 'b': 2, 'c': 2, 'd': 1/2, 'e': 1, 'f': 2, 'g': 2} + sage: setprint(M.max_weight_coindependent(weights=wt)) # optional - sage.rings.finite_rings {'b', 'c', 'f', 'g'} - sage: wt = {'a': 1, 'b': -10, 'c': 2, 'd': 1/2, 'e': 1, 'f': 2, - ....: 'g': 2} - sage: setprint(M.max_weight_coindependent(weights=wt)) # optional - sage.libs.pari + sage: wt = {'a': 1, 'b': -10, 'c': 2, 'd': 1/2, 'e': 1, 'f': 2, 'g': 2} + sage: setprint(M.max_weight_coindependent(weights=wt)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: nonnegative weights were expected. @@ -6643,9 +6644,7 @@ cdef class Matroid(SageObject): - ``weights`` -- a dictionary or function mapping the elements of ``X`` to nonnegative weights. - OUTPUT: - - Boolean. + OUTPUT: Boolean. ALGORITHM: @@ -6660,8 +6659,8 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.is_max_weight_independent_generic() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.is_max_weight_independent_generic() # optional - sage.rings.finite_rings False sage: def wt(x): @@ -6810,8 +6809,8 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.is_max_weight_coindependent_generic() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.is_max_weight_coindependent_generic() # optional - sage.rings.finite_rings False sage: def wt(x): @@ -6958,18 +6957,18 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari + sage: M = matroids.named_matroids.T12() # optional - sage.rings.finite_rings + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.rings.finite_rings sage: w = {'a':30, 'b':10, 'c':11, 'd':20, 'e':70, 'f':21, 'g':90, ....: 'h':12, 'i':80, 'j':13, 'k':40, 'l':21} - sage: Y = M.intersection(N, w) # optional - sage.libs.pari - sage: sorted(Y) # optional - sage.libs.pari + sage: Y = M.intersection(N, w) # optional - sage.rings.finite_rings + sage: sorted(Y) # optional - sage.rings.finite_rings ['a', 'd', 'e', 'g', 'i', 'k'] - sage: sum([w[y] for y in Y]) # optional - sage.libs.pari + sage: sum([w[y] for y in Y]) # optional - sage.rings.finite_rings 330 - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings sage: N = matroids.Uniform(4, 7) - sage: M.intersection(N) # optional - sage.libs.pari + sage: M.intersection(N) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matroid intersection requires equal groundsets. @@ -7017,14 +7016,14 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari + sage: M = matroids.named_matroids.T12() # optional - sage.rings.finite_rings + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.rings.finite_rings sage: w = {'a':30, 'b':10, 'c':11, 'd':20, 'e':70, 'f':21, 'g':90, ....: 'h':12, 'i':80, 'j':13, 'k':40, 'l':21} - sage: Y = M._intersection(N, w) # optional - sage.libs.pari - sage: sorted(Y) # optional - sage.libs.pari + sage: Y = M._intersection(N, w) # optional - sage.rings.finite_rings + sage: sorted(Y) # optional - sage.rings.finite_rings ['a', 'd', 'e', 'g', 'i', 'k'] - sage: sum([w[y] for y in Y]) # optional - sage.libs.pari + sage: sum([w[y] for y in Y]) # optional - sage.rings.finite_rings 330 """ Y = set() @@ -7063,14 +7062,14 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari + sage: M = matroids.named_matroids.T12() # optional - sage.rings.finite_rings + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.rings.finite_rings sage: w = {'a':30, 'b':10, 'c':11, 'd':20, 'e':70, 'f':21, 'g':90, ....: 'h':12, 'i':80, 'j':13, 'k':40, 'l':21} - sage: Y = M.intersection(N, w) # optional - sage.libs.pari - sage: sorted(Y) # optional - sage.libs.pari + sage: Y = M.intersection(N, w) # optional - sage.rings.finite_rings + sage: sorted(Y) # optional - sage.rings.finite_rings ['a', 'd', 'e', 'g', 'i', 'k'] - sage: M._intersection_augmentation(N, w, Y)[0] # optional - sage.libs.pari + sage: M._intersection_augmentation(N, w, Y)[0] # optional - sage.rings.finite_rings False """ X = self.groundset() - Y @@ -7144,13 +7143,13 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari - sage: len(M.intersection_unweighted(N)) # optional - sage.libs.pari + sage: M = matroids.named_matroids.T12() # optional - sage.rings.finite_rings + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.rings.finite_rings + sage: len(M.intersection_unweighted(N)) # optional - sage.rings.finite_rings 6 - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: N = matroids.Uniform(4, 7) # optional - sage.libs.pari - sage: M.intersection_unweighted(N) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: N = matroids.Uniform(4, 7) # optional - sage.rings.finite_rings + sage: M.intersection_unweighted(N) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: matroid intersection requires equal groundsets. @@ -7185,9 +7184,9 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari - sage: len(M._intersection_unweighted(N)) # optional - sage.libs.pari + sage: M = matroids.named_matroids.T12() # optional - sage.rings.finite_rings + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.rings.finite_rings + sage: len(M._intersection_unweighted(N)) # optional - sage.rings.finite_rings 6 """ Y = set() @@ -7219,15 +7218,15 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.T12() # optional - sage.libs.pari - sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.libs.pari - sage: Y = M.intersection(N) # optional - sage.libs.pari - sage: M._intersection_augmentation_unweighted(N, Y)[0] # optional - sage.libs.pari + sage: M = matroids.named_matroids.T12() # optional - sage.rings.finite_rings + sage: N = matroids.named_matroids.ExtendedTernaryGolayCode() # optional - sage.rings.finite_rings + sage: Y = M.intersection(N) # optional - sage.rings.finite_rings + sage: M._intersection_augmentation_unweighted(N, Y)[0] # optional - sage.rings.finite_rings False - sage: Y = M._intersection_augmentation_unweighted(N,set()) # optional - sage.libs.pari - sage: Y[0] # optional - sage.libs.pari + sage: Y = M._intersection_augmentation_unweighted(N,set()) # optional - sage.rings.finite_rings + sage: Y[0] # optional - sage.rings.finite_rings True - sage: len(Y[1])>0 # optional - sage.libs.pari + sage: len(Y[1])>0 # optional - sage.rings.finite_rings True """ E = self.groundset() @@ -7425,10 +7424,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: sorted(M._internal({'a', 'b', 'c'})) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: sorted(M._internal({'a', 'b', 'c'})) # optional - sage.rings.finite_rings ['a', 'b', 'c'] - sage: sorted(M._internal({'e', 'f', 'g'})) # optional - sage.libs.pari + sage: sorted(M._internal({'e', 'f', 'g'})) # optional - sage.rings.finite_rings [] """ N = self.groundset() - B @@ -7464,10 +7463,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: sorted(M._external({'a', 'b', 'c'})) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: sorted(M._external({'a', 'b', 'c'})) # optional - sage.rings.finite_rings [] - sage: sorted(M._external({'e', 'f', 'g'})) # optional - sage.libs.pari + sage: sorted(M._external({'e', 'f', 'g'})) # optional - sage.rings.finite_rings ['a', 'b', 'c', 'd'] """ @@ -7517,10 +7516,10 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.tutte_polynomial() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.tutte_polynomial() # optional - sage.rings.finite_rings y^4 + x^3 + 3*y^3 + 4*x^2 + 7*x*y + 6*y^2 + 3*x + 3*y - sage: M.tutte_polynomial(1, 1) == M.bases_count() # optional - sage.libs.pari + sage: M.tutte_polynomial(1, 1) == M.bases_count() # optional - sage.rings.finite_rings True ALGORITHM: @@ -7565,8 +7564,8 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: setprint(M.flat_cover()) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: setprint(M.flat_cover()) # optional - sage.rings.finite_rings [{'a', 'b', 'f'}, {'a', 'c', 'e'}, {'a', 'd', 'g'}, {'b', 'c', 'd'}, {'b', 'e', 'g'}, {'c', 'f', 'g'}, {'d', 'e', 'f'}] @@ -7634,21 +7633,21 @@ cdef class Matroid(SageObject): We construct a more interesting example using the Fano matroid:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: A = M.chow_ring(QQ) # optional - sage.libs.pari - sage: A # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: A = M.chow_ring(QQ) # optional - sage.rings.finite_rings + sage: A # optional - sage.rings.finite_rings Chow ring of Fano: Binary matroid of rank 3 on 7 elements, type (3, 0) over Rational Field Next we get the non-trivial generators and do some computations:: - sage: G = A.gens()[6:] # optional - sage.libs.pari - sage: Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef = G # optional - sage.libs.pari - sage: Ag * Ag # optional - sage.libs.pari + sage: G = A.gens()[6:] # optional - sage.rings.finite_rings + sage: Ag, Aabf, Aace, Aadg, Abcd, Abeg, Acfg, Adef = G # optional - sage.rings.finite_rings + sage: Ag * Ag # optional - sage.rings.finite_rings 2*Adef^2 - sage: Ag * Abeg # optional - sage.libs.pari + sage: Ag * Abeg # optional - sage.rings.finite_rings -Adef^2 - sage: matrix([[x * y for x in G] for y in G]) # optional - sage.libs.pari + sage: matrix([[x * y for x in G] for y in G]) # optional - sage.rings.finite_rings [2*Adef^2 0 0 -Adef^2 0 -Adef^2 -Adef^2 0] [ 0 Adef^2 0 0 0 0 0 0] [ 0 0 Adef^2 0 0 0 0 0] @@ -7723,11 +7722,11 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: G = M.plot() # optional - sage.libs.pari sage.plot - sage: type(G) # optional - sage.libs.pari sage.plot + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: G = M.plot() # optional - sage.rings.finite_rings sage.plot + sage: type(G) # optional - sage.rings.finite_rings sage.plot - sage: G.show() # optional - sage.libs.pari sage.plot + sage: G.show() # optional - sage.rings.finite_rings sage.plot """ from . import matroids_plot_helpers @@ -7780,12 +7779,12 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.TernaryDowling3() # optional - sage.libs.pari - sage: M.show(B=['a','b','c']) # optional - sage.libs.pari sage.plot - sage: M.show(B=['a','b','c'], lineorders=[['f','e','i']]) # optional - sage.libs.pari sage.plot - sage: pos = {'a':(0,0), 'b': (0,1), 'c':(1,0), 'd':(1,1), # optional - sage.libs.pari sage.plot + sage: M = matroids.named_matroids.TernaryDowling3() # optional - sage.rings.finite_rings + sage: M.show(B=['a','b','c']) # optional - sage.rings.finite_rings sage.plot + sage: M.show(B=['a','b','c'], lineorders=[['f','e','i']]) # optional - sage.rings.finite_rings sage.plot + sage: pos = {'a':(0,0), 'b': (0,1), 'c':(1,0), 'd':(1,1), # optional - sage.rings.finite_rings sage.plot ....: 'e':(1,-1), 'f':(-1,1), 'g':(-1,-1),'h':(2,0), 'i':(0,2)} - sage: M.show(pos_method=1, pos_dict=pos, lims=[-3,3,-3,3]) # optional - sage.libs.pari sage.plot + sage: M.show(pos_method=1, pos_dict=pos, lims=[-3,3,-3,3]) # optional - sage.rings.finite_rings sage.plot """ if self.rank() > 3: raise NotImplementedError @@ -7887,8 +7886,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: B = M.bergman_complex(); B # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: B = M.bergman_complex(); B # optional - sage.rings.finite_rings Simplicial complex with 14 vertices and 21 facets .. SEEALSO:: @@ -7926,8 +7925,8 @@ cdef class Matroid(SageObject): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: A = M.augmented_bergman_complex(); A # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: A = M.augmented_bergman_complex(); A # optional - sage.rings.finite_rings Simplicial complex with 22 vertices and 91 facets sage: M = matroids.Uniform(2,3) @@ -8060,7 +8059,7 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.named_matroids.Pappus() - sage: N = matroids.named_matroids.Fano().direct_sum(M); N # optional - sage.libs.pari + sage: N = matroids.named_matroids.Fano().direct_sum(M); N # optional - sage.rings.finite_rings Matroid of rank 6 on 16 elements as matroid sum of Binary matroid of rank 3 on 7 elements, type (3, 0) Matroid of rank 3 on 9 elements with circuit-closures @@ -8068,9 +8067,9 @@ cdef class Matroid(SageObject): {'b', 'd', 'i'}, {'b', 'f', 'g'}, {'c', 'd', 'h'}, {'c', 'e', 'g'}, {'d', 'e', 'f'}, {'g', 'h', 'i'}}, 3: {{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}}} - sage: len(N.independent_sets()) # optional - sage.libs.pari + sage: len(N.independent_sets()) # optional - sage.rings.finite_rings 6897 - sage: len(N.bases()) # optional - sage.libs.pari + sage: len(N.bases()) # optional - sage.rings.finite_rings 2100 """ from . import union_matroid diff --git a/src/sage/matroids/minor_matroid.py b/src/sage/matroids/minor_matroid.py index 7c5cbbc55ba..1c27166d4f8 100644 --- a/src/sage/matroids/minor_matroid.py +++ b/src/sage/matroids/minor_matroid.py @@ -13,23 +13,23 @@ EXAMPLES:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M \ ['a', 'c' ] == M.delete(['a', 'c']) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M \ ['a', 'c' ] == M.delete(['a', 'c']) # optional - sage.rings.finite_rings True - sage: M / 'a' == M.contract('a') # optional - sage.libs.pari + sage: M / 'a' == M.contract('a') # optional - sage.rings.finite_rings True - sage: M / 'c' \ 'ab' == M.minor(contractions='c', deletions='ab') # optional - sage.libs.pari + sage: M / 'c' \ 'ab' == M.minor(contractions='c', deletions='ab') # optional - sage.rings.finite_rings True If a contraction set is not independent (or a deletion set not coindependent), this is taken care of:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.rank('abf') # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.rank('abf') # optional - sage.rings.finite_rings 2 - sage: M / 'abf' == M / 'ab' \ 'f' # optional - sage.libs.pari + sage: M / 'abf' == M / 'ab' \ 'f' # optional - sage.rings.finite_rings True - sage: M / 'abf' == M / 'af' \ 'b' # optional - sage.libs.pari + sage: M / 'abf' == M / 'af' \ 'b' # optional - sage.rings.finite_rings True .. SEEALSO:: @@ -132,9 +132,9 @@ def __init__(self, matroid, contractions=None, deletions=None): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = MinorMatroid(matroids.named_matroids.Fano(), # indirect doctest # optional - sage.libs.pari + sage: M = MinorMatroid(matroids.named_matroids.Fano(), # indirect doctest # optional - sage.rings.finite_rings ....: contractions=set(), deletions=set(['g'])) - sage: M.is_isomorphic(matroids.Wheel(3)) # optional - sage.libs.pari + sage: M.is_isomorphic(matroids.Wheel(3)) # optional - sage.rings.finite_rings True """ if not isinstance(matroid, Matroid): @@ -423,15 +423,15 @@ def __eq__(self, other): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M1 = MinorMatroid(M, set('ab'), set('f')) # optional - sage.libs.pari - sage: M2 = MinorMatroid(M, set('af'), set('b')) # optional - sage.libs.pari - sage: M3 = MinorMatroid(M, set('a'), set('f'))._minor(set('b'), set()) # optional - sage.libs.pari - sage: M1 == M2 # indirect doctest # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M1 = MinorMatroid(M, set('ab'), set('f')) # optional - sage.rings.finite_rings + sage: M2 = MinorMatroid(M, set('af'), set('b')) # optional - sage.rings.finite_rings + sage: M3 = MinorMatroid(M, set('a'), set('f'))._minor(set('b'), set()) # optional - sage.rings.finite_rings + sage: M1 == M2 # indirect doctest # optional - sage.rings.finite_rings False - sage: M1.equals(M2) # optional - sage.libs.pari + sage: M1.equals(M2) # optional - sage.rings.finite_rings True - sage: M1 == M3 # optional - sage.libs.pari + sage: M1 == M3 # optional - sage.rings.finite_rings True """ if not isinstance(other, MinorMatroid): @@ -455,15 +455,15 @@ def __ne__(self, other): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M1 = MinorMatroid(M, set('ab'), set('f')) # optional - sage.libs.pari - sage: M2 = MinorMatroid(M, set('af'), set('b')) # optional - sage.libs.pari - sage: M3 = MinorMatroid(M, set('a'), set('f'))._minor(set('b'), set()) # optional - sage.libs.pari - sage: M1 != M2 # indirect doctest # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M1 = MinorMatroid(M, set('ab'), set('f')) # optional - sage.rings.finite_rings + sage: M2 = MinorMatroid(M, set('af'), set('b')) # optional - sage.rings.finite_rings + sage: M3 = MinorMatroid(M, set('a'), set('f'))._minor(set('b'), set()) # optional - sage.rings.finite_rings + sage: M1 != M2 # indirect doctest # optional - sage.rings.finite_rings True - sage: M1.equals(M2) # optional - sage.libs.pari + sage: M1.equals(M2) # optional - sage.rings.finite_rings True - sage: M1 != M3 # optional - sage.libs.pari + sage: M1 != M3 # optional - sage.rings.finite_rings False """ return not self == other diff --git a/src/sage/matroids/set_system.pyx b/src/sage/matroids/set_system.pyx index 9b68cfe342d..a157b1115d4 100644 --- a/src/sage/matroids/set_system.pyx +++ b/src/sage/matroids/set_system.pyx @@ -38,8 +38,8 @@ cdef class SetSystem: contents. One is most likely to encounter these as output from some Matroid methods:: - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: M.circuits() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M.circuits() # optional - sage.rings.finite_rings Iterator over a system of subsets To access the sets in this structure, simply iterate over them. The @@ -729,9 +729,9 @@ cdef class SetSystem: Check that :trac:`15189` is fixed:: - sage: M = Matroid(ring=GF(5), reduced_matrix=[[1,0,3],[0,1,1],[1,1,0]]) # optional - sage.libs.pari - sage: N = Matroid(ring=GF(5), reduced_matrix=[[1,0,1],[0,1,1],[1,1,0]]) # optional - sage.libs.pari - sage: M.is_field_isomorphic(N) # optional - sage.libs.pari + sage: M = Matroid(ring=GF(5), reduced_matrix=[[1,0,3],[0,1,1],[1,1,0]]) # optional - sage.rings.finite_rings + sage: N = Matroid(ring=GF(5), reduced_matrix=[[1,0,1],[0,1,1],[1,1,0]]) # optional - sage.rings.finite_rings + sage: M.is_field_isomorphic(N) # optional - sage.rings.finite_rings False sage: any(M.is_field_isomorphism(N, p) for p in Permutations(range(6))) # optional - sage.combinat sage.libs.pari False diff --git a/src/sage/matroids/unpickling.pyx b/src/sage/matroids/unpickling.pyx index 8916067025c..a0f8ab1067d 100644 --- a/src/sage/matroids/unpickling.pyx +++ b/src/sage/matroids/unpickling.pyx @@ -211,11 +211,11 @@ def unpickle_binary_matrix(version, data): EXAMPLES:: sage: from sage.matroids.lean_matrix import * - sage: A = BinaryMatrix(2, 5) # optional - sage.libs.pari - sage: A == loads(dumps(A)) # indirect doctest # optional - sage.libs.pari + sage: A = BinaryMatrix(2, 5) # optional - sage.rings.finite_rings + sage: A == loads(dumps(A)) # indirect doctest # optional - sage.rings.finite_rings True - sage: C = BinaryMatrix(2, 2, Matrix(GF(2), [[1, 1], [0, 1]])) # optional - sage.libs.pari - sage: C == loads(dumps(C)) # optional - sage.libs.pari + sage: C = BinaryMatrix(2, 2, Matrix(GF(2), [[1, 1], [0, 1]])) # optional - sage.rings.finite_rings + sage: C == loads(dumps(C)) # optional - sage.rings.finite_rings True """ cdef BinaryMatrix A @@ -240,11 +240,11 @@ def unpickle_ternary_matrix(version, data): EXAMPLES:: sage: from sage.matroids.lean_matrix import * - sage: A = TernaryMatrix(2, 5) # optional - sage.libs.pari - sage: A == loads(dumps(A)) # indirect doctest # optional - sage.libs.pari + sage: A = TernaryMatrix(2, 5) # optional - sage.rings.finite_rings + sage: A == loads(dumps(A)) # indirect doctest # optional - sage.rings.finite_rings True - sage: C = TernaryMatrix(2, 2, Matrix(GF(3), [[1, 1], [0, 1]])) # optional - sage.libs.pari - sage: C == loads(dumps(C)) # optional - sage.libs.pari + sage: C = TernaryMatrix(2, 2, Matrix(GF(3), [[1, 1], [0, 1]])) # optional - sage.rings.finite_rings + sage: C == loads(dumps(C)) # optional - sage.rings.finite_rings True """ cdef TernaryMatrix A @@ -270,11 +270,11 @@ def unpickle_quaternary_matrix(version, data): EXAMPLES:: sage: from sage.matroids.lean_matrix import * - sage: A = QuaternaryMatrix(2, 5, ring=GF(4, 'x')) # optional - sage.libs.pari - sage: A == loads(dumps(A)) # indirect doctest # optional - sage.libs.pari + sage: A = QuaternaryMatrix(2, 5, ring=GF(4, 'x')) # optional - sage.rings.finite_rings + sage: A == loads(dumps(A)) # indirect doctest # optional - sage.rings.finite_rings True - sage: C = QuaternaryMatrix(2, 2, Matrix(GF(4, 'x'), [[1, 1], [0, 1]])) # optional - sage.libs.pari - sage: C == loads(dumps(C)) # optional - sage.libs.pari + sage: C = QuaternaryMatrix(2, 2, Matrix(GF(4, 'x'), [[1, 1], [0, 1]])) # optional - sage.rings.finite_rings + sage: C == loads(dumps(C)) # optional - sage.rings.finite_rings True """ cdef QuaternaryMatrix A @@ -388,12 +388,12 @@ def unpickle_linear_matroid(version, data): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], # optional - sage.libs.pari + sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], # optional - sage.rings.finite_rings ....: [0, 1, 1, 1, 3]])) - sage: M == loads(dumps(M)) # indirect doctest # optional - sage.libs.pari + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.rings.finite_rings True - sage: M.rename("U35") # optional - sage.libs.pari - sage: loads(dumps(M)) # optional - sage.libs.pari + sage: M.rename("U35") # optional - sage.rings.finite_rings + sage: loads(dumps(M)) # optional - sage.rings.finite_rings U35 """ if version != 0: @@ -434,12 +434,12 @@ def unpickle_binary_matroid(version, data): EXAMPLES:: - sage: M = Matroid(Matrix(GF(2), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.libs.pari + sage: M = Matroid(Matrix(GF(2), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.rings.finite_rings ....: [0, 0, 1, 1]])) - sage: M == loads(dumps(M)) # indirect doctest # optional - sage.libs.pari + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.rings.finite_rings True - sage: M.rename("U34") # optional - sage.libs.pari - sage: loads(dumps(M)) # optional - sage.libs.pari + sage: M.rename("U34") # optional - sage.rings.finite_rings + sage: loads(dumps(M)) # optional - sage.rings.finite_rings U34 """ if version != 0: @@ -481,12 +481,12 @@ def unpickle_ternary_matroid(version, data): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = TernaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.libs.pari + sage: M = TernaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.rings.finite_rings ....: [0, 0, 1, 1]])) - sage: M == loads(dumps(M)) # indirect doctest # optional - sage.libs.pari + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.rings.finite_rings True - sage: M.rename("U34") # optional - sage.libs.pari - sage: loads(dumps(M)) # optional - sage.libs.pari + sage: M.rename("U34") # optional - sage.rings.finite_rings + sage: loads(dumps(M)) # optional - sage.rings.finite_rings U34 """ if version != 0: @@ -528,16 +528,16 @@ def unpickle_quaternary_matroid(version, data): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = QuaternaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.libs.pari + sage: M = QuaternaryMatroid(Matrix(GF(3), [[1, 0, 0, 1], [0, 1, 0, 1], # optional - sage.rings.finite_rings ....: [0, 0, 1, 1]])) - sage: M == loads(dumps(M)) # indirect doctest # optional - sage.libs.pari + sage: M == loads(dumps(M)) # indirect doctest # optional - sage.rings.finite_rings True - sage: M.rename("U34") # optional - sage.libs.pari - sage: loads(dumps(M)) # optional - sage.libs.pari + sage: M.rename("U34") # optional - sage.rings.finite_rings + sage: loads(dumps(M)) # optional - sage.rings.finite_rings U34 - sage: M = QuaternaryMatroid(Matrix(GF(4, 'x'), [[1, 0, 1], # optional - sage.libs.pari + sage: M = QuaternaryMatroid(Matrix(GF(4, 'x'), [[1, 0, 1], # optional - sage.rings.finite_rings ....: [1, 0, 1]])) - sage: loads(dumps(M)).representation() # optional - sage.libs.pari + sage: loads(dumps(M)).representation() # optional - sage.rings.finite_rings [1 0 1] [1 0 1] """ diff --git a/src/sage/matroids/utilities.py b/src/sage/matroids/utilities.py index a9764c86891..651804651d1 100644 --- a/src/sage/matroids/utilities.py +++ b/src/sage/matroids/utilities.py @@ -74,10 +74,10 @@ def setprint(X): Note that for iterables, the effect can be undesirable:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.named_matroids.Fano().delete('efg') # optional - sage.libs.pari - sage: M.bases() # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano().delete('efg') # optional - sage.rings.finite_rings + sage: M.bases() # optional - sage.rings.finite_rings Iterator over a system of subsets - sage: setprint(M.bases()) # optional - sage.libs.pari + sage: setprint(M.bases()) # optional - sage.rings.finite_rings [{'a', 'b', 'c'}, {'a', 'b', 'd'}, {'a', 'c', 'd'}] An exception was made for subclasses of SageObject:: @@ -215,20 +215,20 @@ def sanitize_contractions_deletions(matroid, contractions, deletions): sage: from sage.matroids.utilities import setprint sage: from sage.matroids.utilities import sanitize_contractions_deletions - sage: M = matroids.named_matroids.Fano() # optional - sage.libs.pari - sage: setprint(sanitize_contractions_deletions(M, 'abc', 'defg')) # optional - sage.libs.pari + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: setprint(sanitize_contractions_deletions(M, 'abc', 'defg')) # optional - sage.rings.finite_rings [{'a', 'b', 'c'}, {'d', 'e', 'f', 'g'}] - sage: setprint(sanitize_contractions_deletions(M, 'defg', 'abc')) # optional - sage.libs.pari + sage: setprint(sanitize_contractions_deletions(M, 'defg', 'abc')) # optional - sage.rings.finite_rings [{'a', 'b', 'c', 'f'}, {'d', 'e', 'g'}] - sage: setprint(sanitize_contractions_deletions(M, [1, 2, 3], 'efg')) # optional - sage.libs.pari + sage: setprint(sanitize_contractions_deletions(M, [1, 2, 3], 'efg')) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: [1, 2, 3] is not a subset of the groundset - sage: setprint(sanitize_contractions_deletions(M, 'efg', [1, 2, 3])) # optional - sage.libs.pari + sage: setprint(sanitize_contractions_deletions(M, 'efg', [1, 2, 3])) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: [1, 2, 3] is not a subset of the groundset - sage: setprint(sanitize_contractions_deletions(M, 'ade', 'efg')) # optional - sage.libs.pari + sage: setprint(sanitize_contractions_deletions(M, 'ade', 'efg')) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: contraction and deletion sets are not disjoint. @@ -532,25 +532,25 @@ def lift_cross_ratios(A, lift_map=None): EXAMPLES:: sage: from sage.matroids.advanced import lift_cross_ratios, lift_map, LinearMatroid - sage: R = GF(7) # optional - sage.libs.pari + sage: R = GF(7) # optional - sage.rings.finite_rings sage: to_sixth_root_of_unity = lift_map('sru') # optional - sage.rings.number_field - sage: A = Matrix(R, [[1, 0, 6, 1, 2],[6, 1, 0, 0, 1],[0, 6, 3, 6, 0]]) # optional - sage.libs.pari - sage: A # optional - sage.libs.pari + sage: A = Matrix(R, [[1, 0, 6, 1, 2],[6, 1, 0, 0, 1],[0, 6, 3, 6, 0]]) # optional - sage.rings.finite_rings + sage: A # optional - sage.rings.finite_rings [1 0 6 1 2] [6 1 0 0 1] [0 6 3 6 0] - sage: Z = lift_cross_ratios(A, to_sixth_root_of_unity) # optional - sage.libs.pari sage.rings.number_field - sage: Z # optional - sage.libs.pari sage.rings.number_field + sage: Z = lift_cross_ratios(A, to_sixth_root_of_unity) # optional - sage.rings.finite_rings sage.rings.number_field + sage: Z # optional - sage.rings.finite_rings sage.rings.number_field [ 1 0 1 1 1] [ 1 1 0 0 z] [ 0 -1 z 1 0] - sage: M = LinearMatroid(reduced_matrix=A) # optional - sage.libs.pari - sage: sorted(M.cross_ratios()) # optional - sage.libs.pari + sage: M = LinearMatroid(reduced_matrix=A) # optional - sage.rings.finite_rings + sage: sorted(M.cross_ratios()) # optional - sage.rings.finite_rings [3, 5] - sage: N = LinearMatroid(reduced_matrix=Z) # optional - sage.libs.pari sage.rings.number_field - sage: sorted(N.cross_ratios()) # optional - sage.libs.pari sage.rings.number_field + sage: N = LinearMatroid(reduced_matrix=Z) # optional - sage.rings.finite_rings sage.rings.number_field + sage: sorted(N.cross_ratios()) # optional - sage.rings.finite_rings sage.rings.number_field [-z + 1, z] - sage: M.is_isomorphism(N, {e:e for e in M.groundset()}) # optional - sage.libs.pari sage.rings.number_field + sage: M.is_isomorphism(N, {e:e for e in M.groundset()}) # optional - sage.rings.finite_rings sage.rings.number_field True """ @@ -690,8 +690,8 @@ def lift_map(target): EXAMPLES:: sage: from sage.matroids.utilities import lift_map - sage: lm = lift_map('gm') # optional - sage.libs.pari sage.rings.number_field - sage: for x in lm: # optional - sage.libs.pari sage.rings.number_field + sage: lm = lift_map('gm') # optional - sage.rings.finite_rings sage.rings.number_field + sage: for x in lm: # optional - sage.rings.finite_rings sage.rings.number_field ....: if (x == 1) is not (lm[x] == 1): ....: print('not a proper lift map') ....: for y in lm: diff --git a/src/sage/structure/sage_object.pyx b/src/sage/structure/sage_object.pyx index 2140a285f2c..74bac0150ca 100644 --- a/src/sage/structure/sage_object.pyx +++ b/src/sage/structure/sage_object.pyx @@ -360,18 +360,18 @@ cdef class SageObject: modified to return ``True`` for objects which might behave differently in some computations:: - sage: K. = Qq(9) # optional - sage.rings.padics - sage: b = a + O(3) # optional - sage.rings.padics - sage: c = a + 3 # optional - sage.rings.padics - sage: b # optional - sage.rings.padics + sage: K. = Qq(9) # optional - sage.rings.padics + sage: b = a + O(3) # optional - sage.rings.padics + sage: c = a + 3 # optional - sage.rings.padics + sage: b # optional - sage.rings.padics a + O(3) - sage: c # optional - sage.rings.padics + sage: c # optional - sage.rings.padics a + 3 + O(3^20) - sage: b == c # optional - sage.rings.padics + sage: b == c # optional - sage.rings.padics True - sage: b == a # optional - sage.rings.padics + sage: b == a # optional - sage.rings.padics True - sage: c == a # optional - sage.rings.padics + sage: c == a # optional - sage.rings.padics False If such objects defined a non-trivial hash function, this would break @@ -379,20 +379,20 @@ cdef class SageObject: caches. This can be achieved by defining an appropriate ``_cache_key``:: - sage: hash(b) # optional - sage.rings.padics + sage: hash(b) # optional - sage.rings.padics Traceback (most recent call last): ... TypeError: unhashable type: 'sage.rings.padics.qadic_flint_CR.qAdicCappedRelativeElement' sage: @cached_method ....: def f(x): return x==a - sage: f(b) # optional - sage.rings.padics + sage: f(b) # optional - sage.rings.padics True - sage: f(c) # if b and c were hashable, this would return True # optional - sage.rings.padics + sage: f(c) # if b and c were hashable, this would return True # optional - sage.rings.padics False - sage: b._cache_key() # optional - sage.rings.padics + sage: b._cache_key() # optional - sage.rings.padics (..., ((0, 1),), 0, 1) - sage: c._cache_key() # optional - sage.rings.padics + sage: c._cache_key() # optional - sage.rings.padics (..., ((0, 1), (1,)), 0, 20) An implementation must make sure that for elements ``a`` and ``b``, @@ -400,8 +400,8 @@ cdef class SageObject: In practice this means that the ``_cache_key`` should always include the parent as its first argument:: - sage: S. = Qq(4) # optional - sage.rings.padics - sage: d = a + O(2) # optional - sage.rings.padics + sage: S. = Qq(4) # optional - sage.rings.padics + sage: d = a + O(2) # optional - sage.rings.padics sage: b._cache_key() == d._cache_key() # this would be True if the parents were not included # optional - sage.rings.padics False @@ -525,10 +525,10 @@ cdef class SageObject: EXAMPLES:: - sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t # optional - sage.symbolic + sage: t = log(sqrt(2) - 1) + log(sqrt(2) + 1); t # optional - sage.symbolic log(sqrt(2) + 1) + log(sqrt(2) - 1) - sage: u = t.maxima_methods() # optional - sage.symbolic - sage: u.parent() # optional - sage.symbolic + sage: u = t.maxima_methods() # optional - sage.symbolic + sage: u.parent() # optional - sage.symbolic """ return type(self) @@ -847,10 +847,10 @@ cdef class SageObject: sage: x = polygen(ZZ, 'x') sage: K. = NumberField(x^3 + 2) - sage: magma(K) is magma(K) # optional - magma + sage: magma(K) is magma(K) # optional - magma True sage: magma2 = Magma() - sage: magma(K) is magma2(K) # optional - magma + sage: magma(K) is magma2(K) # optional - magma False """ return repr(self) # default From 826e0b0ca9cb8d113a2318e209fec98aecc26879 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 12 May 2023 20:01:52 -0700 Subject: [PATCH 046/205] Fix # optional --- src/sage/docs/instancedoc.py | 8 +- .../arithmetic_dynamics/projective_ds.py | 675 +++++++++--------- src/sage/ext/fast_callable.pyx | 14 +- src/sage/matroids/graphic_matroid.py | 2 + src/sage/matroids/linear_matroid.pyx | 2 +- src/sage/matroids/matroid.pyx | 8 +- src/sage/matroids/set_system.pyx | 2 +- src/sage/misc/functional.py | 4 +- 8 files changed, 377 insertions(+), 338 deletions(-) diff --git a/src/sage/docs/instancedoc.py b/src/sage/docs/instancedoc.py index 5b03886ef02..111c09461e3 100644 --- a/src/sage/docs/instancedoc.py +++ b/src/sage/docs/instancedoc.py @@ -36,7 +36,7 @@ For a Cython ``cdef class``, a decorator cannot be used. Instead, call :func:`instancedoc` as a function after defining the class:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: from sage.misc.instancedoc import instancedoc ....: cdef class Y: @@ -45,9 +45,9 @@ ....: return "Instance docstring" ....: instancedoc(Y) ....: ''') - sage: Y.__doc__ + sage: Y.__doc__ # optional - sage.misc.cython 'File:...\nClass docstring' - sage: Y().__doc__ + sage: Y().__doc__ # optional - sage.misc.cython 'Instance docstring' One can still add a custom ``__doc__`` attribute on a particular @@ -60,7 +60,7 @@ This normally does not work on extension types:: - sage: Y().__doc__ = "Very special doc" + sage: Y().__doc__ = "Very special doc" # optional - sage.misc.cython Traceback (most recent call last): ... AttributeError: attribute '__doc__' of 'Y' objects is not writable diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index a6220f27801..2e40776fb9d 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -196,7 +196,7 @@ class DynamicalSystem_projective(SchemeMorphism_polynomial_projective_space, Symbolic Ring elements are not allowed:: sage: x,y = var('x,y') - sage: DynamicalSystem_projective([x^2,y^2]) + sage: DynamicalSystem_projective([x^2, y^2]) Traceback (most recent call last): ... ValueError: [x^2, y^2] must be elements of a polynomial ring @@ -224,7 +224,7 @@ class DynamicalSystem_projective(SchemeMorphism_polynomial_projective_space, When elements of the quotient ring are used, they are reduced:: sage: P. = ProjectiveSpace(CC, 2) - sage: X = P.subscheme([x-y]) + sage: X = P.subscheme([x - y]) sage: u,v,w = X.coordinate_ring().gens() sage: DynamicalSystem_projective([u^2, v^2, w*u], domain=X) Dynamical System of Closed subscheme of Projective Space of dimension @@ -241,7 +241,7 @@ class DynamicalSystem_projective(SchemeMorphism_polynomial_projective_space, sage: P. = ProjectiveSpace(QQ, 2) sage: f = DynamicalSystem_projective([(x-2*y)^2, (x-2*z)^2, x^2]) - sage: X = P.subscheme(y-z) + sage: X = P.subscheme(y - z) sage: f(f(f(X))) Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: @@ -251,7 +251,7 @@ class DynamicalSystem_projective(SchemeMorphism_polynomial_projective_space, sage: P. = ProjectiveSpace(QQ, 3) sage: f = DynamicalSystem_projective([(x-2*y)^2, (x-2*z)^2, (x-2*w)^2, x^2]) - sage: f(P.subscheme([x,y,z])) + sage: f(P.subscheme([x, y, z])) Closed subscheme of Projective Space of dimension 3 over Rational Field defined by: w, @@ -285,18 +285,18 @@ def __classcall_private__(cls, morphism_or_polys, domain=None, names=None): sage: R. = QQ[] sage: P1 = ProjectiveSpace(R) - sage: f = DynamicalSystem_projective([x-y, x*y]) + sage: f = DynamicalSystem_projective([x - y, x*y]) Traceback (most recent call last): ... ValueError: polys (=[x - y, x*y]) must be of the same degree - sage: DynamicalSystem_projective([x-1, x*y+x]) + sage: DynamicalSystem_projective([x - 1, x*y + x]) Traceback (most recent call last): ... ValueError: polys (=[x - 1, x*y + x]) must be homogeneous :: - sage: DynamicalSystem_projective([exp(x),exp(y)]) + sage: DynamicalSystem_projective([exp(x), exp(y)]) Traceback (most recent call last): ... ValueError: [e^x, e^y] must be elements of a polynomial ring @@ -313,7 +313,7 @@ def __classcall_private__(cls, morphism_or_polys, domain=None, names=None): :: sage: A. = AffineSpace(ZZ, 2) - sage: DynamicalSystem_projective([x^2,y^2], A) + sage: DynamicalSystem_projective([x^2, y^2], A) Traceback (most recent call last): ... ValueError: "domain" must be a projective scheme @@ -505,7 +505,8 @@ def _number_field_from_algebraics(self): sage: P. = ProjectiveSpace(QQbar,1) sage: f = DynamicalSystem_projective([x^2 + QQbar(sqrt(2)) * y^2, y^2]) sage: f._number_field_from_algebraics() - Dynamical System of Projective Space of dimension 1 over Number Field in a with defining polynomial y^2 - 2 with a = 1.414213562373095? + Dynamical System of Projective Space of dimension 1 over Number Field in a + with defining polynomial y^2 - 2 with a = 1.414213562373095? Defn: Defined on coordinates by sending (x : y) to (x^2 + a*y^2 : y^2) """ @@ -528,7 +529,7 @@ def dehomogenize(self, n): If the dehomogenizing indices are the same for the domain and codomain, then a :class:`DynamicalSystem_affine` given by - dehomogenizing the source and target of `self` with respect to + dehomogenizing the source and target of ``self`` with respect to the given indices is returned. If the dehomogenizing indices for the domain and codomain are different then the resulting affine patches are different and a scheme morphism is returned. @@ -536,7 +537,7 @@ def dehomogenize(self, n): EXAMPLES:: sage: P. = ProjectiveSpace(ZZ,1) - sage: f = DynamicalSystem_projective([x^2+y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2]) sage: f.dehomogenize(0) Dynamical System of Affine Space of dimension 1 over Integer Ring Defn: Defined on coordinates by sending (y) to @@ -569,7 +570,7 @@ def dynatomic_polynomial(self, period): ALGORITHM: - For a positive integer `n`, let `[F_n,G_n]` be the coordinates of the `nth` + For a positive integer `n`, let `[F_n,G_n]` be the coordinates of the `n`-th iterate of `f`. Then construct .. MATH:: @@ -676,8 +677,7 @@ def dynatomic_polynomial(self, period): sage: P. = ProjectiveSpace(Qp(5),1) sage: f = DynamicalSystem_projective([x^2 + y^2, y^2]) sage: f.dynatomic_polynomial(2) - (x^4*y + (2 + O(5^20))*x^2*y^3 - x*y^4 + (2 + O(5^20))*y^5)/(x^2*y - - x*y^2 + y^3) + (x^4*y + (2 + O(5^20))*x^2*y^3 - x*y^4 + (2 + O(5^20))*y^5)/(x^2*y - x*y^2 + y^3) :: @@ -728,20 +728,22 @@ def dynatomic_polynomial(self, period): sage: P. = ProjectiveSpace(CC, 1) sage: f = DynamicalSystem_projective([x^2 - CC.0/3*y^2, y^2]) sage: f.dynatomic_polynomial(2) - (x^4*y + (-0.666666666666667*I)*x^2*y^3 - x*y^4 + (-0.111111111111111 - 0.333333333333333*I)*y^5)/(x^2*y - x*y^2 + (-0.333333333333333*I)*y^3) + (x^4*y + (-0.666666666666667*I)*x^2*y^3 - x*y^4 + + (-0.111111111111111 - 0.333333333333333*I)*y^5)/(x^2*y - x*y^2 + + (-0.333333333333333*I)*y^3) :: sage: P. = ProjectiveSpace(CC, 1) - sage: f = DynamicalSystem_projective([x^2-CC.0/5*y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 - CC.0/5*y^2, y^2]) sage: f.dynatomic_polynomial(2) x^2 + x*y + (1.00000000000000 - 0.200000000000000*I)*y^2 :: sage: L. = PolynomialRing(QuadraticField(2).maximal_order()) - sage: P. = ProjectiveSpace(L.fraction_field() , 1) - sage: f = DynamicalSystem_projective([x^2 + (t^2 + 1)*y^2 , y^2]) + sage: P. = ProjectiveSpace(L.fraction_field(), 1) + sage: f = DynamicalSystem_projective([x^2 + (t^2 + 1)*y^2, y^2]) sage: f.dynatomic_polynomial(2) x^2 + x*y + (t^2 + 2)*y^2 @@ -813,7 +815,7 @@ def dynatomic_polynomial(self, period): sage: R. = QQ[] sage: P. = ProjectiveSpace(R,1) - sage: f = DynamicalSystem_projective([x^2 + c*y^2,y^2]) + sage: f = DynamicalSystem_projective([x^2 + c*y^2, y^2]) sage: f.dynatomic_polynomial([1,2]).parent() Multivariate Polynomial Ring in x, y over Univariate Polynomial Ring in c over Rational Field @@ -913,24 +915,23 @@ def nth_iterate_map(self, n, normalize=False): EXAMPLES:: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2+y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2]) sage: f.nth_iterate_map(2) - Dynamical System of Projective Space of dimension 1 over Rational - Field + Dynamical System of Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x : y) to (x^4 + 2*x^2*y^2 + 2*y^4 : y^4) :: sage: P. = ProjectiveSpace(CC,1) - sage: f = DynamicalSystem_projective([x^2-y^2, x*y]) + sage: f = DynamicalSystem_projective([x^2 - y^2, x*y]) sage: f.nth_iterate_map(3) - Dynamical System of Projective Space of dimension 1 over Complex - Field with 53 bits of precision + Dynamical System of Projective Space of dimension 1 + over Complex Field with 53 bits of precision Defn: Defined on coordinates by sending (x : y) to - (x^8 + (-7.00000000000000)*x^6*y^2 + 13.0000000000000*x^4*y^4 + - (-7.00000000000000)*x^2*y^6 + y^8 : x^7*y + (-4.00000000000000)*x^5*y^3 - + 4.00000000000000*x^3*y^5 - x*y^7) + (x^8 + (-7.00000000000000)*x^6*y^2 + 13.0000000000000*x^4*y^4 + + (-7.00000000000000)*x^2*y^6 + y^8 + : x^7*y + (-4.00000000000000)*x^5*y^3 + 4.00000000000000*x^3*y^5 - x*y^7) :: @@ -939,8 +940,8 @@ def nth_iterate_map(self, n, normalize=False): sage: f.nth_iterate_map(2) Dynamical System of Projective Space of dimension 2 over Integer Ring Defn: Defined on coordinates by sending (x : y : z) to - (x^4 - 3*x^2*y^2 + y^4 : x^3*y - x*y^3 : 2*x^4 - 2*x^2*y^2 + y^4 - + 2*x^2*z^2 + z^4) + (x^4 - 3*x^2*y^2 + y^4 : x^3*y - x*y^3 + : 2*x^4 - 2*x^2*y^2 + y^4 + 2*x^2*z^2 + z^4) :: @@ -959,8 +960,7 @@ def nth_iterate_map(self, n, normalize=False): sage: P. = ProjectiveSpace(QQ, 2) sage: f = DynamicalSystem_projective([y^2 * z^3, y^3 * z^2, x^5]) sage: f.nth_iterate_map( 5, normalize=True) - Dynamical System of Projective Space of dimension 2 over Rational - Field + Dynamical System of Projective Space of dimension 2 over Rational Field Defn: Defined on coordinates by sending (x : y : z) to (y^202*z^443 : x^140*y^163*z^342 : x^645) """ @@ -1014,7 +1014,7 @@ def nth_iterate(self, P, n, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(ZZ,1) - sage: f = DynamicalSystem_projective([x^2+y^2, 2*y^2]) + sage: f = DynamicalSystem_projective([x^2 + y^2, 2*y^2]) sage: Q = P(1,1) sage: f.nth_iterate(Q,4) (32768 : 32768) @@ -1022,7 +1022,7 @@ def nth_iterate(self, P, n, **kwds): :: sage: P. = ProjectiveSpace(ZZ,1) - sage: f = DynamicalSystem_projective([x^2+y^2, 2*y^2]) + sage: f = DynamicalSystem_projective([x^2 + y^2, 2*y^2]) sage: Q = P(1,1) sage: f.nth_iterate(Q, 4, normalize=True) (1 : 1) @@ -1030,7 +1030,7 @@ def nth_iterate(self, P, n, **kwds): :: sage: P. = ProjectiveSpace(QQ,2) - sage: f = DynamicalSystem_projective([x^2, 2*y^2, z^2-x^2]) + sage: f = DynamicalSystem_projective([x^2, 2*y^2, z^2 - x^2]) sage: Q = P(2,7,1) sage: f.nth_iterate(Q,2) (-16/7 : -2744 : 1) @@ -1039,11 +1039,11 @@ def nth_iterate(self, P, n, **kwds): sage: R. = PolynomialRing(QQ) sage: P. = ProjectiveSpace(R,2) - sage: f = DynamicalSystem_projective([x^2+t*y^2, (2-t)*y^2, z^2]) - sage: Q = P(2+t,7,t) + sage: f = DynamicalSystem_projective([x^2 + t*y^2, (2-t)*y^2, z^2]) + sage: Q = P(2 + t, 7, t) sage: f.nth_iterate(Q,2) - (t^4 + 2507*t^3 - 6787*t^2 + 10028*t + 16 : -2401*t^3 + 14406*t^2 - - 28812*t + 19208 : t^4) + (t^4 + 2507*t^3 - 6787*t^2 + 10028*t + 16 + : -2401*t^3 + 14406*t^2 - 28812*t + 19208 : t^4) :: @@ -1062,7 +1062,7 @@ def nth_iterate(self, P, n, **kwds): ((c^6 - 9*c^4 + 25*c^2 - c - 21)/(c^2 - 3) : 1) sage: P. = ProjectiveSpace(QQ,2) - sage: f = DynamicalSystem_projective([x^2+3*y^2, 2*y^2,z^2]) + sage: f = DynamicalSystem_projective([x^2 + 3*y^2, 2*y^2, z^2]) sage: f.nth_iterate(P(2, 7, 1), -2) Traceback (most recent call last): ... @@ -1077,7 +1077,8 @@ def nth_iterate(self, P, n, **kwds): sage: f.nth_iterate(P(0, 1), 3) Traceback (most recent call last): ... - ValueError: [0, 0] does not define a point in Projective Space of dimension 1 over Rational Field since all entries are zero + ValueError: [0, 0] does not define a point in Projective Space of + dimension 1 over Rational Field since all entries are zero :: @@ -1091,7 +1092,7 @@ def nth_iterate(self, P, n, **kwds): :: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem([x+y,y]) + sage: f = DynamicalSystem([x + y, y]) sage: Q = (3,1) sage: f.nth_iterate(Q,0) (3 : 1) @@ -1099,7 +1100,7 @@ def nth_iterate(self, P, n, **kwds): TESTS:: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem([x^2+y^2,y^2]) + sage: f = DynamicalSystem([x^2 + y^2, y^2]) sage: f.nth_iterate(0,0) (0 : 1) """ @@ -1480,14 +1481,14 @@ def dynamical_degree(self, N=3, prec=53): EXAMPLES:: sage: P. = ProjectiveSpace(QQ, 1) - sage: f = DynamicalSystem_projective([x^2 + (x*y), y^2]) + sage: f = DynamicalSystem_projective([x^2 + x*y, y^2]) sage: f.dynamical_degree() 2.00000000000000 :: sage: P2. = ProjectiveSpace(ZZ, 2) - sage: f = DynamicalSystem_projective([X*Y, Y*Z+Z^2, Z^2]) + sage: f = DynamicalSystem_projective([X*Y, Y*Z + Z^2, Z^2]) sage: f.dynamical_degree(N=5, prec=100) 1.4309690811052555010452244131 """ @@ -1529,21 +1530,21 @@ def orbit(self, P, N, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(ZZ,2) - sage: f = DynamicalSystem_projective([x^2+y^2, y^2-z^2, 2*z^2]) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2 - z^2, 2*z^2]) sage: f.orbit(P(1,2,1), 3) [(1 : 2 : 1), (5 : 3 : 2), (34 : 5 : 8), (1181 : -39 : 128)] :: sage: P. = ProjectiveSpace(ZZ,2) - sage: f = DynamicalSystem_projective([x^2+y^2, y^2-z^2, 2*z^2]) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2 - z^2, 2*z^2]) sage: f.orbit(P(1,2,1), [2,4]) [(34 : 5 : 8), (1181 : -39 : 128), (1396282 : -14863 : 32768)] :: sage: P. = ProjectiveSpace(ZZ,2) - sage: X = P.subscheme(x^2-y^2) + sage: X = P.subscheme(x^2 - y^2) sage: f = DynamicalSystem_projective([x^2, y^2, x*z], domain=X) sage: f.orbit(X(2,2,3), 3, normalize=True) [(2 : 2 : 3), (2 : 2 : 3), (2 : 2 : 3), (2 : 2 : 3)] @@ -1551,22 +1552,22 @@ def orbit(self, P, N, **kwds): :: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2+y^2, y^2]) - sage: f.orbit(P.point([1,2],False), 4, check=False) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2]) + sage: f.orbit(P.point([1,2], False), 4, check=False) [(1 : 2), (5 : 4), (41 : 16), (1937 : 256), (3817505 : 65536)] :: sage: K. = FunctionField(QQ) sage: P. = ProjectiveSpace(K,1) - sage: f = DynamicalSystem_projective([x^2+c*y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 + c*y^2, y^2]) sage: f.orbit(P(0,1), 3) [(0 : 1), (c : 1), (c^2 + c : 1), (c^4 + 2*c^3 + c^2 + c : 1)] :: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2+y^2,y^2], domain=P) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2], domain=P) sage: f.orbit(P.point([1, 2], False), 4, check=False) [(1 : 2), (5 : 4), (41 : 16), (1937 : 256), (3817505 : 65536)] @@ -1590,7 +1591,8 @@ def orbit(self, P, N, **kwds): sage: f.orbit(P(0, 1), 3) Traceback (most recent call last): ... - ValueError: [0, 0] does not define a point in Projective Space of dimension 1 over Rational Field since all entries are zero + ValueError: [0, 0] does not define a point in Projective Space of + dimension 1 over Rational Field since all entries are zero sage: f.orbit(P(0, 1), 3, check=False) [(0 : 1), (0 : 0), (0 : 0), (0 : 0)] @@ -1607,20 +1609,20 @@ def orbit(self, P, N, **kwds): sage: P. = ProjectiveSpace(QQ,2) sage: f = DynamicalSystem_projective([x^2, y^2, x*z]) - sage: f.orbit((2/3,1/3), 3) + sage: f.orbit((2/3, 1/3), 3) [(2/3 : 1/3 : 1), (2/3 : 1/6 : 1), (2/3 : 1/24 : 1), (2/3 : 1/384 : 1)] TESTS:: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem([x^2+y^2,y^2]) + sage: f = DynamicalSystem([x^2 + y^2, y^2]) sage: f.orbit(0, 0) [(0 : 1)] :: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem([x^2-y^2,y^2]) + sage: f = DynamicalSystem([x^2 - y^2, y^2]) sage: f.orbit(0,2) [(0 : 1), (-1 : 1), (0 : 1)] """ @@ -1656,7 +1658,7 @@ def orbit(self, P, N, **kwds): def resultant(self, normalize=False): r""" - Computes the resultant of the defining polynomials of + Compute the resultant of the defining polynomials of this dynamical system. If ``normalize`` is ``True``, then first normalize the coordinate @@ -1671,7 +1673,7 @@ def resultant(self, normalize=False): EXAMPLES:: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2+y^2, 6*y^2]) + sage: f = DynamicalSystem_projective([x^2 + y^2, 6*y^2]) sage: f.resultant() 36 @@ -1679,7 +1681,7 @@ def resultant(self, normalize=False): sage: R. = PolynomialRing(GF(17)) sage: P. = ProjectiveSpace(R,1) - sage: f = DynamicalSystem_projective([t*x^2+t*y^2, 6*y^2]) + sage: f = DynamicalSystem_projective([t*x^2 + t*y^2, 6*y^2]) sage: f.resultant() 2*t^2 @@ -1687,23 +1689,23 @@ def resultant(self, normalize=False): sage: R. = PolynomialRing(GF(17)) sage: P. = ProjectiveSpace(R,2) - sage: f = DynamicalSystem_projective([t*x^2+t*y^2, 6*y^2, 2*t*z^2]) + sage: f = DynamicalSystem_projective([t*x^2 + t*y^2, 6*y^2, 2*t*z^2]) sage: f.resultant() 13*t^8 :: sage: P. = ProjectiveSpace(QQ,2) - sage: F = DynamicalSystem_projective([x^2+y^2,6*y^2,10*x*z+z^2+y^2]) + sage: F = DynamicalSystem_projective([x^2 + y^2, 6*y^2, 10*x*z + z^2 + y^2]) sage: F.resultant() 1296 :: - sage: R.=PolynomialRing(QQ) - sage: s = (t^3+t+1).roots(QQbar)[0][0] - sage: P.=ProjectiveSpace(QQbar,1) - sage: f = DynamicalSystem_projective([s*x^3-13*y^3, y^3-15*y^3]) + sage: R. = PolynomialRing(QQ) + sage: s = (t^3 + t + 1).roots(QQbar)[0][0] + sage: P. = ProjectiveSpace(QQbar, 1) + sage: f = DynamicalSystem_projective([s*x^3 - 13*y^3, y^3 - 15*y^3]) sage: f.resultant() 871.6925062959149? """ @@ -1764,14 +1766,15 @@ def primes_of_bad_reduction(self, check=True): EXAMPLES:: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([1/3*x^2+1/2*y^2, y^2]) + sage: f = DynamicalSystem_projective([1/3*x^2 + 1/2*y^2, y^2]) sage: f.primes_of_bad_reduction() [2, 3] :: sage: P. = ProjectiveSpace(QQ,3) - sage: f = DynamicalSystem_projective([12*x*z-7*y^2, 31*x^2-y^2, 26*z^2, 3*w^2-z*w]) + sage: f = DynamicalSystem_projective([12*x*z - 7*y^2, 31*x^2 - y^2, + ....: 26*z^2, 3*w^2 - z*w]) sage: f.primes_of_bad_reduction() [2, 3, 7, 13, 31] @@ -1784,7 +1787,7 @@ def primes_of_bad_reduction(self, check=True): sage: f.primes_of_bad_reduction() [Fractional ideal (a), Fractional ideal (3)] - This is an example where check = False returns extra primes:: + This is an example where ``check=False`` returns extra primes:: sage: P. = ProjectiveSpace(ZZ,2) sage: f = DynamicalSystem_projective([3*x*y^2 + 7*y^3 - 4*y^2*z + 5*z^3, @@ -1866,7 +1869,7 @@ def conjugate(self, M, adjugate=False, normalize=False): - ``M`` -- a square invertible matrix - - ``adjugate`` -- (default: ``False``) boolean, also classically called adjoint, takes a square matrix ``M`` and finds the transpose of its cofactor matrix. Used for conjugation in place of inverse when specified ``'True'``. Functionality is the same in projective space. + - ``adjugate`` -- (default: ``False``) boolean, also classically called adjoint, takes a square matrix ``M`` and finds the transpose of its cofactor matrix. Used for conjugation in place of inverse when specified ``True``. Functionality is the same in projective space. - ``normalize`` -- (default: ``False``) boolean, if normalize is ``'True'``, then the function ``normalize_coordinates`` is called. @@ -1875,7 +1878,7 @@ def conjugate(self, M, adjugate=False, normalize=False): EXAMPLES:: sage: P. = ProjectiveSpace(ZZ,1) - sage: f = DynamicalSystem_projective([x^2+y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2]) sage: f.conjugate(matrix([[1,2], [0,1]])) Dynamical System of Projective Space of dimension 1 over Integer Ring Defn: Defined on coordinates by sending (x : y) to @@ -1884,9 +1887,9 @@ def conjugate(self, M, adjugate=False, normalize=False): :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: P. = ProjectiveSpace(ZZ,1) - sage: f = DynamicalSystem_projective([x^3+y^3, y^3]) + sage: f = DynamicalSystem_projective([x^3 + y^3, y^3]) sage: f.conjugate(matrix([[i,0], [0,-i]])) Dynamical System of Projective Space of dimension 1 over Integer Ring Defn: Defined on coordinates by sending (x : y) to @@ -1895,7 +1898,7 @@ def conjugate(self, M, adjugate=False, normalize=False): :: sage: P. = ProjectiveSpace(ZZ,2) - sage: f = DynamicalSystem_projective([x^2+y^2 ,y^2, y*z]) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2, y*z]) sage: f.conjugate(matrix([[1,2,3], [0,1,2], [0,0,1]])) Dynamical System of Projective Space of dimension 2 over Integer Ring Defn: Defined on coordinates by sending (x : y : z) to @@ -1913,25 +1916,26 @@ def conjugate(self, M, adjugate=False, normalize=False): :: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^2+1) + sage: K. = NumberField(x^2 + 1) sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([1/3*x^2+1/2*y^2, y^2]) + sage: f = DynamicalSystem_projective([1/3*x^2 + 1/2*y^2, y^2]) sage: f.conjugate(matrix([[i,0], [0,-i]])) - Dynamical System of Projective Space of dimension 1 over Number Field in i with defining polynomial x^2 + 1 + Dynamical System of Projective Space of dimension 1 + over Number Field in i with defining polynomial x^2 + 1 Defn: Defined on coordinates by sending (x : y) to ((1/3*i)*x^2 + (1/2*i)*y^2 : (-i)*y^2) TESTS:: sage: R = ZZ - sage: P.=ProjectiveSpace(R,1) - sage: f=DynamicalSystem_projective([x^2 + y^2,y^2]) - sage: m=matrix(R,2,[4, 3, 2, 1]) - sage: f.conjugate(m,normalize=False) + sage: P. = ProjectiveSpace(R,1) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2]) + sage: m = matrix(R, 2, [4, 3, 2, 1]) + sage: f.conjugate(m, normalize=False) Dynamical System of Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x : y) to (-4*x^2 - 8*x*y - 7/2*y^2 : 12*x^2 + 20*x*y + 8*y^2) - sage: f.conjugate(m,adjugate=True) + sage: f.conjugate(m, adjugate=True) Dynamical System of Projective Space of dimension 1 over Integer Ring Defn: Defined on coordinates by sending (x : y) to (8*x^2 + 16*x*y + 7*y^2 : -24*x^2 - 40*x*y - 16*y^2) @@ -2005,7 +2009,7 @@ def green_function(self, P, v, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2+y^2, x*y]); + sage: f = DynamicalSystem_projective([x^2 + y^2, x*y]); sage: Q = P(5, 1) sage: f.green_function(Q, 0, N=30) 1.6460930159932946233759277576 @@ -2013,7 +2017,7 @@ def green_function(self, P, v, **kwds): :: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2+y^2, x*y]); + sage: f = DynamicalSystem_projective([x^2 + y^2, x*y]); sage: Q = P(5, 1) sage: f.green_function(Q, 0, N=200, prec=200) 1.6460930160038721802875250367738355497198064992657997569827 @@ -2022,7 +2026,7 @@ def green_function(self, P, v, **kwds): sage: K. = QuadraticField(3) sage: P. = ProjectiveSpace(K,1) - sage: f = DynamicalSystem_projective([17*x^2+1/7*y^2, 17*w*x*y]) + sage: f = DynamicalSystem_projective([17*x^2 + 1/7*y^2, 17*w*x*y]) sage: f.green_function(P.point([w, 2], False), K.places()[1]) 1.7236334013785676107373093775 sage: f.green_function(P([2, 1]), K.ideal(7), N=7) @@ -2033,7 +2037,7 @@ def green_function(self, P, v, **kwds): :: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2+y^2, x*y]) + sage: f = DynamicalSystem_projective([x^2 + y^2, x*y]) sage: f.green_function(P.point([5,2], False), 0, N=30) 1.7315451844777407992085512000 sage: f.green_function(P.point([2,1], False), 0, N=30) @@ -2196,7 +2200,7 @@ def canonical_height(self, P, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(ZZ,1) - sage: f = DynamicalSystem_projective([x^2+y^2, 2*x*y]); + sage: f = DynamicalSystem_projective([x^2 + y^2, 2*x*y]); sage: f.canonical_height(P.point([5,4]), error_bound=0.001) 2.1970553519503404898926835324 sage: f.canonical_height(P.point([2,1]), error_bound=0.001) @@ -2207,18 +2211,18 @@ def canonical_height(self, P, **kwds): sage: R. = PolynomialRing(QQ) sage: K. = NumberField(X^2 + X - 1) sage: P. = ProjectiveSpace(K,1) - sage: f = DynamicalSystem_projective([x^2-2*y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 - 2*y^2, y^2]) sage: Q = P.point([a,1]) - sage: f.canonical_height(Q, error_bound=0.000001) # Answer only within error_bound of 0 + sage: f.canonical_height(Q, error_bound=0.000001) # Answer only within error_bound of 0 5.7364919788790160119266380480e-8 - sage: f.nth_iterate(Q,2) == Q # but it is indeed preperiodic + sage: f.nth_iterate(Q, 2) == Q # but it is indeed preperiodic True :: sage: P. = ProjectiveSpace(QQ,2) - sage: X = P.subscheme(x^2-y^2); - sage: f = DynamicalSystem_projective([x^2,y^2, 4*z^2], domain=X); + sage: X = P.subscheme(x^2 - y^2); + sage: f = DynamicalSystem_projective([x^2, y^2, 4*z^2], domain=X); sage: Q = X([4,4,1]) sage: f.canonical_height(Q, badprimes=[2]) 0.0013538030870311431824555314882 @@ -2226,8 +2230,8 @@ def canonical_height(self, P, **kwds): :: sage: P. = ProjectiveSpace(QQ,2) - sage: X = P.subscheme(x^2-y^2); - sage: f = DynamicalSystem_projective([x^2,y^2, 30*z^2], domain=X) + sage: X = P.subscheme(x^2 - y^2); + sage: f = DynamicalSystem_projective([x^2, y^2, 30*z^2], domain=X) sage: Q = X([4, 4, 1]) sage: f.canonical_height(Q, badprimes=[2,3,5], prec=200) 2.7054056208276961889784303469356774912979228770208655455481 @@ -2235,7 +2239,7 @@ def canonical_height(self, P, **kwds): :: sage: P. = ProjectiveSpace(QQ, 1) - sage: f = DynamicalSystem_projective([1000*x^2-29*y^2, 1000*y^2]) + sage: f = DynamicalSystem_projective([1000*x^2 - 29*y^2, 1000*y^2]) sage: Q = P(-1/4, 1) sage: f.canonical_height(Q, error_bound=0.01) 3.7996079979254623065837411853 @@ -2255,7 +2259,7 @@ def canonical_height(self, P, **kwds): :: sage: P.=ProjectiveSpace(QQ, 1) - sage: f = DynamicalSystem([2*( -2*x^3 + 3*(x^2*y)) + 3*y^3,3*y^3]) + sage: f = DynamicalSystem([2*(-2*x^3 + 3*(x^2*y)) + 3*y^3, 3*y^3]) sage: f.canonical_height(P(1,0)) 0.00000000000000000000000000000 """ @@ -2430,7 +2434,8 @@ def height_difference_bound(self, prec=None): :: sage: P. = ProjectiveSpace(QQbar, 2) - sage: f = DynamicalSystem_projective([x^2, QQbar(sqrt(-1))*y^2, QQbar(sqrt(3))*z^2]) + sage: f = DynamicalSystem_projective([x^2, QQbar(sqrt(-1))*y^2, + ....: QQbar(sqrt(3))*z^2]) sage: f.height_difference_bound() 2.89037175789616 @@ -2494,8 +2499,8 @@ def multiplier(self, P, n, check=True): EXAMPLES:: sage: P. = ProjectiveSpace(QQ,2) - sage: f = DynamicalSystem_projective([x^2,y^2, 4*z^2]); - sage: Q = P.point([4,4,1], False); + sage: f = DynamicalSystem_projective([x^2, y^2, 4*z^2]) + sage: Q = P.point([4,4,1], False) sage: f.multiplier(Q,1) [2 0] [0 2] @@ -2517,23 +2522,23 @@ def multiplier(self, P, n, check=True): :: sage: P. = ProjectiveSpace(RR,1) - sage: f = DynamicalSystem_projective([x^2-2*y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 - 2*y^2, y^2]) sage: f.multiplier(P(2,1), 1) [4.00000000000000] :: sage: P. = ProjectiveSpace(Qp(13),1) - sage: f = DynamicalSystem_projective([x^2-29/16*y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 - 29/16*y^2, y^2]) sage: f.multiplier(P(5,4), 3) [6 + 8*13 + 13^2 + 8*13^3 + 13^4 + 8*13^5 + 13^6 + 8*13^7 + 13^8 + - 8*13^9 + 13^10 + 8*13^11 + 13^12 + 8*13^13 + 13^14 + 8*13^15 + 13^16 + - 8*13^17 + 13^18 + 8*13^19 + O(13^20)] + 8*13^9 + 13^10 + 8*13^11 + 13^12 + 8*13^13 + 13^14 + 8*13^15 + 13^16 + + 8*13^17 + 13^18 + 8*13^19 + O(13^20)] :: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2-y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 - y^2, y^2]) sage: f.multiplier(P(0,1), 1) Traceback (most recent call last): ... @@ -2596,14 +2601,14 @@ def _multipliermod(self, P, n, p, k): EXAMPLES:: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2-29/16*y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 - 29/16*y^2, y^2]) sage: f._multipliermod(P(5,4), 3, 11, 1) [3] :: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2-29/16*y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 - 29/16*y^2, y^2]) sage: f._multipliermod(P(5,4), 3, 11, 2) [80] """ @@ -2754,7 +2759,7 @@ def nth_preimage_tree(self, Q, n, **kwds): :: - sage: P. = ProjectiveSpace(GF(3),1) + sage: P. = ProjectiveSpace(GF(3), 1) sage: f = DynamicalSystem_projective([x^2 + x*y + y^2, y^2]) sage: Q = P(0,1) sage: f.nth_preimage_tree(Q, 2, return_points=True) @@ -2857,7 +2862,7 @@ def possible_periods(self, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2-29/16*y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 - 29/16*y^2, y^2]) sage: f.possible_periods(ncpus=1) [1, 3] @@ -2956,7 +2961,7 @@ def _preperiodic_points_to_cyclegraph(self, preper): EXAMPLES:: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2-2*y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 - 2*y^2, y^2]) sage: preper = [P(-2, 1), P(1, 0), P(0, 1), P(1, 1), P(2, 1), P(-1, 1)] sage: f._preperiodic_points_to_cyclegraph(preper) Looped digraph on 6 vertices @@ -3001,21 +3006,21 @@ def is_PGL_minimal(self, prime_list=None): EXAMPLES:: sage: PS. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([X^2+3*Y^2, X*Y]) + sage: f = DynamicalSystem_projective([X^2 + 3*Y^2, X*Y]) sage: f.is_PGL_minimal() True :: sage: PS. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([6*x^2+12*x*y+7*y^2, 12*x*y]) + sage: f = DynamicalSystem_projective([6*x^2 + 12*x*y + 7*y^2, 12*x*y]) sage: f.is_PGL_minimal() False :: sage: PS. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([6*x^2+12*x*y+7*y^2, y^2]) + sage: f = DynamicalSystem_projective([6*x^2 + 12*x*y + 7*y^2, y^2]) sage: f.is_PGL_minimal() False """ @@ -3061,7 +3066,7 @@ def minimal_model(self, return_transformation=False, prime_list=None, algorithm= - ``algorithm`` -- (optional) string; can be one of the following: - ``check_primes`` -- (optional) boolean: this signals whether to - check whether each element in prime_list is a prime + check whether each element in ``prime_list`` is a prime * ``'BM'`` - the Bruin-Molnar algorithm [BM2012]_ * ``'HS'`` - the Hutz-Stoll algorithm [HS2018]_ @@ -3076,7 +3081,7 @@ def minimal_model(self, return_transformation=False, prime_list=None, algorithm= EXAMPLES:: sage: PS. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([X^2+3*Y^2, X*Y]) + sage: f = DynamicalSystem_projective([X^2 + 3*Y^2, X*Y]) sage: f.minimal_model(return_transformation=True) ( Dynamical System of Projective Space of dimension 1 over Rational @@ -3091,8 +3096,10 @@ def minimal_model(self, return_transformation=False, prime_list=None, algorithm= :: sage: PS. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([7365/2*X^4 + 6282*X^3*Y + 4023*X^2*Y^2 + 1146*X*Y^3 + 245/2*Y^4, - ....: -12329/2*X^4 - 10506*X^3*Y - 6723*X^2*Y^2 - 1914*X*Y^3 - 409/2*Y^4]) + sage: f = DynamicalSystem_projective([7365/2*X^4 + 6282*X^3*Y + 4023*X^2*Y^2 + ....: + 1146*X*Y^3 + 245/2*Y^4, + ....: -12329/2*X^4 - 10506*X^3*Y - 6723*X^2*Y^2 + ....: - 1914*X*Y^3 - 409/2*Y^4]) sage: f.minimal_model(return_transformation=True) ( Dynamical System of Projective Space of dimension 1 over Rational Field @@ -3107,17 +3114,16 @@ def minimal_model(self, return_transformation=False, prime_list=None, algorithm= :: sage: PS. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([6*x^2+12*x*y+7*y^2, 12*x*y]) + sage: f = DynamicalSystem_projective([6*x^2 + 12*x*y + 7*y^2, 12*x*y]) sage: f.minimal_model() - Dynamical System of Projective Space of dimension 1 over Rational - Field + Dynamical System of Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x : y) to (x^2 + 12*x*y + 42*y^2 : 2*x*y) :: sage: PS. = ProjectiveSpace(ZZ,1) - sage: f = DynamicalSystem_projective([6*x^2+12*x*y+7*y^2, 12*x*y + 42*y^2]) + sage: f = DynamicalSystem_projective([6*x^2 + 12*x*y + 7*y^2, 12*x*y + 42*y^2]) sage: g,M = f.minimal_model(return_transformation=True, algorithm='BM') sage: f.conjugate(M) == g True @@ -3142,7 +3148,7 @@ def minimal_model(self, return_transformation=False, prime_list=None, algorithm= TESTS:: sage: PS. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([X+Y, X-3*Y]) + sage: f = DynamicalSystem_projective([X + Y, X - 3*Y]) sage: f.minimal_model() Traceback (most recent call last): ... @@ -3151,7 +3157,7 @@ def minimal_model(self, return_transformation=False, prime_list=None, algorithm= :: sage: PS. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([X^2-Y^2, X^2+X*Y]) + sage: f = DynamicalSystem_projective([X^2 - Y^2, X^2 + X*Y]) sage: f.minimal_model() Traceback (most recent call last): ... @@ -3161,10 +3167,11 @@ def minimal_model(self, return_transformation=False, prime_list=None, algorithm= sage: P. = ProjectiveSpace(QQ,1) sage: f = DynamicalSystem([2*x^2, y^2]) - sage: f.minimal_model(algorithm = 'BM') + sage: f.minimal_model(algorithm='BM') Traceback (most recent call last): ... - TypeError: affine minimality is only considered for maps not of the form f or 1/f for a polynomial f + TypeError: affine minimality is only considered for + maps not of the form f or 1/f for a polynomial f :: @@ -3382,34 +3389,35 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): sage: g.periodic_points(1) [(-1 : -1 : 1), - (-1/2 : -1 : 1), - (-1/2 : -1/2 : 1), - (-1/3 : -2/3 : 1), - (0 : -1 : 1), - (0 : -1/2 : 1), - (0 : 0 : 1)] + (-1/2 : -1 : 1), + (-1/2 : -1/2 : 1), + (-1/3 : -2/3 : 1), + (0 : -1 : 1), + (0 : -1/2 : 1), + (0 : 0 : 1)] :: sage: P. = ProjectiveSpace(GF(9), 2) sage: f = DynamicalSystem_projective([x^2, y^2, z^2]) sage: f.affine_preperiodic_model(0, 1) - Dynamical System of Projective Space of dimension 2 over Finite Field in z2 of size 3^2 - Defn: Defined on coordinates by sending (x : y : z) to - ((-z2)*x^2 : z2*x^2 + (-z2)*x*y + (-z2)*y^2 : - (-z2)*x^2 + z2*x*y + (z2 + 1)*y^2 - y*z + z^2) + Dynamical System of Projective Space of dimension 2 + over Finite Field in z2 of size 3^2 + Defn: Defined on coordinates by sending (x : y : z) to + ((-z2)*x^2 : z2*x^2 + (-z2)*x*y + (-z2)*y^2 : + (-z2)*x^2 + z2*x*y + (z2 + 1)*y^2 - y*z + z^2) :: sage: R. = GF(3)[] sage: P. = ProjectiveSpace(R, 2) sage: f = DynamicalSystem_projective([x^2, y^2, z^2]) - sage: f.affine_preperiodic_model(0, 1) # long time + sage: f.affine_preperiodic_model(0, 1) # long time Dynamical System of Projective Space of dimension 2 over - Univariate Polynomial Ring in c over Finite Field of size 3 + Univariate Polynomial Ring in c over Finite Field of size 3 Defn: Defined on coordinates by sending (x : y : z) to (2*c^3*x^2 : c^3*x^2 + 2*c^3*x*y + 2*c^3*y^2 : - 2*c^3*x^2 + c^3*x*y + (c^3 + c^2)*y^2 + 2*c^2*y*z + c^2*z^2) + 2*c^3*x^2 + c^3*x*y + (c^3 + c^2)*y^2 + 2*c^2*y*z + c^2*z^2) :: @@ -3418,7 +3426,7 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): sage: f = DynamicalSystem_projective([x^2 + k*x*y + y^2, z^2, y^2]) sage: f.affine_preperiodic_model(1, 1) Dynamical System of Projective Space of dimension 2 - over Cyclotomic Field of order 3 and degree 2 + over Cyclotomic Field of order 3 and degree 2 Defn: Defined on coordinates by sending (x : y : z) to (-y^2 : x^2 : x^2 + (-k)*x*z + z^2) @@ -3436,8 +3444,8 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): sage: X = P.subscheme(2*y - z) sage: f = DynamicalSystem_projective([x^2 + y^2, z^2 + y^2, z^2], domain=X) sage: f.affine_preperiodic_model(0, 1) - Dynamical System of Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - 2*y - z + Dynamical System of Closed subscheme of Projective Space of dimension 2 + over Rational Field defined by: 2*y - z Defn: Defined on coordinates by sending (x : y : z) to (-x^2 - y^2 : y^2 : x^2 + z^2) @@ -3583,7 +3591,7 @@ def automorphism_group(self, **kwds): EXAMPLES:: sage: R. = ProjectiveSpace(QQ, 1) - sage: f = DynamicalSystem_projective([x^2-y^2, x*y]) + sage: f = DynamicalSystem_projective([x^2 - y^2, x*y]) sage: f.automorphism_group(return_functions=True) [x, -x] @@ -3607,7 +3615,7 @@ def automorphism_group(self, **kwds): :: sage: R. = ProjectiveSpace(QQ, 1) - sage: f = DynamicalSystem_projective([x^2-2*x*y-2*y^2, -2*x^2-2*x*y+y^2]) + sage: f = DynamicalSystem_projective([x^2 - 2*x*y - 2*y^2, -2*x^2 - 2*x*y + y^2]) sage: f.automorphism_group(return_functions=True) [x, 1/x, -x - 1, -x/(x + 1), (-x - 1)/x, -1/(x + 1)] @@ -3615,10 +3623,12 @@ def automorphism_group(self, **kwds): sage: R. = ProjectiveSpace(QQ, 1) sage: f = DynamicalSystem_projective([3*x^2*y - y^3, x^3 - 3*x*y^2]) - sage: lst, label = f.automorphism_group(algorithm='CRT', return_functions=True, iso_type=True) + sage: lst, label = f.automorphism_group(algorithm='CRT', return_functions=True, + ....: iso_type=True) sage: sorted(lst), label ([-1/x, 1/x, (-x - 1)/(x - 1), (-x + 1)/(x + 1), (x - 1)/(x + 1), - (x + 1)/(x - 1), -x, x], 'Dihedral of order 8') + (x + 1)/(x - 1), -x, x], + 'Dihedral of order 8') :: @@ -3646,7 +3656,7 @@ def automorphism_group(self, **kwds): sage: K. = CyclotomicField(3) sage: P. = ProjectiveSpace(K, 1) - sage: D6 = DynamicalSystem_projective([y^2,x^2]) + sage: D6 = DynamicalSystem_projective([y^2, x^2]) sage: sorted(D6.automorphism_group()) [ [-w - 1 0] [ 0 -w - 1] [w 0] [0 w] [0 1] [1 0] @@ -3689,35 +3699,35 @@ def critical_subscheme(self): sage: set_verbose(None) sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^3-2*x*y^2 + 2*y^3, y^3]) + sage: f = DynamicalSystem_projective([x^3 - 2*x*y^2 + 2*y^3, y^3]) sage: f.critical_subscheme() Closed subscheme of Projective Space of dimension 1 over Rational Field defined by: - 9*x^2*y^2 - 6*y^4 + 9*x^2*y^2 - 6*y^4 :: sage: set_verbose(None) sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([2*x^2-y^2, x*y]) + sage: f = DynamicalSystem_projective([2*x^2 - y^2, x*y]) sage: f.critical_subscheme() Closed subscheme of Projective Space of dimension 1 over Rational Field defined by: - 4*x^2 + 2*y^2 + 4*x^2 + 2*y^2 :: sage: P. = ProjectiveSpace(QQ,2) - sage: f = DynamicalSystem_projective([2*x^2-y^2, x*y, z^2]) + sage: f = DynamicalSystem_projective([2*x^2 - y^2, x*y, z^2]) sage: f.critical_subscheme() Closed subscheme of Projective Space of dimension 2 over Rational Field defined by: - 8*x^2*z + 4*y^2*z + 8*x^2*z + 4*y^2*z :: - sage: P. = ProjectiveSpace(GF(81),3) - sage: g = DynamicalSystem_projective([x^3+y^3, y^3+z^3, z^3+x^3, w^3]) + sage: P. = ProjectiveSpace(GF(81), 3) + sage: g = DynamicalSystem_projective([x^3 + y^3, y^3 + z^3, z^3 + x^3, w^3]) sage: g.critical_subscheme() Closed subscheme of Projective Space of dimension 3 over Finite Field in z4 of size 3^4 defined by: @@ -3726,7 +3736,7 @@ def critical_subscheme(self): :: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2,x*y]) + sage: f = DynamicalSystem_projective([x^2, x*y]) sage: f.critical_subscheme() Traceback (most recent call last): ... @@ -3758,7 +3768,7 @@ def critical_points(self, R=None): sage: set_verbose(None) sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^3-2*x*y^2 + 2*y^3, y^3]) + sage: f = DynamicalSystem_projective([x^3 - 2*x*y^2 + 2*y^3, y^3]) sage: f.critical_points() [(1 : 0)] sage: K. = QuadraticField(6) @@ -3769,7 +3779,7 @@ def critical_points(self, R=None): sage: set_verbose(None) sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([2*x^2-y^2, x*y]) + sage: f = DynamicalSystem_projective([2*x^2 - y^2, x*y]) sage: f.critical_points(QQbar) [(-0.7071067811865475?*I : 1), (0.7071067811865475?*I : 1)] """ @@ -3834,7 +3844,7 @@ def ramification_type(self, R=None, stable=True): sage: F.ramification_type() [[3], [3], [3]] - sage: F = DynamicalSystem_projective([x^3-2*x*y^2 + 2*y^3, y^3]) + sage: F = DynamicalSystem_projective([x^3 - 2*x*y^2 + 2*y^3, y^3]) sage: F.ramification_type() [[2], [2], [3]] sage: F.ramification_type(R=F.base_ring()) @@ -3868,7 +3878,7 @@ def is_postcritically_finite(self, err=0.01, use_algebraic_closure=True): Only for endomorphisms of `\mathbb{P}^1`. It checks if each critical point is preperiodic. The optional parameter ``err`` is passed into - ``is_preperiodic()`` as part of the preperiodic check. + :meth:`is_preperiodic` as part of the preperiodic check. The computations can be done either over the algebraic closure of the base field or over the minimal extension of the base field that @@ -3878,8 +3888,8 @@ def is_postcritically_finite(self, err=0.01, use_algebraic_closure=True): - ``err`` -- (default: 0.01) positive real number - - ``use_algebraic_closure`` -- boolean (default: True) -- If True uses the - algebraic closure. If False, uses the smallest extension of the base field + - ``use_algebraic_closure`` -- boolean (default: ``True``) -- If ``True``, uses the + algebraic closure. If ``False``, uses the smallest extension of the base field containing all the critical points. OUTPUT: boolean @@ -3903,14 +3913,15 @@ def is_postcritically_finite(self, err=0.01, use_algebraic_closure=True): sage: R. = QQ[] sage: K. = NumberField(z^8 + 3*z^6 + 3*z^4 + z^2 + 1) sage: PS. = ProjectiveSpace(K,1) - sage: f = DynamicalSystem_projective([x^3+v*y^3, y^3]) + sage: f = DynamicalSystem_projective([x^3 + v*y^3, y^3]) sage: f.is_postcritically_finite() # long time True :: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([6*x^2+16*x*y+16*y^2, -3*x^2-4*x*y-4*y^2]) + sage: f = DynamicalSystem_projective([6*x^2 + 16*x*y + 16*y^2, + ....: -3*x^2 - 4*x*y - 4*y^2]) sage: f.is_postcritically_finite() True @@ -3926,7 +3937,7 @@ def is_postcritically_finite(self, err=0.01, use_algebraic_closure=True): sage: P. = ProjectiveSpace(QQ,1) sage: f = DynamicalSystem_projective([8*x^4 - 8*x^2*y^2 + y^4, y^4]) - sage: f.is_postcritically_finite(use_algebraic_closure=False) #long time + sage: f.is_postcritically_finite(use_algebraic_closure=False) # long time True :: @@ -3985,7 +3996,7 @@ def is_dynamical_belyi_map(self): EXAMPLES:: sage: P.=ProjectiveSpace(QQ, 1) - sage: f=DynamicalSystem_projective([-2*x^3 - 9*x^2*y - 12*x*y^2 - 6*y^3, y^3]) + sage: f = DynamicalSystem_projective([-2*x^3 - 9*x^2*y - 12*x*y^2 - 6*y^3, y^3]) sage: f.is_dynamical_belyi_map() True @@ -3999,7 +4010,7 @@ def is_dynamical_belyi_map(self): :: sage: P. = ProjectiveSpace(QQ, 1) - sage: f = DynamicalSystem_projective([x^2 + y^2,y^2]) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2]) sage: f.is_dynamical_belyi_map() False @@ -4030,7 +4041,7 @@ def is_dynamical_belyi_map(self): :: sage: P. = ProjectiveSpace(GF(7), 1) - sage: f = DynamicalSystem_projective([x^3 + 6*y^3, y^3]) + sage: f = DynamicalSystem_projective([x^3 + 6*y^3, y^3]) sage: f.is_dynamical_belyi_map() False """ @@ -4066,8 +4077,8 @@ def critical_point_portrait(self, check=True, use_algebraic_closure=True): - ``check`` -- boolean (default: True) - - ``use_algebraic_closure`` -- boolean (default: True) -- If True uses the - algebraic closure. If False, uses the smallest extension of the base field + - ``use_algebraic_closure`` -- boolean (default: ``True``) -- If ``True``, uses the + algebraic closure. If ``False``, uses the smallest extension of the base field containing all the critical points. OUTPUT: a digraph @@ -4077,8 +4088,8 @@ def critical_point_portrait(self, check=True, use_algebraic_closure=True): sage: R. = QQ[] sage: K. = NumberField(z^6 + 2*z^5 + 2*z^4 + 2*z^3 + z^2 + 1) sage: PS. = ProjectiveSpace(K,1) - sage: f = DynamicalSystem_projective([x^2+v*y^2, y^2]) - sage: f.critical_point_portrait(check=False) # long time + sage: f = DynamicalSystem_projective([x^2 + v*y^2, y^2]) + sage: f.critical_point_portrait(check=False) # long time Looped digraph on 6 vertices :: @@ -4111,7 +4122,7 @@ def critical_point_portrait(self, check=True, use_algebraic_closure=True): sage: P. = ProjectiveSpace(QQ,1) sage: f = DynamicalSystem_projective([8*x^4 - 8*x^2*y^2 + y^4, y^4]) - sage: f.critical_point_portrait(use_algebraic_closure=False) #long time + sage: f.critical_point_portrait(use_algebraic_closure=False) # long time Looped digraph on 6 vertices :: @@ -4189,8 +4200,8 @@ def critical_height(self, **kwds): - ``error_bound`` -- (optional) a positive real number - - ``use_algebraic_closure`` -- boolean (default: True) -- If True uses the - algebraic closure. If False, uses the smallest extension of the base field + - ``use_algebraic_closure`` -- boolean (default: ``True``) -- If ``True``, uses the + algebraic closure. If ``False``, uses the smallest extension of the base field containing all the critical points. OUTPUT: real number @@ -4198,7 +4209,7 @@ def critical_height(self, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^3+7*y^3, 11*y^3]) + sage: f = DynamicalSystem_projective([x^3 + 7*y^3, 11*y^3]) sage: f.critical_height() 1.1989273321156851418802151128 @@ -4206,21 +4217,21 @@ def critical_height(self, **kwds): sage: K. = QuadraticField(2) sage: P. = ProjectiveSpace(K,1) - sage: f = DynamicalSystem_projective([x^2+w*y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 + w*y^2, y^2]) sage: f.critical_height() 0.16090842452312941163719755472 Postcritically finite maps have critical height 0:: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^3-3/4*x*y^2 + 3/4*y^3, y^3]) + sage: f = DynamicalSystem_projective([x^3 - 3/4*x*y^2 + 3/4*y^3, y^3]) sage: f.critical_height(error_bound=0.0001) 0.00000000000000000000000000000 :: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^3+3*x*y^2, y^3]) + sage: f = DynamicalSystem_projective([x^3 + 3*x*y^2, y^3]) sage: f.critical_height(use_algebraic_closure=False) 0.000023477016733897112886491967991 sage: f.critical_height() @@ -4375,7 +4386,8 @@ def preperiodic_points(self, m, n, **kwds): sage: P. = ProjectiveSpace(QQ, 2) sage: X = P.subscheme(2*x - y) - sage: f = DynamicalSystem_projective([x^2 - y^2, 2*(x^2 - y^2), y^2 - z^2], domain=X) + sage: f = DynamicalSystem_projective([x^2 - y^2, 2*(x^2 - y^2), y^2 - z^2], + ....: domain=X) sage: f.preperiodic_points(1, 1) [(-1/4 : -1/2 : 1), (1 : 2 : 1)] @@ -4401,7 +4413,8 @@ def preperiodic_points(self, m, n, **kwds): sage: P. = ProjectiveSpace(GF(5), 2) sage: f = DynamicalSystem_projective([x^2, x*y, z^2]) sage: f.preperiodic_points(2, 1, return_scheme=True, minimal=False) - Closed subscheme of Projective Space of dimension 2 over Finite Field of size 5 defined by: + Closed subscheme of + Projective Space of dimension 2 over Finite Field of size 5 defined by: 0, x^8*z^4 - x^4*z^8, x^7*y*z^4 - x^3*y*z^8 @@ -4432,7 +4445,7 @@ def preperiodic_points(self, m, n, **kwds): sage: f = DynamicalSystem_projective([x^2 + c*y^2, y^2]) sage: f.preperiodic_points(1, 2, return_scheme=True) Closed subscheme of Projective Space of dimension 1 over Univariate - Polynomial Ring in c over Rational Field defined by: + Polynomial Ring in c over Rational Field defined by: x^2 - x*y + (c + 1)*y^2 TESTS:: @@ -4460,7 +4473,7 @@ def preperiodic_points(self, m, n, **kwds): :: sage: P. = ProjectiveSpace(QQ, 2) - sage: f=DynamicalSystem([x^2 - z^2, y^2 - 21/16*z^2, z^2]) + sage: f = DynamicalSystem([x^2 - z^2, y^2 - 21/16*z^2, z^2]) sage: len(f.preperiodic_points(1, 2, minimal=True, formal=False)) == 16 True @@ -4471,7 +4484,8 @@ def preperiodic_points(self, m, n, **kwds): sage: f.preperiodic_points(2, 2) Traceback (most recent call last): ... - ValueError: dynamical system is not a morphism, cannot calculate minimal or formal preperiodic points + ValueError: dynamical system is not a morphism, + cannot calculate minimal or formal preperiodic points """ n = ZZ(n) m = ZZ(m) @@ -4757,7 +4771,8 @@ def periodic_points(self, n, minimal=True, formal=False, R=None, algorithm='vari sage: K. = NumberField(x^2 - x + 3) sage: P. = ProjectiveSpace(K, 2) sage: X = P.subscheme(2*x - y) - sage: f = DynamicalSystem_projective([x^2 - y^2, 2*(x^2 - y^2), y^2 - z^2], domain=X) + sage: f = DynamicalSystem_projective([x^2 - y^2, 2*(x^2 - y^2), y^2 - z^2], + ....: domain=X) sage: f.periodic_points(2) [(-1/5*u - 1/5 : -2/5*u - 2/5 : 1), (1/5*u - 2/5 : 2/5*u - 4/5 : 1)] @@ -5032,21 +5047,23 @@ def multiplier_spectra(self, n, formal=False, type='point', use_algebraic_closur :: sage: P. = ProjectiveSpace(QQ, 1) - sage: f = DynamicalSystem_projective([4608*x^10 - 2910096*x^9*y + 325988068*x^8*y^2 + 31825198932*x^7*y^3 - 4139806626613*x^6*y^4\ - - 44439736715486*x^5*y^5 + 2317935971590902*x^4*y^6 - 15344764859590852*x^3*y^7 + 2561851642765275*x^2*y^8\ - + 113578270285012470*x*y^9 - 150049940203963800*y^10, 4608*y^10]) + sage: f = DynamicalSystem_projective([4608*x^10 - 2910096*x^9*y + 325988068*x^8*y^2 + ....: + 31825198932*x^7*y^3 - 4139806626613*x^6*y^4 - 44439736715486*x^5*y^5 + ....: + 2317935971590902*x^4*y^6 - 15344764859590852*x^3*y^7 + ....: + 2561851642765275*x^2*y^8 + 113578270285012470*x*y^9 + ....: - 150049940203963800*y^10, 4608*y^10]) sage: sorted(f.multiplier_spectra(1)) [-119820502365680843999, - -7198147681176255644585/256, - -3086380435599991/9, - -3323781962860268721722583135/35184372088832, - -4290991994944936653/2097152, - 0, - 529278480109921/256, - 1061953534167447403/19683, - 848446157556848459363/19683, - 82911372672808161930567/8192, - 3553497751559301575157261317/8192] + -7198147681176255644585/256, + -3086380435599991/9, + -3323781962860268721722583135/35184372088832, + -4290991994944936653/2097152, + 0, + 529278480109921/256, + 1061953534167447403/19683, + 848446157556848459363/19683, + 82911372672808161930567/8192, + 3553497751559301575157261317/8192] :: @@ -5494,9 +5511,10 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', sage: P. = ProjectiveSpace(QQ, 2) sage: f = DynamicalSystem_projective([x^2, z^2, y^2]) sage: f.sigma_invariants(1, chow=True) - [1, 7, -6, -12, 21, -36, -60, 72, 48, 35, -90, -120, 352, 96, -288, -64, 35, -120, -120, 688, -96, - -1056, 320, 384, 0, 21, -90, -60, 672, -384, -1440, 1344, 768, -768, 0, 0, 7, -36, -12, 328, -336, - -864, 1472, 384, -1536, 512, 0, 0, 0, 1, -6, 0, 64, -96, -192, 512, 0, -768, 512, 0, 0, 0, 0, 0] + [1, 7, -6, -12, 21, -36, -60, 72, 48, 35, -90, -120, 352, 96, -288, -64, 35, + -120, -120, 688, -96, -1056, 320, 384, 0, 21, -90, -60, 672, -384, -1440, 1344, + 768, -768, 0, 0, 7, -36, -12, 328, -336, -864, 1472, 384, -1536, 512, 0, 0, 0, + 1, -6, 0, 64, -96, -192, 512, 0, -768, 512, 0, 0, 0, 0, 0] When calculating the sigma invariants for `\mathbb{P}^N`, with `N > 1`, the default algorithm loses information about multiplicities. Note that @@ -5560,13 +5578,13 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', :: sage: P. = ProjectiveSpace(QQ, 1) - sage: f = DynamicalSystem_projective([512*x^5 - 378128*x^4*y + 76594292*x^3*y^2 - 4570550136*x^2*y^3 - 2630045017*x*y^4\ - + 28193217129*y^5, 512*y^5]) + sage: f = DynamicalSystem_projective([512*x^5 - 378128*x^4*y + 76594292*x^3*y^2 + ....: - 4570550136*x^2*y^3 - 2630045017*x*y^4 + 28193217129*y^5, 512*y^5]) sage: f.sigma_invariants(1) [19575526074450617/1048576, -9078122048145044298567432325/2147483648, - -2622661114909099878224381377917540931367/1099511627776, - -2622661107937102104196133701280271632423/549755813888, - 338523204830161116503153209450763500631714178825448006778305/72057594037927936, 0] + -2622661114909099878224381377917540931367/1099511627776, + -2622661107937102104196133701280271632423/549755813888, + 338523204830161116503153209450763500631714178825448006778305/72057594037927936, 0] :: @@ -5979,15 +5997,15 @@ def reduced_form(self, **kwds): sage: f = DynamicalSystem_projective([x^3 + x*y^2, y^3]) sage: m = matrix(QQ, 2, 2, [-201221, -1, 1, 0]) sage: f = f.conjugate(m) - sage: f.reduced_form(prec=50, smallest_coeffs=False) #needs 2 periodic + sage: f.reduced_form(prec=50, smallest_coeffs=False) # needs 2 periodic Traceback (most recent call last): ... - ValueError: accuracy of Newton's root not within tolerance(0.000066... > 1e-06), increase precision + ValueError: accuracy of Newton's root not within tolerance(0.000066... > 1e-06), + increase precision sage: f.reduced_form(smallest_coeffs=False) ( Dynamical System of Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y) to - (x^3 + x*y^2 : y^3) + Defn: Defined on coordinates by sending (x : y) to (x^3 + x*y^2 : y^3) , [ 0 -1] @@ -5997,14 +6015,13 @@ def reduced_form(self, **kwds): :: sage: PS. = ProjectiveSpace(ZZ, 1) - sage: f = DynamicalSystem_projective([x^2+ x*y, y^2]) #needs 3 periodic + sage: f = DynamicalSystem_projective([x^2 + x*y, y^2]) # needs 3 periodic sage: m = matrix(QQ, 2, 2, [-221, -1, 1, 0]) sage: f = f.conjugate(m) sage: f.reduced_form(prec=200, smallest_coeffs=False) ( Dynamical System of Projective Space of dimension 1 over Integer Ring - Defn: Defined on coordinates by sending (x : y) to - (-x^2 + x*y - y^2 : -y^2) + Defn: Defined on coordinates by sending (x : y) to (-x^2 + x*y - y^2 : -y^2) , [ 0 -1] [ 1 220] @@ -6017,8 +6034,7 @@ def reduced_form(self, **kwds): sage: f.reduced_form(smallest_coeffs=False) ( Dynamical System of Projective Space of dimension 1 over Rational Field - Defn: Defined on coordinates by sending (x : y) to - (x^3 : y^3) + Defn: Defined on coordinates by sending (x : y) to (x^3 : y^3) , [1 0] @@ -6028,8 +6044,10 @@ def reduced_form(self, **kwds): :: sage: PS. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([7365*X^4 + 12564*X^3*Y + 8046*X^2*Y^2 + 2292*X*Y^3 + 245*Y^4,\ - -12329*X^4 - 21012*X^3*Y - 13446*X^2*Y^2 - 3828*X*Y^3 - 409*Y^4]) + sage: f = DynamicalSystem_projective([7365*X^4 + 12564*X^3*Y + 8046*X^2*Y^2 + ....: + 2292*X*Y^3 + 245*Y^4, + ....: -12329*X^4 - 21012*X^3*Y - 13446*X^2*Y^2 + ....: - 3828*X*Y^3 - 409*Y^4]) sage: f.reduced_form(prec=30, smallest_coeffs=False) Traceback (most recent call last): ... @@ -6038,7 +6056,8 @@ def reduced_form(self, **kwds): ( Dynamical System of Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (X : Y) to - (-7*X^4 - 12*X^3*Y - 42*X^2*Y^2 - 12*X*Y^3 - 7*Y^4 : -X^4 - 4*X^3*Y - 6*X^2*Y^2 - 4*X*Y^3 - Y^4), + (-7*X^4 - 12*X^3*Y - 42*X^2*Y^2 - 12*X*Y^3 - 7*Y^4 + : -X^4 - 4*X^3*Y - 6*X^2*Y^2 - 4*X*Y^3 - Y^4), [-1 2] [ 2 -5] @@ -6073,9 +6092,9 @@ def reduced_form(self, **kwds): sage: f = f.conjugate(m) sage: f.reduced_form(smallest_coeffs=False) ( - Dynamical System of Projective Space of dimension 1 over Number Field in w with defining polynomial x^2 - 2 with w = 1.414213562373095? - Defn: Defined on coordinates by sending (x : y) to - (x^3 : w*y^3) , + Dynamical System of Projective Space of dimension 1 over Number Field in w + with defining polynomial x^2 - 2 with w = 1.414213562373095? + Defn: Defined on coordinates by sending (x : y) to (x^3 : w*y^3) , [ 1 -12] [ 0 1] @@ -6084,16 +6103,18 @@ def reduced_form(self, **kwds): :: sage: R. = QQ[] - sage: K. = NumberField(x^5+x-3, embedding=(x^5+x-3).roots(ring=CC)[0][0]) + sage: K. = NumberField(x^5 + x - 3, + ....: embedding=(x^5 + x - 3).roots(ring=CC)[0][0]) sage: P. = ProjectiveSpace(K, 1) sage: f = DynamicalSystem_projective([12*x^3, 2334*w*y^3]) sage: m = matrix(K, 2, 2, [-12,1,1,0]) sage: f = f.conjugate(m) sage: f.reduced_form(smallest_coeffs=False) ( - Dynamical System of Projective Space of dimension 1 over Number Field in w with defining polynomial x^5 + x - 3 with w = 1.132997565885066? + Dynamical System of Projective Space of dimension 1 over Number Field in w + with defining polynomial x^5 + x - 3 with w = 1.132997565885066? Defn: Defined on coordinates by sending (x : y) to - (12*x^3 : (2334*w)*y^3) , + (12*x^3 : (2334*w)*y^3) , [ 0 -1] [ 1 -12] @@ -6148,7 +6169,7 @@ def reduced_form(self, **kwds): sage: P. = QQ[] sage: f = DynamicalSystem([4*x^2 + y^2, 4*y^2]) - sage: f.reduced_form() #long time + sage: f.reduced_form() # long time ( Dynamical System of Projective Space of dimension 1 over Rational Field Defn: Defined on coordinates by sending (x : y) to @@ -6268,7 +6289,7 @@ def _is_preperiodic(self, P, err=0.1, return_period=False): EXAMPLES:: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^3-3*x*y^2, y^3], domain=P) + sage: f = DynamicalSystem_projective([x^3 - 3*x*y^2, y^3], domain=P) sage: Q = P(-1, 1) sage: f._is_preperiodic(Q) True @@ -6278,7 +6299,7 @@ def _is_preperiodic(self, P, err=0.1, return_period=False): sage: R. = PolynomialRing(QQ) sage: K. = NumberField(X^2 + X - 1) sage: P. = ProjectiveSpace(K,1) - sage: f = DynamicalSystem_projective([x^2-2*y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 - 2*y^2, y^2]) sage: Q = P.point([a,1]) sage: Q.is_preperiodic(f) True @@ -6494,7 +6515,7 @@ def lift_to_rational_periodic(self, points_modp, B=None): There may be multiple points in the lift. sage: P. = ProjectiveSpace(QQ,1) sage: f = DynamicalSystem_projective([-5*x^2 + 4*y^2, 4*x*y]) - sage: f.lift_to_rational_periodic([[P(1,0).change_ring(GF(3)), 1]]) # long time + sage: f.lift_to_rational_periodic([[P(1,0).change_ring(GF(3)), 1]]) # long time [[(1 : 0), 1], [(2/3 : 1), 1], [(-2/3 : 1), 1]] :: @@ -6507,8 +6528,11 @@ def lift_to_rational_periodic(self, points_modp, B=None): :: sage: P. = ProjectiveSpace(QQ, 2) - sage: f = DynamicalSystem_projective([76*x^2 - 180*x*y + 45*y^2 + 14*x*z + 45*y*z - 90*z^2, 67*x^2 - 180*x*y - 157*x*z + 90*y*z, -90*z^2]) - sage: f.lift_to_rational_periodic([[P(14,19,1).change_ring(GF(23)), 9]]) # long time + sage: f = DynamicalSystem_projective([76*x^2 - 180*x*y + 45*y^2 + ....: + 14*x*z + 45*y*z - 90*z^2, + ....: 67*x^2 - 180*x*y - 157*x*z + 90*y*z, + ....: -90*z^2]) + sage: f.lift_to_rational_periodic([[P(14,19,1).change_ring(GF(23)), 9]]) # long time [[(-9 : -4 : 1), 9]] """ if not points_modp: @@ -6721,8 +6745,8 @@ def all_periodic_points(self, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(QQ,1) - sage: f = DynamicalSystem_projective([x^2-3/4*y^2, y^2]) - sage: sorted(f.all_periodic_points(prime_bound=20, lifting_prime=7)) # long time + sage: f = DynamicalSystem_projective([x^2 - 3/4*y^2, y^2]) + sage: sorted(f.all_periodic_points(prime_bound=20, lifting_prime=7)) # long time [(-1/2 : 1), (1 : 0), (3/2 : 1)] :: @@ -6741,28 +6765,29 @@ def all_periodic_points(self, **kwds): sage: P. = ProjectiveSpace(QQ,1) sage: f = DynamicalSystem_projective([-5*x^2 + 4*y^2, 4*x*y]) - sage: sorted(f.all_periodic_points()) # long time + sage: sorted(f.all_periodic_points()) # long time [(-2 : 1), (-2/3 : 1), (2/3 : 1), (1 : 0), (2 : 1)] :: sage: R. = QQ[] - sage: K. = NumberField(x^2-x+1) + sage: K. = NumberField(x^2 - x + 1) sage: P. = ProjectiveSpace(K,1) - sage: f = DynamicalSystem_projective([u^2 + v^2,v^2]) + sage: f = DynamicalSystem_projective([u^2 + v^2, v^2]) sage: sorted(f.all_periodic_points()) [(-w + 1 : 1), (w : 1), (1 : 0)] :: sage: R. = QQ[] - sage: K. = NumberField(x^2-x+1) + sage: K. = NumberField(x^2 - x + 1) sage: P. = ProjectiveSpace(K,1) - sage: f = DynamicalSystem_projective([u^2+v^2,u*v]) + sage: f = DynamicalSystem_projective([u^2 + v^2, u*v]) sage: f.all_periodic_points() Traceback (most recent call last): ... - NotImplementedError: rational periodic points for number fields only implemented for polynomials + NotImplementedError: rational periodic points for number fields + only implemented for polynomials :: @@ -6776,7 +6801,8 @@ def all_periodic_points(self, **kwds): :: sage: P. = ProjectiveSpace(QQ, 3) - sage: f = DynamicalSystem_projective([x^2 - (3/4)*w^2, y^2 - 3/4*w^2, z^2 - 3/4*w^2, w^2]) + sage: f = DynamicalSystem_projective([x^2 - (3/4)*w^2, y^2 - 3/4*w^2, + ....: z^2 - 3/4*w^2, w^2]) sage: sorted(f.all_periodic_points(algorithm="dynatomic")) [(-1/2 : -1/2 : -1/2 : 1), (-1/2 : -1/2 : 3/2 : 1), @@ -6804,7 +6830,7 @@ def all_periodic_points(self, **kwds): TESTS:: sage: P. = ProjectiveSpace(QQ, 1) - sage: f = DynamicalSystem([x^2+ y^2, x*y]) + sage: f = DynamicalSystem([x^2 + y^2, x*y]) sage: f.all_periodic_points(algorithm="banana") Traceback (most recent call last): ... @@ -6934,7 +6960,7 @@ def all_rational_preimages(self, points): In others words, all the rational points which have some iterate in the set points. This function repeatedly calls - ``rational_preimages``. If the degree is at least two, + :meth:`rational_preimages`. If the degree is at least two, by Northocott, this is always a finite set. The map must be defined over number fields and be an endomorphism. @@ -6950,12 +6976,15 @@ def all_rational_preimages(self, points): sage: f = DynamicalSystem_projective([16*x^2 - 29*y^2, 16*y^2]) sage: sorted(f.all_rational_preimages([P(-1,4)])) [(-7/4 : 1), (-5/4 : 1), (-3/4 : 1), (-1/4 : 1), (1/4 : 1), (3/4 : 1), - (5/4 : 1), (7/4 : 1)] + (5/4 : 1), (7/4 : 1)] :: sage: P. = ProjectiveSpace(QQ,2) - sage: f = DynamicalSystem_projective([76*x^2 - 180*x*y + 45*y^2 + 14*x*z + 45*y*z - 90*z^2, 67*x^2 - 180*x*y - 157*x*z + 90*y*z, -90*z^2]) + sage: f = DynamicalSystem_projective([76*x^2 - 180*x*y + 45*y^2 + 14*x*z + ....: + 45*y*z - 90*z^2, + ....: 67*x^2 - 180*x*y - 157*x*z + 90*y*z, + ....: -90*z^2]) sage: sorted(f.all_rational_preimages([P(-9,-4,1)])) [(-9 : -4 : 1), (0 : -1 : 1), (0 : 0 : 1), (0 : 1 : 1), (0 : 4 : 1), (1 : 0 : 1), (1 : 1 : 1), (1 : 2 : 1), (1 : 3 : 1)] @@ -6970,10 +6999,10 @@ def all_rational_preimages(self, points): A number field example:: sage: z = QQ['z'].0 - sage: K. = NumberField(z^3 + (z^2)/4 - (41/16)*z + 23/64); + sage: K. = NumberField(z^3 + (z^2)/4 - (41/16)*z + 23/64) sage: P. = ProjectiveSpace(K,1) sage: f = DynamicalSystem_projective([16*x^2 - 29*y^2, 16*y^2]) - sage: sorted(f.all_rational_preimages([P(16*w^2 - 29,16)]), key=str) + sage: sorted(f.all_rational_preimages([P(16*w^2 - 29, 16)]), key=str) [(-w - 1/2 : 1), (-w : 1), (-w^2 + 21/16 : 1), @@ -6991,7 +7020,7 @@ def all_rational_preimages(self, points): sage: K. = QuadraticField(3) sage: P. = ProjectiveSpace(K,1) - sage: f = DynamicalSystem_projective([u^2+v^2, v^2]) + sage: f = DynamicalSystem_projective([u^2 + v^2, v^2]) sage: f.all_rational_preimages(P(4)) [(-w : 1), (w : 1)] """ @@ -7070,10 +7099,9 @@ def all_preperiodic_points(self, **kwds): EXAMPLES:: sage: PS. = ProjectiveSpace(1,QQ) - sage: f = DynamicalSystem_projective([x^2 -y^2, 3*x*y]) + sage: f = DynamicalSystem_projective([x^2 - y^2, 3*x*y]) sage: sorted(f.all_preperiodic_points()) - [(-2 : 1), (-1 : 1), (-1/2 : 1), (0 : 1), (1/2 : 1), (1 : 0), (1 : 1), - (2 : 1)] + [(-2 : 1), (-1 : 1), (-1/2 : 1), (0 : 1), (1/2 : 1), (1 : 0), (1 : 1), (2 : 1)] :: @@ -7085,20 +7113,20 @@ def all_preperiodic_points(self, **kwds): :: sage: PS. = ProjectiveSpace(2,QQ) - sage: f = DynamicalSystem_projective([x^2 - 21/16*z^2, y^2-2*z^2, z^2]) - sage: sorted(f.all_preperiodic_points(prime_bound=[1,8], lifting_prime=7, periods=[2])) # long time - [(-5/4 : -2 : 1), (-5/4 : -1 : 1), (-5/4 : 0 : 1), (-5/4 : 1 : 1), (-5/4 - : 2 : 1), (-1/4 : -2 : 1), (-1/4 : -1 : 1), (-1/4 : 0 : 1), (-1/4 : 1 : - 1), (-1/4 : 2 : 1), (1/4 : -2 : 1), (1/4 : -1 : 1), (1/4 : 0 : 1), (1/4 - : 1 : 1), (1/4 : 2 : 1), (5/4 : -2 : 1), (5/4 : -1 : 1), (5/4 : 0 : 1), - (5/4 : 1 : 1), (5/4 : 2 : 1)] + sage: f = DynamicalSystem_projective([x^2 - 21/16*z^2, y^2 - 2*z^2, z^2]) + sage: sorted(f.all_preperiodic_points(prime_bound=[1,8], # long time + ....: lifting_prime=7, periods=[2])) + [(-5/4 : -2 : 1), (-5/4 : -1 : 1), (-5/4 : 0 : 1), (-5/4 : 1 : 1), (-5/4 : 2 : 1), + (-1/4 : -2 : 1), (-1/4 : -1 : 1), (-1/4 : 0 : 1), (-1/4 : 1 : 1), (-1/4 : 2 : 1), + (1/4 : -2 : 1), (1/4 : -1 : 1), (1/4 : 0 : 1), (1/4 : 1 : 1), (1/4 : 2 : 1), + (5/4 : -2 : 1), (5/4 : -1 : 1), (5/4 : 0 : 1), (5/4 : 1 : 1), (5/4 : 2 : 1)] :: sage: K. = QuadraticField(33) sage: PS. = ProjectiveSpace(K,1) - sage: f = DynamicalSystem_projective([x^2-71/48*y^2, y^2]) - sage: sorted(f.all_preperiodic_points()) # long time + sage: f = DynamicalSystem_projective([x^2 - 71/48*y^2, y^2]) + sage: sorted(f.all_preperiodic_points()) # long time [(-1/12*w - 1 : 1), (-1/6*w - 1/4 : 1), (-1/12*w - 1/2 : 1), @@ -7239,7 +7267,7 @@ def rational_preperiodic_graph(self, **kwds): :: sage: PS. = ProjectiveSpace(1,QQ) - sage: f = DynamicalSystem_projective([-3/2*x^3 +19/6*x*y^2, y^3]) + sage: f = DynamicalSystem_projective([-3/2*x^3 + 19/6*x*y^2, y^3]) sage: f.rational_preperiodic_graph(prime_bound=[1,8]) Looped digraph on 12 vertices @@ -7248,15 +7276,16 @@ def rational_preperiodic_graph(self, **kwds): sage: PS. = ProjectiveSpace(2,QQ) sage: f = DynamicalSystem_projective([2*x^3 - 50*x*z^2 + 24*z^3, ....: 5*y^3 - 53*y*z^2 + 24*z^3, 24*z^3]) - sage: f.rational_preperiodic_graph(prime_bound=[1,11], lifting_prime=13) # long time + sage: f.rational_preperiodic_graph(prime_bound=[1,11], # long time + ....: lifting_prime=13) Looped digraph on 30 vertices :: sage: K. = QuadraticField(-3) sage: P. = ProjectiveSpace(K,1) - sage: f = DynamicalSystem_projective([x^2+y^2, y^2]) - sage: f.rational_preperiodic_graph() # long time + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2]) + sage: f.rational_preperiodic_graph() # long time Looped digraph on 5 vertices """ #input checking done in .rational_preperiodic_points() @@ -7286,7 +7315,7 @@ def connected_rational_component(self, P, n=0): EXAMPLES:: sage: R. = PolynomialRing(QQ) - sage: K. = NumberField(x^3+1/4*x^2-41/16*x+23/64) + sage: K. = NumberField(x^3 + 1/4*x^2 - 41/16*x + 23/64) sage: PS. = ProjectiveSpace(1,K) sage: f = DynamicalSystem_projective([x^2 - 29/16*y^2, y^2]) sage: P = PS([w,1]) @@ -7307,9 +7336,9 @@ def connected_rational_component(self, P, n=0): :: sage: PS. = ProjectiveSpace(2,QQ) - sage: f = DynamicalSystem_projective([x^2 - 21/16*z^2, y^2-2*z^2, z^2]) - sage: P = PS([17/16,7/4,1]) - sage: f.connected_rational_component(P,3) + sage: f = DynamicalSystem_projective([x^2 - 21/16*z^2, y^2 - 2*z^2, z^2]) + sage: P = PS([17/16, 7/4, 1]) + sage: f.connected_rational_component(P, 3) [(17/16 : 7/4 : 1), (-47/256 : 17/16 : 1), (-83807/65536 : -223/256 : 1), @@ -7463,7 +7492,8 @@ def conjugating_set(self, other, R=None, num_cpus=2): sage: D8.conjugating_set(D8) Traceback (most recent call last): ... - ValueError: no more rational preimages; try extending the base field and trying again + ValueError: no more rational preimages; + try extending the base field and trying again :: @@ -7508,7 +7538,7 @@ def conjugating_set(self, other, R=None, num_cpus=2): note that only one possible conjugation is returned:: sage: P. = ProjectiveSpace(GF(11), 2) - sage: f = DynamicalSystem_projective([2*x + 12*y, 11*y+2*z, x+z]) + sage: f = DynamicalSystem_projective([2*x + 12*y, 11*y + 2*z, x + z]) sage: m1 = matrix(GF(11), 3, 3, [1,4,1,0,2,1,1,1,1]) sage: g = f.conjugate(m1) sage: f.conjugating_set(g) @@ -7522,7 +7552,7 @@ def conjugating_set(self, other, R=None, num_cpus=2): sage: L. = CyclotomicField(8) sage: P. = ProjectiveSpace(L, 2) - sage: f = DynamicalSystem_projective([2*x + 12*y, 11*y+2*z, x+z]) + sage: f = DynamicalSystem_projective([2*x + 12*y, 11*y + 2*z, x + z]) sage: m1 = matrix(L, 3, 3, [1,4,v^2,0,2,1,1,1,1]) sage: g = f.conjugate(m1) sage: m = f.conjugating_set(g)[0] # long time @@ -7717,7 +7747,7 @@ def is_conjugate(self, other, R=None, num_cpus=2): sage: f.is_conjugate(g) True - conjugation is only checked over the base field by default:: + Conjugation is only checked over the base field by default:: sage: P. = ProjectiveSpace(QQ, 1) sage: f = DynamicalSystem_projective([-3*y^2, 3*x^2]) @@ -7728,7 +7758,7 @@ def is_conjugate(self, other, R=None, num_cpus=2): :: sage: P. = ProjectiveSpace(QQ, 2) - sage: f = DynamicalSystem_projective([7*x + 12*y, 8*y+2*z, x+z]) + sage: f = DynamicalSystem_projective([7*x + 12*y, 8*y + 2*z, x + z]) sage: m1 = matrix(QQ, 3, 3, [1,4,1,0,2,1,1,1,1]) sage: g = f.conjugate(m1) sage: f.is_conjugate(g) @@ -7737,7 +7767,7 @@ def is_conjugate(self, other, R=None, num_cpus=2): :: sage: P. = ProjectiveSpace(GF(7), 2) - sage: f = DynamicalSystem_projective([2*x + 12*y, 11*y+2*z, x+z]) + sage: f = DynamicalSystem_projective([2*x + 12*y, 11*y + 2*z, x + z]) sage: m1 = matrix(GF(7), 3, 3, [1,4,1,0,2,1,1,1,1]) sage: g = f.conjugate(m1) sage: f.is_conjugate(g) @@ -7746,7 +7776,7 @@ def is_conjugate(self, other, R=None, num_cpus=2): :: sage: P. = ProjectiveSpace(QQ, 2) - sage: f = DynamicalSystem_projective([2*x^2 + 12*y*x, 11*y*x+2*y^2, x^2+z^2]) + sage: f = DynamicalSystem_projective([2*x^2 + 12*y*x, 11*y*x + 2*y^2, x^2 + z^2]) sage: m1 = matrix(QQ, 3, 3, [1,4,1,0,2,1,1,1,1]) sage: g = f.conjugate(m1) sage: f.is_conjugate(g) @@ -7848,7 +7878,7 @@ def is_polynomial(self): sage: K. = QuadraticField(4/27) sage: P. = ProjectiveSpace(K,1) - sage: f = DynamicalSystem_projective([x**3 + w*y^3,x*y**2]) + sage: f = DynamicalSystem_projective([x**3 + w*y^3, x*y**2]) sage: f.is_polynomial() False @@ -7863,7 +7893,7 @@ def is_polynomial(self): :: sage: PS. = ProjectiveSpace(QQ, 1) - sage: f = DynamicalSystem_projective([6*x^2+12*x*y+7*y^2, 12*x*y + 42*y^2]) + sage: f = DynamicalSystem_projective([6*x^2 + 12*x*y + 7*y^2, 12*x*y + 42*y^2]) sage: f.is_polynomial() False @@ -7872,7 +7902,7 @@ def is_polynomial(self): See :trac:`25242`:: sage: P. = ProjectiveSpace(QQ, 1) - sage: F = DynamicalSystem([x^2+ y^2, x*y]) + sage: F = DynamicalSystem([x^2 + y^2, x*y]) sage: F2 = F.conjugate(matrix(QQ,2,2, [1,2,3,5])) sage: F2.is_polynomial() False @@ -7996,13 +8026,14 @@ def normal_form(self, return_conjugation=False): :: - sage: K = GF(3^3, prefix = 'w') + sage: K = GF(3^3, prefix='w') sage: P. = ProjectiveSpace(K,1) sage: f = DynamicalSystem_projective([x^3 + 2*x^2*y + 2*x*y^2 + K.gen()*y^3, y^3]) sage: f.normal_form() - Dynamical System of Projective Space of dimension 1 over Finite Field in w3 of size 3^3 - Defn: Defined on coordinates by sending (x : y) to - (x^3 + x^2*y + x*y^2 + (-w3)*y^3 : y^3) + Dynamical System of Projective Space of dimension 1 + over Finite Field in w3 of size 3^3 + Defn: Defined on coordinates by sending (x : y) to + (x^3 + x^2*y + x*y^2 + (-w3)*y^3 : y^3) :: @@ -8165,24 +8196,26 @@ def potential_good_reduction(self, prime, return_conjugation=False): A tuple: - The first element is: - - ``False`` if this dynamical system does not have potential good reduction. - - ``True`` if this dynamical system does have potential good reduction. + - ``False`` if this dynamical system does not have potential good reduction. + - ``True`` if this dynamical system does have potential good reduction. + - The second element is: - - ``None`` if this dynamical system does not have potential good reduction. - - A dynamical system with good reduction at ``prime`` otherwise. + - ``None`` if this dynamical system does not have potential good reduction. + - A dynamical system with good reduction at ``prime`` otherwise. + - If ``return_conjugation`` is ``True``, then the tuple will have a third element, which is: - - ``None`` if this dynamical system does not have potential good reduction. - - The `PGL_2` map used to achieve good reduction otherwise. + - ``None`` if this dynamical system does not have potential good reduction. + - The `PGL_2` map used to achieve good reduction otherwise. EXAMPLES:: sage: P. = ProjectiveSpace(QQ, 1) - sage: system = DynamicalSystem_projective([x^2-y^2, 2*x*y]) + sage: system = DynamicalSystem_projective([x^2 - y^2, 2*x*y]) sage: prime = system.field_of_definition_periodic(1).prime_above(2) sage: new_system = system.potential_good_reduction(prime)[1] sage: new_system Dynamical System of Projective Space of dimension 1 over Number Field - in a with defining polynomial x^2 + 1 + in a with defining polynomial x^2 + 1 Defn: Defined on coordinates by sending (x : y) to ((-1/2*a)*x^2 + (-5/2*a)*y^2 : (-a)*x*y + y^2) @@ -8205,7 +8238,7 @@ def potential_good_reduction(self, prime, return_conjugation=False): :: sage: P. = ProjectiveSpace(QQ, 1) - sage: system = DynamicalSystem_projective([3^4*x^3+3*x*y^2+y^3, 3^6*y^3]) + sage: system = DynamicalSystem_projective([3^4*x^3 + 3*x*y^2 + y^3, 3^6*y^3]) sage: prime = system.field_of_definition_periodic(1).prime_above(3) sage: system.potential_good_reduction(prime) (False, None) @@ -8213,7 +8246,7 @@ def potential_good_reduction(self, prime, return_conjugation=False): :: sage: P. = ProjectiveSpace(QQ, 1) - sage: system = DynamicalSystem_projective([x^5-x*y^4, 5*y^5]) + sage: system = DynamicalSystem_projective([x^5 - x*y^4, 5*y^5]) sage: prime = system.field_of_definition_periodic(1).prime_above(5) sage: system.potential_good_reduction(prime) (False, None) @@ -8227,15 +8260,16 @@ def potential_good_reduction(self, prime, return_conjugation=False): sage: system = DynamicalSystem_projective([x^2 - y^2, 2*x*y]) sage: system.potential_good_reduction(prime) (True, - Dynamical System of Projective Space of dimension 1 over - Number Field in a with defining polynomial x^2 + 1 - Defn: Defined on coordinates by sending (x : y) to - ((-1/2*a)*x^2 + (-5/2*a)*y^2 : (-a)*x*y + y^2)) + Dynamical System of Projective Space of dimension 1 over + Number Field in a with defining polynomial x^2 + 1 + Defn: Defined on coordinates by sending (x : y) to + ((-1/2*a)*x^2 + (-5/2*a)*y^2 : (-a)*x*y + y^2)) :: sage: P. = ProjectiveSpace(QQ, 1) - sage: system = DynamicalSystem_projective([3^5*x^3 + x^2*y - 3^5*x*y^2, -3^5*x^2*y + x*y^2 + 3^5*y^3]) + sage: system = DynamicalSystem_projective([3^5*x^3 + x^2*y - 3^5*x*y^2, + ....: -3^5*x^2*y + x*y^2 + 3^5*y^3]) sage: system.potential_good_reduction(3, return_conjugation=True) # long time (False, None, None) @@ -8252,7 +8286,7 @@ def potential_good_reduction(self, prime, return_conjugation=False): :: sage: P. = ProjectiveSpace(QQ, 1) - sage: system = DynamicalSystem_projective([3*x^2 + x*y+y^2, 9*y^2]) + sage: system = DynamicalSystem_projective([3*x^2 + x*y + y^2, 9*y^2]) sage: prime = system.field_of_definition_periodic(1).prime_above(3) sage: system.potential_good_reduction(prime) (False, None) @@ -8359,20 +8393,22 @@ def reduce_base_field(self): :: sage: P. = ProjectiveSpace(QQbar, 2) - sage: f = DynamicalSystem_projective([x^2 + QQbar(sqrt(3))*y^2, y^2, QQbar(sqrt(2))*z^2]) + sage: f = DynamicalSystem_projective([x^2 + QQbar(sqrt(3))*y^2, + ....: y^2, QQbar(sqrt(2))*z^2]) sage: f.reduce_base_field() Dynamical System of Projective Space of dimension 2 over Number Field in a with - defining polynomial y^4 - 4*y^2 + 1 with a = -0.5176380902050415? + defining polynomial y^4 - 4*y^2 + 1 with a = -0.5176380902050415? Defn: Defined on coordinates by sending (x : y : z) to (x^2 + (-a^2 + 2)*y^2 : y^2 : (a^3 - 3*a)*z^2) :: sage: R. = QQ[] - sage: K. = NumberField(x^3-2, embedding=(x^3-2).roots(ring=CC)[0][0]) + sage: K. = NumberField(x^3 - 2, embedding=(x^3 - 2).roots(ring=CC)[0][0]) sage: R. = QQ[] - sage: L. = NumberField(x^6 + 9*x^4 - 4*x^3 + 27*x^2 + 36*x + 31, \ - ....: embedding=(x^6 + 9*x^4 - 4*x^3 + 27*x^2 + 36*x + 31).roots(ring=CC)[0][0]) + sage: L. = NumberField(x^6 + 9*x^4 - 4*x^3 + 27*x^2 + 36*x + 31, + ....: embedding=(x^6 + 9*x^4 - 4*x^3 + ....: + 27*x^2 + 36*x + 31).roots(ring=CC)[0][0]) sage: P. = ProjectiveSpace(L,1) sage: f = DynamicalSystem([L(v)*x^2 + y^2, x*y]) sage: f.reduce_base_field().base_ring().is_isomorphic(K) @@ -8420,7 +8456,7 @@ def is_newton(self, return_conjugation=False): sage: F = f.homogenize(1) sage: F.is_newton(return_conjugation=True) ( - [1 0] + [1 0] True, [0 1] ) @@ -8510,7 +8546,7 @@ def is_postcritically_finite(self, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(GF(5),2) - sage: f = DynamicalSystem_projective([x^2 + y^2,y^2, z^2 + y*z], domain=P) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2, z^2 + y*z], domain=P) sage: f.is_postcritically_finite() True @@ -8541,14 +8577,14 @@ def _is_preperiodic(self, P, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(GF(5),2) - sage: f = DynamicalSystem_projective([x^2 + y^2,y^2, z^2 + y*z], domain=P) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2, z^2 + y*z], domain=P) sage: f._is_preperiodic(P(2,1,2)) True :: sage: P. = ProjectiveSpace(GF(5),2) - sage: f = DynamicalSystem_projective([x^2 + y^2,y^2, z^2 + y*z], domain=P) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2, z^2 + y*z], domain=P) sage: f._is_preperiodic(P(2,1,2), return_period=True) (0, 6) """ @@ -8575,14 +8611,14 @@ def orbit_structure(self, P): EXAMPLES:: sage: P. = ProjectiveSpace(GF(5),2) - sage: f = DynamicalSystem_projective([x^2 + y^2,y^2, z^2 + y*z], domain=P) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2, z^2 + y*z], domain=P) sage: f.orbit_structure(P(2,1,2)) (0, 6) :: sage: P. = ProjectiveSpace(GF(7),2) - sage: X = P.subscheme(x^2-y^2) + sage: X = P.subscheme(x^2 - y^2) sage: f = DynamicalSystem_projective([x^2, y^2, z^2], domain=X) sage: f.orbit_structure(X(1,1,2)) (0, 2) @@ -8628,21 +8664,21 @@ def cyclegraph(self): EXAMPLES:: sage: P. = ProjectiveSpace(GF(13),1) - sage: f = DynamicalSystem_projective([x^2-y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 - y^2, y^2]) sage: f.cyclegraph() Looped digraph on 14 vertices :: sage: P. = ProjectiveSpace(GF(3^2,'t'),2) - sage: f = DynamicalSystem_projective([x^2+y^2, y^2, z^2+y*z]) + sage: f = DynamicalSystem_projective([x^2 + y^2, y^2, z^2 + y*z]) sage: f.cyclegraph() Looped digraph on 91 vertices :: sage: P. = ProjectiveSpace(GF(7),2) - sage: X = P.subscheme(x^2-y^2) + sage: X = P.subscheme(x^2 - y^2) sage: f = DynamicalSystem_projective([x^2, y^2, z^2], domain=X) sage: f.cyclegraph() Looped digraph on 15 vertices @@ -8650,15 +8686,15 @@ def cyclegraph(self): :: sage: P. = ProjectiveSpace(GF(3),2) - sage: f = DynamicalSystem_projective([x*z-y^2, x^2-y^2, y^2-z^2]) + sage: f = DynamicalSystem_projective([x*z - y^2, x^2 - y^2, y^2 - z^2]) sage: f.cyclegraph() Looped digraph on 13 vertices :: sage: P. = ProjectiveSpace(GF(3),2) - sage: X = P.subscheme([x-y]) - sage: f = DynamicalSystem_projective([x^2-y^2, x^2-y^2, y^2-z^2], domain=X) + sage: X = P.subscheme([x - y]) + sage: f = DynamicalSystem_projective([x^2 - y^2, x^2 - y^2, y^2 - z^2], domain=X) sage: f.cyclegraph() Looped digraph on 4 vertices """ @@ -8720,7 +8756,7 @@ def possible_periods(self, return_points=False): :: sage: P. = ProjectiveSpace(GF(13),1) - sage: f = DynamicalSystem_projective([x^2-y^2, y^2]) + sage: f = DynamicalSystem_projective([x^2 - y^2, y^2]) sage: sorted(f.possible_periods(True)) [[(0 : 1), 2], [(1 : 0), 1], [(3 : 1), 3], [(3 : 1), 36]] @@ -8784,7 +8820,7 @@ def automorphism_group(self, **kwds): EXAMPLES:: sage: R. = ProjectiveSpace(GF(7^3,'t'),1) - sage: f = DynamicalSystem_projective([x^2-y^2, x*y]) + sage: f = DynamicalSystem_projective([x^2 - y^2, x*y]) sage: f.automorphism_group() [ [1 0] [6 0] @@ -8794,9 +8830,10 @@ def automorphism_group(self, **kwds): :: sage: R. = ProjectiveSpace(GF(3^2,'t'),1) - sage: f = DynamicalSystem_projective([x^3,y^3]) - sage: lst, label = f.automorphism_group(return_functions=True, iso_type=True) # long time - sage: sorted(lst, key=str), label # long time + sage: f = DynamicalSystem_projective([x^3, y^3]) + sage: lst, label = f.automorphism_group(return_functions=True, # long time + ....: iso_type=True) + sage: sorted(lst, key=str), label # long time ([(2*x + 1)/(x + 1), (2*x + 1)/x, (2*x + 2)/(x + 2), @@ -8826,14 +8863,14 @@ def automorphism_group(self, **kwds): :: sage: R. = ProjectiveSpace(GF(2^5,'t'),1) - sage: f = DynamicalSystem_projective([x^5,y^5]) + sage: f = DynamicalSystem_projective([x^5, y^5]) sage: f.automorphism_group(return_functions=True, iso_type=True) ([x, 1/x], 'Cyclic of order 2') :: sage: R. = ProjectiveSpace(GF(3^4,'t'),1) - sage: f = DynamicalSystem_projective([x^2+25*x*y+y^2, x*y+3*y^2]) + sage: f = DynamicalSystem_projective([x^2 + 25*x*y + y^2, x*y + 3*y^2]) sage: f.automorphism_group(absolute=True) [Univariate Polynomial Ring in w over Finite Field in b of size 3^4, [ @@ -8882,14 +8919,14 @@ def all_periodic_points(self, **kwds): EXAMPLES:: sage: P. = ProjectiveSpace(GF(5^2),1) - sage: f = DynamicalSystem_projective([x^2+y^2, x*y]) + sage: f = DynamicalSystem_projective([x^2 + y^2, x*y]) sage: f.all_periodic_points() [(1 : 0), (z2 + 2 : 1), (4*z2 + 3 : 1)] :: sage: P. = ProjectiveSpace(GF(5),2) - sage: f = DynamicalSystem_projective([x^2+y^2+z^2, x*y+x*z, z^2]) + sage: f = DynamicalSystem_projective([x^2 + y^2 + z^2, x*y + x*z, z^2]) sage: f.all_periodic_points() [(1 : 0 : 0), (0 : 0 : 1), diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index d21bddd5deb..27ed329e75e 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -1772,18 +1772,18 @@ cpdef generate_code(Expression expr, InstructionStream stream): 25 sage: fc.op_list() [('load_arg', 0), ('load_arg', 1), ('py_call', , 2), 'return'] - sage: fc = fast_callable(expr) - sage: fc(3.0r) + sage: fc = fast_callable(expr) # optional - sage.symbolic + sage: fc(3.0r) # optional - sage.symbolic 4.0*pi + 12.0 - sage: fc = fast_callable(x+3, domain=ZZ) - sage: fc(4) + sage: fc = fast_callable(x+3, domain=ZZ) # optional - sage.symbolic + sage: fc(4) # optional - sage.symbolic 7 - sage: fc = fast_callable(x/3, domain=ZZ) - sage: fc(4) + sage: fc = fast_callable(x/3, domain=ZZ) # optional - sage.symbolic + sage: fc(4) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: no conversion of this rational to integer - sage: fc(6) + sage: fc(6) # optional - sage.symbolic 2 sage: fc = fast_callable(etb.call(sin, x), domain=ZZ) sage: fc(0) diff --git a/src/sage/matroids/graphic_matroid.py b/src/sage/matroids/graphic_matroid.py index f91ad67ddcc..0fd64969f9d 100644 --- a/src/sage/matroids/graphic_matroid.py +++ b/src/sage/matroids/graphic_matroid.py @@ -1336,6 +1336,8 @@ def _subgraph_from_set(self, X): sage: M._subgraph_from_set([0,1,2]) Looped multi-graph on 3 vertices """ + from sage.graphs.graph import Graph + edge_list = self._groundset_to_edges(X) return Graph(edge_list, loops=True, multiedges=True) diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index 100f5c3e74f..916c933555f 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -3633,7 +3633,7 @@ cdef class BinaryMatroid(LinearMatroid): 2 sage: for i in [-1, 0, 1]: # optional - sage.rings.finite_rings ....: print(sorted(e for e in M.groundset() - ....: if (M\e).bicycle_dimension() == 2 + i])) + ....: if (M\e).bicycle_dimension() == 2 + i)) ['a', 'b', 'c', 'e', 'f', 'g'] ['d'] ['h'] diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 0a49ae27cb9..721567c1aca 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -3126,12 +3126,12 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.Whirl(4) # optional - sage.rings.finite_rings - sage: P = M.matroid_polytope(); P # optional - sage.geometry.polyhedron sage.libs.pari + sage: P = M.matroid_polytope(); P # optional - sage.geometry.polyhedron sage.rings.finite_rings A 7-dimensional polyhedron in ZZ^8 defined as the convex hull of 46 vertices sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings - sage: M.matroid_polytope() # optional - sage.geometry.polyhedron sage.libs.pari + sage: M.matroid_polytope() # optional - sage.geometry.polyhedron sage.rings.finite_rings A 6-dimensional polyhedron in ZZ^7 defined as the convex hull of 29 vertices @@ -3169,12 +3169,12 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.Whirl(4) # optional - sage.rings.finite_rings - sage: M.independence_matroid_polytope() # optional - sage.geometry.polyhedron sage.libs.pari + sage: M.independence_matroid_polytope() # optional - sage.geometry.polyhedron sage.rings.finite_rings A 8-dimensional polyhedron in ZZ^8 defined as the convex hull of 135 vertices sage: M = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings - sage: M.independence_matroid_polytope() # optional - sage.geometry.polyhedron sage.libs.pari + sage: M.independence_matroid_polytope() # optional - sage.geometry.polyhedron sage.rings.finite_rings A 7-dimensional polyhedron in ZZ^7 defined as the convex hull of 58 vertices diff --git a/src/sage/matroids/set_system.pyx b/src/sage/matroids/set_system.pyx index a157b1115d4..14a95f4dce6 100644 --- a/src/sage/matroids/set_system.pyx +++ b/src/sage/matroids/set_system.pyx @@ -733,7 +733,7 @@ cdef class SetSystem: sage: N = Matroid(ring=GF(5), reduced_matrix=[[1,0,1],[0,1,1],[1,1,0]]) # optional - sage.rings.finite_rings sage: M.is_field_isomorphic(N) # optional - sage.rings.finite_rings False - sage: any(M.is_field_isomorphism(N, p) for p in Permutations(range(6))) # optional - sage.combinat sage.libs.pari + sage: any(M.is_field_isomorphism(N, p) for p in Permutations(range(6))) # optional - sage.combinat sage.rings.finite_rings False """ cdef long v diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py index 9407f588848..cd79889fb14 100644 --- a/src/sage/misc/functional.py +++ b/src/sage/misc/functional.py @@ -1337,9 +1337,9 @@ def norm(x): sage: M = matrix(ZZ, [[1,2,4,3], [-1,0,3,-10]]) sage: norm(M) # abs tol 1e-14 10.690331129154467 - sage: norm(CDF(z)) + sage: norm(CDF(z)) # optional - sage.modules 5.0 - sage: norm(CC(z)) + sage: norm(CC(z)) # optional - sage.modules 5.00000000000000 The norm of complex numbers:: From 228c2120dc4b148b062f0bf1b1cc20df68d4ca3c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 3 Jun 2023 19:28:06 -0700 Subject: [PATCH 047/205] sage.matroids: Modularization fixes --- src/sage/matroids/matroid.pyx | 8 ++--- src/sage/matroids/matroids_plot_helpers.py | 40 +++++++++++----------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 721567c1aca..bc4cd0df316 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -7823,15 +7823,15 @@ cdef class Matroid(SageObject): sage: t="fghij" sage: x=1.61 sage: y=1/1.61 - sage: for i in range(5): + sage: for i in range(5): # optional - sage.symbolic ....: pos[s[i]]=(RR(x*sin(2*pi*i/5)), RR(x*cos(2*pi*i/5))) ....: pos[t[i]]=(RR(y*sin(2*pi*(i+1/2)/5)), RR(y*cos(2*pi*(i+1/2)/5))) ....: sage: pos['k']=(0,0) - sage: M._fix_positions(pos_dict=pos) - sage: M._cached_info['lineorders'] is None + sage: M._fix_positions(pos_dict=pos) # optional - sage.symbolic + sage: M._cached_info['lineorders'] is None # optional - sage.symbolic True - sage: M._cached_info['plot_positions']['k'] + sage: M._cached_info['plot_positions']['k'] # optional - sage.symbolic (0, 0) """ if self.rank() > 3: diff --git a/src/sage/matroids/matroids_plot_helpers.py b/src/sage/matroids/matroids_plot_helpers.py index 99ada7f3b3a..73980d8e408 100644 --- a/src/sage/matroids/matroids_plot_helpers.py +++ b/src/sage/matroids/matroids_plot_helpers.py @@ -56,7 +56,7 @@ ....: 4: (0.5, 1.0), 5: (1.0, 0.0), 6: (1.0, 0.666666666666667), ....: 7: (3,3), 8: (4,0), 9: (-1,1), 10: (-2,-2)} sage: M1._cached_info={'plot_positions': pos_dict, 'plot_lineorders': None} - sage: matroids_plot_helpers.geomrep(M1, sp=True) + sage: matroids_plot_helpers.geomrep(M1, sp=True) # optional - sage.plot Graphics object consisting of 22 graphics primitives """ @@ -321,22 +321,22 @@ def createline(ptsdict, ll, lineorders2=None): EXAMPLES:: sage: from sage.matroids import matroids_plot_helpers - sage: ptsdict={'a':(1,3),'b':(2,1),'c':(4,5),'d':(5,2)} - sage: x,y,x_i,y_i=matroids_plot_helpers.createline(ptsdict, + sage: ptsdict = {'a':(1,3),'b':(2,1),'c':(4,5),'d':(5,2)} + sage: x,y,x_i,y_i = matroids_plot_helpers.createline(ptsdict, ....: ['a','b','c','d']) sage: [len(x), len(y), len(x_i), len(y_i)] [4, 4, 100, 100] - sage: G = line(zip(x_i, y_i),color='black',thickness=3,zorder=1) - sage: G+=points(zip(x, y), color='black', size=300,zorder=2) - sage: G.show() - sage: x,y,x_i,y_i=matroids_plot_helpers.createline(ptsdict, + sage: G = line(zip(x_i, y_i), color='black', thickness=3, zorder=1) # optional - sage.plot + sage: G += points(zip(x, y), color='black', size=300, zorder=2) # optional - sage.plot + sage: G.show() # optional - sage.plot + sage: x,y,x_i,y_i = matroids_plot_helpers.createline(ptsdict, ....: ['a','b','c','d'],lineorders2=[['b','a','c','d'], ....: ['p','q','r','s']]) sage: [len(x), len(y), len(x_i), len(y_i)] [4, 4, 100, 100] - sage: G = line(zip(x_i, y_i),color='black',thickness=3,zorder=1) - sage: G+=points(zip(x, y), color='black', size=300,zorder=2) - sage: G.show() + sage: G = line(zip(x_i, y_i), color='black', thickness=3, zorder=1) # optional - sage.plot + sage: G += points(zip(x, y), color='black', size=300, zorder=2) # optional - sage.plot + sage: G.show() # optional - sage.plot .. NOTE:: @@ -483,11 +483,11 @@ def addlp(M, M1, L, P, ptsdict, G=None, limits=None): EXAMPLES:: sage: from sage.matroids import matroids_plot_helpers - sage: M=Matroid(ring=GF(2), matrix=[[1, 0, 0, 0, 1, 1, 1,0,1], + sage: M = Matroid(ring=GF(2), matrix=[[1, 0, 0, 0, 1, 1, 1,0,1], ....: [0, 1, 0, 1, 0, 1, 1,0,0],[0, 0, 1, 1, 1, 0, 1,0,0]]) - sage: [M1,L,P]=matroids_plot_helpers.slp(M) - sage: G,lims=matroids_plot_helpers.addlp(M,M1,L,P,{0:(0,0)}) - sage: G.show(axes=False) + sage: [M1,L,P] = matroids_plot_helpers.slp(M) + sage: G, lims = matroids_plot_helpers.addlp(M,M1,L,P,{0:(0,0)}) # optional - sage.plot + sage: G.show(axes=False) # optional - sage.plot .. NOTE:: @@ -757,12 +757,12 @@ def geomrep(M1, B1=None, lineorders1=None, pd=None, sp=False): EXAMPLES:: sage: from sage.matroids import matroids_plot_helpers - sage: M=matroids.named_matroids.P7() - sage: G=matroids_plot_helpers.geomrep(M) - sage: G.show(xmin=-2, xmax=3, ymin=-2, ymax=3) - sage: M=matroids.named_matroids.P7() - sage: G=matroids_plot_helpers.geomrep(M,lineorders1=[['f','e','d']]) - sage: G.show(xmin=-2, xmax=3, ymin=-2, ymax=3) + sage: M = matroids.named_matroids.P7() + sage: G = matroids_plot_helpers.geomrep(M) # optional - sage.plot + sage: G.show(xmin=-2, xmax=3, ymin=-2, ymax=3) # optional - sage.plot + sage: M = matroids.named_matroids.P7() + sage: G = matroids_plot_helpers.geomrep(M, lineorders1=[['f','e','d']]) # optional - sage.plot + sage: G.show(xmin=-2, xmax=3, ymin=-2, ymax=3) # optional - sage.plot .. NOTE:: From b0913f095bf37a03e72c14041da627582afcc472 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 31 May 2023 14:50:10 -0700 Subject: [PATCH 048/205] sage.matroids: Add # optional --- src/sage/matroids/graphic_matroid.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/matroids/graphic_matroid.py b/src/sage/matroids/graphic_matroid.py index 0fd64969f9d..b20d538030e 100644 --- a/src/sage/matroids/graphic_matroid.py +++ b/src/sage/matroids/graphic_matroid.py @@ -1,5 +1,4 @@ # sage.doctest: optional - sage.graphs -# sage.doctest: optional - sage.groups (for DisjointSet) r""" Graphic Matroids From 1872fcb0f4fe66f1e8d8d9845888c8ddd5b9f68e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 1 Jun 2023 23:01:32 -0700 Subject: [PATCH 049/205] sage.matroids: Add # optional --- src/sage/matroids/basis_exchange_matroid.pyx | 22 +- src/sage/matroids/basis_matroid.pyx | 12 +- src/sage/matroids/catalog.py | 44 +-- .../matroids/circuit_closures_matroid.pyx | 26 +- src/sage/matroids/constructor.py | 137 +++++----- src/sage/matroids/lean_matrix.pyx | 1 + src/sage/matroids/linear_matroid.pyx | 250 +++++++++--------- src/sage/matroids/matroids_plot_helpers.py | 68 ++--- src/sage/matroids/unpickling.pyx | 4 +- src/sage/matroids/utilities.py | 50 ++-- 10 files changed, 312 insertions(+), 302 deletions(-) diff --git a/src/sage/matroids/basis_exchange_matroid.pyx b/src/sage/matroids/basis_exchange_matroid.pyx index 360ec9538aa..6501c592662 100644 --- a/src/sage/matroids/basis_exchange_matroid.pyx +++ b/src/sage/matroids/basis_exchange_matroid.pyx @@ -516,10 +516,10 @@ cdef class BasisExchangeMatroid(Matroid): EXAMPLES:: - sage: M = matroids.named_matroids.Fano() - sage: len(M) + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: len(M) # optional - sage.rings.finite_rings 7 - sage: len(M.groundset()) + sage: len(M.groundset()) # optional - sage.rings.finite_rings 7 """ @@ -2146,8 +2146,8 @@ cdef class BasisExchangeMatroid(Matroid): ....: return min(len(X), 2) ....: sage: M = Matroid(groundset='abcd', rank_function=f) - sage: N = Matroid(field=GF(3), reduced_matrix=[[1,1],[1,-1]]) - sage: N._is_isomorphism(M, {0:'a', 1:'b', 2:'c', 3:'d'}) + sage: N = Matroid(field=GF(3), reduced_matrix=[[1,1],[1,-1]]) # optional - sage.rings.finite_rings + sage: N._is_isomorphism(M, {0:'a', 1:'b', 2:'c', 3:'d'}) # optional - sage.rings.finite_rings True """ if not isinstance(other, BasisExchangeMatroid): @@ -2195,9 +2195,9 @@ cdef class BasisExchangeMatroid(Matroid): sage: from sage.matroids.advanced import * sage: M1 = matroids.Wheel(3) - sage: M2 = matroids.CompleteGraphic(4) - sage: morphism = M1._isomorphism(M2) - sage: M1._is_isomorphism(M2, morphism) + sage: M2 = matroids.CompleteGraphic(4) # optional - sage.graphs + sage: morphism = M1._isomorphism(M2) # optional - sage.graphs + sage: M1._is_isomorphism(M2, morphism) # optional - sage.graphs True sage: M1 = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings sage: M2 = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings @@ -2289,10 +2289,10 @@ cdef class BasisExchangeMatroid(Matroid): sage: from sage.matroids.advanced import * sage: M1 = BasisMatroid(matroids.Wheel(3)) - sage: M2 = matroids.CompleteGraphic(4) - sage: M1._is_isomorphic(M2) + sage: M2 = matroids.CompleteGraphic(4) # optional - sage.graphs + sage: M1._is_isomorphic(M2) # optional - sage.graphs True - sage: M1._is_isomorphic(M2, certificate=True) + sage: M1._is_isomorphic(M2, certificate=True) # optional - sage.graphs (True, {0: 0, 1: 1, 2: 2, 3: 3, 4: 5, 5: 4}) sage: M1 = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings sage: M2 = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings diff --git a/src/sage/matroids/basis_matroid.pyx b/src/sage/matroids/basis_matroid.pyx index b7007314b1b..e9ac791d729 100644 --- a/src/sage/matroids/basis_matroid.pyx +++ b/src/sage/matroids/basis_matroid.pyx @@ -55,9 +55,9 @@ AUTHORS: TESTS:: - sage: F = matroids.named_matroids.Fano() - sage: M = Matroid(bases=F.bases()) - sage: TestSuite(M).run() + sage: F = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M = Matroid(bases=F.bases()) # optional - sage.rings.finite_rings + sage: TestSuite(M).run() # optional - sage.rings.finite_rings Methods ======= @@ -975,9 +975,9 @@ cdef class BasisMatroid(BasisExchangeMatroid): sage: from sage.matroids.advanced import * sage: M = BasisMatroid(matroids.Wheel(3)) - sage: N = BasisMatroid(matroids.CompleteGraphic(4)) - sage: morphism = M._isomorphism(N) - sage: M._is_isomorphism(N, morphism) + sage: N = BasisMatroid(matroids.CompleteGraphic(4)) # optional - sage.graphs + sage: morphism = M._isomorphism(N) # optional - sage.graphs + sage: M._is_isomorphism(N, morphism) # optional - sage.graphs True sage: M = BasisMatroid(matroids.named_matroids.NonFano()) # optional - sage.rings.finite_rings sage: N = BasisMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings diff --git a/src/sage/matroids/catalog.py b/src/sage/matroids/catalog.py index 01b1ad09a1f..c19acdfe8a5 100644 --- a/src/sage/matroids/catalog.py +++ b/src/sage/matroids/catalog.py @@ -39,8 +39,6 @@ from sage.graphs.graph_generators import graphs from sage.rings.integer_ring import ZZ -from sage.rings.finite_rings.finite_field_constructor import GF -from sage.schemes.projective.projective_space import ProjectiveSpace import sage.matroids.matroid import sage.matroids.basis_exchange_matroid @@ -52,6 +50,10 @@ from sage.matroids.rank_matroid import RankMatroid from sage.matroids.constructor import Matroid +lazy_import('sage.rings.finite_rings.finite_field_constructor', 'GF') +lazy_import('sage.schemes.projective.projective_space', 'ProjectiveSpace') + + # The order is the same as in Oxley. @@ -299,15 +301,15 @@ def AG32prime(): {'b', 'e', 'g', 'h'}, {'c', 'd', 'e', 'h'}, {'c', 'f', 'g', 'h'}, {'d', 'e', 'f', 'g'}}, 4: {{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}}} - sage: M.contract('c').is_isomorphic(matroids.named_matroids.Fano()) + sage: M.contract('c').is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings True - sage: setprint(M.noncospanning_cocircuits()) + sage: setprint(M.noncospanning_cocircuits()) # optional - sage.rings.finite_rings [{'a', 'b', 'c', 'h'}, {'a', 'b', 'd', 'e'}, {'a', 'b', 'f', 'g'}, {'a', 'c', 'd', 'f'}, {'a', 'd', 'g', 'h'}, {'a', 'e', 'f', 'h'}, {'b', 'c', 'd', 'g'}, {'b', 'c', 'e', 'f'}, {'b', 'd', 'f', 'h'}, {'b', 'e', 'g', 'h'}, {'c', 'd', 'e', 'h'}, {'c', 'f', 'g', 'h'}, {'d', 'e', 'f', 'g'}] - sage: M.is_valid() # long time + sage: M.is_valid() # long time # optional - sage.rings.finite_rings True """ E = 'abcdefgh' @@ -374,11 +376,11 @@ def F8(): ....: for i in M.groundset()]) sage: len(D) 3 - sage: [N.is_isomorphic(matroids.named_matroids.Fano()) for N in D] + sage: [N.is_isomorphic(matroids.named_matroids.Fano()) for N in D] # optional - sage.rings.finite_rings [...True...] - sage: [N.is_isomorphic(matroids.named_matroids.NonFano()) for N in D] + sage: [N.is_isomorphic(matroids.named_matroids.NonFano()) for N in D] # optional - sage.rings.finite_rings [...True...] - sage: M.is_valid() # long time + sage: M.is_valid() # long time # optional - sage.rings.finite_rings True """ E = 'abcdefgh' @@ -690,12 +692,12 @@ def K33dual(): EXAMPLES:: - sage: M = matroids.named_matroids.K33dual(); M + sage: M = matroids.named_matroids.K33dual(); M # optional - sage.graphs M*(K3, 3): Regular matroid of rank 4 on 9 elements with 81 bases - sage: any(N.is_3connected() + sage: any(N.is_3connected() # optional - sage.graphs ....: for N in M.linear_extensions(simple=True)) False - sage: M.is_valid() # long time + sage: M.is_valid() # long time # optional - sage.graphs True """ E = 'abcdefghi' @@ -756,16 +758,16 @@ def CompleteGraphic(n): EXAMPLES:: sage: from sage.matroids.advanced import setprint - sage: M = matroids.CompleteGraphic(5); M + sage: M = matroids.CompleteGraphic(5); M # optional - sage.graphs M(K5): Graphic matroid of rank 4 on 10 elements - sage: M.has_minor(matroids.Uniform(2, 4)) + sage: M.has_minor(matroids.Uniform(2, 4)) # optional - sage.graphs False - sage: simplify(M.contract(randrange(0, + sage: simplify(M.contract(randrange(0, # optional - sage.graphs ....: 10))).is_isomorphic(matroids.CompleteGraphic(4)) True - sage: setprint(M.closure([0, 2, 4, 5])) + sage: setprint(M.closure([0, 2, 4, 5])) # optional - sage.graphs {0, 1, 2, 4, 5, 7} - sage: M.is_valid() + sage: M.is_valid() # optional - sage.graphs True """ M = Matroid(groundset=list(range((n * (n - 1)) // 2)), @@ -802,11 +804,11 @@ def Wheel(n, field=None, ring=None): sage: M.is_valid() True sage: M = matroids.Wheel(3) - sage: M.is_isomorphic(matroids.CompleteGraphic(4)) + sage: M.is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.graphs True - sage: M.is_isomorphic(matroids.Wheel(3,field=GF(3))) + sage: M.is_isomorphic(matroids.Wheel(3, field=GF(3))) # optional - sage.rings.finite_rings True - sage: M = matroids.Wheel(3,field=GF(3)); M + sage: M = matroids.Wheel(3, field=GF(3)); M # optional - sage.rings.finite_rings Wheel(3): Ternary matroid of rank 3 on 6 elements, type 0+ """ base_ring = ZZ @@ -1045,7 +1047,7 @@ def R10(): {4, 6} sage: M.equals(M.dual()) False - sage: M.is_isomorphic(M.dual()) + sage: M.is_isomorphic(M.dual()) # optional - sage.graphs True sage: M.is_valid() True @@ -1083,7 +1085,7 @@ def R12(): R12: Regular matroid of rank 6 on 12 elements with 441 bases sage: M.equals(M.dual()) False - sage: M.is_isomorphic(M.dual()) + sage: M.is_isomorphic(M.dual()) # optional - sage.graphs True sage: M.is_valid() True diff --git a/src/sage/matroids/circuit_closures_matroid.pyx b/src/sage/matroids/circuit_closures_matroid.pyx index ebbea7c26cd..3c6200bb48b 100644 --- a/src/sage/matroids/circuit_closures_matroid.pyx +++ b/src/sage/matroids/circuit_closures_matroid.pyx @@ -348,17 +348,17 @@ cdef class CircuitClosuresMatroid(Matroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) - sage: CC = M.circuit_closures() - sage: len(CC[2]) + sage: M = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: CC = M.circuit_closures() # optional - sage.rings.finite_rings + sage: len(CC[2]) # optional - sage.rings.finite_rings 7 - sage: len(CC[3]) + sage: len(CC[3]) # optional - sage.rings.finite_rings 1 - sage: len(CC[1]) + sage: len(CC[1]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... KeyError: 1 - sage: [sorted(X) for X in CC[3]] + sage: [sorted(X) for X in CC[3]] # optional - sage.rings.finite_rings [['a', 'b', 'c', 'd', 'e', 'f', 'g']] """ return self._circuit_closures @@ -387,16 +387,16 @@ cdef class CircuitClosuresMatroid(Matroid): sage: from sage.matroids.advanced import * sage: M1 = CircuitClosuresMatroid(matroids.Wheel(3)) - sage: M2 = matroids.CompleteGraphic(4) - sage: M1._is_isomorphic(M2) + sage: M2 = matroids.CompleteGraphic(4) # optional - sage.graphs + sage: M1._is_isomorphic(M2) # optional - sage.graphs True - sage: M1._is_isomorphic(M2, certificate=True) + sage: M1._is_isomorphic(M2, certificate=True) # optional - sage.graphs (True, {0: 0, 1: 1, 2: 2, 3: 3, 4: 5, 5: 4}) - sage: M1 = CircuitClosuresMatroid(matroids.named_matroids.Fano()) - sage: M2 = matroids.named_matroids.NonFano() - sage: M1._is_isomorphic(M2) + sage: M1 = CircuitClosuresMatroid(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings + sage: M2 = matroids.named_matroids.NonFano() # optional - sage.rings.finite_rings + sage: M1._is_isomorphic(M2) # optional - sage.rings.finite_rings False - sage: M1._is_isomorphic(M2, certificate=True) + sage: M1._is_isomorphic(M2, certificate=True) # optional - sage.rings.finite_rings (False, None) diff --git a/src/sage/matroids/constructor.py b/src/sage/matroids/constructor.py index 8d3abb1df0d..11221faf9a1 100644 --- a/src/sage/matroids/constructor.py +++ b/src/sage/matroids/constructor.py @@ -75,8 +75,8 @@ sage: M.is_isomorphic(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings True - sage: M = Matroid(graphs.PetersenGraph()) - sage: M.rank() + sage: M = Matroid(graphs.PetersenGraph()) # optional - sage.graphs + sage: M.rank() # optional - sage.graphs 9 AUTHORS: @@ -148,8 +148,8 @@ def Matroid(groundset=None, data=None, **kwds): You will see a list of methods which will construct matroids. For example:: - sage: F7 = matroids.named_matroids.Fano() - sage: len(F7.nonspanning_circuits()) + sage: F7 = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: len(F7.nonspanning_circuits()) # optional - sage.rings.finite_rings 7 or:: @@ -335,54 +335,54 @@ def Matroid(groundset=None, data=None, **kwds): :: - sage: G = graphs.PetersenGraph() - sage: Matroid(G) + sage: G = graphs.PetersenGraph() # optional - sage.graphs + sage: Matroid(G) # optional - sage.graphs Graphic matroid of rank 9 on 15 elements If each edge has a unique label, then those are used as the ground set labels:: - sage: G = Graph([(0, 1, 'a'), (0, 2, 'b'), (1, 2, 'c')]) - sage: M = Matroid(G) - sage: sorted(M.groundset()) + sage: G = Graph([(0, 1, 'a'), (0, 2, 'b'), (1, 2, 'c')]) # optional - sage.graphs + sage: M = Matroid(G) # optional - sage.graphs + sage: sorted(M.groundset()) # optional - sage.graphs ['a', 'b', 'c'] If there are parallel edges, then integers are used for the ground set. If there are no edges in parallel, and is not a complete list of labels, or the labels are not unique, then vertex tuples are used:: - sage: G = Graph([(0, 1, 'a'), (0, 2, 'b'), (1, 2, 'b')]) - sage: M = Matroid(G) - sage: sorted(M.groundset()) + sage: G = Graph([(0, 1, 'a'), (0, 2, 'b'), (1, 2, 'b')]) # optional - sage.graphs + sage: M = Matroid(G) # optional - sage.graphs + sage: sorted(M.groundset()) # optional - sage.graphs [(0, 1), (0, 2), (1, 2)] - sage: H = Graph([(0, 1, 'a'), (0, 2, 'b'), (1, 2, 'b'), (1, 2, 'c')], multiedges=True) - sage: N = Matroid(H) - sage: sorted(N.groundset()) + sage: H = Graph([(0, 1, 'a'), (0, 2, 'b'), (1, 2, 'b'), (1, 2, 'c')], # optional - sage.graphs + ....: multiedges=True) + sage: N = Matroid(H) # optional - sage.graphs + sage: sorted(N.groundset()) # optional - sage.graphs [0, 1, 2, 3] The GraphicMatroid object forces its graph to be connected. If a disconnected graph is used as input, it will connect the components:: - sage: G1 = graphs.CycleGraph(3); G2 = graphs.DiamondGraph() - sage: G = G1.disjoint_union(G2) - sage: M = Matroid(G) - sage: M + sage: G1 = graphs.CycleGraph(3); G2 = graphs.DiamondGraph() # optional - sage.graphs + sage: G = G1.disjoint_union(G2) # optional - sage.graphs + sage: M = Matroid(G); M # optional - sage.graphs Graphic matroid of rank 5 on 8 elements - sage: M.graph() + sage: M.graph() # optional - sage.graphs Looped multi-graph on 6 vertices - sage: M.graph().is_connected() + sage: M.graph().is_connected() # optional - sage.graphs True - sage: M.is_connected() + sage: M.is_connected() # optional - sage.graphs False If the keyword ``regular`` is set to ``True``, the output will instead - be an instance of ``RegularMatroid``. + be an instance of :class:`RegularMatroid`. :: - sage: G = Graph([(0, 1), (0, 2), (1, 2)]) - sage: M = Matroid(G, regular=True); M + sage: G = Graph([(0, 1), (0, 2), (1, 2)]) # optional - sage.graphs + sage: M = Matroid(G, regular=True); M # optional - sage.graphs Regular matroid of rank 2 on 3 elements with 3 bases Note: if a groundset is specified, we assume it is in the same order @@ -390,9 +390,9 @@ def Matroid(groundset=None, data=None, **kwds): :meth:`G.edge_iterator() ` provides:: - sage: G = Graph([(0, 1), (0, 2), (0, 2), (1, 2)], multiedges=True) - sage: M = Matroid('abcd', G) - sage: M.rank(['b', 'c']) + sage: G = Graph([(0, 1), (0, 2), (0, 2), (1, 2)], multiedges=True) # optional - sage.graphs + sage: M = Matroid('abcd', G) # optional - sage.graphs + sage: M.rank(['b', 'c']) # optional - sage.graphs 1 As before, @@ -400,14 +400,14 @@ def Matroid(groundset=None, data=None, **kwds): tuples ``(i, j)`` of endpoints. If that fails, we simply use a list ``[0..m-1]`` :: - sage: G = Graph([(0, 1), (0, 2), (1, 2)]) - sage: M = Matroid(G, regular=True) - sage: sorted(M.groundset()) + sage: G = Graph([(0, 1), (0, 2), (1, 2)]) # optional - sage.graphs + sage: M = Matroid(G, regular=True) # optional - sage.graphs + sage: sorted(M.groundset()) # optional - sage.graphs [(0, 1), (0, 2), (1, 2)] - sage: G = Graph([(0, 1), (0, 2), (0, 2), (1, 2)], multiedges=True) - sage: M = Matroid(G, regular=True) - sage: sorted(M.groundset()) + sage: G = Graph([(0, 1), (0, 2), (0, 2), (1, 2)], multiedges=True) # optional - sage.graphs + sage: M = Matroid(G, regular=True) # optional - sage.graphs + sage: sorted(M.groundset()) # optional - sage.graphs [0, 1, 2, 3] When the ``graph`` keyword is used, a variety of inputs can be @@ -415,12 +415,12 @@ def Matroid(groundset=None, data=None, **kwds): (see the :class:`Graph ` method's documentation):: - sage: Matroid(graph=':I`AKGsaOs`cI]Gb~') + sage: Matroid(graph=':I`AKGsaOs`cI]Gb~') # optional - sage.graphs Graphic matroid of rank 9 on 17 elements However, this method is no more clever than ``Graph()``:: - sage: Matroid(graph=41/2) + sage: Matroid(graph=41/2) # optional - sage.graphs Traceback (most recent call last): ... ValueError: This input cannot be turned into a graph @@ -430,31 +430,31 @@ def Matroid(groundset=None, data=None, **kwds): The basic input is a :mod:`Sage matrix `:: - sage: A = Matrix(GF(2), [[1, 0, 0, 1, 1, 0], + sage: A = Matrix(GF(2), [[1, 0, 0, 1, 1, 0], # optional - sage.rings.finite_rings ....: [0, 1, 0, 1, 0, 1], ....: [0, 0, 1, 0, 1, 1]]) - sage: M = Matroid(matrix=A) - sage: M.is_isomorphic(matroids.CompleteGraphic(4)) + sage: M = Matroid(matrix=A) # optional - sage.rings.finite_rings + sage: M.is_isomorphic(matroids.CompleteGraphic(4)) # optional - sage.graphs sage.rings.finite_rings True Various shortcuts are possible:: - sage: M1 = Matroid(matrix=[[1, 0, 0, 1, 1, 0], + sage: M1 = Matroid(matrix=[[1, 0, 0, 1, 1, 0], # optional - sage.rings.finite_rings ....: [0, 1, 0, 1, 0, 1], ....: [0, 0, 1, 0, 1, 1]], ring=GF(2)) - sage: M2 = Matroid(reduced_matrix=[[1, 1, 0], + sage: M2 = Matroid(reduced_matrix=[[1, 1, 0], # optional - sage.rings.finite_rings ....: [1, 0, 1], ....: [0, 1, 1]], ring=GF(2)) - sage: M3 = Matroid(groundset=[0, 1, 2, 3, 4, 5], + sage: M3 = Matroid(groundset=[0, 1, 2, 3, 4, 5], # optional - sage.rings.finite_rings ....: matrix=[[1, 1, 0], [1, 0, 1], [0, 1, 1]], ....: ring=GF(2)) - sage: A = Matrix(GF(2), [[1, 1, 0], [1, 0, 1], [0, 1, 1]]) - sage: M4 = Matroid([0, 1, 2, 3, 4, 5], A) - sage: M1 == M2 + sage: A = Matrix(GF(2), [[1, 1, 0], [1, 0, 1], [0, 1, 1]]) # optional - sage.rings.finite_rings + sage: M4 = Matroid([0, 1, 2, 3, 4, 5], A) # optional - sage.rings.finite_rings + sage: M1 == M2 # optional - sage.rings.finite_rings True - sage: M1 == M3 + sage: M1 == M3 # optional - sage.rings.finite_rings True - sage: M1 == M4 + sage: M1 == M4 # optional - sage.rings.finite_rings True However, with unnamed arguments the input has to be a ``Matrix`` @@ -469,36 +469,36 @@ def Matroid(groundset=None, data=None, **kwds): identity matrix is prepended. Otherwise the groundset size must equal the number of columns:: - sage: A = Matrix(GF(2), [[1, 1, 0], [1, 0, 1], [0, 1, 1]]) - sage: M = Matroid([0, 1, 2], A) - sage: N = Matroid([0, 1, 2, 3, 4, 5], A) - sage: M.rank() + sage: A = Matrix(GF(2), [[1, 1, 0], [1, 0, 1], [0, 1, 1]]) # optional - sage.rings.finite_rings + sage: M = Matroid([0, 1, 2], A) # optional - sage.rings.finite_rings + sage: N = Matroid([0, 1, 2, 3, 4, 5], A) # optional - sage.rings.finite_rings + sage: M.rank() # optional - sage.rings.finite_rings 2 - sage: N.rank() + sage: N.rank() # optional - sage.rings.finite_rings 3 We automatically create an optimized subclass, if available:: - sage: Matroid([0, 1, 2, 3, 4, 5], + sage: Matroid([0, 1, 2, 3, 4, 5], # optional - sage.rings.finite_rings ....: matrix=[[1, 1, 0], [1, 0, 1], [0, 1, 1]], ....: field=GF(2)) Binary matroid of rank 3 on 6 elements, type (2, 7) - sage: Matroid([0, 1, 2, 3, 4, 5], + sage: Matroid([0, 1, 2, 3, 4, 5], # optional - sage.rings.finite_rings ....: matrix=[[1, 1, 0], [1, 0, 1], [0, 1, 1]], ....: field=GF(3)) Ternary matroid of rank 3 on 6 elements, type 0- - sage: Matroid([0, 1, 2, 3, 4, 5], + sage: Matroid([0, 1, 2, 3, 4, 5], # optional - sage.rings.finite_rings ....: matrix=[[1, 1, 0], [1, 0, 1], [0, 1, 1]], ....: field=GF(4, 'x')) Quaternary matroid of rank 3 on 6 elements - sage: Matroid([0, 1, 2, 3, 4, 5], + sage: Matroid([0, 1, 2, 3, 4, 5], # optional - sage.rings.finite_rings ....: matrix=[[1, 1, 0], [1, 0, 1], [0, 1, 1]], ....: field=GF(2), regular=True) Regular matroid of rank 3 on 6 elements with 16 bases Otherwise the generic LinearMatroid class is used:: - sage: Matroid([0, 1, 2, 3, 4, 5], + sage: Matroid([0, 1, 2, 3, 4, 5], # optional - sage.rings.finite_rings ....: matrix=[[1, 1, 0], [1, 0, 1], [0, 1, 1]], ....: field=GF(83)) Linear matroid of rank 3 on 6 elements represented over the Finite @@ -592,9 +592,9 @@ def Matroid(groundset=None, data=None, **kwds): Most of the time, the matroid itself is returned:: - sage: M = matroids.named_matroids.Fano() - sage: N = Matroid(M) - sage: N is M + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: N = Matroid(M) # optional - sage.rings.finite_rings + sage: N is M # optional - sage.rings.finite_rings True But it can be useful with the ``regular`` option:: @@ -627,27 +627,26 @@ def Matroid(groundset=None, data=None, **kwds): By default we check if the resulting matroid is actually regular. To increase speed, this check can be skipped:: - sage: M = matroids.named_matroids.Fano() - sage: N = Matroid(M, regular=True) + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: N = Matroid(M, regular=True) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: input is not a valid regular matroid - sage: N = Matroid(M, regular=True, check=False) - sage: N + sage: N = Matroid(M, regular=True, check=False); N # optional - sage.rings.finite_rings Regular matroid of rank 3 on 7 elements with 32 bases - sage: N.is_valid() + sage: N.is_valid() # optional - sage.rings.finite_rings False Sometimes the output is regular, but represents a different matroid from the one you intended:: - sage: M = Matroid(Matrix(GF(3), [[1, 0, 1, 1], [0, 1, 1, 2]])) - sage: N = Matroid(Matrix(GF(3), [[1, 0, 1, 1], [0, 1, 1, 2]]), + sage: M = Matroid(Matrix(GF(3), [[1, 0, 1, 1], [0, 1, 1, 2]])) # optional - sage.rings.finite_rings + sage: N = Matroid(Matrix(GF(3), [[1, 0, 1, 1], [0, 1, 1, 2]]), # optional - sage.rings.finite_rings ....: regular=True) - sage: N.is_valid() + sage: N.is_valid() # optional - sage.rings.finite_rings True - sage: N.is_isomorphic(M) + sage: N.is_isomorphic(M) # optional - sage.rings.finite_rings False TESTS:: diff --git a/src/sage/matroids/lean_matrix.pyx b/src/sage/matroids/lean_matrix.pyx index 145bdd47544..d202f2d91d2 100644 --- a/src/sage/matroids/lean_matrix.pyx +++ b/src/sage/matroids/lean_matrix.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings # cython: profile=True """ Lean matrices diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index 916c933555f..7e7701aeed3 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -266,7 +266,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: LinearMatroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1], # indirect doctest + sage: LinearMatroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1], # indirect doctest, optional - sage.rings.finite_rings ....: [0, 1, 1, 2, 3]])) Linear matroid of rank 2 on 5 elements represented over the Finite Field of size 5 @@ -289,7 +289,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = LinearMatroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1], # indirect doctest + sage: M = LinearMatroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1], # indirect doctest, optional - sage.rings.finite_rings ....: [0, 1, 1, 2, 3]])) sage: M = None """ @@ -1087,7 +1087,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): object has no attribute '_invariant' sage: M1._fast_isom_test(M3) is None # optional - sage.rings.finite_rings True - sage: Matroid(graphs.WheelGraph(6), regular = True)._fast_isom_test( + sage: Matroid(graphs.WheelGraph(6), regular=True)._fast_isom_test( # optional - sage.graphs ....: matroids.Wheel(5)) True """ @@ -1122,8 +1122,8 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: sage: M1 = matroids.Wheel(3) - sage: M2 = Matroid(graphs.CompleteGraph(4), regular = True) - sage: M1.is_field_isomorphic(M2) + sage: M2 = Matroid(graphs.CompleteGraph(4), regular=True) # optional - sage.graphs + sage: M1.is_field_isomorphic(M2) # optional - sage.graphs True sage: M3 = Matroid(bases=M1.bases()) sage: M1.is_field_isomorphic(M3) @@ -1702,8 +1702,8 @@ cdef class LinearMatroid(BasisExchangeMatroid): ....: [0, 0, 1, 3, 2, 5]])) sage: sorted(M.cross_ratios()) # optional - sage.rings.finite_rings [2, 3, 4, 5, 6] - sage: M = Matroid(graphs.CompleteGraph(5), regular = True) - sage: M.cross_ratios() + sage: M = Matroid(graphs.CompleteGraph(5), regular=True) # optional - sage.graphs + sage: M.cross_ratios() # optional - sage.graphs set() """ if hyperlines is None: @@ -2491,25 +2491,24 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: sage: M = Matroid(ring=GF(2), # optional - sage.rings.finite_rings - ....: reduced_matrix=[[-1, 0, 1], [1, -1, 0], [0, 1, -1]]) + ....: reduced_matrix=[[-1, 0, 1], [1, -1, 0], [0, 1, -1]]) sage: len(M.linear_extensions()) # optional - sage.rings.finite_rings 8 - sage: S = M.linear_extensions(simple=True) # optional - sage.rings.finite_rings - sage: S # optional - sage.rings.finite_rings + sage: S = M.linear_extensions(simple=True); S # optional - sage.rings.finite_rings [Binary matroid of rank 3 on 7 elements, type (3, 0)] sage: S[0].is_field_isomorphic(matroids.named_matroids.Fano()) # optional - sage.rings.finite_rings True sage: M = Matroid(ring=QQ, - ....: reduced_matrix=[[1, 0, 1], [1, 1, 0], [0, 1, 1]]) + ....: reduced_matrix=[[1, 0, 1], [1, 1, 0], [0, 1, 1]]) sage: S = M.linear_extensions(simple=True, ....: fundamentals=[1, -1, 1/2, 2]) sage: len(S) 7 - sage: any(N.is_isomorphic(matroids.named_matroids.NonFano()) + sage: any(N.is_isomorphic(matroids.named_matroids.NonFano()) # optional - sage.rings.finite_rings ....: for N in S) True sage: len(M.linear_extensions(simple=True, - ....: fundamentals=[1, -1, 1/2, 2], F=[0, 1])) + ....: fundamentals=[1, -1, 1/2, 2], F=[0, 1])) 1 """ if element is None: @@ -2663,25 +2662,25 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: matroids.Uniform(2, 3)._is_3connected_shifting() + sage: matroids.Uniform(2, 3)._is_3connected_shifting() # optional - sage.graphs True - sage: M = Matroid(ring=QQ, matrix=[[1, 0, 0, 1, 1, 0], + sage: M = Matroid(ring=QQ, matrix=[[1, 0, 0, 1, 1, 0], # optional - sage.graphs ....: [0, 1, 0, 1, 2, 0], ....: [0, 0, 1, 0, 0, 1]]) - sage: M._is_3connected_shifting() + sage: M._is_3connected_shifting() # optional - sage.graphs False - sage: N = Matroid(circuit_closures={2: ['abc', 'cdef'], + sage: N = Matroid(circuit_closures={2: ['abc', 'cdef'], # optional - sage.graphs ....: 3: ['abcdef']}, ....: groundset='abcdef') - sage: N._is_3connected_shifting() + sage: N._is_3connected_shifting() # optional - sage.graphs False - sage: matroids.named_matroids.BetsyRoss()._is_3connected_shifting() + sage: matroids.named_matroids.BetsyRoss()._is_3connected_shifting() # optional - sage.graphs True - sage: M = matroids.named_matroids.R6() - sage: M._is_3connected_shifting() + sage: M = matroids.named_matroids.R6() # optional - sage.graphs + sage: M._is_3connected_shifting() # optional - sage.graphs False - sage: B, X = M._is_3connected_shifting(True) - sage: M.connectivity(X)<3 + sage: B, X = M._is_3connected_shifting(True) # optional - sage.graphs + sage: M.connectivity(X) < 3 # optional - sage.graphs True """ if not self.is_connected(): @@ -2742,17 +2741,17 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: sage: M = matroids.Uniform(2, 6) - sage: B, X = M._is_4connected_shifting(True) - sage: (B, M.connectivity(X)<=3) + sage: B, X = M._is_4connected_shifting(True) # optional - sage.graphs + sage: (B, M.connectivity(X)<=3) # optional - sage.graphs (False, True) - sage: matroids.Uniform(4, 8)._is_4connected_shifting() + sage: matroids.Uniform(4, 8)._is_4connected_shifting() # optional - sage.graphs True sage: M = Matroid(field=GF(2), matrix=[[1,0,0,1,0,1,1,0,0,1,1,1], # optional - sage.rings.finite_rings ....: [0,1,0,1,0,1,0,1,0,0,0,1], ....: [0,0,1,1,0,0,1,1,0,1,0,1], ....: [0,0,0,0,1,1,1,1,0,0,1,1], ....: [0,0,0,0,0,0,0,0,1,1,1,1]]) - sage: M._is_4connected_shifting() # optional - sage.rings.finite_rings + sage: M._is_4connected_shifting() # optional - sage.graphs sage.rings.finite_rings True """ if self.rank()>self.size()-self.rank(): @@ -2898,10 +2897,10 @@ cdef class LinearMatroid(BasisExchangeMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], + sage: M = Matroid(Matrix(GF(7), [[1, 0, 0, 1, 1], [0, 1, 0, 1, 2], # optional - sage.rings.finite_rings ....: [0, 0, 1, 1, 3]])) - sage: N = copy(M) # indirect doctest - sage: M == N + sage: N = copy(M) # indirect doctest # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings True """ cdef LinearMatroid N @@ -3068,7 +3067,7 @@ cdef class BinaryMatroid(LinearMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: BinaryMatroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1], # indirect doctest + sage: BinaryMatroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1], # indirect doctest, optional - sage.rings.finite_rings ....: [0, 1, 1, 2, 3]])) Binary matroid of rank 2 on 5 elements, type (1, 7) """ @@ -3814,12 +3813,12 @@ cdef class BinaryMatroid(LinearMatroid): ....: reduced=True, labels=False)) sage: M.is_graphic() # optional - sage.rings.finite_rings False - sage: K5 = Matroid(graphs.CompleteGraph(5), regular = True) - sage: M = Matroid(ring=GF(2), reduced_matrix=K5.representation( # optional - sage.rings.finite_rings + sage: K5 = Matroid(graphs.CompleteGraph(5), regular=True) # optional - sage.graphs + sage: M = Matroid(ring=GF(2), reduced_matrix=K5.representation( # optional - sage.graphs sage.rings.finite_rings ....: reduced=True, labels=False)) - sage: M.is_graphic() # optional - sage.rings.finite_rings + sage: M.is_graphic() # optional - sage.graphs sage.rings.finite_rings True - sage: M.dual().is_graphic() # optional - sage.rings.finite_rings + sage: M.dual().is_graphic() # optional - sage.graphs sage.rings.finite_rings False ALGORITHM: @@ -4134,7 +4133,7 @@ cdef class TernaryMatroid(LinearMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: TernaryMatroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1], # indirect doctest + sage: TernaryMatroid(matrix=Matrix(GF(5), [[1, 0, 1, 1, 1], # indirect doctest, optional - sage.rings.finite_rings ....: [0, 1, 1, 2, 3]])) Ternary matroid of rank 2 on 5 elements, type 1+ """ @@ -5101,9 +5100,9 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(ring=GF(4, 'y'), reduced_matrix=[[1, 0, 1], + sage: M = Matroid(ring=GF(4, 'y'), reduced_matrix=[[1, 0, 1], # optional - sage.rings.finite_rings ....: [0, 1, 1]]) - sage: M.base_ring() + sage: M.base_ring() # optional - sage.rings.finite_rings Finite Field in y of size 2^2 """ return (self._A).base_ring() @@ -5115,9 +5114,9 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(ring=GF(4, 'y'), reduced_matrix=[[1, 0, 1], + sage: M = Matroid(ring=GF(4, 'y'), reduced_matrix=[[1, 0, 1], # optional - sage.rings.finite_rings ....: [0, 1, 1]]) - sage: M.characteristic() + sage: M.characteristic() # optional - sage.rings.finite_rings 2 """ return 2 @@ -5178,9 +5177,9 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(ring=GF(4, 'x'), matrix=[[1, 0, 1], [0, 1, 1]]) - sage: M.rename() - sage: repr(M) # indirect doctest + sage: M = Matroid(ring=GF(4, 'x'), matrix=[[1, 0, 1], [0, 1, 1]]) # optional - sage.rings.finite_rings + sage: M.rename() # optional - sage.rings.finite_rings + sage: repr(M) # indirect doctest # optional - sage.rings.finite_rings 'Quaternary matroid of rank 2 on 3 elements' """ S = "Quaternary matroid of rank " + str(self.rank()) + " on " + str(self.size()) + " elements" @@ -5204,13 +5203,13 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Q10() - sage: A = M._reduced_representation('efghi') - sage: R, C = M._current_rows_cols() - sage: (sorted(R), sorted(C)) + sage: M = matroids.named_matroids.Q10() # optional - sage.rings.finite_rings + sage: A = M._reduced_representation('efghi') # optional - sage.rings.finite_rings + sage: R, C = M._current_rows_cols() # optional - sage.rings.finite_rings + sage: (sorted(R), sorted(C)) # optional - sage.rings.finite_rings (['e', 'f', 'g', 'h', 'i'], ['a', 'b', 'c', 'd', 'j']) - sage: R, C = M._current_rows_cols(B='abcde') - sage: (sorted(R), sorted(C)) + sage: R, C = M._current_rows_cols(B='abcde') # optional - sage.rings.finite_rings + sage: (sorted(R), sorted(C)) # optional - sage.rings.finite_rings (['a', 'b', 'c', 'd', 'e'], ['f', 'g', 'h', 'i', 'j']) """ @@ -5252,15 +5251,15 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Q10() - sage: M._basic_representation() + sage: M = matroids.named_matroids.Q10() # optional - sage.rings.finite_rings + sage: M._basic_representation() # optional - sage.rings.finite_rings 5 x 10 QuaternaryMatrix [100001x00y] [01000y1x00] [001000y1x0] [0001000y1x] [00001x00y1] - sage: matrix(M._basic_representation('efghi')) + sage: matrix(M._basic_representation('efghi')) # optional - sage.rings.finite_rings [ 1 0 x + 1 1 0 1 0 0 0 1] [ x x + 1 0 0 0 0 0 1 0 1] [ 0 0 x x + 1 0 0 1 0 0 1] @@ -5295,15 +5294,15 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Q10() - sage: M._reduced_representation() + sage: M = matroids.named_matroids.Q10() # optional - sage.rings.finite_rings + sage: M._reduced_representation() # optional - sage.rings.finite_rings 5 x 5 QuaternaryMatrix [1x00y] [y1x00] [0y1x0] [00y1x] [x00y1] - sage: matrix(M._reduced_representation('efghi')) + sage: matrix(M._reduced_representation('efghi')) # optional - sage.rings.finite_rings [ 1 0 x + 1 1 1] [ x x + 1 0 0 1] [ 0 0 x x + 1 1] @@ -5323,8 +5322,8 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Q10() - sage: M._invariant() # indirect doctest + sage: M = matroids.named_matroids.Q10() # optional - sage.rings.finite_rings + sage: M._invariant() # indirect doctest # optional - sage.rings.finite_rings (0, 0, 5, 5, 20, 10, 25) """ cdef QuaternaryMatrix Q, QT @@ -5402,8 +5401,8 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Q10() - sage: M._invariant() + sage: M = matroids.named_matroids.Q10() # optional - sage.rings.finite_rings + sage: M._invariant() # optional - sage.rings.finite_rings (0, 0, 5, 5, 20, 10, 25) """ @@ -5430,8 +5429,8 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Q10() - sage: M.bicycle_dimension() + sage: M = matroids.named_matroids.Q10() # optional - sage.rings.finite_rings + sage: M.bicycle_dimension() # optional - sage.rings.finite_rings 0 """ if self._q_invariant is None: @@ -5457,14 +5456,16 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Q10()\'a' - sage: for F in M._principal_tripartition(): print(sorted(F)) + sage: M = matroids.named_matroids.Q10()\'a' # optional - sage.rings.finite_rings + sage: for F in M._principal_tripartition(): print(sorted(F)) # optional - sage.rings.finite_rings ['b', 'c', 'd', 'e', 'h', 'i'] ['f', 'g', 'j'] [] - sage: M.bicycle_dimension() + sage: M.bicycle_dimension() # optional - sage.rings.finite_rings 1 - sage: for i in [-1, 0, 1]: print(sorted([e for e in M.groundset() if (M\e).bicycle_dimension() == 1 + i])) + sage: for i in [-1, 0, 1]: # optional - sage.rings.finite_rings + ....: print(sorted(e for e in M.groundset() + ....: if (M\e).bicycle_dimension() == 1 + i)) ['b', 'c', 'd', 'e', 'h', 'i'] ['f', 'g', 'j'] [] @@ -5493,9 +5494,9 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Q10()\'a' - sage: N = matroids.named_matroids.Q10()\'b' - sage: M._fast_isom_test(N) is None + sage: M = matroids.named_matroids.Q10()\'a' # optional - sage.rings.finite_rings + sage: N = matroids.named_matroids.Q10()\'b' # optional - sage.rings.finite_rings + sage: M._fast_isom_test(N) is None # optional - sage.rings.finite_rings True """ if self._invariant() != other._invariant(): @@ -5529,9 +5530,9 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.Q10() - sage: N = M._minor(contractions=set(['a']), deletions=set([])) - sage: N._minor(contractions=set([]), deletions=set(['b', 'c'])) + sage: M = matroids.named_matroids.Q10() # optional - sage.rings.finite_rings + sage: N = M._minor(contractions=set(['a']), deletions=set([])) # optional - sage.rings.finite_rings + sage: N._minor(contractions=set([]), deletions=set(['b', 'c'])) # optional - sage.rings.finite_rings Quaternary matroid of rank 4 on 7 elements """ self._move_current_basis(contractions, deletions) @@ -5558,8 +5559,8 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(4, 'x'), [[]])) - sage: M.is_valid() + sage: M = Matroid(Matrix(GF(4, 'x'), [[]])) # optional - sage.rings.finite_rings + sage: M.is_valid() # optional - sage.rings.finite_rings True """ return True @@ -5570,10 +5571,10 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(4, 'x'), [[1, 0, 0, 1, 1], + sage: M = Matroid(Matrix(GF(4, 'x'), [[1, 0, 0, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 0, 1, 2], [0, 0, 1, 1, 3]])) - sage: N = copy(M) # indirect doctest - sage: M == N + sage: N = copy(M) # indirect doctest # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings True """ cdef QuaternaryMatroid N @@ -5594,10 +5595,10 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(GF(4, 'x'), [[1, 0, 0, 1, 1], + sage: M = Matroid(Matrix(GF(4, 'x'), [[1, 0, 0, 1, 1], # optional - sage.rings.finite_rings ....: [0, 1, 0, 1, 2], [0, 0, 1, 1, -1]])) - sage: N = deepcopy(M) # indirect doctest - sage: M == N + sage: N = deepcopy(M) # indirect doctest # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings True """ from copy import deepcopy @@ -5734,16 +5735,15 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: sage: A = Matrix(ZZ, 2, 4, [[1, 0, 1, 1], [0, 1, 1, 1]]) - sage: M = Matroid(A, regular=True) - sage: M + sage: M = Matroid(A, regular=True); M # optional - sage.graphs Regular matroid of rank 2 on 4 elements with 5 bases - sage: sorted(M.groundset()) + sage: sorted(M.groundset()) # optional - sage.graphs [0, 1, 2, 3] - sage: Matrix(M) + sage: Matrix(M) # optional - sage.graphs [1 0 1 1] [0 1 1 1] - sage: M = Matroid(matrix=A, groundset='abcd', regular=True) - sage: sorted(M.groundset()) + sage: M = Matroid(matrix=A, groundset='abcd', regular=True) # optional - sage.graphs + sage: sorted(M.groundset()) # optional - sage.graphs ['a', 'b', 'c', 'd'] """ def __init__(self, matrix=None, groundset=None, reduced_matrix=None, ring=None, keep_initial_representation=True): @@ -5759,7 +5759,7 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: RegularMatroid(matrix=Matrix(ZZ, [[1, 0, 1, 1, 1], # indirect doctest + sage: RegularMatroid(matrix=Matrix(ZZ, [[1, 0, 1, 1, 1], # indirect doctest, optional - sage.graphs ....: [0, 1, 1, 1, 1]])) Regular matroid of rank 2 on 5 elements with 7 bases """ @@ -5898,8 +5898,8 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(graphs.CompleteGraph(5), regular = True) - sage: M.bases_count() + sage: M = Matroid(graphs.CompleteGraph(5), regular=True) # optional - sage.graphs + sage: M.bases_count() # optional - sage.graphs 125 ALGORITHM: @@ -6026,8 +6026,8 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: sage: M = matroids.named_matroids.R10() - sage: PV, tups, G = M._hypergraph() - sage: G + sage: PV, tups, G = M._hypergraph() # optional - sage.graphs + sage: G # optional - sage.graphs Digraph on 55 vertices """ # NEW VERSION, Uses Sage'S Graph Isomorphism @@ -6108,20 +6108,20 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: sage: M1 = matroids.Wheel(3) - sage: M2 = Matroid(groundset = list(range(6)), - ....: graph = graphs.CompleteGraph(4), regular = True) - sage: M1._is_isomorphic(M2) + sage: M2 = Matroid(groundset=list(range(6)), # optional - sage.graphs + ....: graph=graphs.CompleteGraph(4), regular=True) + sage: M1._is_isomorphic(M2) # optional - sage.graphs True - sage: M1._is_isomorphic(M2, certificate=True) + sage: M1._is_isomorphic(M2, certificate=True) # optional - sage.graphs (True, {0: 0, 1: 1, 2: 2, 3: 3, 4: 5, 5: 4}) sage: M1 = matroids.Wheel(3) - sage: M2 = matroids.named_matroids.Fano() - sage: M1._is_isomorphic(M2) + sage: M2 = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M1._is_isomorphic(M2) # optional - sage.rings.finite_rings False - sage: M1._is_isomorphic(M2.delete('a')) + sage: M1._is_isomorphic(M2.delete('a')) # optional - sage.rings.finite_rings True - sage: M1._is_isomorphic(M2.delete('a'), certificate=True) + sage: M1._is_isomorphic(M2.delete('a'), certificate=True) # optional - sage.rings.finite_rings (True, {0: 'g', 1: 'b', 2: 'c', 3: 'e', 4: 'd', 5: 'f'}) Check that :trac:`17316` was fixed:: @@ -6180,7 +6180,7 @@ cdef class RegularMatroid(LinearMatroid): sage: M = matroids.named_matroids.R10()\'a' sage: N = matroids.named_matroids.R10()\'b' - sage: M._fast_isom_test(N) + sage: M._fast_isom_test(N) # optional - sage.graphs True """ if self.bases_count() != other.bases_count(): @@ -6211,9 +6211,9 @@ cdef class RegularMatroid(LinearMatroid): Check that :trac:`22263` was fixed:: - sage: m1 = Matroid(graph='H?ABC~}') - sage: m2 = Matroid(graph='H?ACNr}') - sage: m1.is_isomorphic(m2) + sage: m1 = Matroid(graph='H?ABC~}') # optional - sage.graphs + sage: m2 = Matroid(graph='H?ACNr}') # optional - sage.graphs + sage: m1.is_isomorphic(m2) # optional - sage.graphs False """ from sage.groups.perm_gps.partn_ref.refinement_graphs import isomorphic @@ -6332,13 +6332,13 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.R10() - sage: M.is_graphic() + sage: M = matroids.named_matroids.R10() # optional - sage.rings.finite_rings + sage: M.is_graphic() # optional - sage.rings.finite_rings False - sage: M = Matroid(graphs.CompleteGraph(5), regular = True) - sage: M.is_graphic() + sage: M = Matroid(graphs.CompleteGraph(5), regular=True) # optional - sage.graphs + sage: M.is_graphic() # optional - sage.graphs True - sage: M.dual().is_graphic() + sage: M.dual().is_graphic() # optional - sage.graphs False ALGORITHM: @@ -6364,14 +6364,14 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: - sage: M = Matroid(Matrix(ZZ, [[1, 0, 0, 1, 1, 0, 1], + sage: M = Matroid(Matrix(ZZ, [[1, 0, 0, 1, 1, 0, 1], # optional - sage.graphs ....: [0, 1, 0, 1, 0, 1, 1], ....: [0, 0, 1, 0, 1, 1, 1]]), ....: regular=True, check=False) - sage: M.is_valid() + sage: M.is_valid() # optional - sage.graphs False - sage: M = Matroid(graphs.PetersenGraph()) - sage: M.is_valid() + sage: M = Matroid(graphs.PetersenGraph()) # optional - sage.graphs + sage: M.is_valid() # optional - sage.graphs True """ M = LinearMatroid(ring=QQ, reduced_matrix=self.representation(self.basis(), True, False)) @@ -6404,8 +6404,8 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: - sage: N = matroids.named_matroids.R10() - sage: N.binary_matroid() + sage: N = matroids.named_matroids.R10() # optional - sage.rings.finite_rings + sage: N.binary_matroid() # optional - sage.rings.finite_rings Binary matroid of rank 5 on 10 elements, type (1, None) """ @@ -6434,8 +6434,8 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: - sage: N = matroids.named_matroids.R10() - sage: N.is_binary() + sage: N = matroids.named_matroids.R10() # optional - sage.rings.finite_rings + sage: N.is_binary() # optional - sage.rings.finite_rings True """ return True @@ -6464,8 +6464,8 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: - sage: N = matroids.named_matroids.R10() - sage: N.ternary_matroid() + sage: N = matroids.named_matroids.R10() # optional - sage.rings.finite_rings + sage: N.ternary_matroid() # optional - sage.rings.finite_rings Ternary matroid of rank 5 on 10 elements, type 4+ """ @@ -6494,8 +6494,8 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: - sage: N = matroids.named_matroids.R10() - sage: N.is_ternary() + sage: N = matroids.named_matroids.R10() # optional - sage.rings.finite_rings + sage: N.is_ternary() # optional - sage.rings.finite_rings True """ return True @@ -6508,9 +6508,9 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.R10() - sage: N = copy(M) # indirect doctest - sage: M == N + sage: M = matroids.named_matroids.R10() # optional - sage.rings.finite_rings + sage: N = copy(M) # indirect doctest # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings True """ cdef RegularMatroid N @@ -6528,9 +6528,9 @@ cdef class RegularMatroid(LinearMatroid): EXAMPLES:: - sage: M = matroids.named_matroids.R10() - sage: N = deepcopy(M) # indirect doctest - sage: M == N + sage: M = matroids.named_matroids.R10() # optional - sage.rings.finite_rings + sage: N = deepcopy(M) # indirect doctest # optional - sage.rings.finite_rings + sage: M == N # optional - sage.rings.finite_rings True """ cdef RegularMatroid N diff --git a/src/sage/matroids/matroids_plot_helpers.py b/src/sage/matroids/matroids_plot_helpers.py index 73980d8e408..dedb0b11df6 100644 --- a/src/sage/matroids/matroids_plot_helpers.py +++ b/src/sage/matroids/matroids_plot_helpers.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - scipy r""" Helper functions for plotting the geometric representation of matroids @@ -50,13 +51,14 @@ EXAMPLES:: sage: from sage.matroids import matroids_plot_helpers - sage: M1=Matroid(ring=GF(2), matrix=[[1, 0, 0, 0, 1, 1, 1,0,1,0,1], - ....: [0, 1, 0, 1, 0, 1, 1,0,0,1,0], [0, 0, 1, 1, 1, 0, 1,0,0,0,0]]) - sage: pos_dict= {0: (0, 0), 1: (2, 0), 2: (1, 2), 3: (1.5, 1.0), - ....: 4: (0.5, 1.0), 5: (1.0, 0.0), 6: (1.0, 0.666666666666667), - ....: 7: (3,3), 8: (4,0), 9: (-1,1), 10: (-2,-2)} - sage: M1._cached_info={'plot_positions': pos_dict, 'plot_lineorders': None} - sage: matroids_plot_helpers.geomrep(M1, sp=True) # optional - sage.plot + sage: M1 = Matroid(ring=GF(2), matrix=[[1, 0, 0, 0, 1, 1, 1,0,1,0,1], # optional - sage.rings.finite_rings + ....: [0, 1, 0, 1, 0, 1, 1,0,0,1,0], + ....: [0, 0, 1, 1, 1, 0, 1,0,0,0,0]]) + sage: pos_dict = {0: (0, 0), 1: (2, 0), 2: (1, 2), 3: (1.5, 1.0), + ....: 4: (0.5, 1.0), 5: (1.0, 0.0), 6: (1.0, 0.666666666666667), + ....: 7: (3,3), 8: (4,0), 9: (-1,1), 10: (-2,-2)} + sage: M1._cached_info = {'plot_positions': pos_dict, 'plot_lineorders': None} # optional - sage.rings.finite_rings + sage: matroids_plot_helpers.geomrep(M1, sp=True) # optional - sage.plot sage.rings.finite_rings Graphics object consisting of 22 graphics primitives """ @@ -401,21 +403,23 @@ def slp(M1, pos_dict=None, B=None): sage: from sage.matroids import matroids_plot_helpers sage: from sage.matroids.advanced import setprint - sage: M1=Matroid(ring=GF(2), matrix=[[1, 0, 0, 0, 1, 1, 1,0,1,0,1], - ....: [0, 1, 0, 1, 0, 1, 1,0,0,1,0],[0, 0, 1, 1, 1, 0, 1,0,0,0,0]]) - sage: [M,L,P]=matroids_plot_helpers.slp(M1) - sage: M.is_simple() + sage: M1 = Matroid(ring=GF(2), matrix=[[1, 0, 0, 0, 1, 1, 1,0,1,0,1], # optional - sage.rings.finite_rings + ....: [0, 1, 0, 1, 0, 1, 1,0,0,1,0], + ....: [0, 0, 1, 1, 1, 0, 1,0,0,0,0]]) + sage: [M,L,P] = matroids_plot_helpers.slp(M1) # optional - sage.rings.finite_rings + sage: M.is_simple() # optional - sage.rings.finite_rings True - sage: setprint([L,P]) + sage: setprint([L,P]) # optional - sage.rings.finite_rings [{10, 8, 9}, {7}] - sage: M1=Matroid(ring=GF(2), matrix=[[1, 0, 0, 0, 1, 1, 1,0,1,0,1], - ....: [0, 1, 0, 1, 0, 1, 1,0,0,1,0],[0, 0, 1, 1, 1, 0, 1,0,0,0,0]]) - sage: posdict= {8: (0, 0), 1: (2, 0), 2: (1, 2), 3: (1.5, 1.0), - ....: 4: (0.5, 1.0), 5: (1.0, 0.0), 6: (1.0, 0.6666666666666666)} - sage: [M,L,P]=matroids_plot_helpers.slp(M1,pos_dict=posdict) - sage: M.is_simple() + sage: M1 = Matroid(ring=GF(2), matrix=[[1, 0, 0, 0, 1, 1, 1,0,1,0,1], # optional - sage.rings.finite_rings + ....: [0, 1, 0, 1, 0, 1, 1,0,0,1,0], + ....: [0, 0, 1, 1, 1, 0, 1,0,0,0,0]]) + sage: posdict = {8: (0, 0), 1: (2, 0), 2: (1, 2), 3: (1.5, 1.0), # optional - sage.rings.finite_rings + ....: 4: (0.5, 1.0), 5: (1.0, 0.0), 6: (1.0, 0.6666666666666666)} + sage: [M,L,P] = matroids_plot_helpers.slp(M1, pos_dict=posdict) # optional - sage.rings.finite_rings + sage: M.is_simple() # optional - sage.rings.finite_rings True - sage: setprint([L,P]) + sage: setprint([L,P]) # optional - sage.rings.finite_rings [{0, 10, 9}, {7}] .. NOTE:: @@ -483,11 +487,12 @@ def addlp(M, M1, L, P, ptsdict, G=None, limits=None): EXAMPLES:: sage: from sage.matroids import matroids_plot_helpers - sage: M = Matroid(ring=GF(2), matrix=[[1, 0, 0, 0, 1, 1, 1,0,1], - ....: [0, 1, 0, 1, 0, 1, 1,0,0],[0, 0, 1, 1, 1, 0, 1,0,0]]) - sage: [M1,L,P] = matroids_plot_helpers.slp(M) - sage: G, lims = matroids_plot_helpers.addlp(M,M1,L,P,{0:(0,0)}) # optional - sage.plot - sage: G.show(axes=False) # optional - sage.plot + sage: M = Matroid(ring=GF(2), matrix=[[1, 0, 0, 0, 1, 1, 1,0,1], # optional - sage.rings.finite_rings + ....: [0, 1, 0, 1, 0, 1, 1,0,0], + ....: [0, 0, 1, 1, 1, 0, 1,0,0]]) + sage: [M1,L,P] = matroids_plot_helpers.slp(M) # optional - sage.rings.finite_rings + sage: G, lims = matroids_plot_helpers.addlp(M,M1,L,P,{0:(0,0)}) # optional - sage.plot sage.rings.finite_rings + sage: G.show(axes=False) # optional - sage.plot sage.rings.finite_rings .. NOTE:: @@ -664,15 +669,16 @@ def posdict_is_sane(M1, pos_dict): EXAMPLES:: sage: from sage.matroids import matroids_plot_helpers - sage: M1=Matroid(ring=GF(2), matrix=[[1, 0, 0, 0, 1, 1, 1,0,1,0,1], - ....: [0, 1, 0, 1, 0, 1, 1,0,0,1,0],[0, 0, 1, 1, 1, 0, 1,0,0,0,0]]) - sage: pos_dict= {0: (0, 0), 1: (2, 0), 2: (1, 2), 3: (1.5, 1.0), + sage: M1 = Matroid(ring=GF(2), matrix=[[1, 0, 0, 0, 1, 1, 1,0,1,0,1], # optional - sage.rings.finite_rings + ....: [0, 1, 0, 1, 0, 1, 1,0,0,1,0], + ....: [0, 0, 1, 1, 1, 0, 1,0,0,0,0]]) + sage: pos_dict = {0: (0, 0), 1: (2, 0), 2: (1, 2), 3: (1.5, 1.0), # optional - sage.rings.finite_rings ....: 4: (0.5, 1.0), 5: (1.0, 0.0), 6: (1.0, 0.6666666666666666)} - sage: matroids_plot_helpers.posdict_is_sane(M1,pos_dict) + sage: matroids_plot_helpers.posdict_is_sane(M1,pos_dict) # optional - sage.rings.finite_rings True - sage: pos_dict= {1: (2, 0), 2: (1, 2), 3: (1.5, 1.0), - ....: 4: (0.5, 1.0), 5: (1.0, 0.0), 6: (1.0, 0.6666666666666666)} - sage: matroids_plot_helpers.posdict_is_sane(M1,pos_dict) + sage: pos_dict = {1: (2, 0), 2: (1, 2), 3: (1.5, 1.0), + ....: 4: (0.5, 1.0), 5: (1.0, 0.0), 6: (1.0, 0.6666666666666666)} + sage: matroids_plot_helpers.posdict_is_sane(M1,pos_dict) # optional - sage.rings.finite_rings False .. NOTE:: diff --git a/src/sage/matroids/unpickling.pyx b/src/sage/matroids/unpickling.pyx index a0f8ab1067d..1167bb8c230 100644 --- a/src/sage/matroids/unpickling.pyx +++ b/src/sage/matroids/unpickling.pyx @@ -670,8 +670,8 @@ def unpickle_graphic_matroid(version, data): EXAMPLES:: - sage: M = Matroid(graphs.DiamondGraph()) - sage: M == loads(dumps(M)) + sage: M = Matroid(graphs.DiamondGraph()) # optional - sage.graphs + sage: M == loads(dumps(M)) # optional - sage.graphs True """ if version != 0: diff --git a/src/sage/matroids/utilities.py b/src/sage/matroids/utilities.py index 651804651d1..ab4985eb0e7 100644 --- a/src/sage/matroids/utilities.py +++ b/src/sage/matroids/utilities.py @@ -83,10 +83,10 @@ def setprint(X): An exception was made for subclasses of SageObject:: sage: from sage.matroids.advanced import setprint - sage: G = graphs.PetersenGraph() - sage: list(G) + sage: G = graphs.PetersenGraph() # optional - sage.graphs + sage: list(G) # optional - sage.graphs [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - sage: setprint(G) + sage: setprint(G) # optional - sage.graphs Petersen graph: Graph on 10 vertices """ print(setprint_s(X, toplevel=True)) @@ -270,7 +270,7 @@ def make_regular_matroid_from_matroid(matroid): EXAMPLES:: sage: from sage.matroids.utilities import make_regular_matroid_from_matroid - sage: make_regular_matroid_from_matroid( + sage: make_regular_matroid_from_matroid( # optional - sage.graphs ....: matroids.CompleteGraphic(6)).is_isomorphic( ....: matroids.CompleteGraphic(6)) True @@ -378,9 +378,10 @@ def spanning_forest(M): EXAMPLES:: - sage: len(sage.matroids.utilities.spanning_forest(matrix([[1,1,1],[1,1,1],[1,1,1]]))) + sage: from sage.matroids.utilities import spanning_forest + sage: len(spanning_forest(matrix([[1,1,1],[1,1,1],[1,1,1]]))) # optional - sage.graphs 5 - sage: len(sage.matroids.utilities.spanning_forest(matrix([[0,0,1],[0,1,0],[0,1,0]]))) + sage: len(spanning_forest(matrix([[0,0,1],[0,1,0],[0,1,0]]))) # optional - sage.graphs 3 """ # Given a matrix, produce a spanning tree @@ -418,8 +419,9 @@ def spanning_stars(M): EXAMPLES:: - sage: edges = sage.matroids.utilities.spanning_stars(matrix([[1,1,1],[1,1,1],[1,1,1]])) - sage: Graph([(x+3, y) for x,y in edges]).is_connected() + sage: from sage.matroids.utilities import spanning_stars + sage: edges = spanning_stars(matrix([[1,1,1],[1,1,1],[1,1,1]])) # optional - sage.graphs + sage: Graph([(x+3, y) for x,y in edges]).is_connected() # optional - sage.graphs True """ @@ -532,25 +534,25 @@ def lift_cross_ratios(A, lift_map=None): EXAMPLES:: sage: from sage.matroids.advanced import lift_cross_ratios, lift_map, LinearMatroid - sage: R = GF(7) # optional - sage.rings.finite_rings - sage: to_sixth_root_of_unity = lift_map('sru') # optional - sage.rings.number_field - sage: A = Matrix(R, [[1, 0, 6, 1, 2],[6, 1, 0, 0, 1],[0, 6, 3, 6, 0]]) # optional - sage.rings.finite_rings - sage: A # optional - sage.rings.finite_rings + sage: R = GF(7) # optional - sage.graphs sage.rings.finite_rings + sage: to_sixth_root_of_unity = lift_map('sru') # optional - sage.graphs sage.rings.number_field + sage: A = Matrix(R, [[1, 0, 6, 1, 2],[6, 1, 0, 0, 1],[0, 6, 3, 6, 0]]) # optional - sage.graphs sage.rings.finite_rings + sage: A # optional - sage.graphs sage.rings.finite_rings [1 0 6 1 2] [6 1 0 0 1] [0 6 3 6 0] - sage: Z = lift_cross_ratios(A, to_sixth_root_of_unity) # optional - sage.rings.finite_rings sage.rings.number_field - sage: Z # optional - sage.rings.finite_rings sage.rings.number_field + sage: Z = lift_cross_ratios(A, to_sixth_root_of_unity) # optional - sage.graphs sage.rings.finite_rings sage.rings.number_field + sage: Z # optional - sage.graphs sage.rings.finite_rings sage.rings.number_field [ 1 0 1 1 1] [ 1 1 0 0 z] [ 0 -1 z 1 0] - sage: M = LinearMatroid(reduced_matrix=A) # optional - sage.rings.finite_rings - sage: sorted(M.cross_ratios()) # optional - sage.rings.finite_rings + sage: M = LinearMatroid(reduced_matrix=A) # optional - sage.graphs sage.rings.finite_rings + sage: sorted(M.cross_ratios()) # optional - sage.graphs sage.rings.finite_rings [3, 5] - sage: N = LinearMatroid(reduced_matrix=Z) # optional - sage.rings.finite_rings sage.rings.number_field - sage: sorted(N.cross_ratios()) # optional - sage.rings.finite_rings sage.rings.number_field + sage: N = LinearMatroid(reduced_matrix=Z) # optional - sage.graphs sage.rings.finite_rings sage.rings.number_field + sage: sorted(N.cross_ratios()) # optional - sage.graphs sage.rings.finite_rings sage.rings.number_field [-z + 1, z] - sage: M.is_isomorphism(N, {e:e for e in M.groundset()}) # optional - sage.rings.finite_rings sage.rings.number_field + sage: M.is_isomorphism(N, {e:e for e in M.groundset()}) # optional - sage.graphs sage.rings.finite_rings sage.rings.number_field True """ @@ -740,7 +742,7 @@ def split_vertex(G, u, v=None, edges=None): INPUT: - - ``G`` -- A SageMath Graph. + - ``G`` -- A SageMath :class:`Graph`. - ``u`` -- A vertex in ``G``. - ``v`` -- (optional) The name of the new vertex after the splitting. If ``v`` is specified and already in the graph, it must be an isolated vertex. @@ -751,13 +753,13 @@ def split_vertex(G, u, v=None, edges=None): EXAMPLES:: sage: from sage.matroids.utilities import split_vertex - sage: G = graphs.BullGraph() - sage: split_vertex(G, u=1, v=55, edges=[(1, 3)]) + sage: G = graphs.BullGraph() # optional - sage.graphs + sage: split_vertex(G, u=1, v=55, edges=[(1, 3)]) # optional - sage.graphs Traceback (most recent call last): ... ValueError: the edges are not all incident with u - sage: split_vertex(G, u=1, v=55, edges=[(1, 3, None)]) - sage: list(G.edges(sort=True)) + sage: split_vertex(G, u=1, v=55, edges=[(1, 3, None)]) # optional - sage.graphs + sage: list(G.edges(sort=True)) # optional - sage.graphs [(0, 1, None), (0, 2, None), (1, 2, None), (2, 4, None), (3, 55, None)] """ if v is None: From a1213398077a8913d5eafb0c767cc3da8fb87684 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 3 Jun 2023 16:38:13 -0700 Subject: [PATCH 050/205] src/sage/matroids/linear_matroid.pyx: Modularization fix --- src/sage/matroids/linear_matroid.pyx | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index 7e7701aeed3..7a8b945ee3e 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -826,12 +826,6 @@ cdef class LinearMatroid(BasisExchangeMatroid): True """ # TODO: ensure this is safe for noncommutative rings - global GF2, GF2_zero, GF2_one, GF2_not_defined - if GF2_not_defined: - GF2 = GF(2) - GF2_zero = GF2(0) - GF2_one = GF2(1) - GF2_not_defined = False B = self.basis() N = self.groundset() - B Bo = frozenset([morphism[e] for e in B]) @@ -845,8 +839,18 @@ cdef class LinearMatroid(BasisExchangeMatroid): if other._cocircuit(No | set([morphism[e]])) != frozenset([morphism[f] for f in C[e]]): return False - if self.base_ring() == GF2: - return True + global GF2, GF2_zero, GF2_one, GF2_not_defined + try: + if GF2_not_defined: + GF2 = GF(2) + GF2_zero = GF2(0) + GF2_one = GF2(1) + GF2_not_defined = False + except ImportError: + pass + else: + if self.base_ring() == GF2: + return True self._set_current_basis(B) other._set_current_basis(Bo) From c9aa7b952517ee4e7550c641faf888f1c43511ce Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 3 Jun 2023 17:01:23 -0700 Subject: [PATCH 051/205] Fix # optional --- src/sage/matroids/matroid.pyx | 14 +++++++------- src/sage/repl/rich_output/pretty_print.py | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index bc4cd0df316..b91539ae82a 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -5081,7 +5081,7 @@ cdef class Matroid(SageObject): False sage: matroids.named_matroids.BetsyRoss().is_kconnected(3) True - sage: matroids.AG(5,2).is_kconnected(4) + sage: matroids.AG(5,2).is_kconnected(4) # optional - sage.rings.finite_rings True sage: M = matroids.named_matroids.R6() sage: M.is_kconnected(3) @@ -6295,12 +6295,12 @@ cdef class Matroid(SageObject): sage: M = matroids.Uniform(2,4) sage: [M._is_circuit_chordal(C) for C in M.circuits()] [False, False, False, False] - sage: M = matroids.named_matroids.Fano() - sage: M._is_circuit_chordal(frozenset(['b','c','d'])) + sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings + sage: M._is_circuit_chordal(frozenset(['b','c','d'])) # optional - sage.rings.finite_rings False - sage: M._is_circuit_chordal(frozenset(['b','c','d']), certificate=True) + sage: M._is_circuit_chordal(frozenset(['b','c','d']), certificate=True) # optional - sage.rings.finite_rings (False, None) - sage: M._is_circuit_chordal(frozenset(['a','b','d','e'])) + sage: M._is_circuit_chordal(frozenset(['a','b','d','e'])) # optional - sage.rings.finite_rings True """ cdef set X @@ -7926,11 +7926,11 @@ cdef class Matroid(SageObject): EXAMPLES:: sage: M = matroids.named_matroids.Fano() # optional - sage.rings.finite_rings - sage: A = M.augmented_bergman_complex(); A # optional - sage.rings.finite_rings + sage: A = M.augmented_bergman_complex(); A # optional - sage.graphs sage.rings.finite_rings Simplicial complex with 22 vertices and 91 facets sage: M = matroids.Uniform(2,3) - sage: A = M.augmented_bergman_complex(); A + sage: A = M.augmented_bergman_complex(); A # optional - sage.graphs Simplicial complex with 7 vertices and 9 facets Both the independent set complex of the matroid and the usual diff --git a/src/sage/repl/rich_output/pretty_print.py b/src/sage/repl/rich_output/pretty_print.py index 4fcbfe4d5af..05c9a102876 100644 --- a/src/sage/repl/rich_output/pretty_print.py +++ b/src/sage/repl/rich_output/pretty_print.py @@ -246,10 +246,10 @@ def pretty_print(*args, **kwds): sage: pretty_print(x^2 / (x + 1)) # optional - sage.symbolic x^2/(x + 1) - sage: t = BinaryTrees(3).first() # optional - sage.combinat - sage: pretty_print(t) # optional - sage.combinat + sage: t = BinaryTrees(3).first() # optional - sage.graphs + sage: pretty_print(t) # optional - sage.graphs [., [., [., .]]] - sage: print(t) # optional - sage.combinat + sage: print(t) # optional - sage.graphs [., [., [., .]]] TESTS:: @@ -263,7 +263,7 @@ def pretty_print(*args, **kwds): The following illustrates a possible use-case:: sage: %display ascii_art # not tested - sage: for t in BinaryTrees(3)[:3]: # optional - sage.combinat + sage: for t in BinaryTrees(3)[:3]: # optional - sage.graphs ....: pretty_print(t) o \ From a244872427b90c797368eab1d3c12d9fa86c5392 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 3 Jun 2023 22:51:32 -0700 Subject: [PATCH 052/205] src/sage/matroids/catalog.py: Import lazy_import --- src/sage/matroids/catalog.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/matroids/catalog.py b/src/sage/matroids/catalog.py index c19acdfe8a5..0397436a5f8 100644 --- a/src/sage/matroids/catalog.py +++ b/src/sage/matroids/catalog.py @@ -49,6 +49,7 @@ QuaternaryMatroid) from sage.matroids.rank_matroid import RankMatroid from sage.matroids.constructor import Matroid +from sage.misc.lazy_import import lazy_import lazy_import('sage.rings.finite_rings.finite_field_constructor', 'GF') lazy_import('sage.schemes.projective.projective_space', 'ProjectiveSpace') 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 053/205] 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 054/205] 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 055/205] 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 056/205] 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 057/205] 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 058/205] 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 059/205] 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 060/205] 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 061/205] 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 062/205] 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 063/205] 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 064/205] 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 065/205] 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 066/205] 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 067/205] 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 068/205] 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 069/205] 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 070/205] 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 d98dfed5b0d31f53b21f38ebe9933e85d8cfffb4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 8 Mar 2023 19:02:43 -0800 Subject: [PATCH 071/205] sage.features: Add sage.libs.flint, sage.libs.ntl, sage.rings.polynomial.pbori; add # optional --- src/sage/arith/functions.pyx | 12 +- src/sage/arith/misc.py | 1099 ++++++++++++------------ src/sage/arith/multi_modular.pyx | 1 + src/sage/features/sagemath.py | 72 ++ src/sage/misc/functional.py | 4 +- src/sage/misc/lazy_list.pyx | 29 +- src/sage/misc/prandom.py | 8 +- src/sage/misc/randstate.pyx | 19 +- src/sage/misc/table.py | 2 +- src/sage/structure/category_object.pyx | 4 +- 10 files changed, 662 insertions(+), 588 deletions(-) diff --git a/src/sage/arith/functions.pyx b/src/sage/arith/functions.pyx index 2fe15bbb974..0f2c07d247a 100644 --- a/src/sage/arith/functions.pyx +++ b/src/sage/arith/functions.pyx @@ -72,25 +72,25 @@ def lcm(a, b=None): Make sure we try `\QQ` and not merely `\ZZ` (:trac:`13014`):: - sage: bool(lcm(2/5, 3/7) == lcm(SR(2/5), SR(3/7))) + sage: bool(lcm(2/5, 3/7) == lcm(SR(2/5), SR(3/7))) # optional - sage.symbolic True Make sure that the lcm of Expressions stays symbolic:: sage: parent(lcm(2, 4)) Integer Ring - sage: parent(lcm(SR(2), 4)) + sage: parent(lcm(SR(2), 4)) # optional - sage.symbolic Symbolic Ring - sage: parent(lcm(2, SR(4))) + sage: parent(lcm(2, SR(4))) # optional - sage.symbolic Symbolic Ring - sage: parent(lcm(SR(2), SR(4))) + sage: parent(lcm(SR(2), SR(4))) # optional - sage.symbolic Symbolic Ring Verify that objects without lcm methods but which can't be coerced to `\ZZ` or `\QQ` raise an error:: - sage: F. = FreeMonoid(2) - sage: lcm(x,y) + sage: F. = FreeMonoid(2) # optional - sage.groups + sage: lcm(x,y) # optional - sage.groups Traceback (most recent call last): ... TypeError: unable to find lcm of x and y diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index d3b5d164054..e5cb916200a 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -82,26 +82,26 @@ def algdep(z, degree, known_bits=None, use_bits=None, known_digits=None, EXAMPLES:: - sage: algdep(1.888888888888888, 1) + sage: algdep(1.888888888888888, 1) # optional - sage.libs.pari 9*x - 17 - sage: algdep(0.12121212121212,1) + sage: algdep(0.12121212121212, 1) # optional - sage.libs.pari 33*x - 4 - sage: algdep(sqrt(2),2) + sage: algdep(sqrt(2), 2) # optional - sage.libs.pari sage.symbolic x^2 - 2 This example involves a complex number:: - sage: z = (1/2)*(1 + RDF(sqrt(3)) *CC.0); z + sage: z = (1/2) * (1 + RDF(sqrt(3)) * CC.0); z # optional - sage.symbolic 0.500000000000000 + 0.866025403784439*I - sage: algdep(z, 6) + sage: algdep(z, 6) # optional - sage.symbolic x^2 - x + 1 This example involves a `p`-adic number:: - sage: K = Qp(3, print_mode = 'series') - sage: a = K(7/19); a + sage: K = Qp(3, print_mode='series') # optional - sage.rings.padics + sage: a = K(7/19); a # optional - sage.rings.padics 1 + 2*3 + 3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^8 + 2*3^9 + 3^11 + 3^12 + 2*3^15 + 2*3^16 + 3^17 + 2*3^19 + O(3^20) - sage: algdep(a, 1) + sage: algdep(a, 1) # optional - sage.rings.padics 19*x - 7 These examples show the importance of proper precision control. We @@ -109,82 +109,82 @@ def algdep(z, degree, known_bits=None, use_bits=None, known_digits=None, 33'rd bit:: sage: z = sqrt(RealField(200)(2)) + (1/2)^33 - sage: p = algdep(z, 4); p + sage: p = algdep(z, 4); p # optional - sage.libs.pari 227004321085*x^4 - 216947902586*x^3 - 99411220986*x^2 + 82234881648*x - 211871195088 - sage: factor(p) + sage: factor(p) # optional - sage.libs.pari 227004321085*x^4 - 216947902586*x^3 - 99411220986*x^2 + 82234881648*x - 211871195088 - sage: algdep(z, 4, known_bits=32) + sage: algdep(z, 4, known_bits=32) # optional - sage.libs.pari x^2 - 2 - sage: algdep(z, 4, known_digits=10) + sage: algdep(z, 4, known_digits=10) # optional - sage.libs.pari x^2 - 2 - sage: algdep(z, 4, use_bits=25) + sage: algdep(z, 4, use_bits=25) # optional - sage.libs.pari x^2 - 2 - sage: algdep(z, 4, use_digits=8) + sage: algdep(z, 4, use_digits=8) # optional - sage.libs.pari x^2 - 2 Using the ``height_bound`` and ``proof`` parameters, we can see that `pi` is not the root of an integer polynomial of degree at most 5 and coefficients bounded above by 10:: - sage: algdep(pi.n(), 5, height_bound=10, proof=True) is None + sage: algdep(pi.n(), 5, height_bound=10, proof=True) is None # optional - sage.libs.pari sage.symbolic True For stronger results, we need more precision:: - sage: algdep(pi.n(), 5, height_bound=100, proof=True) is None + sage: algdep(pi.n(), 5, height_bound=100, proof=True) is None # optional - sage.libs.pari sage.symbolic Traceback (most recent call last): ... ValueError: insufficient precision for non-existence proof - sage: algdep(pi.n(200), 5, height_bound=100, proof=True) is None + sage: algdep(pi.n(200), 5, height_bound=100, proof=True) is None # optional - sage.libs.pari sage.symbolic True - sage: algdep(pi.n(), 10, height_bound=10, proof=True) is None + sage: algdep(pi.n(), 10, height_bound=10, proof=True) is None # optional - sage.libs.pari sage.symbolic Traceback (most recent call last): ... ValueError: insufficient precision for non-existence proof - sage: algdep(pi.n(200), 10, height_bound=10, proof=True) is None + sage: algdep(pi.n(200), 10, height_bound=10, proof=True) is None # optional - sage.libs.pari sage.symbolic True We can also use ``proof=True`` to get positive results:: - sage: a = sqrt(2) + sqrt(3) + sqrt(5) - sage: algdep(a.n(), 8, height_bound=1000, proof=True) + sage: a = sqrt(2) + sqrt(3) + sqrt(5) # optional - sage.libs.pari sage.symbolic + sage: algdep(a.n(), 8, height_bound=1000, proof=True) # optional - sage.libs.pari sage.symbolic Traceback (most recent call last): ... ValueError: insufficient precision for uniqueness proof - sage: f = algdep(a.n(1000), 8, height_bound=1000, proof=True); f + sage: f = algdep(a.n(1000), 8, height_bound=1000, proof=True); f # optional - sage.libs.pari sage.symbolic x^8 - 40*x^6 + 352*x^4 - 960*x^2 + 576 - sage: f(a).expand() + sage: f(a).expand() # optional - sage.libs.pari sage.symbolic 0 TESTS:: - sage: algdep(complex("1+2j"), 4) + sage: algdep(complex("1+2j"), 4) # optional - sage.libs.pari x^2 - 2*x + 5 We get an irreducible polynomial even if PARI returns a reducible one:: sage: z = CDF(1, RR(3).sqrt())/2 - sage: pari(z).algdep(5) + sage: pari(z).algdep(5) # optional - sage.libs.pari x^5 + x^2 - sage: algdep(z, 5) + sage: algdep(z, 5) # optional - sage.libs.pari x^2 - x + 1 Check that cases where a constant polynomial might look better get handled correctly:: - sage: z=CC(-1)**(1/3) - sage: algdep(z,1) + sage: z = CC(-1)**(1/3) + sage: algdep(z, 1) # optional - sage.libs.pari x Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8, float64 - sage: algdep(float64(1.888888888888888), int8(1)) + sage: from numpy import int8, float64 # optional - numpy + sage: algdep(float64(1.888888888888888), int8(1)) # optional - numpy sage.libs.pari 9*x - 17 sage: from gmpy2 import mpz, mpfr - sage: algdep(mpfr(1.888888888888888), mpz(1)) + sage: algdep(mpfr(1.888888888888888), mpz(1)) # optional - sage.libs.pari 9*x - 17 """ if proof and not height_bound: @@ -303,24 +303,24 @@ def bernoulli(n, algorithm='default', num_threads=1): EXAMPLES:: - sage: bernoulli(12) + sage: bernoulli(12) # optional - sage.libs.flint -691/2730 - sage: bernoulli(50) + sage: bernoulli(50) # optional - sage.libs.flint 495057205241079648212477525/66 We demonstrate each of the alternative algorithms:: - sage: bernoulli(12, algorithm='arb') + sage: bernoulli(12, algorithm='arb') # optional - sage.libs.flint -691/2730 - sage: bernoulli(12, algorithm='flint') + sage: bernoulli(12, algorithm='flint') # optional - sage.libs.flint -691/2730 - sage: bernoulli(12, algorithm='gap') + sage: bernoulli(12, algorithm='gap') # optional - sage.libs.gap -691/2730 - sage: bernoulli(12, algorithm='gp') + sage: bernoulli(12, algorithm='gp') # optional - sage.libs.pari -691/2730 sage: bernoulli(12, algorithm='magma') # optional - magma -691/2730 - sage: bernoulli(12, algorithm='pari') + sage: bernoulli(12, algorithm='pari') # optional - sage.libs.pari -691/2730 sage: bernoulli(12, algorithm='bernmm') -691/2730 @@ -329,21 +329,28 @@ def bernoulli(n, algorithm='default', num_threads=1): TESTS:: - sage: algs = ['arb', 'gap', 'gp', 'pari', 'bernmm', 'flint'] + sage: algs = [] + sage: algs += ['arb'] # optional - sage.libs.flint + sage: algs += ['gap'] # optional - sage.libs.gap + sage: algs += ['gp', 'pari'] # optional - sage.libs.pari + sage: algs += ['bernmm'] + sage: algs += ['flint'] # optional - sage.libs.flint sage: test_list = [ZZ.random_element(2, 2255) for _ in range(500)] sage: vals = [[bernoulli(i, algorithm=j) for j in algs] for i in test_list] # long time (up to 21s on sage.math, 2011) - sage: all(len(set(x))==1 for x in vals) # long time (depends on previous line) + sage: all(len(set(x)) == 1 for x in vals) # long time (depends on previous line) True - sage: algs = ['gp', 'pari', 'bernmm'] + sage: algs = [] + sage: algs += ['gp', 'pari'] # optional - sage.libs.pari + sage: algs += ['bernmm'] sage: test_list = [ZZ.random_element(2256, 5000) for _ in range(500)] sage: vals = [[bernoulli(i, algorithm=j) for j in algs] for i in test_list] # long time (up to 30s on sage.math, 2011) sage: all(len(set(x))==1 for x in vals) # long time (depends on previous line) True - sage: from numpy import int8 - sage: bernoulli(int8(12)) + sage: from numpy import int8 # optional - numpy + sage: bernoulli(int8(12)) # optional - numpy sage.libs.flint -691/2730 sage: from gmpy2 import mpz - sage: bernoulli(mpz(12)) + sage: bernoulli(mpz(12)) # optional - sage.libs.flint -691/2730 AUTHOR: @@ -433,8 +440,8 @@ def factorial(n, algorithm='gmp'): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: factorial(int8(4)) + sage: from numpy import int8 # optional - numpy + sage: factorial(int8(4)) # optional - numpy 24 sage: from gmpy2 import mpz sage: factorial(mpz(4)) @@ -519,7 +526,7 @@ def is_prime(n): sage: a = 2**2048 + 981 sage: is_prime(a) # not tested - takes ~ 1min sage: proof.arithmetic(False) - sage: is_prime(a) # instantaneous! + sage: is_prime(a) # instantaneous! # optional - sage.libs.pari True sage: proof.arithmetic(True) @@ -544,8 +551,8 @@ def is_prime(n): (cf. :trac:`32340`) and we should not warn:: sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field - sage: is_prime(1 + i) # optional - sage.rings.number_field + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: is_prime(1 + i) # optional - sage.rings.number_field True """ try: @@ -586,19 +593,19 @@ def is_pseudoprime(n): EXAMPLES:: - sage: is_pseudoprime(389) + sage: is_pseudoprime(389) # optional - sage.libs.pari True - sage: is_pseudoprime(2000) + sage: is_pseudoprime(2000) # optional - sage.libs.pari False - sage: is_pseudoprime(2) + sage: is_pseudoprime(2) # optional - sage.libs.pari True - sage: is_pseudoprime(-1) + sage: is_pseudoprime(-1) # optional - sage.libs.pari False sage: factor(-6) -1 * 2 * 3 - sage: is_pseudoprime(1) + sage: is_pseudoprime(1) # optional - sage.libs.pari False - sage: is_pseudoprime(-2) + sage: is_pseudoprime(-2) # optional - sage.libs.pari False """ return ZZ(n).is_pseudoprime() @@ -621,51 +628,51 @@ def is_prime_power(n, get_data=False): EXAMPLES:: - sage: is_prime_power(389) + sage: is_prime_power(389) # optional - sage.libs.pari True - sage: is_prime_power(2000) + sage: is_prime_power(2000) # optional - sage.libs.pari False - sage: is_prime_power(2) + sage: is_prime_power(2) # optional - sage.libs.pari True - sage: is_prime_power(1024) + sage: is_prime_power(1024) # optional - sage.libs.pari True - sage: is_prime_power(1024, get_data=True) + sage: is_prime_power(1024, get_data=True) # optional - sage.libs.pari (2, 10) The same results can be obtained with:: - sage: 389.is_prime_power() + sage: 389.is_prime_power() # optional - sage.libs.pari True - sage: 2000.is_prime_power() + sage: 2000.is_prime_power() # optional - sage.libs.pari False - sage: 2.is_prime_power() + sage: 2.is_prime_power() # optional - sage.libs.pari True - sage: 1024.is_prime_power() + sage: 1024.is_prime_power() # optional - sage.libs.pari True - sage: 1024.is_prime_power(get_data=True) + sage: 1024.is_prime_power(get_data=True) # optional - sage.libs.pari (2, 10) TESTS:: - sage: is_prime_power(-1) + sage: is_prime_power(-1) # optional - sage.libs.pari False - sage: is_prime_power(1) + sage: is_prime_power(1) # optional - sage.libs.pari False - sage: is_prime_power(QQ(997^100)) + sage: is_prime_power(QQ(997^100)) # optional - sage.libs.pari True - sage: is_prime_power(1/2197) + sage: is_prime_power(1/2197) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: no conversion of this rational to integer - sage: is_prime_power("foo") + sage: is_prime_power("foo") # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: unable to convert 'foo' to an integer sage: from gmpy2 import mpz - sage: is_prime_power(mpz(389)) + sage: is_prime_power(mpz(389)) # optional - sage.libs.pari True - sage: from numpy import int16 - sage: is_prime_power(int16(389)) + sage: from numpy import int16 # optional - numpy + sage: is_prime_power(int16(389)) # optional - numpy sage.libs.pari True """ return ZZ(n).is_prime_power(get_data=get_data) @@ -688,39 +695,39 @@ def is_pseudoprime_power(n, get_data=False): EXAMPLES:: - sage: is_pseudoprime_power(389) + sage: is_pseudoprime_power(389) # optional - sage.libs.pari True - sage: is_pseudoprime_power(2000) + sage: is_pseudoprime_power(2000) # optional - sage.libs.pari False - sage: is_pseudoprime_power(2) + sage: is_pseudoprime_power(2) # optional - sage.libs.pari True - sage: is_pseudoprime_power(1024) + sage: is_pseudoprime_power(1024) # optional - sage.libs.pari True - sage: is_pseudoprime_power(-1) + sage: is_pseudoprime_power(-1) # optional - sage.libs.pari False - sage: is_pseudoprime_power(1) + sage: is_pseudoprime_power(1) # optional - sage.libs.pari False - sage: is_pseudoprime_power(997^100) + sage: is_pseudoprime_power(997^100) # optional - sage.libs.pari True Use of the get_data keyword:: - sage: is_pseudoprime_power(3^1024, get_data=True) + sage: is_pseudoprime_power(3^1024, get_data=True) # optional - sage.libs.pari (3, 1024) - sage: is_pseudoprime_power(2^256, get_data=True) + sage: is_pseudoprime_power(2^256, get_data=True) # optional - sage.libs.pari (2, 256) - sage: is_pseudoprime_power(31, get_data=True) + sage: is_pseudoprime_power(31, get_data=True) # optional - sage.libs.pari (31, 1) - sage: is_pseudoprime_power(15, get_data=True) + sage: is_pseudoprime_power(15, get_data=True) # optional - sage.libs.pari (15, 0) Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: is_pseudoprime_power(int16(1024)) + sage: from numpy import int16 # optional - numpy + sage: is_pseudoprime_power(int16(1024)) # optional - numpy sage.libs.pari True sage: from gmpy2 import mpz - sage: is_pseudoprime_power(mpz(1024)) + sage: is_pseudoprime_power(mpz(1024)) # optional - sage.libs.pari True """ return ZZ(n).is_prime_power(proof=False, get_data=get_data) @@ -784,8 +791,8 @@ def valuation(m, *args, **kwds): Traceback (most recent call last): ... ValueError: You can only compute the valuation with respect to a integer larger than 1. - sage: from numpy import int16 - sage: valuation(int16(512), int16(2)) + sage: from numpy import int16 # optional - numpy + sage: valuation(int16(512), int16(2)) # optional - numpy 9 sage: from gmpy2 import mpz sage: valuation(mpz(512), mpz(2)) @@ -822,49 +829,49 @@ def prime_powers(start, stop=None): EXAMPLES:: - sage: prime_powers(20) + sage: prime_powers(20) # optional - sage.libs.pari [2, 3, 4, 5, 7, 8, 9, 11, 13, 16, 17, 19] - sage: len(prime_powers(1000)) + sage: len(prime_powers(1000)) # optional - sage.libs.pari 193 - sage: len(prime_range(1000)) + sage: len(prime_range(1000)) # optional - sage.libs.pari 168 - sage: a = [z for z in range(95,1234) if is_prime_power(z)] - sage: b = prime_powers(95,1234) - sage: len(b) + sage: a = [z for z in range(95, 1234) if is_prime_power(z)] # optional - sage.libs.pari + sage: b = prime_powers(95, 1234) # optional - sage.libs.pari + sage: len(b) # optional - sage.libs.pari 194 - sage: len(a) + sage: len(a) # optional - sage.libs.pari 194 - sage: a[:10] + sage: a[:10] # optional - sage.libs.pari [97, 101, 103, 107, 109, 113, 121, 125, 127, 128] - sage: b[:10] + sage: b[:10] # optional - sage.libs.pari [97, 101, 103, 107, 109, 113, 121, 125, 127, 128] - sage: a == b + sage: a == b # optional - sage.libs.pari True - sage: prime_powers(100) == [i for i in range(100) if is_prime_power(i)] + sage: prime_powers(100) == [i for i in range(100) if is_prime_power(i)] # optional - sage.libs.pari True - sage: prime_powers(10,7) + sage: prime_powers(10, 7) # optional - sage.libs.pari [] - sage: prime_powers(-5) + sage: prime_powers(-5) # optional - sage.libs.pari [] - sage: prime_powers(-1,3) + sage: prime_powers(-1, 3) # optional - sage.libs.pari [2] TESTS: Check that output are always Sage integers (:trac:`922`):: - sage: v = prime_powers(10) - sage: type(v[0]) + sage: v = prime_powers(10) # optional - sage.libs.pari + sage: type(v[0]) # optional - sage.libs.pari - sage: prime_powers(0,1) + sage: prime_powers(0, 1) # optional - sage.libs.pari [] - sage: prime_powers(2) + sage: prime_powers(2) # optional - sage.libs.pari [] - sage: prime_powers(3) + sage: prime_powers(3) # optional - sage.libs.pari [2] sage: prime_powers("foo") @@ -879,18 +886,18 @@ def prime_powers(start, stop=None): Check that long input are accepted (:trac:`17852`):: - sage: prime_powers(6l) + sage: prime_powers(6l) # optional - sage.libs.pari [2, 3, 4, 5] - sage: prime_powers(6l,10l) + sage: prime_powers(6l, 10l) # optional - sage.libs.pari [7, 8, 9] Check numpy and gmpy2 support:: - sage: from numpy import int8 - sage: prime_powers(int8(20)) + sage: from numpy import int8 # optional - numpy + sage: prime_powers(int8(20)) # optional - numpy sage.libs.pari [2, 3, 4, 5, 7, 8, 9, 11, 13, 16, 17, 19] sage: from gmpy2 import mpz - sage: prime_powers(mpz(20)) + sage: prime_powers(mpz(20)) # optional - sage.libs.pari [2, 3, 4, 5, 7, 8, 9, 11, 13, 16, 17, 19] """ start = ZZ(start) @@ -932,11 +939,11 @@ def primes_first_n(n, leave_pari=False): EXAMPLES:: - sage: primes_first_n(10) + sage: primes_first_n(10) # optional - sage.libs.pari [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] - sage: len(primes_first_n(1000)) + sage: len(primes_first_n(1000)) # optional - sage.libs.pari 1000 - sage: primes_first_n(0) + sage: primes_first_n(0) # optional - sage.libs.pari [] """ if n < 0: @@ -974,13 +981,13 @@ def eratosthenes(n): [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47] sage: len(eratosthenes(100)) 25 - sage: eratosthenes(213) == prime_range(213) + sage: eratosthenes(213) == prime_range(213) # optional - sage.libs.pari True TESTS:: - sage: from numpy import int8 - sage: eratosthenes(int8(3)) + sage: from numpy import int8 # optional - numpy + sage: eratosthenes(int8(3)) # optional - numpy [2, 3] sage: from gmpy2 import mpz sage: eratosthenes(mpz(3)) @@ -1011,7 +1018,7 @@ def eratosthenes(n): return [ZZ(2)] + [ZZ(x) for x in s if x and x <= n] -def primes(start=2, stop=None, proof=None): +def primes(start, stop=None, proof=None): r""" Return an iterator over all primes between start and stop-1, inclusive. This is much slower than ``prime_range``, but @@ -1028,11 +1035,10 @@ def primes(start=2, stop=None, proof=None): INPUT: - - ``start`` - an integer (default: 2) optional argument - - giving lower bound for the primes + - ``start`` - an integer - lower bound for the primes - - ``stop`` - an integer (or infinity) - giving upper (open) bound for the - primes + - ``stop`` - an integer (or infinity) optional argument - + giving upper (open) bound for the primes - ``proof`` - bool or None (default: None) If True, the function yields only proven primes. If False, the function uses a @@ -1047,41 +1053,41 @@ def primes(start=2, stop=None, proof=None): EXAMPLES:: - sage: for p in primes(5,10): + sage: for p in primes(5, 10): # optional - sage.libs.pari ....: print(p) 5 7 - sage: list(primes(13)) + sage: list(primes(13)) # optional - sage.libs.pari [2, 3, 5, 7, 11] - sage: list(primes(10000000000, 10000000100)) + sage: list(primes(10000000000, 10000000100)) # optional - sage.libs.pari [10000000019, 10000000033, 10000000061, 10000000069, 10000000097] - sage: max(primes(10^100, 10^100+10^4, proof=False)) + sage: max(primes(10^100, 10^100+10^4, proof=False)) # optional - sage.libs.pari 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009631 - sage: next(p for p in primes(10^20, infinity) if is_prime(2*p+1)) + sage: next(p for p in primes(10^20, infinity) if is_prime(2*p+1)) # optional - sage.libs.pari 100000000000000001243 TESTS:: - sage: for a in range(-10, 50): + sage: for a in range(-10, 50): # optional - sage.libs.pari ....: for b in range(-10, 50): ....: assert list(primes(a,b)) == list(filter(is_prime, range(a,b))) - sage: sum(primes(-10, 9973, proof=False)) == sum(filter(is_prime, range(-10, 9973))) + sage: sum(primes(-10, 9973, proof=False)) == sum(filter(is_prime, range(-10, 9973))) # optional - sage.libs.pari True - sage: for p in primes(10, infinity): + sage: for p in primes(10, infinity): # optional - sage.libs.pari ....: if p > 20: break ....: print(p) 11 13 17 19 - sage: next(p for p in primes(10,oo)) # checks alternate infinity notation + sage: next(p for p in primes(10,oo)) # checks alternate infinity notation # optional - sage.libs.pari 11 - sage: from numpy import int8 - sage: list(primes(int8(13))) + sage: from numpy import int8 # optional - numpy + sage: list(primes(int8(13))) # optional - numpy sage.libs.pari [2, 3, 5, 7, 11] sage: from gmpy2 import mpz - sage: list(primes(mpz(13))) + sage: list(primes(mpz(13))) # optional - sage.libs.pari [2, 3, 5, 7, 11] """ from sage.rings.infinity import infinity @@ -1121,40 +1127,40 @@ def next_prime_power(n): EXAMPLES:: - sage: next_prime_power(1) + sage: next_prime_power(1) # optional - sage.libs.pari 2 - sage: next_prime_power(2) + sage: next_prime_power(2) # optional - sage.libs.pari 3 - sage: next_prime_power(10) + sage: next_prime_power(10) # optional - sage.libs.pari 11 - sage: next_prime_power(7) + sage: next_prime_power(7) # optional - sage.libs.pari 8 - sage: next_prime_power(99) + sage: next_prime_power(99) # optional - sage.libs.pari 101 The same results can be obtained with:: - sage: 1.next_prime_power() + sage: 1.next_prime_power() # optional - sage.libs.pari 2 - sage: 2.next_prime_power() + sage: 2.next_prime_power() # optional - sage.libs.pari 3 - sage: 10.next_prime_power() + sage: 10.next_prime_power() # optional - sage.libs.pari 11 Note that `2` is the smallest prime power:: - sage: next_prime_power(-10) + sage: next_prime_power(-10) # optional - sage.libs.pari 2 - sage: next_prime_power(0) + sage: next_prime_power(0) # optional - sage.libs.pari 2 TESTS:: - sage: from numpy import int8 - sage: next_prime_power(int8(10)) + sage: from numpy import int8 # optional - numpy + sage: next_prime_power(int8(10)) # optional - numpy sage.libs.pari 11 sage: from gmpy2 import mpz - sage: next_prime_power(mpz(10)) + sage: next_prime_power(mpz(10)) # optional - sage.libs.pari 11 """ return ZZ(n).next_prime_power() @@ -1172,22 +1178,22 @@ def next_probable_prime(n): EXAMPLES:: - sage: next_probable_prime(-100) + sage: next_probable_prime(-100) # optional - sage.libs.pari 2 - sage: next_probable_prime(19) + sage: next_probable_prime(19) # optional - sage.libs.pari 23 - sage: next_probable_prime(int(999999999)) + sage: next_probable_prime(int(999999999)) # optional - sage.libs.pari 1000000007 - sage: next_probable_prime(2^768) + sage: next_probable_prime(2^768) # optional - sage.libs.pari 1552518092300708935148979488462502555256886017116696611139052038026050952686376886330878408828646477950487730697131073206171580044114814391444287275041181139204454976020849905550265285631598444825262999193716468750892846853816058039 TESTS:: - sage: from numpy import int8 - sage: next_probable_prime(int8(19)) + sage: from numpy import int8 # optional - numpy + sage: next_probable_prime(int8(19)) # optional - numpy sage.libs.pari 23 sage: from gmpy2 import mpz - sage: next_probable_prime(mpz(19)) + sage: next_probable_prime(mpz(19)) # optional - sage.libs.pari 23 """ return ZZ(n).next_probable_prime() @@ -1211,33 +1217,33 @@ def next_prime(n, proof=None): EXAMPLES:: - sage: next_prime(-100) + sage: next_prime(-100) # optional - sage.libs.pari 2 - sage: next_prime(1) + sage: next_prime(1) # optional - sage.libs.pari 2 - sage: next_prime(2) + sage: next_prime(2) # optional - sage.libs.pari 3 - sage: next_prime(3) + sage: next_prime(3) # optional - sage.libs.pari 5 - sage: next_prime(4) + sage: next_prime(4) # optional - sage.libs.pari 5 Notice that the next_prime(5) is not 5 but 7. :: - sage: next_prime(5) + sage: next_prime(5) # optional - sage.libs.pari 7 - sage: next_prime(2004) + sage: next_prime(2004) # optional - sage.libs.pari 2011 TESTS:: - sage: from numpy import int8 - sage: next_prime(int8(3)) + sage: from numpy import int8 # optional - numpy + sage: next_prime(int8(3)) # optional - numpy sage.libs.pari 5 sage: from gmpy2 import mpz - sage: next_probable_prime(mpz(3)) + sage: next_probable_prime(mpz(3)) # optional - sage.libs.pari 5 """ return ZZ(n).next_prime(proof) @@ -1250,38 +1256,38 @@ def previous_prime(n): EXAMPLES:: - sage: previous_prime(10) + sage: previous_prime(10) # optional - sage.libs.pari 7 - sage: previous_prime(7) + sage: previous_prime(7) # optional - sage.libs.pari 5 - sage: previous_prime(8) + sage: previous_prime(8) # optional - sage.libs.pari 7 - sage: previous_prime(7) + sage: previous_prime(7) # optional - sage.libs.pari 5 - sage: previous_prime(5) + sage: previous_prime(5) # optional - sage.libs.pari 3 - sage: previous_prime(3) + sage: previous_prime(3) # optional - sage.libs.pari 2 - sage: previous_prime(2) + sage: previous_prime(2) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no previous prime - sage: previous_prime(1) + sage: previous_prime(1) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no previous prime - sage: previous_prime(-20) + sage: previous_prime(-20) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no previous prime TESTS:: - sage: from numpy import int8 - sage: previous_prime(int8(7)) + sage: from numpy import int8 # optional - numpy + sage: previous_prime(int8(7)) # optional - numpy sage.libs.pari 5 sage: from gmpy2 import mpz - sage: previous_prime(mpz(7)) + sage: previous_prime(mpz(7)) # optional - sage.libs.pari 5 """ n = ZZ(n) - 1 @@ -1316,52 +1322,52 @@ def previous_prime_power(n): EXAMPLES:: - sage: previous_prime_power(3) + sage: previous_prime_power(3) # optional - sage.libs.pari 2 - sage: previous_prime_power(10) + sage: previous_prime_power(10) # optional - sage.libs.pari 9 - sage: previous_prime_power(7) + sage: previous_prime_power(7) # optional - sage.libs.pari 5 - sage: previous_prime_power(127) + sage: previous_prime_power(127) # optional - sage.libs.pari 125 The same results can be obtained with:: - sage: 3.previous_prime_power() + sage: 3.previous_prime_power() # optional - sage.libs.pari 2 - sage: 10.previous_prime_power() + sage: 10.previous_prime_power() # optional - sage.libs.pari 9 - sage: 7.previous_prime_power() + sage: 7.previous_prime_power() # optional - sage.libs.pari 5 - sage: 127.previous_prime_power() + sage: 127.previous_prime_power() # optional - sage.libs.pari 125 Input less than or equal to `2` raises errors:: - sage: previous_prime_power(2) + sage: previous_prime_power(2) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no prime power less than 2 - sage: previous_prime_power(-10) + sage: previous_prime_power(-10) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no prime power less than 2 :: - sage: n = previous_prime_power(2^16 - 1) - sage: while is_prime(n): + sage: n = previous_prime_power(2^16 - 1) # optional - sage.libs.pari + sage: while is_prime(n): # optional - sage.libs.pari ....: n = previous_prime_power(n) - sage: factor(n) + sage: factor(n) # optional - sage.libs.pari 251^2 TESTS:: - sage: from numpy import int8 - sage: previous_prime_power(int8(10)) + sage: from numpy import int8 # optional - numpy + sage: previous_prime_power(int8(10)) # optional - numpy sage.libs.pari 9 sage: from gmpy2 import mpz - sage: previous_prime_power(mpz(10)) + sage: previous_prime_power(mpz(10)) # optional - sage.libs.pari 9 """ return ZZ(n).previous_prime_power() @@ -1389,42 +1395,42 @@ def random_prime(n, proof=None, lbound=2): EXAMPLES:: - sage: p = random_prime(100000) - sage: p.is_prime() + sage: p = random_prime(100000) # optional - sage.libs.pari + sage: p.is_prime() # optional - sage.libs.pari True - sage: p <= 100000 + sage: p <= 100000 # optional - sage.libs.pari True - sage: random_prime(2) + sage: random_prime(2) # optional - sage.libs.pari 2 Here we generate a random prime between 100 and 200:: - sage: p = random_prime(200, lbound=100) - sage: p.is_prime() + sage: p = random_prime(200, lbound=100) # optional - sage.libs.pari + sage: p.is_prime() # optional - sage.libs.pari True - sage: 100 <= p <= 200 + sage: 100 <= p <= 200 # optional - sage.libs.pari True If all we care about is finding a pseudo prime, then we can pass in ``proof=False`` :: - sage: p = random_prime(200, proof=False, lbound=100) - sage: p.is_pseudoprime() + sage: p = random_prime(200, proof=False, lbound=100) # optional - sage.libs.pari + sage: p.is_pseudoprime() # optional - sage.libs.pari True - sage: 100 <= p <= 200 + sage: 100 <= p <= 200 # optional - sage.libs.pari True TESTS:: - sage: type(random_prime(2)) + sage: type(random_prime(2)) # optional - sage.libs.pari - sage: type(random_prime(100)) + sage: type(random_prime(100)) # optional - sage.libs.pari - sage: random_prime(1, lbound=-2) #caused Sage hang #10112 + sage: random_prime(1, lbound=-2) #caused Sage hang #10112 # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: n must be greater than or equal to 2 - sage: random_prime(126, lbound=114) + sage: random_prime(126, lbound=114) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: there are no primes between 114 and 126 (inclusive) @@ -1516,13 +1522,13 @@ def divisors(n): This function works whenever one has unique factorization:: - sage: K. = QuadraticField(7) - sage: divisors(K.ideal(7)) + sage: K. = QuadraticField(7) # optional - sage.rings.number_field + sage: divisors(K.ideal(7)) # optional - sage.rings.number_field [Fractional ideal (1), Fractional ideal (a), Fractional ideal (7)] - sage: divisors(K.ideal(3)) + sage: divisors(K.ideal(3)) # optional - sage.rings.number_field [Fractional ideal (1), Fractional ideal (3), Fractional ideal (a - 2), Fractional ideal (a + 2)] - sage: divisors(K.ideal(35)) + sage: divisors(K.ideal(35)) # optional - sage.rings.number_field [Fractional ideal (1), Fractional ideal (5), Fractional ideal (a), Fractional ideal (7), Fractional ideal (5*a), Fractional ideal (35)] @@ -1530,8 +1536,8 @@ def divisors(n): sage: divisors(int(300)) [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 25, 30, 50, 60, 75, 100, 150, 300] - sage: import numpy - sage: divisors(numpy.int8(100)) + sage: import numpy # optional - numpy + sage: divisors(numpy.int8(100)) # optional - numpy [1, 2, 4, 5, 10, 20, 25, 50, 100] sage: import gmpy2 sage: divisors(gmpy2.mpz(100)) @@ -1593,13 +1599,13 @@ class Sigma: :: - sage: P = plot(sigma, 1, 100) + sage: P = plot(sigma, 1, 100) # optional - sage.plot This method also works with k-th powers. :: - sage: P = plot(sigma, 1, 100, k=2) + sage: P = plot(sigma, 1, 100, k=2) # optional - sage.plot AUTHORS: @@ -1611,21 +1617,21 @@ class Sigma: sage: sigma(100,4) 106811523 - sage: sigma(factorial(100),3).mod(144169) + sage: sigma(factorial(100),3).mod(144169) # optional - sage.libs.pari 3672 - sage: sigma(factorial(150),12).mod(691) + sage: sigma(factorial(150),12).mod(691) # optional - sage.libs.pari 176 - sage: RR(sigma(factorial(133),20)) + sage: RR(sigma(factorial(133),20)) # optional - sage.libs.pari 2.80414775675747e4523 - sage: sigma(factorial(100),0) + sage: sigma(factorial(100),0) # optional - sage.libs.pari 39001250856960000 - sage: sigma(factorial(41),1) + sage: sigma(factorial(41),1) # optional - sage.libs.pari 229199532273029988767733858700732906511758707916800 - sage: from numpy import int8 - sage: sigma(int8(100),int8(4)) + sage: from numpy import int8 # optional - numpy + sage: sigma(int8(100), int8(4)) # optional - numpy sage.libs.pari 106811523 sage: from gmpy2 import mpz - sage: sigma(mpz(100),mpz(4)) + sage: sigma(mpz(100), mpz(4)) # optional - sage.libs.pari 106811523 """ def __repr__(self): @@ -1649,9 +1655,9 @@ def __call__(self, n, k=1): sage: from sage.arith.misc import Sigma sage: q = Sigma() - sage: q(10) + sage: q(10) # optional - sage.libs.pari 18 - sage: q(10,2) + sage: q(10,2) # optional - sage.libs.pari 130 """ n = ZZ(n) @@ -1693,8 +1699,8 @@ def plot(self, xmin=1, xmax=50, k=1, pointsize=30, rgbcolor=(0,0,1), join=True, EXAMPLES:: sage: from sage.arith.misc import Sigma - sage: p = Sigma().plot() - sage: p.ymax() + sage: p = Sigma().plot() # optional - sage.plot # optional - sage.libs.pari + sage: p.ymax() # optional - sage.plot # optional - sage.libs.pari 124.0 """ v = [(n, sigma(n, k)) for n in range(xmin, xmax + 1)] @@ -1784,33 +1790,33 @@ def gcd(a, b=None, **kwargs): Make sure we try QQ and not merely ZZ (:trac:`13014`):: - sage: bool(gcd(2/5, 3/7) == gcd(SR(2/5), SR(3/7))) + sage: bool(gcd(2/5, 3/7) == gcd(SR(2/5), SR(3/7))) # optional - sage.symbolic True Make sure that the gcd of Expressions stays symbolic:: sage: parent(gcd(2, 4)) Integer Ring - sage: parent(gcd(SR(2), 4)) + sage: parent(gcd(SR(2), 4)) # optional - sage.symbolic Symbolic Ring - sage: parent(gcd(2, SR(4))) + sage: parent(gcd(2, SR(4))) # optional - sage.symbolic Symbolic Ring - sage: parent(gcd(SR(2), SR(4))) + sage: parent(gcd(SR(2), SR(4))) # optional - sage.symbolic Symbolic Ring Verify that objects without gcd methods but which cannot be coerced to ZZ or QQ raise an error:: - sage: F. = FreeMonoid(2) - sage: gcd(a,b) + sage: F. = FreeMonoid(2) # optional - sage.groups + sage: gcd(a, b) # optional - sage.groups Traceback (most recent call last): ... TypeError: unable to call gcd with a Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: GCD(int8(97),int8(100)) + sage: from numpy import int8 # optional - numpy + sage: GCD(int8(97), int8(100)) # optional - numpy 1 sage: from gmpy2 import mpq, mpz sage: GCD(mpq(2/3), mpq(4/5)) @@ -1909,8 +1915,8 @@ def xlcm(m, n): TESTS:: - sage: from numpy import int16 - sage: xlcm(int16(120), int16(36)) + sage: from numpy import int16 # optional - numpy + sage: xlcm(int16(120), int16(36)) # optional - numpy (360, 40, 9) sage: from gmpy2 import mpz sage: xlcm(mpz(120), mpz(36)) @@ -1975,15 +1981,15 @@ def xgcd(a, b): sage: xgcd(x^3 - 1, x^2 - 1) (x - 1, 1, -x) - sage: K. = NumberField(x^2-3) - sage: g.xgcd(g+2) + sage: K. = NumberField(x^2 - 3) # optional - sage.rings.number_field + sage: g.xgcd(g + 2) # optional - sage.rings.number_field (1, 1/3*g, 0) - sage: R. = K[] - sage: S. = R.fraction_field()[] - sage: xgcd(y^2, a*y+b) + sage: R. = K[] # optional - sage.rings.number_field + sage: S. = R.fraction_field()[] # optional - sage.rings.number_field + sage: xgcd(y^2, a*y + b) # optional - sage.rings.number_field (1, a^2/b^2, ((-a)/b^2)*y + 1/b) - sage: xgcd((b+g)*y^2, (a+g)*y+b) + sage: xgcd((b+g)*y^2, (a+g)*y + b) # optional - sage.rings.number_field (1, (a^2 + (2*g)*a + 3)/(b^3 + g*b^2), ((-a + (-g))/b^2)*y + 1/b) Here is an example of a xgcd for two polynomials over the integers, where the linear @@ -1999,10 +2005,10 @@ def xgcd(a, b): Tests with numpy and gmpy2 types:: - sage: from numpy import int8 - sage: xgcd(4,int8(8)) + sage: from numpy import int8 # optional - numpy + sage: xgcd(4,int8(8)) # optional - numpy (4, 1, 0) - sage: xgcd(int8(4),int8(8)) + sage: xgcd(int8(4),int8(8)) # optional - numpy (4, 1, 0) sage: from gmpy2 import mpz sage: xgcd(mpz(4), mpz(8)) @@ -2014,10 +2020,10 @@ def xgcd(a, b): We check that :trac:`3330` has been fixed:: - sage: R. = NumberField(x^2-3,'g').extension(x^2-7,'h')[] - sage: h = R.base_ring().gen() - sage: S. = R.fraction_field()[] - sage: xgcd(y^2, a*h*y+b) + sage: R. = NumberField(x^2 - 3, 'g').extension(x^2 - 7, 'h')[] # optional - sage.rings.number_field + sage: h = R.base_ring().gen() # optional - sage.rings.number_field + sage: S. = R.fraction_field()[] # optional - sage.rings.number_field + sage: xgcd(y^2, a*h*y + b) # optional - sage.rings.number_field (1, 7*a^2/b^2, (((-h)*a)/b^2)*y + 1/b) """ try: @@ -2141,8 +2147,8 @@ def inverse_mod(a, m): Tests with numpy and mpz numbers:: - sage: from numpy import int8 - sage: inverse_mod(int8(5),int8(14)) + sage: from numpy import int8 # optional - numpy + sage: inverse_mod(int8(5),int8(14)) # optional - numpy 3 sage: from gmpy2 import mpz sage: inverse_mod(mpz(5),mpz(14)) @@ -2250,8 +2256,8 @@ def power_mod(a, n, m): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int32 - sage: power_mod(int32(2),int32(390),int32(391)) + sage: from numpy import int32 # optional - numpy + sage: power_mod(int32(2), int32(390), int32(391)) # optional - numpy 285 sage: from gmpy2 import mpz sage: power_mod(mpz(2),mpz(390),mpz(391)) @@ -2373,8 +2379,8 @@ def rational_reconstruction(a, m, algorithm='fast'): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int32 - sage: rational_reconstruction(int32(3), int32(292393)) + sage: from numpy import int32 # optional - numpy + sage: rational_reconstruction(int32(3), int32(292393)) # optional - numpy 3 sage: from gmpy2 import mpz sage: rational_reconstruction(mpz(3), mpz(292393)) @@ -2413,8 +2419,8 @@ def mqrr_rational_reconstruction(u, m, T): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: mqrr_rational_reconstruction(int16(21),int16(3100),int16(13)) + sage: from numpy import int16 # optional - numpy + sage: mqrr_rational_reconstruction(int16(21), int16(3100), int16(13)) # optional - numpy (21, 1) sage: from gmpy2 import mpz sage: mqrr_rational_reconstruction(mpz(21),mpz(3100),mpz(13)) @@ -2481,8 +2487,8 @@ def trial_division(n, bound=None): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: trial_division(int8(91)) + sage: from numpy import int8 # optional - numpy + sage: trial_division(int8(91)) # optional - numpy 7 sage: from gmpy2 import mpz sage: trial_division(mpz(91)) @@ -2513,10 +2519,10 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): EXAMPLES:: - sage: f(n)=n^2 - sage: is_prime(f(3)) + sage: f(n) = n^2 # optional - sage.symbolic + sage: is_prime(f(3)) # optional - sage.symbolic False - sage: factor(f(3)) + sage: factor(f(3)) # optional - sage.symbolic 9 INPUT: @@ -2532,8 +2538,6 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): - ``'pari'`` - (default) use the PARI c library - - ``'flint'`` - use the FLINT library - - ``'kash'`` - use KASH computer algebra system (requires that kash be installed) @@ -2579,14 +2583,9 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): -1 sage: f.value() -20 - sage: factor( -next_prime(10^2) * next_prime(10^7) ) + sage: factor(-next_prime(10^2) * next_prime(10^7)) # optional - sage.libs.pari -1 * 101 * 10000019 - :: - - sage: factor(293292629867846432923017396246429, algorithm='flint') - 3 * 4852301647696687 * 20148007492971089 - :: sage: factor(-500, algorithm='kash') # optional - kash @@ -2607,7 +2606,7 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): 1 sage: factor(-1) -1 - sage: factor(2^(2^7)+1) + sage: factor(2^(2^7)+1) # optional - sage.libs.pari 59649589127497217 * 5704689200685129054721 Sage calls PARI's factor, which has proof False by default. @@ -2617,42 +2616,42 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): :: - sage: factor(3^89-1, proof=False) + sage: factor(3^89-1, proof=False) # optional - sage.libs.pari 2 * 179 * 1611479891519807 * 5042939439565996049162197 :: - sage: factor(2^197 + 1) # long time (2s) + sage: factor(2^197 + 1) # long time (2s) # optional - sage.libs.pari 3 * 197002597249 * 1348959352853811313 * 251951573867253012259144010843 Any object which has a factor method can be factored like this:: - sage: K. = QuadraticField(-1) - sage: factor(122 - 454*i) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: factor(122 - 454*i) # optional - sage.rings.number_field (-i) * (-i - 2)^3 * (i + 1)^3 * (-2*i + 3) * (i + 4) To access the data in a factorization:: - sage: f = factor(420); f + sage: f = factor(420); f # optional - sage.libs.pari 2^2 * 3 * 5 * 7 - sage: [x for x in f] + sage: [x for x in f] # optional - sage.libs.pari [(2, 2), (3, 1), (5, 1), (7, 1)] - sage: [p for p,e in f] + sage: [p for p,e in f] # optional - sage.libs.pari [2, 3, 5, 7] - sage: [e for p,e in f] + sage: [e for p,e in f] # optional - sage.libs.pari [2, 1, 1, 1] - sage: [p^e for p,e in f] + sage: [p^e for p,e in f] # optional - sage.libs.pari [4, 3, 5, 7] We can factor Python, numpy and gmpy2 numbers:: sage: factor(math.pi) 3.141592653589793 - sage: import numpy - sage: factor(numpy.int8(30)) + sage: import numpy # optional - numpy + sage: factor(numpy.int8(30)) # optional - numpy sage.libs.pari 2 * 3 * 5 sage: import gmpy2 - sage: factor(gmpy2.mpz(30)) + sage: factor(gmpy2.mpz(30)) # optional - sage.libs.pari 2 * 3 * 5 TESTS:: @@ -2704,14 +2703,14 @@ def radical(n, *args, **kwds): Traceback (most recent call last): ... ArithmeticError: radical of 0 is not defined - sage: K. = QuadraticField(-1) - sage: radical(K(2)) + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: radical(K(2)) # optional - sage.rings.number_field i + 1 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: radical(int8(50)) + sage: from numpy import int8 # optional - numpy + sage: radical(int8(50)) # optional - numpy 10 sage: from gmpy2 import mpz sage: radical(mpz(50)) @@ -2764,13 +2763,13 @@ def prime_divisors(n): For polynomials we get all irreducible factors:: sage: R. = PolynomialRing(QQ) - sage: prime_divisors(x^12 - 1) + sage: prime_divisors(x^12 - 1) # optional - sage.libs.pari [x - 1, x + 1, x^2 - x + 1, x^2 + 1, x^2 + x + 1, x^4 - x^2 + 1] Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: prime_divisors(int8(-100)) + sage: from numpy import int8 # optional - numpy + sage: prime_divisors(int8(-100)) # optional - numpy [2, 5] sage: from gmpy2 import mpz sage: prime_divisors(mpz(-100)) @@ -2802,8 +2801,8 @@ def odd_part(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: odd_part(int8(5)) + sage: from numpy import int8 # optional - numpy + sage: odd_part(int8(5)) # optional - numpy 5 sage: from gmpy2 import mpz sage: odd_part(mpz(5)) @@ -2846,8 +2845,8 @@ def prime_to_m_part(n, m): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: prime_to_m_part(int16(240), int16(2)) + sage: from numpy import int16 # optional - numpy + sage: prime_to_m_part(int16(240), int16(2)) # optional - numpy 15 sage: from gmpy2 import mpz sage: prime_to_m_part(mpz(240), mpz(2)) @@ -2902,8 +2901,8 @@ def is_square(n, root=False): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: is_square(int8(4)) + sage: from numpy import int8 # optional - numpy + sage: is_square(int8(4)) # optional - numpy True sage: from gmpy2 import mpz sage: is_square(mpz(4)) @@ -2941,47 +2940,47 @@ def is_squarefree(n): EXAMPLES:: - sage: is_squarefree(100) + sage: is_squarefree(100) # optional - sage.libs.pari False - sage: is_squarefree(101) + sage: is_squarefree(101) # optional - sage.libs.pari True sage: R = ZZ['x'] sage: x = R.gen() - sage: is_squarefree((x^2+x+1) * (x-2)) + sage: is_squarefree((x^2+x+1) * (x-2)) # optional - sage.libs.pari True - sage: is_squarefree((x-1)**2 * (x-3)) + sage: is_squarefree((x-1)**2 * (x-3)) # optional - sage.libs.pari False - sage: O = ZZ[sqrt(-1)] - sage: I = O.gen(1) - sage: is_squarefree(I+1) + sage: O = ZZ[sqrt(-1)] # optional - sage.rings.number_field sage.symbolic + sage: I = O.gen(1) # optional - sage.rings.number_field sage.symbolic + sage: is_squarefree(I + 1) # optional - sage.rings.number_field sage.symbolic True - sage: is_squarefree(O(2)) + sage: is_squarefree(O(2)) # optional - sage.rings.number_field sage.symbolic False - sage: O(2).factor() + sage: O(2).factor() # optional - sage.rings.number_field sage.symbolic (-I) * (I + 1)^2 This method fails on domains which are not Unique Factorization Domains:: - sage: O = ZZ[sqrt(-5)] - sage: a = O.gen(1) - sage: is_squarefree(a - 3) + sage: O = ZZ[sqrt(-5)] # optional - sage.rings.number_field sage.symbolic + sage: a = O.gen(1) # optional - sage.rings.number_field sage.symbolic + sage: is_squarefree(a - 3) # optional - sage.rings.number_field sage.symbolic Traceback (most recent call last): ... ArithmeticError: non-principal ideal in factorization Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: is_squarefree(int8(100)) + sage: from numpy import int8 # optional - numpy + sage: is_squarefree(int8(100)) # optional - numpy # optional - sage.libs.pari False - sage: is_squarefree(int8(101)) + sage: is_squarefree(int8(101)) # optional - numpy # optional - sage.libs.pari True sage: from gmpy2 import mpz - sage: is_squarefree(mpz(100)) + sage: is_squarefree(mpz(100)) # optional - sage.libs.pari False - sage: is_squarefree(mpz(101)) + sage: is_squarefree(mpz(101)) # optional - sage.libs.pari True """ e = py_scalar_to_element(n) @@ -3018,11 +3017,11 @@ class Euler_Phi: 1 sage: euler_phi(2) 1 - sage: euler_phi(3) + sage: euler_phi(3) # optional - sage.libs.pari 2 - sage: euler_phi(12) + sage: euler_phi(12) # optional - sage.libs.pari 4 - sage: euler_phi(37) + sage: euler_phi(37) # optional - sage.libs.pari 36 Notice that euler_phi is defined to be 0 on negative numbers and @@ -3041,7 +3040,7 @@ class Euler_Phi: :: - sage: euler_phi(21) + sage: euler_phi(21) # optional - sage.libs.pari 12 sage: [i for i in range(21) if gcd(21,i) == 1] [1, 2, 4, 5, 8, 10, 11, 13, 16, 17, 19, 20] @@ -3051,22 +3050,22 @@ class Euler_Phi: :: - sage: len([i for i in range(21) if gcd(21,i) == 1]) == euler_phi(21) + sage: len([i for i in range(21) if gcd(21,i) == 1]) == euler_phi(21) # optional - sage.libs.pari True The phi function also has a special plotting method. :: - sage: P = plot(euler_phi, -3, 71) + sage: P = plot(euler_phi, -3, 71) # optional - sage.libs.pari sage.plot Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: euler_phi(int8(37)) + sage: from numpy import int8 # optional - numpy + sage: euler_phi(int8(37)) # optional - numpy sage.libs.pari sage.plot 36 sage: from gmpy2 import mpz - sage: euler_phi(mpz(37)) + sage: euler_phi(mpz(37)) # optional - sage.libs.pari sage.plot 36 AUTHORS: @@ -3094,9 +3093,9 @@ def __call__(self, n): EXAMPLES:: sage: from sage.arith.misc import Euler_Phi - sage: Euler_Phi()(10) + sage: Euler_Phi()(10) # optional - sage.libs.pari 4 - sage: Euler_Phi()(720) + sage: Euler_Phi()(720) # optional - sage.libs.pari 192 """ if n <= 0: @@ -3130,8 +3129,8 @@ def plot(self, xmin=1, xmax=50, pointsize=30, rgbcolor=(0, 0, 1), EXAMPLES:: sage: from sage.arith.misc import Euler_Phi - sage: p = Euler_Phi().plot() - sage: p.ymax() + sage: p = Euler_Phi().plot() # optional - sage.plot + sage: p.ymax() # optional - sage.plot 46.0 """ v = [(n, euler_phi(n)) for n in range(xmin, xmax + 1)] @@ -3187,7 +3186,7 @@ def carmichael_lambda(n): The Carmichael function of the first ten primes:: - sage: list(map(carmichael_lambda, primes_first_n(10))) + sage: list(map(carmichael_lambda, primes_first_n(10))) # optional - sage.libs.pari [1, 2, 4, 6, 10, 12, 16, 18, 22, 28] Cases where the Carmichael function is equivalent to the Euler phi @@ -3195,19 +3194,19 @@ def carmichael_lambda(n): sage: carmichael_lambda(2) == euler_phi(2) True - sage: carmichael_lambda(4) == euler_phi(4) + sage: carmichael_lambda(4) == euler_phi(4) # optional - sage.libs.pari True sage: p = random_prime(1000, lbound=3, proof=True) sage: k = randint(1, 1000) - sage: carmichael_lambda(p^k) == euler_phi(p^k) + sage: carmichael_lambda(p^k) == euler_phi(p^k) # optional - sage.libs.pari True A case where `\lambda(n) \neq \varphi(n)`:: sage: k = randint(3, 1000) - sage: carmichael_lambda(2^k) == 2^(k - 2) + sage: carmichael_lambda(2^k) == 2^(k - 2) # optional - sage.libs.pari True - sage: carmichael_lambda(2^k) == 2^(k - 2) == euler_phi(2^k) + sage: carmichael_lambda(2^k) == 2^(k - 2) == euler_phi(2^k) # optional - sage.libs.pari False Verifying the current implementation of the Carmichael function using @@ -3217,7 +3216,7 @@ def carmichael_lambda(n): sage: from sage.arith.misc import carmichael_lambda sage: n = randint(1, 500) - sage: c = carmichael_lambda(n) + sage: c = carmichael_lambda(n) # optional - sage.libs.pari sage: def coprime(n): ....: return [i for i in range(n) if gcd(i, n) == 1] sage: def znpower(n, k): @@ -3232,7 +3231,7 @@ def carmichael_lambda(n): ....: T = [L[i] == ones[i] for i in range(len(L))] ....: if all(T): ....: return k - sage: c == my_carmichael(n) + sage: c == my_carmichael(n) # optional - sage.libs.pari True Carmichael's theorem states that `a^{\lambda(n)} \equiv 1 \pmod{n}` @@ -3241,12 +3240,12 @@ def carmichael_lambda(n): sage: from sage.arith.misc import carmichael_lambda sage: n = randint(2, 1000) - sage: c = carmichael_lambda(n) + sage: c = carmichael_lambda(n) # optional - sage.libs.pari sage: ZnZ = IntegerModRing(n) sage: M = ZnZ.list_of_elements_of_multiplicative_group() sage: ones = [1] * len(M) - sage: P = [power_mod(a, c, n) for a in M] - sage: P == ones + sage: P = [power_mod(a, c, n) for a in M] # optional - sage.libs.pari + sage: P == ones # optional - sage.libs.pari True TESTS: @@ -3266,7 +3265,7 @@ def carmichael_lambda(n): Bug reported in :trac:`8283`:: sage: from sage.arith.misc import carmichael_lambda - sage: type(carmichael_lambda(16)) + sage: type(carmichael_lambda(16)) # optional - sage.libs.pari REFERENCES: @@ -3348,33 +3347,33 @@ def crt(a, b, m=None, n=None): Note that this also works for polynomial rings:: sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^3 - 7) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: f = y^2 + 3 # optional - sage.rings.number_field - sage: g = y^3 - 5 # optional - sage.rings.number_field - sage: CRT(1, 3, f, g) # optional - sage.rings.number_field + sage: K. = NumberField(x^3 - 7) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: f = y^2 + 3 # optional - sage.rings.number_field + sage: g = y^3 - 5 # optional - sage.rings.number_field + sage: CRT(1, 3, f, g) # optional - sage.rings.number_field -3/26*y^4 + 5/26*y^3 + 15/26*y + 53/26 - sage: CRT(1,a,f,g) + sage: CRT(1, a, f, g) # optional - sage.rings.number_field (-3/52*a + 3/52)*y^4 + (5/52*a - 5/52)*y^3 + (15/52*a - 15/52)*y + 27/52*a + 25/52 You can also do this for any number of moduli:: - sage: K. = NumberField(x^3 - 7) - sage: R. = K[] - sage: CRT([], []) + sage: K. = NumberField(x^3 - 7) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: CRT([], []) # optional - sage.rings.number_field 0 - sage: CRT([a], [x]) + sage: CRT([a], [x]) # optional - sage.rings.number_field a - sage: f = x^2 + 3 - sage: g = x^3 - 5 - sage: h = x^5 + x^2 - 9 - sage: k = CRT([1, a, 3], [f, g, h]); k + sage: f = x^2 + 3 # optional - sage.rings.number_field + sage: g = x^3 - 5 # optional - sage.rings.number_field + sage: h = x^5 + x^2 - 9 # optional - sage.rings.number_field + sage: k = CRT([1, a, 3], [f, g, h]); k # optional - sage.rings.number_field (127/26988*a - 5807/386828)*x^9 + (45/8996*a - 33677/1160484)*x^8 + (2/173*a - 6/173)*x^7 + (133/6747*a - 5373/96707)*x^6 + (-6/2249*a + 18584/290121)*x^5 + (-277/8996*a + 38847/386828)*x^4 + (-135/4498*a + 42673/193414)*x^3 + (-1005/8996*a + 470245/1160484)*x^2 + (-1215/8996*a + 141165/386828)*x + 621/8996*a + 836445/386828 - sage: k.mod(f) + sage: k.mod(f) # optional - sage.rings.number_field 1 - sage: k.mod(g) + sage: k.mod(g) # optional - sage.rings.number_field a - sage: k.mod(h) + sage: k.mod(h) # optional - sage.rings.number_field 3 If the moduli are not coprime, a solution may not exist:: @@ -3401,13 +3400,13 @@ def crt(a, b, m=None, n=None): crt also work with numpy and gmpy2 numbers:: - sage: import numpy - sage: crt(numpy.int8(2), numpy.int8(3), numpy.int8(7), numpy.int8(11)) + sage: import numpy # optional - numpy + sage: crt(numpy.int8(2), numpy.int8(3), numpy.int8(7), numpy.int8(11)) # optional - numpy 58 sage: from gmpy2 import mpz sage: crt(mpz(2), mpz(3), mpz(7), mpz(11)) 58 - sage: crt(mpz(2), 3, mpz(7), numpy.int8(11)) + sage: crt(mpz(2), 3, mpz(7), numpy.int8(11)) # optional - numpy 58 """ if isinstance(a, list): @@ -3494,8 +3493,8 @@ def CRT_list(values, moduli): sage: CRT([32r,2r,2r],[60r,90r,150r]) 452 - sage: from numpy import int8 - sage: CRT_list([int8(2),int8(3),int8(2)], [int8(3),int8(5),int8(7)]) + sage: from numpy import int8 # optional - numpy + sage: CRT_list([int8(2), int8(3), int8(2)], [int8(3), int8(5), int8(7)]) # optional - numpy 23 sage: from gmpy2 import mpz sage: CRT_list([mpz(2),mpz(3),mpz(2)], [mpz(3),mpz(5),mpz(7)]) @@ -3599,7 +3598,7 @@ def CRT_vectors(X, moduli): sage: CRT_vectors([[3,5,7],[3,5,11]], [2,3]) [3, 5, 5] - sage: CRT_vectors([vector(ZZ, [2,3,1]), Sequence([1,7,8],ZZ)], [8,9]) + sage: CRT_vectors([vector(ZZ, [2,3,1]), Sequence([1,7,8], ZZ)], [8,9]) # optional - sage.modules [10, 43, 17] """ # First find the CRT basis: @@ -3645,7 +3644,7 @@ def binomial(x, m, **kwds): 10 sage: binomial(2,0) 1 - sage: binomial(1/2, 0) + sage: binomial(1/2, 0) # optional - sage.libs.pari 1 sage: binomial(3,-1) 0 @@ -3657,11 +3656,11 @@ def binomial(x, m, **kwds): 0 sage: binomial(RealField()('2.5'), 2) 1.87500000000000 - sage: n=var('n'); binomial(n,2) + sage: n = var('n'); binomial(n, 2) # optional - sage.symbolic 1/2*(n - 1)*n - sage: n=var('n'); binomial(n,n) + sage: n = var('n'); binomial(n, n) # optional - sage.symbolic 1 - sage: n=var('n'); binomial(n,n-1) + sage: n = var('n'); binomial(n, n-1) # optional - sage.symbolic n sage: binomial(2^100, 2^100) 1 @@ -3690,13 +3689,13 @@ def binomial(x, m, **kwds): We test conversion of arguments to Integers -- see :trac:`6870`:: - sage: binomial(1/2,1/1) + sage: binomial(1/2, 1/1) 1/2 - sage: binomial(10^20+1/1,10^20) + sage: binomial(10^20 + 1/1, 10^20) 100000000000000000001 - sage: binomial(SR(10**7),10**7) + sage: binomial(SR(10**7), 10**7) # optional - sage.symbolic 1 - sage: binomial(3/2,SR(1/1)) + sage: binomial(3/2, SR(1/1)) # optional - sage.symbolic 3/2 Some floating point cases -- see :trac:`7562`, :trac:`9633`, and @@ -3761,8 +3760,8 @@ def binomial(x, m, **kwds): ... TypeError: either m or x-m must be an integer - sage: k, i = var('k,i') - sage: binomial(k,i) + sage: k, i = var('k,i') # optional - sage.symbolic + sage: binomial(k,i) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: either m or x-m must be an integer @@ -3799,15 +3798,15 @@ def binomial(x, m, **kwds): :func:`~sage.functions.other.binomial` from the module :mod:`sage.functions.other`:: - sage: from sage.functions.other import binomial - sage: binomial(k, i) + sage: from sage.functions.other import binomial # optional - sage.symbolic + sage: binomial(k, i) # optional - sage.symbolic binomial(k, i) binomial support numpy and gmpy2 parameters:: sage: from sage.arith.misc import binomial - sage: import numpy - sage: binomial(numpy.int32(20), numpy.int32(10)) + sage: import numpy # optional - numpy + sage: binomial(numpy.int32(20), numpy.int32(10)) # optional - numpy 184756 sage: import gmpy2 sage: binomial(gmpy2.mpz(20), gmpy2.mpz(10)) @@ -3888,17 +3887,17 @@ def multinomial(*ks): 618970023101454657175683075 sage: multinomial([2^30, 2, 1]) 618970023101454657175683075 - sage: multinomial(Composition([1, 3])) + sage: multinomial(Composition([1, 3])) # optional - sage.combinat 4 - sage: multinomial(Partition([4, 2])) + sage: multinomial(Partition([4, 2])) # optional - sage.combinat 15 TESTS: Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: multinomial(int8(3), int8(2)) + sage: from numpy import int8 # optional - numpy + sage: multinomial(int8(3), int8(2)) # optional - numpy 10 sage: from gmpy2 import mpz sage: multinomial(mpz(3), mpz(2)) @@ -3954,8 +3953,8 @@ def binomial_coefficients(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: sorted(binomial_coefficients(int8(3)).items()) + sage: from numpy import int8 # optional - numpy + sage: sorted(binomial_coefficients(int8(3)).items()) # optional - numpy [((0, 3), 1), ((1, 2), 3), ((2, 1), 3), ((3, 0), 1)] sage: from gmpy2 import mpz sage: sorted(binomial_coefficients(mpz(3)).items()) @@ -4031,8 +4030,8 @@ def multinomial_coefficients(m, n): {(): 1} sage: multinomial_coefficients(0, 3) {} - sage: from numpy import int8 - sage: sorted(multinomial_coefficients(int8(2), int8(5)).items()) + sage: from numpy import int8 # optional - numpy + sage: sorted(multinomial_coefficients(int8(2), int8(5)).items()) # optional - numpy [((0, 5), 1), ((1, 4), 5), ((2, 3), 10), ((3, 2), 10), ((4, 1), 5), ((5, 0), 1)] sage: from gmpy2 import mpz sage: sorted(multinomial_coefficients(mpz(2), mpz(5)).items()) @@ -4120,8 +4119,8 @@ def kronecker_symbol(x,y): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: kronecker_symbol(int8(13),int8(21)) + sage: from numpy import int8 # optional - numpy + sage: kronecker_symbol(int8(13),int8(21)) # optional - numpy -1 sage: from gmpy2 import mpz sage: kronecker_symbol(mpz(13),mpz(21)) @@ -4172,8 +4171,8 @@ def legendre_symbol(x, p): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: legendre_symbol(int8(2),int8(3)) + sage: from numpy import int8 # optional - numpy + sage: legendre_symbol(int8(2), int8(3)) # optional - numpy -1 sage: from gmpy2 import mpz sage: legendre_symbol(mpz(2),mpz(3)) @@ -4228,8 +4227,8 @@ def jacobi_symbol(a, b): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: jacobi_symbol(int16(10),int16(777)) + sage: from numpy import int16 # optional - numpy + sage: jacobi_symbol(int16(10), int16(777)) # optional - numpy -1 sage: from gmpy2 import mpz sage: jacobi_symbol(mpz(10),mpz(777)) @@ -4264,15 +4263,15 @@ def primitive_root(n, check=True): EXAMPLES:: - sage: primitive_root(23) + sage: primitive_root(23) # optional - sage.libs.pari 5 - sage: primitive_root(-46) + sage: primitive_root(-46) # optional - sage.libs.pari 5 - sage: primitive_root(25) + sage: primitive_root(25) # optional - sage.libs.pari 2 - sage: print([primitive_root(p) for p in primes(100)]) + sage: print([primitive_root(p) for p in primes(100)]) # optional - sage.libs.pari [1, 2, 2, 3, 2, 2, 3, 2, 5, 2, 3, 2, 6, 3, 5, 2, 2, 2, 2, 7, 5, 3, 2, 3, 5] - sage: primitive_root(8) + sage: primitive_root(8) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root @@ -4288,57 +4287,57 @@ def primitive_root(n, check=True): :: sage: n = 10^50 + 151 # a prime - sage: primitive_root(n) + sage: primitive_root(n) # optional - sage.libs.pari 11 - sage: primitive_root(n, check=False) + sage: primitive_root(n, check=False) # optional - sage.libs.pari 11 TESTS: Various special cases:: - sage: primitive_root(-1) + sage: primitive_root(-1) # optional - sage.libs.pari 0 - sage: primitive_root(0) + sage: primitive_root(0) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root - sage: primitive_root(1) + sage: primitive_root(1) # optional - sage.libs.pari 0 - sage: primitive_root(2) + sage: primitive_root(2) # optional - sage.libs.pari 1 - sage: primitive_root(3) + sage: primitive_root(3) # optional - sage.libs.pari 2 - sage: primitive_root(4) + sage: primitive_root(4) # optional - sage.libs.pari 3 We test that various numbers without primitive roots give an error - see :trac:`10836`:: - sage: primitive_root(15) + sage: primitive_root(15) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root - sage: primitive_root(16) + sage: primitive_root(16) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root - sage: primitive_root(1729) + sage: primitive_root(1729) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root - sage: primitive_root(4*7^8) + sage: primitive_root(4*7^8) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: primitive_root(int8(-46)) + sage: from numpy import int8 # optional - numpy + sage: primitive_root(int8(-46)) # optional - numpy sage.libs.pari 5 sage: from gmpy2 import mpz - sage: primitive_root(mpz(-46)) + sage: primitive_root(mpz(-46)) # optional - sage.libs.pari 5 """ from sage.libs.pari.all import pari @@ -4374,29 +4373,29 @@ def nth_prime(n): EXAMPLES:: - sage: nth_prime(3) + sage: nth_prime(3) # optional - sage.libs.pari 5 - sage: nth_prime(10) + sage: nth_prime(10) # optional - sage.libs.pari 29 - sage: nth_prime(10^7) + sage: nth_prime(10^7) # optional - sage.libs.pari 179424673 :: - sage: nth_prime(0) + sage: nth_prime(0) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: nth prime meaningless for non-positive n (=0) TESTS:: - sage: all(prime_pi(nth_prime(j)) == j for j in range(1, 1000, 10)) + sage: all(prime_pi(nth_prime(j)) == j for j in range(1, 1000, 10)) # optional - sage.libs.pari True - sage: from numpy import int8 - sage: nth_prime(int8(10)) + sage: from numpy import int8 # optional - numpy + sage: nth_prime(int8(10)) # optional - numpy sage.libs.pari 29 sage: from gmpy2 import mpz - sage: nth_prime(mpz(10)) + sage: nth_prime(mpz(10)) # optional - sage.libs.pari 29 """ if n <= 0: @@ -4427,8 +4426,8 @@ def quadratic_residues(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: quadratic_residues(int8(11)) + sage: from numpy import int8 # optional - numpy + sage: quadratic_residues(int8(11)) # optional - numpy [0, 1, 3, 4, 5, 9] sage: from gmpy2 import mpz sage: quadratic_residues(mpz(11)) @@ -4462,39 +4461,39 @@ class Moebius: EXAMPLES:: - sage: moebius(-5) + sage: moebius(-5) # optional - sage.libs.pari -1 - sage: moebius(9) + sage: moebius(9) # optional - sage.libs.pari 0 - sage: moebius(12) + sage: moebius(12) # optional - sage.libs.pari 0 - sage: moebius(-35) + sage: moebius(-35) # optional - sage.libs.pari 1 - sage: moebius(-1) + sage: moebius(-1) # optional - sage.libs.pari 1 - sage: moebius(7) + sage: moebius(7) # optional - sage.libs.pari -1 :: - sage: moebius(0) # potentially nonstandard! + sage: moebius(0) # potentially nonstandard! # optional - sage.libs.pari 0 The moebius function even makes sense for non-integer inputs. :: - sage: x = GF(7)['x'].0 - sage: moebius(x+2) + sage: x = GF(7)['x'].0 # optional - sage.libs.pari + sage: moebius(x + 2) # optional - sage.libs.pari -1 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: moebius(int8(-5)) + sage: from numpy import int8 # optional - numpy + sage: moebius(int8(-5)) # optional - numpy sage.libs.pari -1 sage: from gmpy2 import mpz - sage: moebius(mpz(-5)) + sage: moebius(mpz(-5)) # optional - sage.libs.pari -1 """ def __call__(self, n): @@ -4502,7 +4501,7 @@ def __call__(self, n): EXAMPLES:: sage: from sage.arith.misc import Moebius - sage: Moebius().__call__(7) + sage: Moebius().__call__(7) # optional - sage.libs.pari -1 """ n = py_scalar_to_element(n) @@ -4560,8 +4559,8 @@ def plot(self, xmin=0, xmax=50, pointsize=30, rgbcolor=(0,0,1), join=True, EXAMPLES:: sage: from sage.arith.misc import Moebius - sage: p = Moebius().plot() - sage: p.ymax() + sage: p = Moebius().plot() # optional - sage.plot + sage: p.ymax() # optional - sage.plot 1.0 """ values = self.range(xmin, xmax + 1) @@ -4583,12 +4582,12 @@ def range(self, start, stop=None, step=None): EXAMPLES:: - sage: v = moebius.range(-10,10); v + sage: v = moebius.range(-10, 10); v # optional - sage.libs.pari [1, 0, 0, -1, 1, -1, 0, -1, -1, 1, 0, 1, -1, -1, 0, -1, 1, -1, 0, 0] - sage: v == [moebius(n) for n in range(-10,10)] + sage: v == [moebius(n) for n in range(-10, 10)] # optional - sage.libs.pari True - sage: v = moebius.range(-1000, 2000, 4) - sage: v == [moebius(n) for n in range(-1000,2000, 4)] + sage: v = moebius.range(-1000, 2000, 4) # optional - sage.libs.pari + sage: v == [moebius(n) for n in range(-1000, 2000, 4)] # optional - sage.libs.pari True """ if stop is None: @@ -4652,7 +4651,7 @@ def continuant(v, n=None): sage: q = continuant([1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10]) sage: p/q 517656/190435 - sage: continued_fraction([2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10]).convergent(14) + sage: continued_fraction([2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10]).convergent(14) # optional - sage.libs.pari 517656/190435 sage: x = PolynomialRing(RationalField(),'x',5).gens() sage: continuant(x) @@ -4681,8 +4680,8 @@ def continuant(v, n=None): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: continuant([int8(1),int8(2),int8(3)]) + sage: from numpy import int8 # optional - numpy + sage: continuant([int8(1), int8(2), int8(3)]) # optional - numpy 10 sage: from gmpy2 import mpz sage: continuant([mpz(1),mpz(2),mpz(3)]) @@ -4719,18 +4718,18 @@ def number_of_divisors(n): EXAMPLES:: - sage: number_of_divisors(100) + sage: number_of_divisors(100) # optional - sage.libs.pari 9 - sage: number_of_divisors(-720) + sage: number_of_divisors(-720) # optional - sage.libs.pari 30 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: number_of_divisors(int8(100)) + sage: from numpy import int8 # optional - numpy + sage: number_of_divisors(int8(100)) # optional - numpy sage.libs.pari 9 sage: from gmpy2 import mpz - sage: number_of_divisors(mpz(100)) + sage: number_of_divisors(mpz(100)) # optional - sage.libs.pari 9 """ m = ZZ(n) @@ -4768,33 +4767,33 @@ def hilbert_symbol(a, b, p, algorithm="pari"): EXAMPLES:: - sage: hilbert_symbol (-1, -1, -1, algorithm='all') + sage: hilbert_symbol(-1, -1, -1, algorithm='all') # optional - sage.libs.pari -1 - sage: hilbert_symbol (2,3, 5, algorithm='all') + sage: hilbert_symbol(2, 3, 5, algorithm='all') # optional - sage.libs.pari 1 - sage: hilbert_symbol (4, 3, 5, algorithm='all') + sage: hilbert_symbol(4, 3, 5, algorithm='all') # optional - sage.libs.pari 1 - sage: hilbert_symbol (0, 3, 5, algorithm='all') + sage: hilbert_symbol(0, 3, 5, algorithm='all') # optional - sage.libs.pari 0 - sage: hilbert_symbol (-1, -1, 2, algorithm='all') + sage: hilbert_symbol(-1, -1, 2, algorithm='all') # optional - sage.libs.pari -1 - sage: hilbert_symbol (1, -1, 2, algorithm='all') + sage: hilbert_symbol(1, -1, 2, algorithm='all') # optional - sage.libs.pari 1 - sage: hilbert_symbol (3, -1, 2, algorithm='all') + sage: hilbert_symbol(3, -1, 2, algorithm='all') # optional - sage.libs.pari -1 - sage: hilbert_symbol(QQ(-1)/QQ(4), -1, 2) == -1 + sage: hilbert_symbol(QQ(-1)/QQ(4), -1, 2) == -1 # optional - sage.libs.pari True - sage: hilbert_symbol(QQ(-1)/QQ(4), -1, 3) == 1 + sage: hilbert_symbol(QQ(-1)/QQ(4), -1, 3) == 1 # optional - sage.libs.pari True Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: hilbert_symbol(int8(2),int8(3),int8(5),algorithm='all') + sage: from numpy import int8 # optional - numpy + sage: hilbert_symbol(int8(2), int8(3), int8(5), algorithm='all') # optional - numpy sage.libs.pari 1 sage: from gmpy2 import mpz - sage: hilbert_symbol(mpz(2),mpz(3),mpz(5),algorithm='all') + sage: hilbert_symbol(mpz(2), mpz(3), mpz(5), algorithm='all') # optional - sage.libs.pari 1 AUTHORS: @@ -4873,22 +4872,22 @@ def hilbert_conductor(a, b): EXAMPLES:: - sage: hilbert_conductor(-1, -1) + sage: hilbert_conductor(-1, -1) # optional - sage.libs.pari 2 - sage: hilbert_conductor(-1, -11) + sage: hilbert_conductor(-1, -11) # optional - sage.libs.pari 11 - sage: hilbert_conductor(-2, -5) + sage: hilbert_conductor(-2, -5) # optional - sage.libs.pari 5 - sage: hilbert_conductor(-3, -17) + sage: hilbert_conductor(-3, -17) # optional - sage.libs.pari 17 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: hilbert_conductor(int8(-3), int8(-17)) + sage: from numpy import int8 # optional - numpy + sage: hilbert_conductor(int8(-3), int8(-17)) # optional - numpy sage.libs.pari 17 sage: from gmpy2 import mpz - sage: hilbert_conductor(mpz(-3), mpz(-17)) + sage: hilbert_conductor(mpz(-3), mpz(-17)) # optional - sage.libs.pari 17 AUTHOR: @@ -4916,19 +4915,19 @@ def hilbert_conductor_inverse(d): EXAMPLES:: - sage: hilbert_conductor_inverse(2) + sage: hilbert_conductor_inverse(2) # optional - sage.libs.pari (-1, -1) - sage: hilbert_conductor_inverse(3) + sage: hilbert_conductor_inverse(3) # optional - sage.libs.pari (-1, -3) - sage: hilbert_conductor_inverse(6) + sage: hilbert_conductor_inverse(6) # optional - sage.libs.pari (-1, 3) - sage: hilbert_conductor_inverse(30) + sage: hilbert_conductor_inverse(30) # optional - sage.libs.pari (-3, -10) - sage: hilbert_conductor_inverse(4) + sage: hilbert_conductor_inverse(4) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: d needs to be squarefree - sage: hilbert_conductor_inverse(-1) + sage: hilbert_conductor_inverse(-1) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: d needs to be positive @@ -4939,18 +4938,18 @@ def hilbert_conductor_inverse(d): TESTS:: - sage: for i in range(100): + sage: for i in range(100): # optional - sage.libs.pari ....: d = ZZ.random_element(2**32).squarefree_part() ....: if hilbert_conductor(*hilbert_conductor_inverse(d)) != d: ....: print("hilbert_conductor_inverse failed for d = {}".format(d)) Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: hilbert_conductor_inverse(int8(30)) + sage: from numpy import int8 # optional - numpy + sage: hilbert_conductor_inverse(int8(30)) # optional - numpy sage.libs.pari (-3, -10) sage: from gmpy2 import mpz - sage: hilbert_conductor_inverse(mpz(30)) + sage: hilbert_conductor_inverse(mpz(30)) # optional - sage.libs.pari (-3, -10) """ Z = ZZ @@ -5026,17 +5025,17 @@ def falling_factorial(x, a): sage: falling_factorial(10, 3) 720 - sage: falling_factorial(10, RR('3.0')) + sage: falling_factorial(10, RR('3.0')) # optional - sage.symbolic 720.000000000000 - sage: falling_factorial(10, RR('3.3')) + sage: falling_factorial(10, RR('3.3')) # optional - sage.symbolic 1310.11633396601 sage: falling_factorial(10, 10) 3628800 sage: factorial(10) 3628800 - sage: a = falling_factorial(1+I, I); a + sage: a = falling_factorial(1+I, I); a # optional - sage.symbolic gamma(I + 2) - sage: CC(a) + sage: CC(a) # optional - sage.symbolic 0.652965496420167 + 0.343065839816545*I sage: falling_factorial(1+I, 4) 4*I + 2 @@ -5059,13 +5058,13 @@ def falling_factorial(x, a): Check that :trac:`14858` is fixed:: - sage: falling_factorial(-4, SR(2)) + sage: falling_factorial(-4, SR(2)) # optional - sage.symbolic 20 Check that :trac:`16770` is fixed:: - sage: d = var('d') - sage: parent(falling_factorial(d, 0)) + sage: d = var('d') # optional - sage.symbolic + sage: parent(falling_factorial(d, 0)) # optional - sage.symbolic Symbolic Ring Check that :trac:`20075` is fixed:: @@ -5075,8 +5074,8 @@ def falling_factorial(x, a): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: falling_factorial(int8(10), int8(3)) + sage: from numpy import int8 # optional - numpy + sage: falling_factorial(int8(10), int8(3)) # optional - numpy 720 sage: from gmpy2 import mpz sage: falling_factorial(mpz(10), mpz(3)) @@ -5151,7 +5150,7 @@ def rising_factorial(x, a): Check that :trac:`14858` is fixed:: - sage: bool(rising_factorial(-4, 2) == + sage: bool(rising_factorial(-4, 2) == # optional - sage.symbolic ....: rising_factorial(-4, SR(2)) == ....: rising_factorial(SR(-4), SR(2))) True @@ -5169,8 +5168,8 @@ def rising_factorial(x, a): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: rising_factorial(int8(10), int8(3)) + sage: from numpy import int8 # optional - numpy + sage: rising_factorial(int8(10), int8(3)) # optional - numpy 1320 sage: from gmpy2 import mpz sage: rising_factorial(mpz(10), mpz(3)) @@ -5199,15 +5198,15 @@ def integer_ceil(x): sage: integer_ceil(5.4) 6 - sage: integer_ceil(x) + sage: integer_ceil(x) # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError: computation of ceil of x not implemented Tests with numpy and gmpy2 numbers:: - sage: from numpy import float32 - sage: integer_ceil(float32(5.4)) + sage: from numpy import float32 # optional - numpy + sage: integer_ceil(float32(5.4)) # optional - numpy 6 sage: from gmpy2 import mpfr sage: integer_ceil(mpfr(5.4)) @@ -5245,15 +5244,15 @@ def integer_floor(x): sage: integer_floor(RDF(-5/2)) -3 - sage: integer_floor(x) + sage: integer_floor(x) # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError: computation of floor of x not implemented Tests with numpy and gmpy2 numbers:: - sage: from numpy import float32 - sage: integer_floor(float32(5.4)) + sage: from numpy import float32 # optional - numpy + sage: integer_floor(float32(5.4)) # optional - numpy 5 sage: from gmpy2 import mpfr sage: integer_floor(mpfr(5.4)) @@ -5333,8 +5332,8 @@ def two_squares(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: two_squares(int16(389)) + sage: from numpy import int16 # optional - numpy + sage: two_squares(int16(389)) # optional - numpy (10, 17) sage: from gmpy2 import mpz sage: two_squares(mpz(389)) @@ -5458,8 +5457,8 @@ def three_squares(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: three_squares(int16(389)) + sage: from numpy import int16 # optional - numpy + sage: three_squares(int16(389)) # optional - numpy (1, 8, 18) sage: from gmpy2 import mpz sage: three_squares(mpz(389)) @@ -5590,8 +5589,8 @@ def four_squares(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: four_squares(int16(389)) + sage: from numpy import int16 # optional - numpy + sage: four_squares(int16(389)) # optional - numpy (0, 1, 8, 18) sage: from gmpy2 import mpz sage: four_squares(mpz(389)) @@ -5685,8 +5684,8 @@ def sum_of_k_squares(k, n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 - sage: sum_of_k_squares(int16(2), int16(9634)) + sage: from numpy import int16 # optional - numpy + sage: sum_of_k_squares(int16(2), int16(9634)) # optional - numpy (15, 97) sage: from gmpy2 import mpz sage: sum_of_k_squares(mpz(2), mpz(9634)) @@ -5757,8 +5756,8 @@ def subfactorial(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: subfactorial(int8(8)) + sage: from numpy import int8 # optional - numpy + sage: subfactorial(int8(8)) # optional - numpy 14833 sage: from gmpy2 import mpz sage: subfactorial(mpz(8)) @@ -5798,10 +5797,10 @@ def is_power_of_two(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: is_power_of_two(int8(16)) + sage: from numpy import int8 # optional - numpy + sage: is_power_of_two(int8(16)) # optional - numpy True - sage: is_power_of_two(int8(24)) + sage: is_power_of_two(int8(24)) # optional - numpy False sage: from gmpy2 import mpz sage: is_power_of_two(mpz(16)) @@ -5818,7 +5817,7 @@ def differences(lis, n=1): EXAMPLES:: - sage: differences(prime_range(50)) + sage: differences(prime_range(50)) # optional - sage.libs.pari [1, 2, 2, 4, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4] sage: differences([i^2 for i in range(1,11)]) [3, 5, 7, 9, 11, 13, 15, 17, 19] @@ -5826,13 +5825,13 @@ def differences(lis, n=1): [10, 22, 40, 64, 94, 130, 172, 220, 274, 334, 400, 472, 550, 634, 724, 820, 922, 1030, 1144] sage: differences([i^3 - i^2 for i in range(1,21)], 2) [10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70, 76, 82, 88, 94, 100, 106, 112] - sage: differences([p - i^2 for i, p in enumerate(prime_range(50))], 3) + sage: differences([p - i^2 for i, p in enumerate(prime_range(50))], 3) # optional - sage.libs.pari [-1, 2, -4, 4, -4, 4, 0, -6, 8, -6, 0, 4] Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: differences([int8(1),int8(4),int8(6),int8(19)]) + sage: from numpy import int8 # optional - numpy + sage: differences([int8(1), int8(4), int8(6), int8(19)]) # optional - numpy [3, 2, 13] sage: from gmpy2 import mpz sage: differences([mpz(1),mpz(4),mpz(6),mpz(19)]) @@ -5977,8 +5976,8 @@ def fundamental_discriminant(D): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: fundamental_discriminant(int8(102)) + sage: from numpy import int8 # optional - numpy + sage: fundamental_discriminant(int8(102)) # optional - numpy 408 sage: from gmpy2 import mpz sage: fundamental_discriminant(mpz(102)) @@ -6035,8 +6034,8 @@ def squarefree_divisors(x): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: list(squarefree_divisors(int8(12))) + sage: from numpy import int8 # optional - numpy + sage: list(squarefree_divisors(int8(12))) # optional - numpy [1, 2, 3, 6] sage: from gmpy2 import mpz sage: list(squarefree_divisors(mpz(12))) @@ -6086,7 +6085,7 @@ def dedekind_sum(p, q, algorithm='default'): Several small values:: - sage: for q in range(10): print([dedekind_sum(p,q) for p in range(q+1)]) + sage: for q in range(10): print([dedekind_sum(p,q) for p in range(q+1)]) # optional - sage.libs.flint [0] [0, 0] [0, 0, 0] @@ -6100,44 +6099,44 @@ def dedekind_sum(p, q, algorithm='default'): Check relations for restricted arguments:: - sage: q = 23; dedekind_sum(1, q); (q-1)*(q-2)/(12*q) + sage: q = 23; dedekind_sum(1, q); (q-1)*(q-2)/(12*q) # optional - sage.libs.flint 77/46 77/46 sage: p, q = 100, 723 # must be coprime - sage: dedekind_sum(p, q) + dedekind_sum(q, p) + sage: dedekind_sum(p, q) + dedekind_sum(q, p) # optional - sage.libs.flint 31583/86760 - sage: -1/4 + (p/q + q/p + 1/(p*q))/12 + sage: -1/4 + (p/q + q/p + 1/(p*q))/12 # optional - sage.libs.flint 31583/86760 We check that evaluation works with large input:: - sage: dedekind_sum(3^54 - 1, 2^93 + 1) + sage: dedekind_sum(3^54 - 1, 2^93 + 1) # optional - sage.libs.flint 459340694971839990630374299870/29710560942849126597578981379 - sage: dedekind_sum(3^54 - 1, 2^93 + 1, algorithm='pari') + sage: dedekind_sum(3^54 - 1, 2^93 + 1, algorithm='pari') # optional - sage.libs.pari 459340694971839990630374299870/29710560942849126597578981379 We check consistency of the results:: - sage: dedekind_sum(5, 7, algorithm='default') + sage: dedekind_sum(5, 7, algorithm='default') # optional - sage.libs.flint -1/14 - sage: dedekind_sum(5, 7, algorithm='flint') + sage: dedekind_sum(5, 7, algorithm='flint') # optional - sage.libs.flint -1/14 - sage: dedekind_sum(5, 7, algorithm='pari') + sage: dedekind_sum(5, 7, algorithm='pari') # optional - sage.libs.pari -1/14 - sage: dedekind_sum(6, 8, algorithm='default') + sage: dedekind_sum(6, 8, algorithm='default') # optional - sage.libs.flint -1/8 - sage: dedekind_sum(6, 8, algorithm='flint') + sage: dedekind_sum(6, 8, algorithm='flint') # optional - sage.libs.flint -1/8 - sage: dedekind_sum(6, 8, algorithm='pari') + sage: dedekind_sum(6, 8, algorithm='pari') # optional - sage.libs.pari -1/8 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 - sage: dedekind_sum(int8(5), int8(7), algorithm='default') + sage: from numpy import int8 # optional - numpy + sage: dedekind_sum(int8(5), int8(7), algorithm='default') # optional - numpy sage.libs.flint -1/14 sage: from gmpy2 import mpz - sage: dedekind_sum(mpz(5), mpz(7), algorithm='default') + sage: dedekind_sum(mpz(5), mpz(7), algorithm='default') # optional - sage.libs.flint -1/14 REFERENCES: @@ -6196,45 +6195,45 @@ def gauss_sum(char_value, finite_field): EXAMPLES:: sage: from sage.arith.misc import gauss_sum - sage: F = GF(5); q = 5 - sage: zq = UniversalCyclotomicField().zeta(q-1) - sage: L = [gauss_sum(zq**i,F) for i in range(5)]; L + sage: F = GF(5); q = 5 # optional - sage.libs.pari + sage: zq = UniversalCyclotomicField().zeta(q-1) # optional - sage.libs.pari + sage: L = [gauss_sum(zq**i, F) for i in range(5)]; L # optional - sage.libs.pari [-1, E(20)^4 + E(20)^13 - E(20)^16 - E(20)^17, E(5) - E(5)^2 - E(5)^3 + E(5)^4, E(20)^4 - E(20)^13 - E(20)^16 + E(20)^17, -1] - sage: [g*g.conjugate() for g in L] + sage: [g*g.conjugate() for g in L] # optional - sage.libs.pari [1, 5, 5, 5, 1] - sage: F = GF(11**2); q = 11**2 - sage: zq = UniversalCyclotomicField().zeta(q-1) - sage: g = gauss_sum(zq**4,F) - sage: g*g.conjugate() + sage: F = GF(11**2); q = 11**2 # optional - sage.libs.pari + sage: zq = UniversalCyclotomicField().zeta(q - 1) # optional - sage.libs.pari + sage: g = gauss_sum(zq**4, F) # optional - sage.libs.pari + sage: g*g.conjugate() # optional - sage.libs.pari 121 TESTS:: - sage: F = GF(11); q = 11 - sage: zq = UniversalCyclotomicField().zeta(q-1) - sage: gauss_sum(zq**2,F).n(60) + sage: F = GF(11); q = 11 # optional - sage.libs.pari sage.rings.number_field + sage: zq = UniversalCyclotomicField().zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field + sage: gauss_sum(zq**2, F).n(60) # optional - sage.libs.pari sage.rings.number_field 2.6361055643248352 + 2.0126965627574471*I - sage: zq = QQbar.zeta(q-1) - sage: gauss_sum(zq**2,F) + sage: zq = QQbar.zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field + sage: gauss_sum(zq**2, F) # optional - sage.libs.pari sage.rings.number_field 2.636105564324836? + 2.012696562757447?*I - sage: zq = ComplexField(60).zeta(q-1) - sage: gauss_sum(zq**2,F) + sage: zq = ComplexField(60).zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field + sage: gauss_sum(zq**2, F) # optional - sage.libs.pari sage.rings.number_field 2.6361055643248352 + 2.0126965627574471*I - sage: F = GF(7); q = 7 - sage: zq = QQbar.zeta(q-1) - sage: D = DirichletGroup(7, QQbar) - sage: all(D[i].gauss_sum()==gauss_sum(zq**i,F) for i in range(6)) + sage: F = GF(7); q = 7 # optional - sage.libs.pari sage.rings.number_field + sage: zq = QQbar.zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field + sage: D = DirichletGroup(7, QQbar) # optional - sage.libs.pari sage.rings.number_field + sage: all(D[i].gauss_sum() == gauss_sum(zq**i, F) for i in range(6)) # optional - sage.libs.pari sage.rings.number_field True - sage: gauss_sum(1,QQ) + sage: gauss_sum(1, QQ) Traceback (most recent call last): ... ValueError: second input must be a finite field diff --git a/src/sage/arith/multi_modular.pyx b/src/sage/arith/multi_modular.pyx index 766c9923404..17505583fca 100644 --- a/src/sage/arith/multi_modular.pyx +++ b/src/sage/arith/multi_modular.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - primecountpy """ Utility classes for multi-modular algorithms """ diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index 7e545404de2..27faca1d3fa 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -134,6 +134,53 @@ def __init__(self): [PythonModule('sage.groups.perm_gps.permgroup')]) +class sage__libs__flint(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.flint` + and other modules depending on FLINT and arb. + + EXAMPLES:: + + sage: from sage.features.sagemath import sage__libs__flint + sage: sage__libs__flint().is_present() # optional - sage.libs.flint + FeatureTestResult('sage.libs.flint', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__libs__flint + sage: isinstance(sage__libs__flint(), sage__libs__flint) + True + """ + JoinFeature.__init__(self, 'sage.libs.flint', + [PythonModule('sage.libs.flint.flint'), + PythonModule('sage.libs.arb.arith')]) + + +class sage__libs__ntl(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.ntl` + and other modules depending on NTL and arb. + + EXAMPLES:: + + sage: from sage.features.sagemath import sage__libs__ntl + sage: sage__libs__ntl().is_present() # optional - sage.libs.ntl + FeatureTestResult('sage.libs.ntl', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__libs__ntl + sage: isinstance(sage__libs__ntl(), sage__libs__ntl) + True + """ + JoinFeature.__init__(self, 'sage.libs.ntl', + [PythonModule('sage.libs.ntl.convert')]) + + class sage__libs__pari(JoinFeature): r""" A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.pari`. @@ -290,6 +337,28 @@ def __init__(self): [PythonModule('sage.rings.padics.factory')]) +class sage__rings__polynomial__pbori(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of :mod:`sage.rings.polynomial.pbori`. + + EXAMPLES:: + + sage: from sage.features.sagemath import sage__rings__polynomial__pbori + sage: sage__rings__polynomial__pbori().is_present() # optional - sage.rings.polynomial.pbori + FeatureTestResult('sage.rings.polynomial.pbori', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__rings__polynomial__pbori + sage: isinstance(sage__rings__polynomial__pbori(), sage__rings__polynomial__pbori) + True + """ + JoinFeature.__init__(self, 'sage.rings.polynomial.pbori', + [PythonModule('sage.rings.polynomial.pbori.pbori')]) + + class sage__rings__real_double(PythonModule): r""" A :class:`~sage.features.Feature` describing the presence of :mod:`sage.rings.real_double`. @@ -382,6 +451,8 @@ def all_features(): sage__geometry__polyhedron(), sage__graphs(), sage__groups(), + sage__libs__flint(), + sage__libs__ntl(), sage__libs__pari(), sage__modules(), sage__plot(), @@ -389,6 +460,7 @@ def all_features(): sage__rings__function_field(), sage__rings__number_field(), sage__rings__padics(), + sage__rings__polynomial__pbori(), sage__rings__real_double(), sage__rings__real_mpfr(), sage__symbolic()] diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py index 9407f588848..58c4254c278 100644 --- a/src/sage/misc/functional.py +++ b/src/sage/misc/functional.py @@ -1931,9 +1931,9 @@ def sqrt(x, *args, **kwds): For a non-symbolic square root, there are a few options. The best is to numerically approximate afterward:: - sage: sqrt(2).n() + sage: sqrt(2).n() # optional - sage.symbolic 1.41421356237310 - sage: sqrt(2).n(prec=100) + sage: sqrt(2).n(prec=100) # optional - sage.symbolic 1.4142135623730950488016887242 Or one can input a numerical type:: diff --git a/src/sage/misc/lazy_list.pyx b/src/sage/misc/lazy_list.pyx index 4e25ee39299..fb192443494 100644 --- a/src/sage/misc/lazy_list.pyx +++ b/src/sage/misc/lazy_list.pyx @@ -415,8 +415,9 @@ cdef class lazy_list_generic(): sage: from sage.misc.lazy_list import lazy_list sage: P = lazy_list(Primes()) - sage: P[2:143:5].list() - [5, 19, 41, 61, 83, 107, 137, 163, 191, 223, 241, 271, 307, 337, 367, 397, 431, 457, 487, 521, 563, 593, 617, 647, 677, 719, 751, 787, 823] + sage: P[2:143:5].list() # optional - sage.libs.pari + [5, 19, 41, 61, 83, 107, 137, 163, 191, 223, 241, 271, 307, 337, 367, + 397, 431, 457, 487, 521, 563, 593, 617, 647, 677, 719, 751, 787, 823] sage: P = lazy_list(iter([1,2,3])) sage: P.list() [1, 2, 3] @@ -453,9 +454,9 @@ cdef class lazy_list_generic(): start 10 stop 21474838 step 4 - sage: P[0] + sage: P[0] # optional - sage.libs.pari 31 - sage: P._info() + sage: P._info() # optional - sage.libs.pari cache length 11 start 10 stop 21474838 @@ -858,9 +859,9 @@ cdef class lazy_list_generic(): sage: from sage.misc.lazy_list import lazy_list sage: L = lazy_list(Primes())[2:] - sage: L._update_cache_up_to(4) + sage: L._update_cache_up_to(4) # optional - sage.libs.pari 0 - sage: L._info() + sage: L._info() # optional - sage.libs.pari cache length 5 start 2 stop 9223372036854775807 # 64-bit @@ -885,9 +886,9 @@ cdef class lazy_list_generic(): TESTS:: sage: from sage.misc.lazy_list import lazy_list - sage: L = lazy_list(Primes()); L + sage: L = lazy_list(Primes()); L # optional - sage.libs.pari lazy list [2, 3, 5, ...] - sage: L._get_cache_() + sage: L._get_cache_() # optional - sage.libs.pari [2, 3, 5, 7] """ return self.cache @@ -964,9 +965,9 @@ cdef class lazy_list_from_iterator(lazy_list_generic): sage: from sage.misc.lazy_list import lazy_list sage: L = lazy_list(iter(Primes()))[2:] - sage: L._update_cache_up_to(4) + sage: L._update_cache_up_to(4) # optional - sage.libs.pari 0 - sage: L._info() + sage: L._info() # optional - sage.libs.pari cache length 5 start 2 stop 9223372036854775807 # 64-bit @@ -1015,9 +1016,9 @@ cdef class lazy_list_from_function(lazy_list_generic): EXAMPLES:: sage: from sage.misc.lazy_list import lazy_list_from_function - sage: lazy_list_from_function(euler_phi) + sage: lazy_list_from_function(euler_phi) # optional - sage.libs.pari lazy list [0, 1, 1, ...] - sage: lazy_list_from_function(divisors, [None]) + sage: lazy_list_from_function(divisors, [None]) # optional - sage.libs.pari lazy list [None, [1], [1, 2], ...] TESTS:: @@ -1064,9 +1065,9 @@ cdef class lazy_list_from_function(lazy_list_generic): TESTS:: sage: from sage.misc.lazy_list import lazy_list_from_function - sage: loads(dumps(lazy_list_from_function(euler_phi))) + sage: loads(dumps(lazy_list_from_function(euler_phi))) # optional - sage.libs.pari lazy list [0, 1, 1, ...] - sage: loads(dumps(lazy_list_from_function(divisors, [None]))) + sage: loads(dumps(lazy_list_from_function(divisors, [None]))) # optional - sage.libs.pari lazy list [None, [1], [1, 2], ...] """ if self.start != 0 or self.step != 1: diff --git a/src/sage/misc/prandom.py b/src/sage/misc/prandom.py index 751d5b35129..19662a47adb 100644 --- a/src/sage/misc/prandom.py +++ b/src/sage/misc/prandom.py @@ -142,9 +142,9 @@ def choice(seq): EXAMPLES:: - sage: s = [choice(list(primes(10, 100))) for i in range(5)]; s # random + sage: s = [choice(list(primes(10, 100))) for i in range(5)]; s # random # optional - sage.libs.pari [17, 47, 11, 31, 47] - sage: all(t in primes(10, 100) for t in s) + sage: all(t in primes(10, 100) for t in s) # optional - sage.libs.pari True """ return _pyrand().choice(seq) @@ -227,9 +227,9 @@ def uniform(a, b): sage: 0.0 <= s <= 1.0 True - sage: s = uniform(e, pi); s # random + sage: s = uniform(e, pi); s # random # optional - sage.symbolic 0.5143475134191677*pi + 0.48565248658083227*e - sage: bool(e <= s <= pi) + sage: bool(e <= s <= pi) # optional - sage.symbolic True """ return _pyrand().uniform(a, b) diff --git a/src/sage/misc/randstate.pyx b/src/sage/misc/randstate.pyx index e9f3db46753..f2f55bc5c2c 100644 --- a/src/sage/misc/randstate.pyx +++ b/src/sage/misc/randstate.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.groups sage.libs.gap sage.libs.ntl sage.libs.pari r""" Random Number States @@ -678,8 +679,8 @@ cdef class randstate: seed the generator itself. However, we put the call in to make the coverage tester happy. :: - sage: current_randstate().set_seed_ntl(False) - sage: ntl.ZZ_random(10^40) + sage: current_randstate().set_seed_ntl(False) # optional - sage.libs.ntl + sage: ntl.ZZ_random(10^40) # optional - sage.libs.ntl 1495283511775355459459209288047895196007 """ global _ntl_seed_randstate @@ -698,10 +699,10 @@ cdef class randstate: EXAMPLES:: sage: set_random_seed(99900000999) - sage: current_randstate().set_seed_gap() - sage: gap.Random(1, 10^50) + sage: current_randstate().set_seed_gap() # optional - sage.libs.gap + sage: gap.Random(1, 10^50) # optional - sage.libs.gap 1496738263332555434474532297768680634540939580077 - sage: gap(35).SCRRandomString() + sage: gap(35).SCRRandomString() # optional - sage.libs.gap [ 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1 ] """ @@ -736,8 +737,8 @@ cdef class randstate: EXAMPLES:: sage: set_random_seed(987654321) - sage: current_randstate().set_seed_gp() - sage: gp.random() + sage: current_randstate().set_seed_gp() # optional - sage.libs.pari + sage: gp.random() # optional - sage.libs.pari 23289294 """ if gp is None: @@ -783,8 +784,8 @@ cdef class randstate: EXAMPLES:: sage: set_random_seed(5551212) - sage: current_randstate().set_seed_pari() - sage: pari.getrand().type() + sage: current_randstate().set_seed_pari() # optional - sage.libs.pari + sage: pari.getrand().type() # optional - sage.libs.pari 't_INT' """ global _pari_seed_randstate diff --git a/src/sage/misc/table.py b/src/sage/misc/table.py index cbd8b083a6b..978a29f65ec 100644 --- a/src/sage/misc/table.py +++ b/src/sage/misc/table.py @@ -170,7 +170,7 @@ class table(SageObject): To generate HTML you should use ``html(table(...))``:: - sage: data = [["$x$", r"$\sin(x)$"]] + [(x,n(sin(x), digits=2)) for x in [0..3]] + sage: data = [["$x$", r"$\sin(x)$"]] + [(x, n(sin(x), digits=2)) for x in [0..3]] # optional - sage.symbolic sage: output = html(table(data, header_row=True, frame=True)) sage: type(output) diff --git a/src/sage/structure/category_object.pyx b/src/sage/structure/category_object.pyx index f20e3fcf884..4a0240e0c70 100644 --- a/src/sage/structure/category_object.pyx +++ b/src/sage/structure/category_object.pyx @@ -270,8 +270,8 @@ cdef class CategoryObject(SageObject): EXAMPLES:: - sage: B. = BooleanPolynomialRing() - sage: B.gens_dict() + sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: B.gens_dict() # optional - sage.rings.polynomial.pbori {'a': a, 'b': b, 'c': c, 'd': d} TESTS:: From dce0625497e82e79df793a3d7159ebe6a8a982ec Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 4 Apr 2023 23:26:34 -0700 Subject: [PATCH 072/205] sage.structure: Doctest cosmetics, add # optional --- src/sage/structure/category_object.pyx | 93 ++--- src/sage/structure/coerce.pyx | 193 ++++++---- src/sage/structure/coerce_dict.pyx | 12 +- src/sage/structure/coerce_maps.pyx | 74 ++-- src/sage/structure/element.pxd | 8 +- src/sage/structure/element.pyx | 385 ++++++++++---------- src/sage/structure/element_wrapper.pyx | 12 +- src/sage/structure/factorization.py | 167 ++++----- src/sage/structure/factory.pyx | 76 ++-- src/sage/structure/formal_sum.py | 33 +- src/sage/structure/global_options.py | 86 ++--- src/sage/structure/indexed_generators.py | 208 +++++------ src/sage/structure/nonexact.py | 2 +- src/sage/structure/parent.pyx | 263 +++++++------ src/sage/structure/parent_gens.pyx | 44 +-- src/sage/structure/parent_old.pyx | 18 +- src/sage/structure/proof/proof.py | 6 +- src/sage/structure/sequence.py | 28 +- src/sage/structure/unique_representation.py | 46 +-- 19 files changed, 917 insertions(+), 837 deletions(-) diff --git a/src/sage/structure/category_object.pyx b/src/sage/structure/category_object.pyx index 4a0240e0c70..8f5edb766e9 100644 --- a/src/sage/structure/category_object.pyx +++ b/src/sage/structure/category_object.pyx @@ -36,14 +36,14 @@ This example illustrates generators for a free module over `\ZZ`. :: - sage: M = FreeModule(ZZ, 4) - sage: M + sage: M = FreeModule(ZZ, 4) # optional - sage.modules + sage: M # optional - sage.modules Ambient free module of rank 4 over the principal ideal domain Integer Ring - sage: M.ngens() + sage: M.ngens() # optional - sage.modules 4 - sage: M.gen(0) + sage: M.gen(0) # optional - sage.modules (1, 0, 0, 0) - sage: M.gens() + sage: M.gens() # optional - sage.modules ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)) """ @@ -270,8 +270,8 @@ cdef class CategoryObject(SageObject): EXAMPLES:: - sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori - sage: B.gens_dict() # optional - sage.rings.polynomial.pbori + sage: B. = BooleanPolynomialRing() # optional - sage.rings.polynomial.pbori + sage: B.gens_dict() # optional - sage.rings.polynomial.pbori {'a': a, 'b': b, 'c': c, 'd': d} TESTS:: @@ -351,16 +351,16 @@ cdef class CategoryObject(SageObject): For orders, we correctly use the ring generator, see :trac:`15348`:: - sage: A. = ZZ.extension(x^2 + 1) - sage: i + sage: A. = ZZ.extension(x^2 + 1) # optional - sage.rings.number_field + sage: i # optional - sage.rings.number_field i - sage: parent(i) + sage: parent(i) # optional - sage.rings.number_field Order in Number Field in i with defining polynomial x^2 + 1 :: - sage: B. = EquationOrder(x^2 + 3) - sage: z.minpoly() + sage: B. = EquationOrder(x^2 + 3) # optional - sage.rings.number_field + sage: z.minpoly() # optional - sage.rings.number_field x^2 + 3 """ return self._defining_names()[:n] @@ -388,18 +388,18 @@ cdef class CategoryObject(SageObject): For orders, we correctly use the ring generator, see :trac:`15348`:: - sage: B. = EquationOrder(x^2 + 3) - sage: B._defining_names() + sage: B. = EquationOrder(x^2 + 3) # optional - sage.rings.number_field + sage: B._defining_names() # optional - sage.rings.number_field (z,) For vector spaces and free modules, we get a basis (which can be different from the given generators):: - sage: V = ZZ^3 - sage: V._defining_names() + sage: V = ZZ^3 # optional - sage.modules + sage: V._defining_names() # optional - sage.modules ((1, 0, 0), (0, 1, 0), (0, 0, 1)) - sage: W = V.span([(0, 1, 0), (1/2, 1, 0)]) - sage: W._defining_names() + sage: W = V.span([(0, 1, 0), (1/2, 1, 0)]) # optional - sage.modules + sage: W._defining_names() # optional - sage.modules ((1/2, 0, 0), (0, 1, 0)) """ return self.gens() @@ -500,10 +500,10 @@ cdef class CategoryObject(SageObject): wants to print elements of the quotient of such an "unnamed" ring, an error resulted. That was fixed in :trac:`11068`:: - sage: MS = MatrixSpace(GF(5),2,2) - sage: I = MS*[MS.0*MS.1,MS.2+MS.3]*MS - sage: Q. = MS.quo(I) - sage: a #indirect doctest + sage: MS = MatrixSpace(GF(5), 2, 2) # optional - sage.rings.finite_rings sage.modules + sage: I = MS * [MS.0*MS.1, MS.2 + MS.3] * MS # optional - sage.rings.finite_rings sage.modules + sage: Q. = MS.quo(I) # optional - sage.rings.finite_rings sage.modules + sage: a #indirect doctest # optional - sage.rings.finite_rings sage.modules [1 0] [0 0] @@ -562,42 +562,42 @@ cdef class CategoryObject(SageObject): EXAMPLES:: - sage: from sage.modules.module import Module - sage: Module(ZZ).base_ring() + sage: from sage.modules.module import Module # optional - sage.modules + sage: Module(ZZ).base_ring() # optional - sage.modules Integer Ring - sage: F = FreeModule(ZZ,3) - sage: F.base_ring() + sage: F = FreeModule(ZZ, 3) # optional - sage.modules + sage: F.base_ring() # optional - sage.modules Integer Ring - sage: F.__class__.base_ring + sage: F.__class__.base_ring # optional - sage.modules Note that the coordinates of the elements of a module can lie in a bigger ring, the ``coordinate_ring``:: - sage: M = (ZZ^2) * (1/2) - sage: v = M([1/2, 0]) - sage: v.base_ring() + sage: M = (ZZ^2) * (1/2) # optional - sage.modules + sage: v = M([1/2, 0]) # optional - sage.modules + sage: v.base_ring() # optional - sage.modules Integer Ring - sage: parent(v[0]) + sage: parent(v[0]) # optional - sage.modules Rational Field - sage: v.coordinate_ring() + sage: v.coordinate_ring() # optional - sage.modules Rational Field More examples:: - sage: F = FreeAlgebra(QQ, 'x') - sage: F.base_ring() + sage: F = FreeAlgebra(QQ, 'x') # optional - sage.combinat sage.modules + sage: F.base_ring() # optional - sage.combinat sage.modules Rational Field - sage: F.__class__.base_ring + sage: F.__class__.base_ring # optional - sage.combinat sage.modules - sage: E = CombinatorialFreeModule(ZZ, [1,2,3]) - sage: F = CombinatorialFreeModule(ZZ, [2,3,4]) - sage: H = Hom(E, F) - sage: H.base_ring() + sage: E = CombinatorialFreeModule(ZZ, [1,2,3]) # optional - sage.modules + sage: F = CombinatorialFreeModule(ZZ, [2,3,4]) # optional - sage.modules + sage: H = Hom(E, F) # optional - sage.modules + sage: H.base_ring() # optional - sage.modules Integer Ring - sage: H.__class__.base_ring + sage: H.__class__.base_ring # optional - sage.modules .. TODO:: @@ -626,7 +626,9 @@ cdef class CategoryObject(SageObject): sage: R. = PolynomialRing(QQ, 2) sage: R.Hom(QQ) - Set of Homomorphisms from Multivariate Polynomial Ring in x, y over Rational Field to Rational Field + Set of Homomorphisms + from Multivariate Polynomial Ring in x, y over Rational Field + to Rational Field Homspaces are defined for very general Sage objects, even elements of familiar rings. @@ -634,7 +636,7 @@ cdef class CategoryObject(SageObject): sage: n = 5; Hom(n,7) Set of Morphisms from 5 to 7 in Category of elements of Integer Ring - sage: z=(2/3); Hom(z,8/1) + sage: z = 2/3; Hom(z, 8/1) Set of Morphisms from 2/3 to 8 in Category of elements of Rational Field This example illustrates the optional third argument:: @@ -662,7 +664,8 @@ cdef class CategoryObject(SageObject): sage: x (x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) sage: R.latex_variable_names () - ['x_{0}', 'x_{1}', 'x_{2}', 'x_{3}', 'x_{4}', 'x_{5}', 'x_{6}', 'x_{7}', 'x_{8}', 'x_{9}', 'x_{10}', 'x_{11}'] + ['x_{0}', 'x_{1}', 'x_{2}', 'x_{3}', 'x_{4}', 'x_{5}', 'x_{6}', + 'x_{7}', 'x_{8}', 'x_{9}', 'x_{10}', 'x_{11}'] sage: f = x[0]^3 + 15/3 * x[1]^10 sage: print(latex(f)) 5 x_{1}^{10} + x_{0}^{3} @@ -890,8 +893,8 @@ cdef class CategoryObject(SageObject): _test_some_elements _test_zero _test_zero_divisors - sage: F = GF(9,'a') - sage: dir(F) + sage: F = GF(9,'a') # optional - sage.rings.finite_rings + sage: dir(F) # optional - sage.rings.finite_rings [..., '__class__', ..., '_test_pickling', ..., 'extension', ...] """ diff --git a/src/sage/structure/coerce.pyx b/src/sage/structure/coerce.pyx index d5b4c12aaae..c916f877fe2 100644 --- a/src/sage/structure/coerce.pyx +++ b/src/sage/structure/coerce.pyx @@ -21,9 +21,9 @@ there. For example:: Rational Field sage: b = ZZ['x'].gen(); b.parent() Univariate Polynomial Ring in x over Integer Ring - sage: a+b + sage: a + b x + 1/2 - sage: (a+b).parent() + sage: (a + b).parent() Univariate Polynomial Ring in x over Rational Field If there is a coercion (see below) from one of the parents to the other, @@ -254,8 +254,8 @@ cpdef py_scalar_to_element(x): ....: numpy.int64('-3'), numpy.uint64('552'), ....: numpy.float16('-1.23'), numpy.float32('-2.22'), ....: numpy.float64('-3.412'), numpy.complex64(1.2+I), - ....: numpy.complex128(-2+I)] - sage: for x in elt: + ....: numpy.complex128(-2+I)] + sage: for x in elt: # optional - numpy ....: assert py_scalar_parent(type(x)) == py_scalar_to_element(x).parent() sage: elt = [gmpy2.mpz(42), gmpy2.mpq('3/4'), @@ -364,12 +364,17 @@ def parent_is_numerical(P): EXAMPLES:: sage: from sage.structure.coerce import parent_is_numerical - sage: import gmpy2, numpy - sage: [parent_is_numerical(R) for R in [RR, CC, QQ, QuadraticField(-1), - ....: int, complex, gmpy2.mpc, numpy.complexfloating]] - [True, True, True, True, True, True, True, True] - sage: [parent_is_numerical(R) for R in [SR, QQ['x'], QQ[['x']], str]] - [False, False, False, False] + sage: import gmpy2 + sage: [parent_is_numerical(R) for R in [RR, CC, QQ, int, complex, gmpy2.mpc]] + [True, True, True, True, True, True] + sage: parent_is_numerical(QuadraticField(-1)) # optional - sage.rings.number_field + True + sage: import numpy; parent_is_numerical(numpy.complexfloating) # optional - numpy + True + sage: parent_is_numerical(SR) # optional - sage.symbolic + False + sage: [parent_is_numerical(R) for R in [QQ['x'], QQ[['x']], str]] + [False, False, False] sage: [parent_is_numerical(R) for R in [RIF, RBF, CIF, CBF]] [False, False, False, False] """ @@ -387,15 +392,22 @@ def parent_is_real_numerical(P): EXAMPLES:: sage: from sage.structure.coerce import parent_is_real_numerical - sage: import gmpy2, numpy - sage: [parent_is_real_numerical(R) for R in [RR, QQ, ZZ, RLF, - ....: QuadraticField(2), int, float, gmpy2.mpq, numpy.integer]] - [True, True, True, True, True, True, True, True, True] - sage: [parent_is_real_numerical(R) for R in [CC, QuadraticField(-1), - ....: complex, gmpy2.mpc, numpy.complexfloating]] - [False, False, False, False, False] - sage: [parent_is_real_numerical(R) for R in [SR, QQ['x'], QQ[['x']], str]] + sage: import gmpy2 + sage: [parent_is_real_numerical(R) for R in [RR, QQ, ZZ, RLF, int, float, gmpy2.mpq]] + [True, True, True, True, True, True, True] + sage: parent_is_real_numerical(QuadraticField(2)) # optional - sage.rings.number_field + True + sage: import numpy; parent_is_real_numerical(numpy.integer) # optional - numpy + True + sage: parent_is_real_numerical(QuadraticField(-1)) # optional - sage.rings.number_field + False + sage: [parent_is_real_numerical(R) + ....: for R in [CC, complex, gmpy2.mpc, numpy.complexfloating]] [False, False, False, False] + sage: [parent_is_real_numerical(R) for R in [QQ['x'], QQ[['x']], str]] + [False, False, False] + sage: parent_is_real_numerical(SR) # optional - sage.symbolic + False sage: [parent_is_real_numerical(R) for R in [RIF, RBF, CIF, CBF]] [False, False, False, False] """ @@ -482,10 +494,11 @@ cdef class CoercionModel: EXAMPLES:: - sage: f = ZZ['t','x'].0 + QQ['x'].0 + CyclotomicField(13).gen(); f + sage: f = ZZ['t', 'x'].0 + QQ['x'].0 + CyclotomicField(13).gen(); f # optional - sage.rings.number_field t + x + zeta13 - sage: f.parent() - Multivariate Polynomial Ring in t, x over Cyclotomic Field of order 13 and degree 12 + sage: f.parent() # optional - sage.rings.number_field + Multivariate Polynomial Ring in t, x + over Cyclotomic Field of order 13 and degree 12 sage: ZZ['x','y'].0 + ~Frac(QQ['y']).0 (x*y + 1)/y sage: MatrixSpace(ZZ['x'], 2, 2)(2) + ~Frac(QQ['x']).0 @@ -591,7 +604,7 @@ cdef class CoercionModel: EXAMPLES:: sage: cm = sage.structure.element.get_coercion_model() - sage: cm.canonical_coercion(1,2/3) + sage: cm.canonical_coercion(1, 2/3) (1, 2/3) sage: maps, actions = cm.get_cache() @@ -635,7 +648,8 @@ cdef class CoercionModel: 1/2*x sage: maps, actions = cm.get_cache() sage: act = actions[QQ, R, operator.mul]; act - Left scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring + Left scalar multiplication by Rational Field + on Univariate Polynomial Ring in x over Integer Ring sage: act.actor() Rational Field sage: act.domain() @@ -685,7 +699,7 @@ cdef class CoercionModel: sage: cm = sage.structure.element.get_coercion_model() sage: cm.record_exceptions() - sage: 1+1/2+2 # make sure there aren't any errors hanging around + sage: 1 + 1/2 + 2 # make sure there aren't any errors hanging around 7/2 sage: cm.exception_stack() [] @@ -747,29 +761,32 @@ cdef class CoercionModel: 5/2 sage: cm.exception_stack() [] - sage: 1/2 + GF(3)(2) + sage: 1/2 + GF(3)(2) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for +: 'Rational Field' and 'Finite Field of size 3' + TypeError: unsupported operand parent(s) for +: + 'Rational Field' and 'Finite Field of size 3' Now see what the actual problem was:: sage: import traceback - sage: cm.exception_stack() + sage: cm.exception_stack() # optional - sage.rings.finite_rings ['Traceback (most recent call last):...', 'Traceback (most recent call last):...'] - sage: print(cm.exception_stack()[-1]) + sage: print(cm.exception_stack()[-1]) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Rational Field' and 'Finite Field of size 3' + TypeError: no common canonical parent for objects with parents: + 'Rational Field' and 'Finite Field of size 3' This is typically accessed via the :func:`coercion_traceback` function. :: - sage: coercion_traceback() + sage: coercion_traceback() # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Rational Field' and 'Finite Field of size 3' + TypeError: no common canonical parent for objects with parents: + 'Rational Field' and 'Finite Field of size 3' """ if not self._exceptions_cleared: self._exception_stack = [] @@ -805,7 +822,8 @@ cdef class CoercionModel: sage: R = ZZ['x'] sage: cm.explain(R, QQ) Action discovered. - Right scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring + Right scalar multiplication by Rational Field + on Univariate Polynomial Ring in x over Integer Ring Result lives in Univariate Polynomial Ring in x over Rational Field Univariate Polynomial Ring in x over Rational Field @@ -874,7 +892,8 @@ cdef class CoercionModel: sage: cm.explain(ZZx, ZZ, operator.truediv) Action discovered. - Right inverse action by Rational Field on Univariate Polynomial Ring in x over Integer Ring + Right inverse action by Rational Field + on Univariate Polynomial Ring in x over Integer Ring with precomposition on right by Natural morphism: From: Integer Ring To: Rational Field @@ -914,17 +933,17 @@ cdef class CoercionModel: EXAMPLES:: sage: cm = sage.structure.element.get_coercion_model() - sage: GF7 = GF(7) - sage: steps, res = cm.analyse(GF7, ZZ) - sage: steps + sage: GF7 = GF(7) # optional - sage.rings.finite_rings + sage: steps, res = cm.analyse(GF7, ZZ) # optional - sage.rings.finite_rings + sage: steps # optional - sage.rings.finite_rings ['Coercion on right operand via', Natural morphism: From: Integer Ring To: Finite Field of size 7, 'Arithmetic performed after coercions.'] - sage: res + sage: res # optional - sage.rings.finite_rings Finite Field of size 7 - sage: f = steps[1]; type(f) + sage: f = steps[1]; type(f) # optional - sage.rings.finite_rings - sage: f(100) + sage: f(100) # optional - sage.rings.finite_rings 2 """ self._exceptions_cleared = False @@ -1044,7 +1063,9 @@ cdef class CoercionModel: sage: cm.common_parent(QQxy, QQzt, QQyz) Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Multivariate Polynomial Ring in x, y over Rational Field' and 'Multivariate Polynomial Ring in z, t over Rational Field' + TypeError: no common canonical parent for objects with parents: + 'Multivariate Polynomial Ring in x, y over Rational Field' and + 'Multivariate Polynomial Ring in z, t over Rational Field' """ base = None for x in args: @@ -1079,8 +1100,8 @@ cdef class CoercionModel: sage: ZZx = ZZ['x'] sage: cm.division_parent(ZZx) Fraction Field of Univariate Polynomial Ring in x over Integer Ring - sage: K = GF(41) - sage: cm.division_parent(K) + sage: K = GF(41) # optional - sage.rings.finite_rings + sage: cm.division_parent(K) # optional - sage.rings.finite_rings Finite Field of size 41 sage: Zmod100 = Integers(100) sage: cm.division_parent(Zmod100) @@ -1130,14 +1151,14 @@ cdef class CoercionModel: The operator can be any callable:: sage: R. = ZZ['x'] - sage: cm.bin_op(x^2-1, x+1, gcd) + sage: cm.bin_op(x^2 - 1, x + 1, gcd) x + 1 Actions are detected and performed:: - sage: M = matrix(ZZ, 2, 2, range(4)) - sage: V = vector(ZZ, [5,7]) - sage: cm.bin_op(M, V, operator.mul) + sage: M = matrix(ZZ, 2, 2, range(4)) # optional - sage.modules + sage: V = vector(ZZ, [5,7]) # optional - sage.modules + sage: cm.bin_op(M, V, operator.mul) # optional - sage.modules (7, 31) TESTS:: @@ -1261,14 +1282,14 @@ cdef class CoercionModel: sage: cm = sage.structure.element.get_coercion_model() sage: cm.canonical_coercion(mod(2, 10), 17) (2, 7) - sage: x, y = cm.canonical_coercion(1/2, matrix(ZZ, 2, 2, range(4))) - sage: x + sage: x, y = cm.canonical_coercion(1/2, matrix(ZZ, 2, 2, range(4))) # optional - sage.modules + sage: x # optional - sage.modules [1/2 0] [ 0 1/2] - sage: y + sage: y # optional - sage.modules [0 1] [2 3] - sage: parent(x) is parent(y) + sage: parent(x) is parent(y) # optional - sage.modules True There is some support for non-Sage datatypes as well:: @@ -1293,9 +1314,9 @@ cdef class CoercionModel: We also make an exception for 0, even if `\ZZ` does not map in:: - sage: canonical_coercion(vector([1, 2, 3]), 0) + sage: canonical_coercion(vector([1, 2, 3]), 0) # optional - sage.modules ((1, 2, 3), (0, 0, 0)) - sage: canonical_coercion(GF(5)(0), float(0)) + sage: canonical_coercion(GF(5)(0), float(0)) # optional - sage.rings.finite_rings (0, 0) """ xp = parent(x) @@ -1436,8 +1457,8 @@ cdef class CoercionModel: From: Rational Field To: Univariate Polynomial Ring in x over Rational Field - sage: K = GF(7) - sage: cm.coercion_maps(QQ, K) is None + sage: K = GF(7) # optional - sage.rings.finite_rings + sage: cm.coercion_maps(QQ, K) is None # optional - sage.rings.finite_rings True Note that to break symmetry, if there is a coercion map in both @@ -1473,19 +1494,19 @@ cdef class CoercionModel: garbage collection after being involved in binary operations:: sage: import gc - sage: T=type(GF(2)) + sage: T = type(GF(2)) # optional - sage.rings.finite_rings sage: gc.collect() #random 852 - sage: N0=len(list(o for o in gc.get_objects() if type(o) is T)) - sage: L=[ZZ(1)+GF(p)(1) for p in prime_range(2,50)] - sage: N1=len(list(o for o in gc.get_objects() if type(o) is T)) - sage: N1 > N0 + sage: N0 = len(list(o for o in gc.get_objects() if type(o) is T)) # optional - sage.rings.finite_rings + sage: L = [ZZ(1) + GF(p)(1) for p in prime_range(2, 50)] # optional - sage.rings.finite_rings + sage: N1 = len(list(o for o in gc.get_objects() if type(o) is T)) # optional - sage.rings.finite_rings + sage: N1 > N0 # optional - sage.rings.finite_rings True - sage: del L + sage: del L # optional - sage.rings.finite_rings sage: gc.collect() #random 3939 - sage: N2=len(list(o for o in gc.get_objects() if type(o) is T)) - sage: N2-N0 + sage: N2 = len(list(o for o in gc.get_objects() if type(o) is T)) # optional - sage.rings.finite_rings + sage: N2 - N0 # optional - sage.rings.finite_rings 0 """ @@ -1553,9 +1574,11 @@ cdef class CoercionModel: sage: cm.verify_coercion_maps(ZZ, QQ, homs) == homs Traceback (most recent call last): ... - RuntimeError: ('BUG in coercion model, codomains must be identical', Natural morphism: + RuntimeError: ('BUG in coercion model, codomains must be identical', + Natural morphism: From: Integer Ring - To: Rational Field, Generic map: + To: Rational Field, + Generic map: From: Rational Field To: Real Field with 53 bits of precision) """ @@ -1616,7 +1639,7 @@ cdef class CoercionModel: If R is S, then two identity morphisms suffice:: - sage: cm.discover_coercion(SR, SR) + sage: cm.discover_coercion(SR, SR) # optional - sage.symbolic (None, None) If there is a coercion map either direction, use that:: @@ -1693,18 +1716,22 @@ cdef class CoercionModel: sage: cm = sage.structure.element.get_coercion_model() sage: ZZx = ZZ['x'] sage: cm.get_action(ZZx, ZZ, operator.mul) - Right scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Integer Ring + Right scalar multiplication by Integer Ring + on Univariate Polynomial Ring in x over Integer Ring sage: cm.get_action(ZZx, QQ, operator.mul) - Right scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring + Right scalar multiplication by Rational Field + on Univariate Polynomial Ring in x over Integer Ring sage: QQx = QQ['x'] sage: cm.get_action(QQx, int, operator.mul) - Right scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Rational Field + Right scalar multiplication by Integer Ring + on Univariate Polynomial Ring in x over Rational Field with precomposition on right by Native morphism: From: Set of Python objects of class 'int' To: Integer Ring sage: A = cm.get_action(QQx, ZZ, operator.truediv); A - Right inverse action by Rational Field on Univariate Polynomial Ring in x over Rational Field + Right inverse action by Rational Field + on Univariate Polynomial Ring in x over Rational Field with precomposition on right by Natural morphism: From: Integer Ring To: Rational Field @@ -1733,7 +1760,8 @@ cdef class CoercionModel: sage: R. = ZZ['x'] sage: cm = sage.structure.element.get_coercion_model() sage: cm.verify_action(R.get_action(QQ), R, QQ, operator.mul) - Right scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring + Right scalar multiplication by Rational Field + on Univariate Polynomial Ring in x over Integer Ring sage: cm.verify_action(R.get_action(QQ), RDF, R, operator.mul) Traceback (most recent call last): ... @@ -1742,8 +1770,9 @@ cdef class CoercionModel: R = Real Double Field S = Univariate Polynomial Ring in x over Integer Ring (should be Univariate Polynomial Ring in x over Integer Ring, Rational Field) - action = Right scalar multiplication by Rational Field on - Univariate Polynomial Ring in x over Integer Ring () + action = Right scalar multiplication by Rational Field + on Univariate Polynomial Ring in x over Integer Ring + () """ if action is None: return action @@ -1826,13 +1855,14 @@ cdef class CoercionModel: Check that :trac:`17740` is fixed:: - sage: R = GF(5)['x'] - sage: cm.discover_action(R, ZZ, operator.truediv) - Right inverse action by Finite Field of size 5 on Univariate Polynomial Ring in x over Finite Field of size 5 + sage: R = GF(5)['x'] # optional - sage.rings.finite_rings + sage: cm.discover_action(R, ZZ, operator.truediv) # optional - sage.rings.finite_rings + Right inverse action by Finite Field of size 5 + on Univariate Polynomial Ring in x over Finite Field of size 5 with precomposition on right by Natural morphism: From: Integer Ring To: Finite Field of size 5 - sage: cm.bin_op(R.gen(), 7, operator.truediv).parent() + sage: cm.bin_op(R.gen(), 7, operator.truediv).parent() # optional - sage.rings.finite_rings Univariate Polynomial Ring in x over Finite Field of size 5 Check that :trac:`18221` is fixed:: @@ -1932,15 +1962,16 @@ cdef class CoercionModel: If there is no coercion, we only support ``==`` and ``!=``:: - sage: x = QQ.one(); y = GF(2).one() - sage: richcmp(x, y, op_EQ) + sage: x = QQ.one(); y = GF(2).one() # optional - sage.rings.finite_rings + sage: richcmp(x, y, op_EQ) # optional - sage.rings.finite_rings False - sage: richcmp(x, y, op_NE) + sage: richcmp(x, y, op_NE) # optional - sage.rings.finite_rings True - sage: richcmp(x, y, op_GT) + sage: richcmp(x, y, op_GT) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for >: 'Rational Field' and 'Finite Field of size 2' + TypeError: unsupported operand parent(s) for >: + 'Rational Field' and 'Finite Field of size 2' We support non-Sage types with the usual Python convention:: diff --git a/src/sage/structure/coerce_dict.pyx b/src/sage/structure/coerce_dict.pyx index 440993aadd6..d38997d807c 100644 --- a/src/sage/structure/coerce_dict.pyx +++ b/src/sage/structure/coerce_dict.pyx @@ -35,18 +35,18 @@ coerce maps. In previous versions of Sage, the cache was by strong references and resulted in a memory leak in the following example. However, this leak was fixed by :trac:`715`, using weak references:: - sage: K. = GF(2^55) - sage: for i in range(20): + sage: K. = GF(2^55) # optional - sage.rings.finite_rings sage.combinat + sage: for i in range(50): # optional - sage.rings.finite_rings sage.combinat ....: a = K.random_element() ....: E = EllipticCurve(j=a) ....: P = E.random_point() ....: Q = 2*P - sage: L = [Partitions(n) for n in range(200)] # purge strong cache in CachedRepresentation + sage: L = [Partitions(n) for n in range(200)] # purge strong cache in CachedRepresentation # optional - sage.rings.finite_rings sage.combinat sage: import gc sage: n = gc.collect() - sage: from sage.schemes.elliptic_curves.ell_finite_field import EllipticCurve_finite_field - sage: LE = [x for x in gc.get_objects() if isinstance(x, EllipticCurve_finite_field)] - sage: len(LE) + sage: from sage.schemes.elliptic_curves.ell_finite_field import EllipticCurve_finite_field # optional - sage.rings.finite_rings sage.combinat + sage: LE = [x for x in gc.get_objects() if isinstance(x, EllipticCurve_finite_field)] # optional - sage.rings.finite_rings sage.combinat + sage: len(LE) # optional - sage.rings.finite_rings sage.combinat 1 """ diff --git a/src/sage/structure/coerce_maps.pyx b/src/sage/structure/coerce_maps.pyx index 3b4649edead..e40f9ddb5db 100644 --- a/src/sage/structure/coerce_maps.pyx +++ b/src/sage/structure/coerce_maps.pyx @@ -32,16 +32,19 @@ cdef class DefaultConvertMap(Map): Maps of this type are morphisms in the category of sets with partial maps (see :trac:`15618`):: - sage: f = GF(11).convert_map_from(GF(7)); f + sage: f = GF(11).convert_map_from(GF(7)); f # optional - sage.rings.finite_rings Conversion map: From: Finite Field of size 7 To: Finite Field of size 11 - sage: f.parent() - Set of Morphisms from Finite Field of size 7 to Finite Field of size 11 in Category of sets with partial maps + sage: f.parent() # optional - sage.rings.finite_rings + Set of Morphisms + from Finite Field of size 7 + to Finite Field of size 11 + in Category of sets with partial maps Test that :trac:`23211` is resolved:: - sage: f._is_coercion + sage: f._is_coercion # optional - sage.rings.finite_rings False sage: QQ[['x']].coerce_map_from(QQ)._is_coercion True @@ -50,7 +53,8 @@ cdef class DefaultConvertMap(Map): sage: from sage.structure.coerce_maps import DefaultConvertMap sage: DefaultConvertMap(ZZ, ZZ) - doctest:...: DeprecationWarning: DefaultConvertMap is deprecated, use DefaultConvertMap_unique instead. This probably means that _element_constructor_ should be a method and not some other kind of callable + doctest:...: DeprecationWarning: DefaultConvertMap is deprecated, use DefaultConvertMap_unique instead. + This probably means that _element_constructor_ should be a method and not some other kind of callable See https://github.com/sagemath/sage/issues/26879 for details. Conversion map: From: Integer Ring @@ -81,8 +85,8 @@ cdef class DefaultConvertMap(Map): EXAMPLES:: - sage: f = GF(11).convert_map_from(GF(7)) - sage: f._repr_type() + sage: f = GF(11).convert_map_from(GF(7)) # optional - sage.rings.finite_rings + sage: f._repr_type() # optional - sage.rings.finite_rings 'Conversion' """ return self._repr_type_str or ("Coercion" if self._is_coercion else "Conversion") @@ -191,13 +195,13 @@ cdef class NamedConvertMap(Map): EXAMPLES:: sage: from sage.structure.coerce_maps import NamedConvertMap - sage: var('t') + sage: var('t') # optional - sage.symbolic t - sage: mor = NamedConvertMap(SR, QQ['t'], '_polynomial_') - sage: mor(t^2/4+1) + sage: mor = NamedConvertMap(SR, QQ['t'], '_polynomial_') # optional - sage.symbolic + sage: mor(t^2/4 + 1) # optional - sage.symbolic 1/4*t^2 + 1 - sage: mor = NamedConvertMap(SR, GF(7)[['t']], '_polynomial_') - sage: mor(t^2/4+1) + sage: mor = NamedConvertMap(SR, GF(7)[['t']], '_polynomial_') # optional - sage.symbolic + sage: mor(t^2/4 + 1) # optional - sage.symbolic 1 + 2*t^2 """ if isinstance(domain, type): @@ -214,19 +218,19 @@ cdef class NamedConvertMap(Map): EXAMPLES:: sage: from sage.structure.coerce_maps import NamedConvertMap - sage: var('t') + sage: var('t') # optional - sage.symbolic t - sage: phi = NamedConvertMap(SR, QQ['t'], '_polynomial_') - sage: psi = copy(phi) # indirect doctest - sage: psi + sage: phi = NamedConvertMap(SR, QQ['t'], '_polynomial_') # optional - sage.symbolic + sage: psi = copy(phi) # indirect doctest # optional - sage.symbolic + sage: psi # optional - sage.symbolic Conversion via _polynomial_ method map: From: Symbolic Ring To: Univariate Polynomial Ring in t over Rational Field - sage: phi == psi # todo: comparison not implemented + sage: phi == psi # todo: comparison not implemented # optional - sage.symbolic True - sage: psi(t^2/4+1) + sage: psi(t^2/4 + 1) # optional - sage.symbolic 1/4*t^2 + 1 - sage: psi(t^2/4+1) == phi(t^2/4+1) + sage: psi(t^2/4 + 1) == phi(t^2/4 + 1) # optional - sage.symbolic True """ slots = Map._extra_slots(self) @@ -240,19 +244,19 @@ cdef class NamedConvertMap(Map): EXAMPLES:: sage: from sage.structure.coerce_maps import NamedConvertMap - sage: var('t') + sage: var('t') # optional - sage.symbolic t - sage: phi = NamedConvertMap(SR, QQ['t'], '_polynomial_') - sage: psi = copy(phi) # indirect doctest - sage: psi + sage: phi = NamedConvertMap(SR, QQ['t'], '_polynomial_') # optional - sage.symbolic + sage: psi = copy(phi) # indirect doctest # optional - sage.symbolic + sage: psi # optional - sage.symbolic Conversion via _polynomial_ method map: From: Symbolic Ring To: Univariate Polynomial Ring in t over Rational Field - sage: phi == psi # todo: comparison not implemented + sage: phi == psi # todo: comparison not implemented # optional - sage.symbolic True - sage: psi(t^2/4+1) + sage: psi(t^2/4 + 1) # optional - sage.symbolic 1/4*t^2 + 1 - sage: psi(t^2/4+1) == phi(t^2/4+1) + sage: psi(t^2/4 + 1) == phi(t^2/4 + 1) # optional - sage.symbolic True """ self.method_name = _slots['method_name'] @@ -263,13 +267,13 @@ cdef class NamedConvertMap(Map): EXAMPLES:: sage: from sage.structure.coerce_maps import NamedConvertMap - sage: f = NamedConvertMap(GF(5), QQ, '_integer_'); f + sage: f = NamedConvertMap(GF(5), QQ, '_integer_'); f # optional - sage.rings.finite_rings Conversion via _integer_ method map: From: Finite Field of size 5 To: Rational Field - sage: f(19) + sage: f(19) # optional - sage.rings.finite_rings 4 - sage: f(19).parent() + sage: f(19).parent() # optional - sage.rings.finite_rings Rational Field """ cdef Parent C = self._codomain @@ -297,8 +301,8 @@ cdef class NamedConvertMap(Map): EXAMPLES:: sage: from sage.structure.coerce_maps import NamedConvertMap - sage: f = NamedConvertMap(SR, ZZ['x'], '_polynomial_') - sage: f(x^2+1, check=True) + sage: f = NamedConvertMap(SR, ZZ['x'], '_polynomial_') # optional - sage.symbolic + sage: f(x^2 + 1, check=True) # optional - sage.symbolic x^2 + 1 """ cdef Parent C = self._codomain @@ -331,12 +335,12 @@ cdef class CallableConvertMap(Map): :: - sage: f = CallableConvertMap(RR, RR, exp, parent_as_first_arg=False) - sage: f(0) + sage: f = CallableConvertMap(RR, RR, exp, parent_as_first_arg=False) # optional - sage.symbolic + sage: f(0) # optional - sage.symbolic 1.00000000000000 - sage: f(1) + sage: f(1) # optional - sage.symbolic 2.71828182845905 - sage: f(-3) + sage: f(-3) # optional - sage.symbolic 0.0497870683678639 """ if isinstance(domain, type): diff --git a/src/sage/structure/element.pxd b/src/sage/structure/element.pxd index 5c6e295a4b8..4403ddd685a 100644 --- a/src/sage/structure/element.pxd +++ b/src/sage/structure/element.pxd @@ -132,12 +132,12 @@ cpdef inline bint have_same_parent(left, right): These have different types but the same parent:: sage: a = RLF(2) - sage: b = exp(a) - sage: type(a) + sage: b = exp(a) # optional - sage.symbolic + sage: type(a) # optional - sage.symbolic <... 'sage.rings.real_lazy.LazyWrapper'> - sage: type(b) + sage: type(b) # optional - sage.symbolic <... 'sage.rings.real_lazy.LazyNamedUnop'> - sage: have_same_parent(a, b) + sage: have_same_parent(a, b) # optional - sage.symbolic True """ return HAVE_SAME_PARENT(classify_elements(left, right)) diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index 026991c25d8..82031af875a 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -354,7 +354,7 @@ def is_Element(x): sage: from sage.structure.element import is_Element sage: is_Element(2/3) True - sage: is_Element(QQ^3) + sage: is_Element(QQ^3) # optional - sage.modules False """ return isinstance(x, Element) @@ -648,7 +648,7 @@ cdef class Element(SageObject): sage: QQ.base_ring() Rational Field - sage: identity_matrix(3).base_ring() + sage: identity_matrix(3).base_ring() # optional - sage.modules Integer Ring """ return self._parent.base_ring() @@ -893,13 +893,13 @@ cdef class Element(SageObject): sage: mp.dps = 30 sage: 25._mpmath_(53) mpf('25.0') - sage: mpmathify(3+4*I) + sage: mpmathify(3 + 4*I) # optional - mpmath mpc(real='3.0', imag='4.0') - sage: mpmathify(1+pi) + sage: mpmathify(1 + pi) # optional - mpmath mpf('4.14159265358979323846264338327933') - sage: (1+pi)._mpmath_(10) + sage: (1 + pi)._mpmath_(10) # optional - mpmath mpf('4.140625') - sage: (1+pi)._mpmath_(mp.prec) + sage: (1 + pi)._mpmath_(mp.prec) # optional - mpmath mpf('4.14159265358979323846264338327933') """ return self.n(prec)._mpmath_(prec=prec) @@ -920,11 +920,11 @@ cdef class Element(SageObject): EXAMPLES:: - sage: x, y = PolynomialRing(ZZ,2,'xy').gens() + sage: x, y = PolynomialRing(ZZ, 2, 'xy').gens() sage: f = x^2 + y + x^2*y^2 + 5 sage: f((5,y)) 25*y^2 + y + 30 - sage: f.substitute({x:5}) + sage: f.substitute({x: 5}) 25*y^2 + y + 30 sage: f.substitute(x=5) 25*y^2 + y + 30 @@ -1024,13 +1024,13 @@ cdef class Element(SageObject): Verify that :trac:`5185` is fixed:: - sage: v = vector({1: 1, 3: -1}) - sage: w = vector({1: -1, 3: 1}) - sage: v + w + sage: v = vector({1: 1, 3: -1}) # optional - sage.modules + sage: w = vector({1: -1, 3: 1}) # optional - sage.modules + sage: v + w # optional - sage.modules (0, 0, 0, 0) - sage: (v+w).is_zero() + sage: (v + w).is_zero() # optional - sage.modules True - sage: bool(v+w) + sage: bool(v + w) # optional - sage.modules False """ @@ -1130,7 +1130,7 @@ cdef class Element(SageObject): We now create an ``Element`` class where we define ``_richcmp_`` and check that comparison works:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: from sage.structure.richcmp cimport rich_to_bool ....: from sage.structure.element cimport Element @@ -1143,9 +1143,9 @@ cdef class Element(SageObject): ....: cdef float x2 = (other).x ....: return rich_to_bool(op, (x1 > x2) - (x1 < x2)) ....: ''') - sage: a = FloatCmp(1) # optional - sage.misc.cython - sage: b = FloatCmp(2) # optional - sage.misc.cython - sage: a <= b, b <= a # optional - sage.misc.cython + sage: a = FloatCmp(1) # optional - sage.misc.cython + sage: b = FloatCmp(2) # optional - sage.misc.cython + sage: a <= b, b <= a # optional - sage.misc.cython (True, False) """ # Obvious case @@ -1280,16 +1280,16 @@ cdef class Element(SageObject): EXAMPLES:: - sage: cython( # long time # optional - sage.misc.cython + sage: cython( # long time # optional - sage.misc.cython ....: ''' ....: from sage.structure.element cimport Element ....: cdef class MyElement(Element): ....: cdef _add_long(self, long n): ....: return n ....: ''') - sage: e = MyElement(Parent()) # long time # optional - sage.misc.cython - sage: i = int(42) # optional - sage.misc.cython - sage: i + e, e + i # long time # optional - sage.misc.cython + sage: e = MyElement(Parent()) # long time # optional - sage.misc.cython + sage: i = int(42) # optional - sage.misc.cython + sage: i + e, e + i # long time # optional - sage.misc.cython (42, 42) """ return coercion_model.bin_op(self, n, add) @@ -1490,13 +1490,13 @@ cdef class Element(SageObject): :: - sage: A = AlgebrasWithBasis(QQ).example(); A + sage: A = AlgebrasWithBasis(QQ).example(); A # optional - sage.combinat sage.modules An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field - sage: x = A.an_element() - sage: x + sage: x = A.an_element() # optional - sage.combinat sage.modules + sage: x # optional - sage.combinat sage.modules B[word: ] + 2*B[word: a] + 3*B[word: b] + B[word: bab] - sage: x.__mul__(x) + sage: x.__mul__(x) # optional - sage.combinat sage.modules B[word: ] + 4*B[word: a] + 4*B[word: aa] + 6*B[word: ab] + 2*B[word: abab] + 6*B[word: b] + 6*B[word: ba] + 2*B[word: bab] + 2*B[word: baba] + 3*B[word: babb] @@ -1558,16 +1558,16 @@ cdef class Element(SageObject): EXAMPLES:: - sage: cython( # long time # optional - sage.misc.cython + sage: cython( # long time # optional - sage.misc.cython ....: ''' ....: from sage.structure.element cimport Element ....: cdef class MyElement(Element): ....: cdef _mul_long(self, long n): ....: return n ....: ''') - sage: e = MyElement(Parent()) # long time # optional - sage.misc.cython - sage: i = int(42) # optional - sage.misc.cython - sage: i * e, e * i # long time # optional - sage.misc.cython + sage: e = MyElement(Parent()) # long time # optional - sage.misc.cython + sage: i = int(42) # optional - sage.misc.cython + sage: i * e, e * i # long time # optional - sage.misc.cython (42, 42) """ return coercion_model.bin_op(self, n, mul) @@ -1675,11 +1675,11 @@ cdef class Element(SageObject): sage: operator.truediv(2, 3) 2/3 - sage: operator.truediv(pi, 3) + sage: operator.truediv(pi, 3) # optional - sage.symbolic 1/3*pi sage: x = polygen(QQ, 'x') - sage: K. = NumberField(x^2 + 1) - sage: operator.truediv(2, K.ideal(i+1)) + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: operator.truediv(2, K.ideal(i + 1)) # optional - sage.rings.number_field Fractional ideal (-i + 1) :: @@ -1994,15 +1994,15 @@ cdef class Element(SageObject): :: - sage: (2/3)^I + sage: (2/3)^I # optional - sage.symbolic (2/3)^I - sage: (2/3)^sqrt(2) + sage: (2/3)^sqrt(2) # optional - sage.symbolic (2/3)^sqrt(2) - sage: var('x,y,z,n') + sage: var('x,y,z,n') # optional - sage.symbolic (x, y, z, n) - sage: (2/3)^(x^n + y^n + z^n) + sage: (2/3)^(x^n + y^n + z^n) # optional - sage.symbolic (2/3)^(x^n + y^n + z^n) - sage: (-7/11)^(tan(x)+exp(x)) + sage: (-7/11)^(tan(x)+exp(x)) # optional - sage.symbolic (-7/11)^(e^x + tan(x)) sage: float(1.2)**(1/2) 1.0954451150103321 @@ -2140,7 +2140,7 @@ def is_ModuleElement(x): sage: from sage.structure.element import is_ModuleElement sage: is_ModuleElement(2/3) True - sage: is_ModuleElement((QQ^3).0) + sage: is_ModuleElement((QQ^3).0) # optional - sage.modules True sage: is_ModuleElement('a') False @@ -2219,7 +2219,7 @@ cdef class ElementWithCachedMethod(Element): ....: "from sage.structure.parent cimport Parent", ....: "cdef class MyParent(Parent):", ....: " Element = MyElement"] - sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython + sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython sage: cython_code = ["from sage.misc.cachefunc import cached_method", ....: "from sage.misc.cachefunc import cached_in_parent_method", ....: "from sage.categories.category import Category", @@ -2242,21 +2242,21 @@ cdef class ElementWithCachedMethod(Element): ....: " @cached_method", ....: " def invert(self, x):", ....: " return -x"] - sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython - sage: C = MyCategory() # optional - sage.misc.cython - sage: P = MyParent(category=C) # optional - sage.misc.cython - sage: ebroken = MyBrokenElement(P, 5) # optional - sage.misc.cython - sage: e = MyElement(P, 5) # optional - sage.misc.cython + sage: cython('\n'.join(cython_code)) # optional - sage.misc.cython + sage: C = MyCategory() # optional - sage.misc.cython + sage: P = MyParent(category=C) # optional - sage.misc.cython + sage: ebroken = MyBrokenElement(P, 5) # optional - sage.misc.cython + sage: e = MyElement(P, 5) # optional - sage.misc.cython The cached methods inherited by ``MyElement`` works:: - sage: e.element_cache_test() # optional - sage.misc.cython + sage: e.element_cache_test() # optional - sage.misc.cython <-5> - sage: e.element_cache_test() is e.element_cache_test() # optional - sage.misc.cython + sage: e.element_cache_test() is e.element_cache_test() # optional - sage.misc.cython True - sage: e.element_via_parent_test() # optional - sage.misc.cython + sage: e.element_via_parent_test() # optional - sage.misc.cython <-5> - sage: e.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython + sage: e.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython True The other element class can only inherit a @@ -2264,36 +2264,36 @@ cdef class ElementWithCachedMethod(Element): parent. In fact, equal elements share the cache, even if they are of different types:: - sage: e == ebroken # optional - sage.misc.cython + sage: e == ebroken # optional - sage.misc.cython True - sage: type(e) == type(ebroken) # optional - sage.misc.cython + sage: type(e) == type(ebroken) # optional - sage.misc.cython False - sage: ebroken.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython + sage: ebroken.element_via_parent_test() is e.element_via_parent_test() # optional - sage.misc.cython True However, the cache of the other inherited method breaks, although the method as such works:: - sage: ebroken.element_cache_test() # optional - sage.misc.cython + sage: ebroken.element_cache_test() # optional - sage.misc.cython <-5> - sage: ebroken.element_cache_test() is ebroken.element_cache_test() # optional - sage.misc.cython + sage: ebroken.element_cache_test() is ebroken.element_cache_test() # optional - sage.misc.cython False Since ``e`` and ``ebroken`` share the cache, when we empty it for one element it is empty for the other as well:: - sage: b = ebroken.element_via_parent_test() # optional - sage.misc.cython - sage: e.element_via_parent_test.clear_cache() # optional - sage.misc.cython - sage: b is ebroken.element_via_parent_test() # optional - sage.misc.cython + sage: b = ebroken.element_via_parent_test() # optional - sage.misc.cython + sage: e.element_via_parent_test.clear_cache() # optional - sage.misc.cython + sage: b is ebroken.element_via_parent_test() # optional - sage.misc.cython False Note that the cache only breaks for elements that do no allow attribute assignment. A Python version of ``MyBrokenElement`` therefore allows for cached methods:: - sage: epython = MyPythonElement(P, 5) # optional - sage.misc.cython - sage: epython.element_cache_test() # optional - sage.misc.cython + sage: epython = MyPythonElement(P, 5) # optional - sage.misc.cython + sage: epython.element_cache_test() # optional - sage.misc.cython <-5> - sage: epython.element_cache_test() is epython.element_cache_test() # optional - sage.misc.cython + sage: epython.element_cache_test() is epython.element_cache_test() # optional - sage.misc.cython True """ @@ -2310,7 +2310,7 @@ cdef class ElementWithCachedMethod(Element): EXAMPLES:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: from sage.structure.element cimport ElementWithCachedMethod ....: cdef class MyElement(ElementWithCachedMethod): @@ -2336,12 +2336,12 @@ cdef class ElementWithCachedMethod(Element): ....: def my_lazy_attr(self): ....: return 'lazy attribute of <%s>'%self.x ....: ''') - sage: C = MyCategory() # optional - sage.misc.cython - sage: P = MyParent(category=C) # optional - sage.misc.cython - sage: e = MyElement(P, 5) # optional - sage.misc.cython - sage: e.my_lazy_attr # optional - sage.misc.cython + sage: C = MyCategory() # optional - sage.misc.cython + sage: P = MyParent(category=C) # optional - sage.misc.cython + sage: e = MyElement(P, 5) # optional - sage.misc.cython + sage: e.my_lazy_attr # optional - sage.misc.cython 'lazy attribute of <5>' - sage: e.my_lazy_attr is e.my_lazy_attr # optional - sage.misc.cython + sage: e.my_lazy_attr is e.my_lazy_attr # optional - sage.misc.cython True """ try: @@ -2453,8 +2453,8 @@ cdef class ModuleElementWithMutability(ModuleElement): """ EXAMPLES:: - sage: v = sage.modules.free_module_element.FreeModuleElement(QQ^3) - sage: type(v) + sage: v = sage.modules.free_module_element.FreeModuleElement(QQ^3) # optional - sage.modules + sage: type(v) # optional - sage.modules """ self._parent = parent @@ -2466,11 +2466,11 @@ cdef class ModuleElementWithMutability(ModuleElement): EXAMPLES:: - sage: v = vector([1..5]); v + sage: v = vector([1..5]); v # optional - sage.modules (1, 2, 3, 4, 5) - sage: v[1] = 10 - sage: v.set_immutable() - sage: v[1] = 10 + sage: v[1] = 10 # optional - sage.modules + sage: v.set_immutable() # optional - sage.modules + sage: v[1] = 10 # optional - sage.modules Traceback (most recent call last): ... ValueError: vector is immutable; please change a copy instead (use copy()) @@ -2484,10 +2484,10 @@ cdef class ModuleElementWithMutability(ModuleElement): EXAMPLES:: - sage: v = vector(QQ['x,y'], [1..5]); v.is_mutable() + sage: v = vector(QQ['x,y'], [1..5]); v.is_mutable() # optional - sage.modules True - sage: v.set_immutable() - sage: v.is_mutable() + sage: v.set_immutable() # optional - sage.modules + sage: v.is_mutable() # optional - sage.modules False """ return not self._is_immutable @@ -2499,10 +2499,10 @@ cdef class ModuleElementWithMutability(ModuleElement): EXAMPLES:: - sage: v = vector(QQ['x,y'], [1..5]); v.is_immutable() + sage: v = vector(QQ['x,y'], [1..5]); v.is_immutable() # optional - sage.modules False - sage: v.set_immutable() - sage: v.is_immutable() + sage: v.set_immutable() # optional - sage.modules + sage: v.is_immutable() # optional - sage.modules True """ return self._is_immutable @@ -2550,9 +2550,9 @@ cdef class MonoidElement(Element): EXAMPLES:: - sage: G = SymmetricGroup(4) # optional - sage.groups - sage: g = G([2, 3, 4, 1]) # optional - sage.groups - sage: g.powers(4) # optional - sage.groups + sage: G = SymmetricGroup(4) # optional - sage.groups + sage: g = G([2, 3, 4, 1]) # optional - sage.groups + sage: g.powers(4) # optional - sage.groups [(), (1,2,3,4), (1,3)(2,4), (1,4,3,2)] """ if n < 0: @@ -2681,22 +2681,22 @@ cdef class RingElement(ModuleElement): True sage: p(a,200) * p(a,-64) == p(a,136) True - sage: p(2, 1/2) + sage: p(2, 1/2) # optional - sage.symbolic sqrt(2) TESTS: These are not testing this code, but they are probably good to have around:: - sage: 2r**(SR(2)-1-1r) + sage: 2r**(SR(2)-1-1r) # optional - sage.symbolic 1 - sage: 2r^(1/2) + sage: 2r^(1/2) # optional - sage.symbolic sqrt(2) Exponent overflow should throw an OverflowError (:trac:`2956`):: - sage: K. = AA[] - sage: x^(2^64 + 12345) + sage: K. = AA[] # optional - sage.rings.number_field + sage: x^(2^64 + 12345) # optional - sage.rings.number_field Traceback (most recent call last): ... OverflowError: exponent overflow (2147483648) @@ -2793,8 +2793,8 @@ cdef class RingElement(ModuleElement): :: - sage: R. = GF(7)[] - sage: divmod(x^2, x-1) + sage: R. = GF(7)[] # optional - sage.rings.finite_rings + sage: divmod(x^2, x - 1) # optional - sage.rings.finite_rings (x + 1, 1) :: @@ -2839,8 +2839,8 @@ cdef class RingElement(ModuleElement): sage: a = QQ(0) sage: a.is_nilpotent() True - sage: m = matrix(QQ,3,[[3,2,3],[9,0,3],[-9,0,-3]]) - sage: m.is_nilpotent() + sage: m = matrix(QQ, 3, [[3,2,3], [9,0,3], [-9,0,-3]]) # optional - sage.modules + sage: m.is_nilpotent() # optional - sage.modules Traceback (most recent call last): ... AttributeError: ... object has no attribute 'is_nilpotent' @@ -2884,30 +2884,30 @@ cdef class RingElement(ModuleElement): For polynomial rings, prime is the same as irreducible:: sage: R. = QQ[] - sage: x.is_prime() + sage: x.is_prime() # optional - sage.libs.singular True - sage: (x^2 + y^3).is_prime() + sage: (x^2 + y^3).is_prime() # optional - sage.libs.singular True - sage: (x^2 - y^2).is_prime() + sage: (x^2 - y^2).is_prime() # optional - sage.libs.singular False - sage: R(0).is_prime() + sage: R(0).is_prime() # optional - sage.libs.singular False - sage: R(2).is_prime() + sage: R(2).is_prime() # optional - sage.libs.singular False For the Gaussian integers:: - sage: K. = QuadraticField(-1) - sage: ZI = K.ring_of_integers() - sage: ZI(3).is_prime() + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: ZI = K.ring_of_integers() # optional - sage.rings.number_field + sage: ZI(3).is_prime() # optional - sage.rings.number_field True - sage: ZI(5).is_prime() + sage: ZI(5).is_prime() # optional - sage.rings.number_field False - sage: ZI(2+i).is_prime() + sage: ZI(2 + i).is_prime() # optional - sage.rings.number_field True - sage: ZI(0).is_prime() + sage: ZI(0).is_prime() # optional - sage.rings.number_field False - sage: ZI(1).is_prime() + sage: ZI(1).is_prime() # optional - sage.rings.number_field False In fields, an element is never prime:: @@ -2930,13 +2930,13 @@ cdef class RingElement(ModuleElement): redefines :meth:`is_prime` to determine primality in the ring of integers:: - sage: (1+i).is_prime() + sage: (1 + i).is_prime() # optional - sage.rings.number_field True - sage: K(5).is_prime() + sage: K(5).is_prime() # optional - sage.rings.number_field False - sage: K(7).is_prime() + sage: K(7).is_prime() # optional - sage.rings.number_field True - sage: K(7/13).is_prime() + sage: K(7/13).is_prime() # optional - sage.rings.number_field False However, for rationals, :meth:`is_prime` *does* follow the @@ -2980,16 +2980,16 @@ cdef class CommutativeRingElement(RingElement): EXAMPLES:: - sage: F = GF(25) - sage: x = F.gen() - sage: z = F.zero() - sage: x.inverse_mod(F.ideal(z)) + sage: F = GF(25) # optional - sage.rings.finite_rings + sage: x = F.gen() # optional - sage.rings.finite_rings + sage: z = F.zero() # optional - sage.rings.finite_rings + sage: x.inverse_mod(F.ideal(z)) # optional - sage.rings.finite_rings 2*z2 + 3 - sage: x.inverse_mod(F.ideal(1)) + sage: x.inverse_mod(F.ideal(1)) # optional - sage.rings.finite_rings 1 - sage: z.inverse_mod(F.ideal(1)) + sage: z.inverse_mod(F.ideal(1)) # optional - sage.rings.finite_rings 1 - sage: z.inverse_mod(F.ideal(z)) + sage: z.inverse_mod(F.ideal(z)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: an element of a proper ideal does not have an inverse modulo that ideal @@ -3012,24 +3012,24 @@ cdef class CommutativeRingElement(RingElement): sage: P. = PolynomialRing(QQ) sage: x.divides(x^2) True - sage: x.divides(x^2+2) + sage: x.divides(x^2 + 2) False - sage: (x^2+2).divides(x) + sage: (x^2 + 2).divides(x) False sage: P. = PolynomialRing(ZZ) sage: x.divides(x^2) True - sage: x.divides(x^2+2) + sage: x.divides(x^2 + 2) False - sage: (x^2+2).divides(x) + sage: (x^2 + 2).divides(x) False :trac:`5347` has been fixed:: - sage: K = GF(7) - sage: K(3).divides(1) + sage: K = GF(7) # optional - sage.rings.finite_rings + sage: K(3).divides(1) # optional - sage.rings.finite_rings True - sage: K(3).divides(K(1)) + sage: K(3).divides(K(1)) # optional - sage.rings.finite_rings True :: @@ -3059,7 +3059,8 @@ cdef class CommutativeRingElement(RingElement): sage: Zmod(5)(1).divides(Zmod(2)(1)) Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Ring of integers modulo 5' and 'Ring of integers modulo 2' + TypeError: no common canonical parent for objects with parents: + 'Ring of integers modulo 5' and 'Ring of integers modulo 2' sage: Zmod(35)(4).divides(Zmod(7)(1)) True sage: Zmod(35)(7).divides(Zmod(7)(1)) @@ -3360,7 +3361,7 @@ cdef class Expression(CommutativeRingElement): EXAMPLES:: - sage: isinstance(SR.var('y'), sage.structure.element.Expression) # optional - sage.symbolic + sage: isinstance(SR.var('y'), sage.structure.element.Expression) # optional - sage.symbolic True By design, there is a unique direct subclass:: @@ -3606,14 +3607,14 @@ cdef class Vector(ModuleElementWithMutability): TESTS:: - sage: A = matrix([[1, 2], [0, 3]]) - sage: b = vector([0, 1]) - sage: x = b / A; x + sage: A = matrix([[1, 2], [0, 3]]) # optional - sage.modules + sage: b = vector([0, 1]) # optional - sage.modules + sage: x = b / A; x # optional - sage.modules (0, 1/3) - sage: x == b * ~A + sage: x == b * ~A # optional - sage.modules True - sage: A = matrix([[1, 2], [0, 3], [1, 5]]) - sage: (b / A) * A == b + sage: A = matrix([[1, 2], [0, 3], [1, 5]]) # optional - sage.modules + sage: (b / A) * A == b # optional - sage.modules True """ right = py_scalar_to_element(right) @@ -3640,32 +3641,33 @@ cdef class Vector(ModuleElementWithMutability): EXAMPLES:: - sage: v = vector([1,2,3]) - sage: v._magma_init_(magma) # optional - magma + sage: v = vector([1,2,3]) # optional - sage.modules + sage: v._magma_init_(magma) # optional - magma # optional - sage.modules '_sage_[...]![1,2,3]' - sage: mv = magma(v); mv # optional - magma + sage: mv = magma(v); mv # optional - magma # optional - sage.modules (1 2 3) - sage: mv.Type() # optional - magma + sage: mv.Type() # optional - magma # optional - sage.modules ModTupRngElt - sage: mv.Parent() # optional - magma + sage: mv.Parent() # optional - magma # optional - sage.modules Full RSpace of degree 3 over Integer Ring - sage: v = vector(QQ, [1/2, 3/4, 5/6]) - sage: mv = magma(v); mv # optional - magma + sage: v = vector(QQ, [1/2, 3/4, 5/6]) # optional - sage.modules + sage: mv = magma(v); mv # optional - magma # optional - sage.modules (1/2 3/4 5/6) - sage: mv.Type() # optional - magma + sage: mv.Type() # optional - magma # optional - sage.modules ModTupFldElt - sage: mv.Parent() # optional - magma + sage: mv.Parent() # optional - magma # optional - sage.modules Full Vector space of degree 3 over Rational Field A more demanding example:: sage: R. = QQ[] - sage: v = vector([x^3, y, 2/3*z + x/y]) - sage: magma(v) # optional - magma + sage: v = vector([x^3, y, 2/3*z + x/y]) # optional - sage.modules + sage: magma(v) # optional - magma # optional - sage.modules ( x^3 y (2/3*y*z + x)/y) - sage: magma(v).Parent() # optional - magma - Full Vector space of degree 3 over Multivariate rational function field of rank 3 over Rational Field + sage: magma(v).Parent() # optional - magma # optional - sage.modules + Full Vector space of degree 3 + over Multivariate rational function field of rank 3 over Rational Field """ V = magma(self._parent) v = [x._magma_init_(magma) for x in self.list()] @@ -3752,7 +3754,8 @@ cdef class Matrix(ModuleElement): sage: A*B Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 3 by 2 dense matrices over Rational Field' and 'Full MatrixSpace of 3 by 2 dense matrices over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 3 by 2 dense matrices over Rational Field' and 'Full MatrixSpace of 3 by 2 dense matrices over Rational Field' Here we test (matrix * vector) multiplication:: @@ -3800,7 +3803,9 @@ cdef class Matrix(ModuleElement): sage: parent(matrix(QQ['x'],2,2,[1,2,3,4])*vector(QQ['y'],[1,2])) Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' + TypeError: unsupported operand parent(s) for *: + 'Full MatrixSpace of 2 by 2 dense matrices over Univariate Polynomial Ring in x over Rational Field' and + 'Ambient free module of rank 2 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field' Here we test (matrix * scalar) multiplication:: @@ -3954,32 +3959,32 @@ cdef class Matrix(ModuleElement): EXAMPLES:: - sage: a = matrix(ZZ, 2, range(4)) - sage: operator.truediv(a, 5) + sage: a = matrix(ZZ, 2, range(4)) # optional - sage.modules + sage: operator.truediv(a, 5) # optional - sage.modules [ 0 1/5] [2/5 3/5] - sage: a = matrix(ZZ, 2, range(4)) - sage: b = matrix(ZZ, 2, [1,1,0,5]) - sage: operator.truediv(a, b) + sage: a = matrix(ZZ, 2, range(4)) # optional - sage.modules + sage: b = matrix(ZZ, 2, [1,1,0,5]) # optional - sage.modules + sage: operator.truediv(a, b) # optional - sage.modules [ 0 1/5] [ 2 1/5] - sage: c = matrix(QQ, 2, [3,2,5,7]) - sage: operator.truediv(c, a) + sage: c = matrix(QQ, 2, [3,2,5,7]) # optional - sage.modules + sage: operator.truediv(c, a) # optional - sage.modules [-5/2 3/2] [-1/2 5/2] TESTS:: - sage: a = matrix(ZZ, [[1, 2], [0, 3]]) - sage: b = matrix(ZZ, 3, 2, range(6)) - sage: x = b / a; x + sage: a = matrix(ZZ, [[1, 2], [0, 3]]) # optional - sage.modules + sage: b = matrix(ZZ, 3, 2, range(6)) # optional - sage.modules + sage: x = b / a; x # optional - sage.modules [ 0 1/3] [ 2 -1/3] [ 4 -1] - sage: x == b * ~a + sage: x == b * ~a # optional - sage.modules True - sage: a = matrix(ZZ, [[1, 2], [0, 3], [1, 5]]) - sage: (b / a) * a == b + sage: a = matrix(ZZ, [[1, 2], [0, 3], [1, 5]]) # optional - sage.modules + sage: (b / a) * a == b # optional - sage.modules True """ if is_Matrix(right): @@ -4035,14 +4040,14 @@ cdef class PrincipalIdealDomainElement(DedekindDomainElement): :trac:`30849`:: - sage: 2.gcd(pari(3)) + sage: 2.gcd(pari(3)) # optional - sage.libs.pari 1 - sage: type(2.gcd(pari(3))) + sage: type(2.gcd(pari(3))) # optional - sage.libs.pari - sage: 2.gcd(pari('1/3')) + sage: 2.gcd(pari('1/3')) # optional - sage.libs.pari 1/3 - sage: type(2.gcd(pari('1/3'))) + sage: type(2.gcd(pari('1/3'))) # optional - sage.libs.pari sage: import gmpy2 @@ -4053,7 +4058,7 @@ cdef class PrincipalIdealDomainElement(DedekindDomainElement): sage: 2.gcd(gmpy2.mpq(1,3)) 1/3 - sage: type(2.gcd(pari('1/3'))) + sage: type(2.gcd(pari('1/3'))) # optional - sage.libs.pari """ # NOTE: in order to handle nicely pari or gmpy2 integers we do not rely only on coercion @@ -4074,14 +4079,14 @@ cdef class PrincipalIdealDomainElement(DedekindDomainElement): :trac:`30849`:: - sage: 2.lcm(pari(3)) + sage: 2.lcm(pari(3)) # optional - sage.libs.pari 6 - sage: type(2.lcm(pari(3))) + sage: type(2.lcm(pari(3))) # optional - sage.libs.pari - sage: 2.lcm(pari('1/3')) + sage: 2.lcm(pari('1/3')) # optional - sage.libs.pari 2 - sage: type(2.lcm(pari('1/3'))) + sage: type(2.lcm(pari('1/3'))) # optional - sage.libs.pari sage: import gmpy2 @@ -4131,15 +4136,15 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): EXAMPLES:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: from sage.structure.element cimport EuclideanDomainElement ....: cdef class MyElt(EuclideanDomainElement): ....: def quo_rem(self, other): ....: return self._parent.var('quo,rem') ....: ''') - sage: e = MyElt(SR) # optional - sage.misc.cython - sage: e // e # optional - sage.misc.cython + sage: e = MyElt(SR) # optional - sage.misc.cython + sage: e // e # optional - sage.misc.cython quo """ Q, _ = self.quo_rem(right) @@ -4162,15 +4167,15 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): :: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: from sage.structure.element cimport EuclideanDomainElement ....: cdef class MyElt(EuclideanDomainElement): ....: def quo_rem(self, other): ....: return self._parent.var('quo,rem') ....: ''') - sage: e = MyElt(SR) # optional - sage.misc.cython - sage: e % e # optional - sage.misc.cython + sage: e = MyElt(SR) # optional - sage.misc.cython + sage: e % e # optional - sage.misc.cython rem """ _, R = self.quo_rem(other) @@ -4195,9 +4200,9 @@ cdef class FieldElement(CommutativeRingElement): sage: K. = NumberField(x^4 + x^2 + 2/3) # optional - sage.rings.number_field sage: c = (1+b) // (1-b); c # optional - sage.rings.number_field 3/4*b^3 + 3/4*b^2 + 3/2*b + 1/2 - sage: (1+b) / (1-b) == c + sage: (1+b) / (1-b) == c # optional - sage.rings.number_field True - sage: c * (1-b) + sage: c * (1-b) # optional - sage.rings.number_field b + 1 """ return self._div_(right) @@ -4266,14 +4271,14 @@ cdef class FieldElement(CommutativeRingElement): EXAMPLES:: - sage: K. = QQ[sqrt(3)] - sage: K(0).divides(rt3) + sage: K. = QQ[sqrt(3)] # optional - sage.rings.number_field sage.symbolic + sage: K(0).divides(rt3) # optional - sage.rings.number_field sage.symbolic False - sage: rt3.divides(K(17)) + sage: rt3.divides(K(17)) # optional - sage.rings.number_field sage.symbolic True - sage: K(0).divides(K(0)) + sage: K(0).divides(K(0)) # optional - sage.rings.number_field sage.symbolic True - sage: rt3.divides(K(0)) + sage: rt3.divides(K(0)) # optional - sage.rings.number_field sage.symbolic True """ if not (other._parent is self._parent): @@ -4288,8 +4293,8 @@ def is_AlgebraElement(x): TESTS:: sage: from sage.structure.element import is_AlgebraElement - sage: R. = FreeAlgebra(QQ,2) - sage: is_AlgebraElement(x*y) + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules + sage: is_AlgebraElement(x * y) # optional - sage.combinat sage.modules True sage: is_AlgebraElement(1) @@ -4347,8 +4352,8 @@ cpdef canonical_coercion(x, y): EXAMPLES:: - sage: A = Matrix([[0, 1], [1, 0]]) - sage: canonical_coercion(A, 1) + sage: A = Matrix([[0, 1], [1, 0]]) # optional - sage.modules + sage: canonical_coercion(A, 1) # optional - sage.modules ( [0 1] [1 0] [1 0], [0 1] @@ -4398,14 +4403,16 @@ def coercion_traceback(dump=True): sage: 1 + 1/5 6/5 sage: coercion_traceback() # Should be empty, as all went well. - sage: 1/5 + GF(5).gen() + sage: 1/5 + GF(5).gen() # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for +: 'Rational Field' and 'Finite Field of size 5' - sage: coercion_traceback() + TypeError: unsupported operand parent(s) for +: + 'Rational Field' and 'Finite Field of size 5' + sage: coercion_traceback() # optional - sage.rings.finite_rings Traceback (most recent call last): ... - TypeError: no common canonical parent for objects with parents: 'Rational Field' and 'Finite Field of size 5' + TypeError: no common canonical parent for objects with parents: + 'Rational Field' and 'Finite Field of size 5' """ if dump: for traceback in coercion_model.exception_stack(): @@ -4438,7 +4445,7 @@ def coerce_binop(method): Sparse polynomial rings uses `@coerce_binop` on `gcd`:: - sage: S. = PolynomialRing(ZZ,sparse=True) + sage: S. = PolynomialRing(ZZ, sparse=True) sage: f = x^2 sage: g = x sage: f.gcd(g) #indirect doctest @@ -4459,15 +4466,15 @@ def coerce_binop(method): sage: h = R2(1) sage: f.gcd(g) 1 - sage: f.gcd(g,algorithm='modular') + sage: f.gcd(g, algorithm='modular') 1 sage: f.gcd(h) 1 - sage: f.gcd(h,algorithm='modular') + sage: f.gcd(h, algorithm='modular') 1 sage: h.gcd(f) 1 - sage: h.gcd(f,'modular') + sage: h.gcd(f, 'modular') 1 We demonstrate a small class using `@coerce_binop` on a method:: diff --git a/src/sage/structure/element_wrapper.pyx b/src/sage/structure/element_wrapper.pyx index f77bcce6ea5..44aa88ea530 100644 --- a/src/sage/structure/element_wrapper.pyx +++ b/src/sage/structure/element_wrapper.pyx @@ -209,8 +209,8 @@ cdef class ElementWrapper(Element): sage: from sage.structure.element_wrapper import DummyParent sage: ElementWrapper(DummyParent("A parent"), 1)._ascii_art_() 1 - sage: x = var('x') - sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._ascii_art_() + sage: x = var('x') # optional - sage.symbolic + sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._ascii_art_() # optional - sage.symbolic 2 x + x """ @@ -226,8 +226,8 @@ cdef class ElementWrapper(Element): sage: from sage.structure.element_wrapper import DummyParent sage: ElementWrapper(DummyParent("A parent"), 1)._ascii_art_() 1 - sage: x = var('x') - sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._unicode_art_() + sage: x = var('x') # optional - sage.symbolic + sage: ElementWrapper(DummyParent("A parent"), x^2 + x)._unicode_art_() # optional - sage.symbolic 2 x + x """ @@ -561,8 +561,8 @@ cdef class ElementWrapperCheckWrappedClass(ElementWrapper): :: sage: A = cartesian_product([ZZ, ZZ]) - sage: B = cartesian_product([GF(3), GF(5)]) - sage: A((3,5)) == B((0,0)) + sage: B = cartesian_product([GF(3), GF(5)]) # optional - sage.rings.finite_rings + sage: A((3,5)) == B((0,0)) # optional - sage.rings.finite_rings True """ if type(self) is type(right): diff --git a/src/sage/structure/factorization.py b/src/sage/structure/factorization.py index 8fa56d6bf75..0d4a704783c 100644 --- a/src/sage/structure/factorization.py +++ b/src/sage/structure/factorization.py @@ -70,22 +70,22 @@ sage: f = -5*(x-2)*(x-3) sage: f -5*x^2 + 25*x - 30 - sage: F = f.factor(); F + sage: F = f.factor(); F # optional - sage.libs.pari (-5) * (x - 3) * (x - 2) - sage: F.unit() + sage: F.unit() # optional - sage.libs.pari -5 - sage: F.value() + sage: F.value() # optional - sage.libs.pari -5*x^2 + 25*x - 30 The underlying list is the list of pairs `(p_i, e_i)`, where each `p_i` is a 'prime' and each `e_i` is an integer. The unit part is discarded by the list:: - sage: list(F) + sage: list(F) # optional - sage.libs.pari [(x - 3, 1), (x - 2, 1)] - sage: len(F) + sage: len(F) # optional - sage.libs.pari 2 - sage: F[1] + sage: F[1] # optional - sage.libs.pari (x - 2, 1) In the ring `\ZZ[x]`, the integer `-5` is not a unit, so the @@ -95,56 +95,59 @@ sage: f = -5*(x-2)*(x-3) sage: f -5*x^2 + 25*x - 30 - sage: F = f.factor(); F + sage: F = f.factor(); F # optional - sage.libs.pari (-1) * 5 * (x - 3) * (x - 2) - sage: F.universe() + sage: F.universe() # optional - sage.libs.pari Univariate Polynomial Ring in x over Integer Ring - sage: F.unit() + sage: F.unit() # optional - sage.libs.pari -1 - sage: list(F) + sage: list(F) # optional - sage.libs.pari [(5, 1), (x - 3, 1), (x - 2, 1)] - sage: F.value() + sage: F.value() # optional - sage.libs.pari -5*x^2 + 25*x - 30 - sage: len(F) + sage: len(F) # optional - sage.libs.pari 3 On the other hand, -1 is a unit in `\ZZ`, so it is included in the unit:: sage: x = ZZ['x'].0 - sage: f = -1*(x-2)*(x-3) - sage: F = f.factor(); F + sage: f = -1*(x-2)*(x-3) # optional - sage.libs.pari + sage: F = f.factor(); F # optional - sage.libs.pari (-1) * (x - 3) * (x - 2) - sage: F.unit() + sage: F.unit() # optional - sage.libs.pari -1 - sage: list(F) + sage: list(F) # optional - sage.libs.pari [(x - 3, 1), (x - 2, 1)] Factorizations can involve fairly abstract mathematical objects:: sage: F = ModularSymbols(11,4).factorization() sage: F - (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * - (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * - (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) + (Modular Symbols subspace of dimension 2 of Modular Symbols space + of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * + (Modular Symbols subspace of dimension 2 of Modular Symbols space + of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * + (Modular Symbols subspace of dimension 2 of Modular Symbols space + of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) sage: type(F) - sage: K. = NumberField(x^2 + 3); K + sage: K. = NumberField(x^2 + 3); K # optional - sage.rings.number_field Number Field in a with defining polynomial x^2 + 3 - sage: f = K.factor(15); f + sage: f = K.factor(15); f # optional - sage.rings.number_field (Fractional ideal (1/2*a + 3/2))^2 * (Fractional ideal (5)) - sage: f.universe() + sage: f.universe() # optional - sage.rings.number_field Monoid of ideals of Number Field in a with defining polynomial x^2 + 3 - sage: f.unit() + sage: f.unit() # optional - sage.rings.number_field Fractional ideal (1) - sage: g=K.factor(9); g + sage: g = K.factor(9); g # optional - sage.rings.number_field (Fractional ideal (1/2*a + 3/2))^4 - sage: f.lcm(g) + sage: f.lcm(g) # optional - sage.rings.number_field (Fractional ideal (1/2*a + 3/2))^4 * (Fractional ideal (5)) - sage: f.gcd(g) + sage: f.gcd(g) # optional - sage.rings.number_field (Fractional ideal (1/2*a + 3/2))^2 - sage: f.is_integral() + sage: f.is_integral() # optional - sage.rings.number_field True TESTS:: @@ -206,7 +209,7 @@ class Factorization(SageObject): -1 sage: loads(F.dumps()) == F True - sage: F = Factorization([(x,1/3)]) + sage: F = Factorization([(x, 1/3)]) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: no conversion of this rational to integer @@ -281,13 +284,13 @@ def __init__(self, x, unit=None, cr=False, sort=True, simplify=True): sage: Factorization([(2, 7), (5,2), (2, 5)]) 2^12 * 5^2 - sage: R. = FreeAlgebra(QQ,2) - sage: Factorization([(a,1),(b,1),(a,2)]) + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules + sage: Factorization([(a,1), (b,1), (a,2)]) # optional - sage.combinat sage.modules a * b * a^2 Autosorting (the default) swaps around the factors below:: - sage: F = Factorization([(ZZ^3, 2), (ZZ^2, 5)], cr=True); F + sage: F = Factorization([(ZZ^3, 2), (ZZ^2, 5)], cr=True); F # optional - sage.modules (Ambient free module of rank 2 over the principal ideal domain Integer Ring)^5 * (Ambient free module of rank 3 over the principal ideal domain Integer Ring)^2 """ @@ -413,7 +416,7 @@ def __richcmp__(self, other, op): sage: x = polygen(QQ) sage: x^2 - 1 > x^2 - 4 True - sage: factor(x^2 - 1) > factor(x^2 - 4) + sage: factor(x^2 - 1) > factor(x^2 - 4) # optional - sage.libs.pari True """ if not isinstance(other, Factorization): @@ -520,9 +523,9 @@ def universe(self): sage: F.universe() Integer Ring - sage: R. = FreeAlgebra(QQ, 3) - sage: F = Factorization([(z, 2)], 3) - sage: (F*F^-1).universe() + sage: R. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: F = Factorization([(z, 2)], 3) # optional - sage.combinat sage.modules + sage: (F*F^-1).universe() # optional - sage.combinat sage.modules Free Algebra on 3 generators (x, y, z) over Rational Field sage: F = ModularSymbols(11,4).factorization() @@ -551,11 +554,11 @@ def base_change(self, U): possible:: sage: g = x^2 - 1 - sage: F = factor(g); F + sage: F = factor(g); F # optional - sage.libs.pari (x - 1) * (x + 1) - sage: F.universe() + sage: F.universe() # optional - sage.libs.pari Univariate Polynomial Ring in x over Integer Ring - sage: F.base_change(ZZ) + sage: F.base_change(ZZ) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: Impossible to coerce the factors of (x - 1) * (x + 1) into Integer Ring @@ -576,15 +579,15 @@ def is_commutative(self): sage: F = factor(2006) sage: F.is_commutative() True - sage: K = QuadraticField(23, 'a') - sage: F = K.factor(13) - sage: F.is_commutative() + sage: K = QuadraticField(23, 'a') # optional - sage.rings.number_field + sage: F = K.factor(13) # optional - sage.rings.number_field + sage: F.is_commutative() # optional - sage.rings.number_field True - sage: R. = FreeAlgebra(QQ, 3) - sage: F = Factorization([(z, 2)], 3) - sage: F.is_commutative() + sage: R. = FreeAlgebra(QQ, 3) # optional - sage.combinat sage.modules + sage: F = Factorization([(z, 2)], 3) # optional - sage.combinat sage.modules + sage: F.is_commutative() # optional - sage.combinat sage.modules False - sage: (F*F^-1).is_commutative() + sage: (F*F^-1).is_commutative() # optional - sage.combinat sage.modules False """ try: @@ -602,14 +605,14 @@ def _set_cr(self, cr): EXAMPLES:: sage: x = polygen(QQ,'x') - sage: F = factor(x^6 - 1); F + sage: F = factor(x^6 - 1); F # optional - sage.libs.pari (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + x + 1) - sage: F._set_cr(True); F + sage: F._set_cr(True); F # optional - sage.libs.pari (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + x + 1) - sage: F._set_cr(False); F + sage: F._set_cr(False); F # optional - sage.libs.pari (x - 1) * (x + 1) * (x^2 - x + 1) * (x^2 + x + 1) """ self.__cr = bool(cr) @@ -620,12 +623,12 @@ def simplify(self): TESTS:: - sage: R. = FreeAlgebra(ZZ, 2) - sage: F = Factorization([(x,3), (y, 2), (y,2)], simplify=False); F + sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (y,2)], simplify=False); F # optional - sage.combinat sage.modules x^3 * y^2 * y^2 - sage: F.simplify(); F + sage: F.simplify(); F # optional - sage.combinat sage.modules x^3 * y^4 - sage: F * Factorization([(y, -2)], 2) + sage: F * Factorization([(y, -2)], 2) # optional - sage.combinat sage.modules (2) * x^3 * y^2 """ repeat = False @@ -679,8 +682,8 @@ def sort(self, key=None): We sort it by decreasing degree:: - sage: F.sort(key=lambda x:(-x[0].degree(), x)) - sage: F + sage: F.sort(key=lambda x: (-x[0].degree(), x)) # optional - sage.libs.pari + sage: F # optional - sage.libs.pari (x^2 - x + 1) * (x + 1) """ if len(self) == 0: @@ -861,7 +864,7 @@ def _latex_(self): -1 \cdot 2^{2} \cdot 5^{2} sage: f._latex_() '-1 \\cdot 2^{2} \\cdot 5^{2}' - sage: x = AA['x'].0; factor(x^2 + x + 1)._latex_() # trac 12178 + sage: x = AA['x'].0; factor(x^2 + x + 1)._latex_() # trac 12178 # optional - sage.rings.number_field '(x^{2} + x + 1.000000000000000?)' """ if len(self) == 0: @@ -898,12 +901,12 @@ def __pari__(self): EXAMPLES:: sage: f = factor(-24) - sage: pari(f) + sage: pari(f) # optional - sage.libs.pari [-1, 1; 2, 3; 3, 1] sage: R. = QQ[] - sage: g = factor(x^10 - 1) - sage: pari(g) + sage: g = factor(x^10 - 1) # optional - sage.libs.pari + sage: pari(g) # optional - sage.libs.pari [x - 1, 1; x + 1, 1; x^4 - x^3 + x^2 - x + 1, 1; x^4 + x^3 + x^2 + x + 1, 1] """ @@ -1003,12 +1006,12 @@ def __rmul__(self, left): -2 * 3 * 5 sage: a * -2 -2 * 3 * 5 - sage: R. = FreeAlgebra(QQ,2) - sage: f = Factorization([(x,2),(y,3)]); f + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules + sage: f = Factorization([(x,2), (y,3)]); f # optional - sage.combinat sage.modules x^2 * y^3 - sage: x * f + sage: x * f # optional - sage.combinat sage.modules x^3 * y^3 - sage: f * x + sage: f * x # optional - sage.combinat sage.modules x^2 * y^3 * x Note that this does not automatically factor ``left``:: @@ -1035,12 +1038,12 @@ def __mul__(self, other): sage: factor(-10) * factor(16) -1 * 2^5 * 5 - sage: R. = FreeAlgebra(ZZ, 2) - sage: F = Factorization([(x,3), (y, 2), (x,1)]); F + sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # optional - sage.combinat sage.modules x^3 * y^2 * x - sage: F*F + sage: F*F # optional - sage.combinat sage.modules x^3 * y^2 * x^4 * y^2 * x - sage: -1 * F + sage: -1 * F # optional - sage.combinat sage.modules (-1) * x^3 * y^2 * x sage: P. = ZZ[] @@ -1101,13 +1104,13 @@ def __pow__(self, n): sage: K. = NumberField(x^3 - 39*x - 91) # optional - sage.rings.number_field sage: F = K.factor(7); F # optional - sage.rings.number_field (Fractional ideal (7, a)) * (Fractional ideal (7, a + 2)) * (Fractional ideal (7, a - 2)) - sage: F^9 + sage: F^9 # optional - sage.rings.number_field (Fractional ideal (7, a))^9 * (Fractional ideal (7, a + 2))^9 * (Fractional ideal (7, a - 2))^9 - sage: R. = FreeAlgebra(ZZ, 2) - sage: F = Factorization([(x,3), (y, 2), (x,1)]); F + sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # optional - sage.combinat sage.modules x^3 * y^2 * x - sage: F**2 + sage: F**2 # optional - sage.combinat sage.modules x^3 * y^2 * x^4 * y^2 * x """ from sage.rings.integer import Integer @@ -1139,10 +1142,10 @@ def __invert__(self): sage: F^-1 2^-1 * 17^-1 * 59^-1 - sage: R. = FreeAlgebra(QQ, 2) - sage: F = Factorization([(x,3), (y, 2), (x,1)], 2); F + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (x,1)], 2); F # optional - sage.combinat sage.modules (2) * x^3 * y^2 * x - sage: F^-1 + sage: F^-1 # optional - sage.combinat sage.modules (1/2) * x^-1 * y^-2 * x^-3 """ return Factorization([(p,-e) for p,e in reversed(self)], @@ -1160,12 +1163,12 @@ def __truediv__(self, other): sage: factor(-10) / factor(16) -1 * 2^-3 * 5 - sage: R. = FreeAlgebra(QQ, 2) - sage: F = Factorization([(x,3), (y, 2), (x,1)]); F + sage: R. = FreeAlgebra(QQ, 2) # optional - sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # optional - sage.combinat sage.modules x^3 * y^2 * x - sage: G = Factorization([(y, 1), (x,1)],1); G + sage: G = Factorization([(y, 1), (x,1)],1); G # optional - sage.combinat sage.modules y * x - sage: F / G + sage: F / G # optional - sage.combinat sage.modules x^3 * y """ if not isinstance(other, Factorization): @@ -1183,10 +1186,10 @@ def value(self): sage: F.value() -2006 - sage: R. = FreeAlgebra(ZZ, 2) - sage: F = Factorization([(x,3), (y, 2), (x,1)]); F + sage: R. = FreeAlgebra(ZZ, 2) # optional - sage.combinat sage.modules + sage: F = Factorization([(x,3), (y, 2), (x,1)]); F # optional - sage.combinat sage.modules x^3 * y^2 * x - sage: F.value() + sage: F.value() # optional - sage.combinat sage.modules x^3*y^2*x """ from sage.misc.misc_c import prod @@ -1212,7 +1215,7 @@ def gcd(self, other): 2 * 5 sage: R. = ZZ[] - sage: (factor(-20).gcd(factor(5*x+10))).universe() + sage: (factor(-20).gcd(factor(5*x+10))).universe() # optional - sage.libs.pari Univariate Polynomial Ring in x over Integer Ring """ if not isinstance(other, Factorization): @@ -1254,7 +1257,7 @@ def lcm(self, other): 2^4 * 5 sage: R. = ZZ[] - sage: (factor(-20).lcm(factor(5*x+10))).universe() + sage: (factor(-20).lcm(factor(5*x + 10))).universe() # optional - sage.libs.pari Univariate Polynomial Ring in x over Integer Ring """ if not isinstance(other, Factorization): diff --git a/src/sage/structure/factory.pyx b/src/sage/structure/factory.pyx index a1a28a0da7a..f47f0ea96fa 100644 --- a/src/sage/structure/factory.pyx +++ b/src/sage/structure/factory.pyx @@ -196,7 +196,7 @@ cdef class UniqueFactory(SageObject): :class:`object`. The third allows attribute assignment and is derived from :class:`object`. :: - sage: cython("cdef class C: pass") # optional - sage.misc.cython + sage: cython("cdef class C: pass") # optional - sage.misc.cython sage: class D: ....: def __init__(self, *args): ....: self.t = args @@ -214,7 +214,7 @@ cdef class UniqueFactory(SageObject): It is impossible to create an instance of ``C`` with our factory, since it does not allow weak references:: - sage: F(1, impl='C') # optional - sage.misc.cython + sage: F(1, impl='C') # optional - sage.misc.cython Traceback (most recent call last): ... TypeError: cannot create weak reference to '....C' object @@ -222,14 +222,14 @@ cdef class UniqueFactory(SageObject): Let us try again, with a Cython class that does allow weak references. Now, creation of an instance using the factory works:: - sage: cython( # optional - sage.misc.cython + sage: cython( # optional - sage.misc.cython ....: ''' ....: cdef class C: ....: cdef __weakref__ ....: ''') ....: - sage: c = F(1, impl='C') # optional - sage.misc.cython - sage: isinstance(c, C) # optional - sage.misc.cython + sage: c = F(1, impl='C') # optional - sage.misc.cython + sage: isinstance(c, C) # optional - sage.misc.cython True The cache is used when calling the factory again---even if it is suggested @@ -237,16 +237,16 @@ cdef class UniqueFactory(SageObject): only considered an "extra argument" that does not count for the key. :: - sage: c is F(1, impl='C') is F(1, impl="D") is F(1) # optional - sage.misc.cython + sage: c is F(1, impl='C') is F(1, impl="D") is F(1) # optional - sage.misc.cython True However, pickling and unpickling does not use the cache. This is because the factory has tried to assign an attribute to the instance that provides information on the key used to create the instance, but failed:: - sage: loads(dumps(c)) is c # optional - sage.misc.cython + sage: loads(dumps(c)) is c # optional - sage.misc.cython False - sage: hasattr(c, '_factory_data') # optional - sage.misc.cython + sage: hasattr(c, '_factory_data') # optional - sage.misc.cython False We have already seen that our factory will only take the requested @@ -302,7 +302,7 @@ cdef class UniqueFactory(SageObject): sage: fake_factory = UniqueFactory('ZZ') sage: loads(dumps(fake_factory)) Integer Ring - sage: fake_factory = UniqueFactory('sage.rings.all.QQ') + sage: fake_factory = UniqueFactory('sage.rings.rational_field.QQ') sage: loads(dumps(fake_factory)) Rational Field """ @@ -313,17 +313,17 @@ cdef class UniqueFactory(SageObject): """ EXAMPLES:: - sage: A = FiniteField(127) - sage: A is loads(dumps(A)) # indirect doctest + sage: A = FiniteField(127) # optional - sage.rings.finite_rings + sage: A is loads(dumps(A)) # indirect doctest # optional - sage.rings.finite_rings True - sage: B = FiniteField(3^3,'b') - sage: B is loads(dumps(B)) + sage: B = FiniteField(3^3,'b') # optional - sage.rings.finite_rings + sage: B is loads(dumps(B)) # optional - sage.rings.finite_rings True - sage: C = FiniteField(2^16,'c') - sage: C is loads(dumps(C)) + sage: C = FiniteField(2^16,'c') # optional - sage.rings.finite_rings + sage: C is loads(dumps(C)) # optional - sage.rings.finite_rings True - sage: D = FiniteField(3^20,'d') - sage: D is loads(dumps(D)) + sage: D = FiniteField(3^20,'d') # optional - sage.rings.finite_rings + sage: D is loads(dumps(D)) # optional - sage.rings.finite_rings True TESTS:: @@ -396,10 +396,10 @@ cdef class UniqueFactory(SageObject): Check that :trac:`16317` has been fixed, i.e., caching works for unhashable objects:: - sage: K. = Qq(4) - sage: d = test_factory.get_object(3.0, (K(1), 'c'), {}) # optional - sage.rings.padics + sage: K. = Qq(4) # optional - sage.rings.padics + sage: d = test_factory.get_object(3.0, (K(1), 'c'), {}) # optional - sage.rings.padics Making object (1 + O(2^20), 'c') - sage: d is test_factory.get_object(3.0, (K(1), 'c'), {}) # optional - sage.rings.padics + sage: d is test_factory.get_object(3.0, (K(1), 'c'), {}) # optional - sage.rings.padics True """ @@ -468,7 +468,7 @@ cdef class UniqueFactory(SageObject): sage: from sage.structure.test_factory import test_factory sage: test_factory.create_key_and_extra_args(1, 2, key=5) ((1, 2), {}) - sage: GF.create_key_and_extra_args(3) + sage: GF.create_key_and_extra_args(3) # optional - sage.rings.finite_rings ((3, ('x',), None, 'modn', 3, 1, True, None, None, None, True, False), {}) """ return self.create_key(*args, **kwds), {} @@ -518,15 +518,15 @@ cdef class UniqueFactory(SageObject): The ``GF`` factory used to have a custom :meth:`other_keys` method, but this was removed in :trac:`16934`:: - sage: key, _ = GF.create_key_and_extra_args(27, 'k'); key + sage: key, _ = GF.create_key_and_extra_args(27, 'k'); key # optional - sage.rings.finite_rings (27, ('k',), x^3 + 2*x + 1, 'givaro', 3, 3, True, None, 'poly', True, True, True) - sage: K = GF.create_object(0, key); K + sage: K = GF.create_object(0, key); K # optional - sage.rings.finite_rings Finite Field in k of size 3^3 - sage: GF.other_keys(key, K) + sage: GF.other_keys(key, K) # optional - sage.rings.finite_rings [] - sage: K = GF(7^40, 'a') - sage: loads(dumps(K)) is K + sage: K = GF(7^40, 'a') # optional - sage.rings.finite_rings + sage: loads(dumps(K)) is K # optional - sage.rings.finite_rings True """ return [] @@ -540,12 +540,12 @@ cdef class UniqueFactory(SageObject): EXAMPLES:: - sage: from sage.modules.free_module import FreeModuleFactory_with_standard_basis as F - sage: V = F(ZZ, 5) - sage: factory, data = F.reduce_data(V) - sage: factory(*data) + sage: from sage.modules.free_module import FreeModuleFactory_with_standard_basis as F # optional - sage.modules + sage: V = F(ZZ, 5) # optional - sage.modules + sage: factory, data = F.reduce_data(V) # optional - sage.modules + sage: factory(*data) # optional - sage.modules Ambient free module of rank 5 over the principal ideal domain Integer Ring - sage: factory(*data) is V + sage: factory(*data) is V # optional - sage.modules True sage: from sage.structure.test_factory import test_factory @@ -638,12 +638,12 @@ def generic_factory_unpickle(factory, *args): EXAMPLES:: - sage: from sage.modules.free_module import FreeModuleFactory_with_standard_basis as F - sage: V = F(ZZ, 5) - sage: func, data = F.reduce_data(V) - sage: func is sage.structure.factory.generic_factory_unpickle + sage: from sage.modules.free_module import FreeModuleFactory_with_standard_basis as F # optional - sage.modules + sage: V = F(ZZ, 5) # optional - sage.modules + sage: func, data = F.reduce_data(V) # optional - sage.modules + sage: func is sage.structure.factory.generic_factory_unpickle # optional - sage.modules True - sage: sage.structure.factory.generic_factory_unpickle(*data) is V + sage: sage.structure.factory.generic_factory_unpickle(*data) is V # optional - sage.modules True TESTS: @@ -730,8 +730,8 @@ def generic_factory_reduce(self, proto): EXAMPLES:: - sage: V = QQ^6 - sage: sage.structure.factory.generic_factory_reduce(V, 1) == V.__reduce_ex__(1) + sage: V = QQ^6 # optional - sage.modules + sage: sage.structure.factory.generic_factory_reduce(V, 1) == V.__reduce_ex__(1) # optional - sage.modules True """ if self._factory_data is None: diff --git a/src/sage/structure/formal_sum.py b/src/sage/structure/formal_sum.py index 7a788c3994f..deccad76ed2 100644 --- a/src/sage/structure/formal_sum.py +++ b/src/sage/structure/formal_sum.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules """ Formal sums @@ -103,24 +104,24 @@ def __init__(self, x, parent=None, check=True, reduce=True): sage: a.reduce() sage: a 4*2/3 - 5*7 - sage: FormalSum([(1,2/3), (3,2/3), (-5, 7)], parent=FormalSums(GF(5))) + sage: FormalSum([(1, 2/3), (3, 2/3), (-5, 7)], parent=FormalSums(GF(5))) # optional - sage.rings.finite_rings 4*2/3 Notice below that the coefficient 5 doesn't get reduced modulo 5:: - sage: FormalSum([(1,2/3), (3,2/3), (-5, 7)], parent=FormalSums(GF(5)), check=False) + sage: FormalSum([(1,2/3), (3,2/3), (-5, 7)], parent=FormalSums(GF(5)), check=False) # optional - sage.rings.finite_rings 4*2/3 - 5*7 Make sure we first reduce before checking coefficient types:: - sage: x,y = var('x, y') - sage: FormalSum([(1/2,x), (2,y)], FormalSums(QQ)) + sage: x,y = var('x, y') # optional - sage.symbolic + sage: FormalSum([(1/2,x), (2,y)], FormalSums(QQ)) # optional - sage.symbolic 1/2*x + 2*y - sage: FormalSum([(1/2,x), (2,y)], FormalSums(ZZ)) + sage: FormalSum([(1/2,x), (2,y)], FormalSums(ZZ)) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: no conversion of this rational to integer - sage: FormalSum([(1/2,x), (1/2,x), (2,y)], FormalSums(ZZ)) + sage: FormalSum([(1/2,x), (1/2,x), (2,y)], FormalSums(ZZ)) # optional - sage.symbolic x + 2*y """ if x == 0: @@ -309,11 +310,12 @@ class FormalSums(UniqueRepresentation, Module): Abelian Group of all Formal Finite Sums over Integer Ring sage: FormalSums(ZZ) Abelian Group of all Formal Finite Sums over Integer Ring - sage: FormalSums(GF(7)) + sage: FormalSums(GF(7)) # optional - sage.rings.finite_rings Abelian Group of all Formal Finite Sums over Finite Field of size 7 - sage: FormalSums(ZZ[sqrt(2)]) - Abelian Group of all Formal Finite Sums over Order in Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? - sage: FormalSums(GF(9,'a')) + sage: FormalSums(ZZ[sqrt(2)]) # optional - sage.symbolic sage.rings.number_field + Abelian Group of all Formal Finite Sums over Order in Number Field in sqrt2 + with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095? + sage: FormalSums(GF(9,'a')) # optional - sage.rings.finite_rings Abelian Group of all Formal Finite Sums over Finite Field in a of size 3^2 TESTS:: @@ -338,9 +340,9 @@ def _repr_(self): """ EXAMPLES:: - sage: FormalSums(GF(7)) + sage: FormalSums(GF(7)) # optional - sage.rings.finite_rings Abelian Group of all Formal Finite Sums over Finite Field of size 7 - sage: FormalSums(GF(7))._repr_() + sage: FormalSums(GF(7))._repr_() # optional - sage.rings.finite_rings 'Abelian Group of all Formal Finite Sums over Finite Field of size 7' """ return "Abelian Group of all Formal Finite Sums over %s"%self.base_ring() @@ -400,12 +402,12 @@ def base_extend(self, R): """ EXAMPLES:: - sage: F7 = FormalSums(ZZ).base_extend(GF(7)); F7 + sage: F7 = FormalSums(ZZ).base_extend(GF(7)); F7 # optional - sage.rings.finite_rings Abelian Group of all Formal Finite Sums over Finite Field of size 7 The following tests against a bug that was fixed at :trac:`18795`:: - sage: isinstance(F7, F7.category().parent_class) + sage: isinstance(F7, F7.category().parent_class) # optional - sage.rings.finite_rings True """ if self.base_ring().has_coerce_map_from(R): @@ -418,7 +420,8 @@ def _get_action_(self, other, op, self_is_left): EXAMPLES:: sage: A = FormalSums(RR); A.get_action(RR) # indirect doctest - Right scalar multiplication by Real Field with 53 bits of precision on Abelian Group of all Formal Finite Sums over Real Field with 53 bits of precision + Right scalar multiplication by Real Field with 53 bits of precision + on Abelian Group of all Formal Finite Sums over Real Field with 53 bits of precision sage: A = FormalSums(ZZ); A.get_action(QQ) Right scalar multiplication by Rational Field on Abelian Group of all Formal Finite Sums over Rational Field diff --git a/src/sage/structure/global_options.py b/src/sage/structure/global_options.py index c97cee38b3f..b202d7e7871 100644 --- a/src/sage/structure/global_options.py +++ b/src/sage/structure/global_options.py @@ -387,7 +387,7 @@ class options(GlobalOptions): Here is an example to test the pickling of a :class:`GlobalOptions` instance:: - sage: TestSuite(Partitions.options).run() + sage: TestSuite(Partitions.options).run() # optional - sage.combinat TESTS: @@ -526,15 +526,15 @@ class Option(): EXAMPLES:: - sage: Partitions.options.display + sage: Partitions.options.display # optional - sage.combinat list - sage: Partitions.options.display='compact' - sage: Partitions.options.display('list') - sage: Partitions.options._reset() + sage: Partitions.options.display = 'compact' # optional - sage.combinat + sage: Partitions.options.display('list') # optional - sage.combinat + sage: Partitions.options._reset() # optional - sage.combinat TESTS:: - sage: TestSuite(Partitions.options.display).run() + sage: TestSuite(Partitions.options.display).run() # optional - sage.combinat """ __name__ = 'Option class' @@ -545,7 +545,7 @@ def __init__(self, options, name): EXAMPLES:: - sage: type(Partitions.options.display) # indirect doctest + sage: type(Partitions.options.display) # indirect doctest # optional - sage.combinat """ self._name = name @@ -559,7 +559,7 @@ def __repr__(self): EXAMPLES:: - sage: Partitions.options.display # indirect doctest + sage: Partitions.options.display # indirect doctest # optional - sage.combinat list """ # NOTE: we intentionally use str() instead of repr() @@ -572,7 +572,7 @@ def __add__(self, other): EXAMPLES:: - sage: Tableaux.options.convention +' is good' + sage: Tableaux.options.convention + ' is good' # optional - sage.combinat 'English is good' """ return self._options[self._name] + other @@ -584,7 +584,7 @@ def __radd__(self, other): EXAMPLES:: - sage: 'Good '+Tableaux.options.convention + sage: 'Good ' + Tableaux.options.convention # optional - sage.combinat 'Good English' """ return other + self._options[self._name] @@ -596,7 +596,7 @@ def __mul__(self, other): EXAMPLES:: - sage: Tableaux.options.convention +' is good' + sage: Tableaux.options.convention + ' is good' # optional - sage.combinat 'English is good' """ return self._options[self._name] * other @@ -608,7 +608,7 @@ def __rmul__(self, other): EXAMPLES:: - sage: 'Good '+Tableaux.options.convention + sage: 'Good ' + Tableaux.options.convention # optional - sage.combinat 'Good English' """ return other * self._options[self._name] @@ -619,14 +619,14 @@ def __bool__(self) -> bool: EXAMPLES:: - sage: RiggedConfigurations.options.half_width_boxes_type_B + sage: RiggedConfigurations.options.half_width_boxes_type_B # optional - sage.combinat True - sage: 'yes' if RiggedConfigurations.options.half_width_boxes_type_B else 'no' + sage: 'yes' if RiggedConfigurations.options.half_width_boxes_type_B else 'no' # optional - sage.combinat 'yes' - sage: RiggedConfigurations.options.half_width_boxes_type_B=False - sage: 'yes' if RiggedConfigurations.options.half_width_boxes_type_B else 'no' + sage: RiggedConfigurations.options.half_width_boxes_type_B = False # optional - sage.combinat + sage: 'yes' if RiggedConfigurations.options.half_width_boxes_type_B else 'no' # optional - sage.combinat 'no' - sage: RiggedConfigurations.options._reset() + sage: RiggedConfigurations.options._reset() # optional - sage.combinat """ return bool(self._options[self._name]) @@ -636,12 +636,12 @@ def __call__(self, *args, **kwds): EXAMPLES:: - sage: Partitions.options.display() # indirect doctest + sage: Partitions.options.display() # indirect doctest # optional - sage.combinat 'list' - sage: Partitions.options.display('exp') # indirect doctest - sage: Partitions.options.display() # indirect doctest + sage: Partitions.options.display('exp') # indirect doctest # optional - sage.combinat + sage: Partitions.options.display() # indirect doctest # optional - sage.combinat 'exp_low' - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat TESTS: @@ -696,11 +696,11 @@ def __eq__(self, other): EXAMPLES:: - sage: Tableaux.options.convention + sage: Tableaux.options.convention # optional - sage.combinat English - sage: Tableaux.options.convention == "English" + sage: Tableaux.options.convention == "English" # optional - sage.combinat True - sage: Tableaux.options.convention == "French" + sage: Tableaux.options.convention == "French" # optional - sage.combinat False """ return self._options[self._name] == other @@ -712,11 +712,11 @@ def __ne__(self, other): EXAMPLES:: - sage: Tableaux.options.convention + sage: Tableaux.options.convention # optional - sage.combinat English - sage: Tableaux.options.convention != "English" + sage: Tableaux.options.convention != "English" # optional - sage.combinat False - sage: Tableaux.options.convention != "French" + sage: Tableaux.options.convention != "French" # optional - sage.combinat True """ return self._options[self._name] != other @@ -728,7 +728,7 @@ def __hash__(self): EXAMPLES:: - sage: hash(Tableaux.options.convention) == hash(Tableaux.options('convention')) + sage: hash(Tableaux.options.convention) == hash(Tableaux.options('convention')) # optional - sage.combinat True """ return hash(self._options[self._name]) @@ -740,7 +740,7 @@ def __str__(self): EXAMPLES:: - sage: str(Tableaux.options.convention) + sage: str(Tableaux.options.convention) # optional - sage.combinat 'English' """ return str(self._options[self._name]) @@ -1232,7 +1232,7 @@ def _instancedoc_(self): EXAMPLES:: - sage: print(Partitions.options.__doc__) + sage: print(Partitions.options.__doc__) # optional - sage.combinat Sets and displays the global options for elements of the partition, skew partition, and partition tuple classes. If no parameters are @@ -1273,12 +1273,12 @@ def __setattr__(self, name, value=None): EXAMPLES:: - sage: Partitions.options.display = 'exp' - sage: Partitions.options.dispplay = 'list' + sage: Partitions.options.display = 'exp' # optional - sage.combinat + sage: Partitions.options.dispplay = 'list' # optional - sage.combinat Traceback (most recent call last): ... ValueError: dispplay is not an option for Partitions - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat """ # Underscore, and "special", attributes are set using type.__setattr__ if name[0] == '_' or name in ['reset', 'dispatch', 'default_value']: @@ -1298,24 +1298,24 @@ def __setstate__(self, state): EXAMPLES:: - sage: Partitions.options() + sage: Partitions.options() # optional - sage.combinat Current options for Partitions - convention: English - diagram_str: * - display: list - latex: young_diagram - latex_diagram_str: \ast - sage: Partitions.options.convention="French" - sage: pickle = dumps(Partitions.options) - sage: Partitions.options._reset() # reset options - sage: loads(pickle) # indirect doctest + sage: Partitions.options.convention = "French" # optional - sage.combinat + sage: pickle = dumps(Partitions.options) # optional - sage.combinat + sage: Partitions.options._reset() # reset options # optional - sage.combinat + sage: loads(pickle) # indirect doctest # optional - sage.combinat Current options for Partitions - convention: French - diagram_str: * - display: list - latex: young_diagram - latex_diagram_str: \ast - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat """ # open the options for the corresponding "parent" and copy all of # the data from its options class into unpickle @@ -1350,8 +1350,8 @@ def __getstate__(self): EXAMPLES:: - sage: Partitions.options._reset() - sage: Partitions.options.__getstate__() + sage: Partitions.options._reset() # optional - sage.combinat + sage: Partitions.options.__getstate__() # optional - sage.combinat {'convention': 'English', 'option_class': 'Partitions', 'options_module': 'sage.combinat.partition'} @@ -1385,9 +1385,9 @@ def __eq__(self, other): EXAMPLES:: - sage: Partitions.options == PartitionsGreatestLE.options # indirect doctest + sage: Partitions.options == PartitionsGreatestLE.options # indirect doctest # optional - sage.combinat True - sage: Partitions.options == Tableaux.options + sage: Partitions.options == Tableaux.options # optional - sage.combinat False """ return isinstance(other, GlobalOptions) and self.__getstate__() == other.__getstate__() diff --git a/src/sage/structure/indexed_generators.py b/src/sage/structure/indexed_generators.py index 4cf80c3522d..5573ff60834 100644 --- a/src/sage/structure/indexed_generators.py +++ b/src/sage/structure/indexed_generators.py @@ -174,8 +174,8 @@ def indices(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) - sage: F.indices() + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules + sage: F.indices() # optional - sage.modules {'a', 'b', 'c'} """ return self._indices @@ -186,14 +186,14 @@ def prefix(self): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) - sage: F.prefix() + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules + sage: F.prefix() # optional - sage.modules 'B' :: - sage: X = SchubertPolynomialRing(QQ) - sage: X.prefix() + sage: X = SchubertPolynomialRing(QQ) # optional - sage.combinat + sage: X.prefix() # optional - sage.combinat 'X' """ return self._print_options['prefix'] @@ -229,16 +229,16 @@ def print_options(self, **kwds): EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix='x') - sage: F.print_options() + sage: F = CombinatorialFreeModule(ZZ, [1,2,3], prefix='x') # optional - sage.modules + sage: F.print_options() # optional - sage.modules {...'prefix': 'x'...} - sage: F.print_options(bracket='(') - sage: F.print_options() + sage: F.print_options(bracket='(') # optional - sage.modules + sage: F.print_options() # optional - sage.modules {...'bracket': '('...} TESTS:: - sage: sorted(F.print_options().items()) + sage: sorted(F.print_options().items()) # optional - sage.modules [('bracket', '('), ('iterate_key', False), ('latex_bracket', False), ('latex_names', None), ('latex_prefix', None), ('latex_scalar_mult', None), @@ -247,7 +247,7 @@ def print_options(self, **kwds): ('sorting_key', at ...>), ('sorting_reverse', False), ('string_quotes', True), ('tensor_symbol', None)] - sage: F.print_options(bracket='[') # reset + sage: F.print_options(bracket='[') # reset # optional - sage.modules """ # don't just use kwds.get(...) because I want to distinguish # between an argument like "option=None" and the option not @@ -270,33 +270,33 @@ def _parse_names(self, m, use_latex): EXAMPLES:: - sage: F = CombinatorialFreeModule(ZZ, [1,2,3], names='a,b,c', + sage: F = CombinatorialFreeModule(ZZ, [1,2,3], names='a,b,c', # optional - sage.modules ....: latex_names='x,y,z') - sage: F._parse_names(1, False) + sage: F._parse_names(1, False) # optional - sage.modules 'a' - sage: F._parse_names(1, True) + sage: F._parse_names(1, True) # optional - sage.modules 'x' - sage: F.print_options(latex_names=None) - sage: F._parse_names(1, True) + sage: F.print_options(latex_names=None) # optional - sage.modules + sage: F._parse_names(1, True) # optional - sage.modules 'a' - sage: F.print_options(latex_names={1:'x', 2:'y'}, names=None) - sage: F._parse_names(1, False) is None + sage: F.print_options(latex_names={1:'x', 2:'y'}, names=None) # optional - sage.modules + sage: F._parse_names(1, False) is None # optional - sage.modules True - sage: F._parse_names(1, True) + sage: F._parse_names(1, True) # optional - sage.modules 'x' - sage: F._parse_names(3, True) is None + sage: F._parse_names(3, True) is None # optional - sage.modules True - sage: F.print_options(names={1:'a', 3:'c'}, latex_names=None) - sage: F._parse_names(1, False) + sage: F.print_options(names={1:'a', 3:'c'}, latex_names=None) # optional - sage.modules + sage: F._parse_names(1, False) # optional - sage.modules 'a' - sage: F._parse_names(1, True) + sage: F._parse_names(1, True) # optional - sage.modules 'a' - sage: F._parse_names(2, False) is None + sage: F._parse_names(2, False) is None # optional - sage.modules True - sage: F._parse_names(2, True) is None + sage: F._parse_names(2, True) is None # optional - sage.modules True """ names = self._print_options.get('names', None) @@ -349,69 +349,69 @@ def _repr_generator(self, m): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) - sage: e = F.basis() - sage: e['a'] + 2*e['b'] # indirect doctest + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: e['a'] + 2*e['b'] # indirect doctest # optional - sage.modules B['a'] + 2*B['b'] - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="F") - sage: e = F.basis() - sage: e['a'] + 2*e['b'] # indirect doctest + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="F") # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: e['a'] + 2*e['b'] # indirect doctest # optional - sage.modules F['a'] + 2*F['b'] - sage: F.print_options(string_quotes=False) - sage: e['a'] + 2*e['b'] + sage: F.print_options(string_quotes=False) # optional - sage.modules + sage: e['a'] + 2*e['b'] # optional - sage.modules F[a] + 2*F[b] - sage: F = CombinatorialFreeModule(QQ, ['aa', 'bb', 'cc'], prefix="F") - sage: e = F.basis() - sage: F.print_options(iterate_key=True) - sage: e['aa'] + 2*e['bb'] + sage: F = CombinatorialFreeModule(QQ, ['aa', 'bb', 'cc'], prefix="F") # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: F.print_options(iterate_key=True) # optional - sage.modules + sage: e['aa'] + 2*e['bb'] # optional - sage.modules F['a', 'a'] + 2*F['b', 'b'] - sage: F.print_options(string_quotes=False) - sage: e['aa'] + 2*e['bb'] + sage: F.print_options(string_quotes=False) # optional - sage.modules + sage: e['aa'] + 2*e['bb'] # optional - sage.modules F[a, a] + 2*F[b, b] - sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), prefix="") - sage: original_print_options = QS3.print_options() - sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) - sage: a # indirect doctest + sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), prefix="") # optional - sage.combinat sage.modules + sage: original_print_options = QS3.print_options() # optional - sage.combinat sage.modules + sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) # optional - sage.combinat sage.modules + sage: a # indirect doctest # optional - sage.combinat sage.modules 2*[[1, 2, 3]] + 4*[[3, 2, 1]] - sage: QS3.print_options(bracket = False) - sage: a # indirect doctest + sage: QS3.print_options(bracket = False) # optional - sage.combinat sage.modules + sage: a # indirect doctest # optional - sage.combinat sage.modules 2*[1, 2, 3] + 4*[3, 2, 1] - sage: QS3.print_options(prefix='') - sage: a # indirect doctest + sage: QS3.print_options(prefix='') # optional - sage.combinat sage.modules + sage: a # indirect doctest # optional - sage.combinat sage.modules 2*[1, 2, 3] + 4*[3, 2, 1] - sage: QS3.print_options(bracket="|", scalar_mult=" *@* ") - sage: a # indirect doctest + sage: QS3.print_options(bracket="|", scalar_mult=" *@* ") # optional - sage.combinat sage.modules + sage: a # indirect doctest # optional - sage.combinat sage.modules 2 *@* |[1, 2, 3]| + 4 *@* |[3, 2, 1]| - sage: QS3.print_options(bracket="|", scalar_mult="*", iterate_key=True) - sage: a # indirect doctest + sage: QS3.print_options(bracket="|", scalar_mult="*", iterate_key=True) # optional - sage.combinat sage.modules + sage: a # indirect doctest # optional - sage.combinat sage.modules 2*|1, 2, 3| + 4*|3, 2, 1| - sage: QS3.print_options(**original_print_options) # reset + sage: QS3.print_options(**original_print_options) # reset # optional - sage.combinat sage.modules TESTS:: - sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), ('c','d')]) - sage: e = F.basis() - sage: e[('a','b')] + 2*e[('c','d')] # indirect doctest + sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), ('c','d')]) # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: e[('a','b')] + 2*e[('c','d')] # indirect doctest # optional - sage.modules B[('a', 'b')] + 2*B[('c', 'd')] - sage: F. = CombinatorialFreeModule(QQ) - sage: a + 2*b + sage: F. = CombinatorialFreeModule(QQ) # optional - sage.modules + sage: a + 2*b # optional - sage.modules a + 2*b - sage: F = CombinatorialFreeModule(QQ, ZZ) - sage: e = F.basis() - sage: 3*e[1] + 2*e[-2] + sage: F = CombinatorialFreeModule(QQ, ZZ) # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: 3*e[1] + 2*e[-2] # optional - sage.modules 2*B[-2] + 3*B[1] - sage: F.print_options(iterate_key=True) - sage: 3*e[1] + 2*e[-2] + sage: F.print_options(iterate_key=True) # optional - sage.modules + sage: 3*e[1] + 2*e[-2] # optional - sage.modules 2*B[-2] + 3*B[1] """ ret = self._parse_names(m, False) @@ -457,24 +457,24 @@ def _ascii_art_generator(self, m): TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() - sage: ascii_art(R[1,2,2,4]) + sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat + sage: ascii_art(R[1,2,2,4]) # optional - sage.combinat R **** ** ** * - sage: Partitions.options(diagram_str="#", convention="french") - sage: ascii_art(R[1,2,2,4]) + sage: Partitions.options(diagram_str="#", convention="french") # optional - sage.combinat + sage: ascii_art(R[1,2,2,4]) # optional - sage.combinat R # ## ## #### - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat - sage: F. = CombinatorialFreeModule(QQ) - sage: ascii_art(a + 2*b) + sage: F. = CombinatorialFreeModule(QQ) # optional - sage.modules + sage: ascii_art(a + 2*b) # optional - sage.modules a + 2*b """ from sage.typeset.ascii_art import AsciiArt, ascii_art @@ -493,26 +493,26 @@ def _unicode_art_generator(self, m): TESTS:: - sage: R = NonCommutativeSymmetricFunctions(QQ).R() - sage: unicode_art(R[1,2,2,4]) + sage: R = NonCommutativeSymmetricFunctions(QQ).R() # optional - sage.combinat + sage: unicode_art(R[1,2,2,4]) # optional - sage.combinat R ┌┬┬┬┐ ┌┼┼┴┴┘ ┌┼┼┘ ├┼┘ └┘ - sage: Partitions.options.convention="french" - sage: unicode_art(R[1,2,2,4]) + sage: Partitions.options.convention="french" # optional - sage.combinat + sage: unicode_art(R[1,2,2,4]) # optional - sage.combinat R ┌┐ ├┼┐ └┼┼┐ └┼┼┬┬┐ └┴┴┴┘ - sage: Partitions.options._reset() + sage: Partitions.options._reset() # optional - sage.combinat - sage: F. = CombinatorialFreeModule(QQ) - sage: unicode_art(a + 2*b) + sage: F. = CombinatorialFreeModule(QQ) # optional - sage.modules + sage: unicode_art(a + 2*b) # optional - sage.modules a + 2*b """ from sage.typeset.unicode_art import UnicodeArt, unicode_art @@ -546,47 +546,49 @@ def _latex_generator(self, m): EXAMPLES:: - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) - sage: e = F.basis() - sage: latex(e['a'] + 2*e['b']) # indirect doctest + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: latex(e['a'] + 2*e['b']) # indirect doctest # optional - sage.modules B_{a} + 2 B_{b} - sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="C") - sage: e = F.basis() - sage: latex(e['a'] + 2*e['b']) # indirect doctest + sage: F = CombinatorialFreeModule(QQ, ['a', 'b', 'c'], prefix="C") # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: latex(e['a'] + 2*e['b']) # indirect doctest # optional - sage.modules C_{a} + 2 C_{b} - sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), prefix="", scalar_mult="*") - sage: original_print_options = QS3.print_options() - sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) - sage: latex(a) # indirect doctest + sage: QS3 = CombinatorialFreeModule(QQ, Permutations(3), # optional - sage.combinat sage.modules + ....: prefix="", scalar_mult="*") + sage: original_print_options = QS3.print_options() # optional - sage.combinat sage.modules + sage: a = 2*QS3([1,2,3])+4*QS3([3,2,1]) # optional - sage.combinat sage.modules + sage: latex(a) # indirect doctest # optional - sage.combinat sage.modules 2 [1, 2, 3] + 4 [3, 2, 1] - sage: QS3.print_options(latex_bracket=True) - sage: latex(a) # indirect doctest + sage: QS3.print_options(latex_bracket=True) # optional - sage.combinat sage.modules + sage: latex(a) # indirect doctest # optional - sage.combinat sage.modules 2 \left[ [1, 2, 3] \right] + 4 \left[ [3, 2, 1] \right] - sage: QS3.print_options(latex_bracket="(") - sage: latex(a) # indirect doctest + sage: QS3.print_options(latex_bracket="(") # optional - sage.combinat sage.modules + sage: latex(a) # indirect doctest # optional - sage.combinat sage.modules 2 \left( [1, 2, 3] \right) + 4 \left( [3, 2, 1] \right) - sage: QS3.print_options(latex_bracket=('\\myleftbracket', '\\myrightbracket')) - sage: latex(a) # indirect doctest + sage: QS3.print_options(latex_bracket=('\\myleftbracket', # optional - sage.combinat sage.modules + ....: '\\myrightbracket')) + sage: latex(a) # indirect doctest # optional - sage.combinat sage.modules 2 \myleftbracket [1, 2, 3] \myrightbracket + 4 \myleftbracket [3, 2, 1] \myrightbracket - sage: QS3.print_options(**original_print_options) # reset + sage: QS3.print_options(**original_print_options) # reset # optional - sage.combinat sage.modules TESTS:: - sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)]) - sage: e = F.basis() - sage: latex(e[('a','b')]) # indirect doctest + sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)]) # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: latex(e[('a','b')]) # indirect doctest # optional - sage.modules B_{('a', 'b')} - sage: latex(2*e[(0,1,2)]) # indirect doctest + sage: latex(2*e[(0,1,2)]) # indirect doctest # optional - sage.modules 2 B_{\left(0, 1, 2\right)} - sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)], prefix="") - sage: e = F.basis() - sage: latex(2*e[(0,1,2)]) # indirect doctest + sage: F = CombinatorialFreeModule(QQ, [('a', 'b'), (0,1,2)], prefix="") # optional - sage.modules + sage: e = F.basis() # optional - sage.modules + sage: latex(2*e[(0,1,2)]) # indirect doctest # optional - sage.modules 2 \left(0, 1, 2\right) - sage: F. = CombinatorialFreeModule(QQ, latex_names='x,y,z') - sage: latex(a + 2*b) + sage: F. = CombinatorialFreeModule(QQ, latex_names='x,y,z') # optional - sage.modules + sage: latex(a + 2*b) # optional - sage.modules x + 2 y """ from sage.misc.latex import latex diff --git a/src/sage/structure/nonexact.py b/src/sage/structure/nonexact.py index ffb39e5f579..f5894af43ac 100644 --- a/src/sage/structure/nonexact.py +++ b/src/sage/structure/nonexact.py @@ -9,7 +9,7 @@ sage: R. = PowerSeriesRing(QQ) sage: R.default_prec() 20 - sage: cos(x) + sage: cos(x) # optional - sage.symbolic 1 - 1/2*x^2 + 1/24*x^4 - 1/720*x^6 + 1/40320*x^8 - 1/3628800*x^10 + 1/479001600*x^12 - 1/87178291200*x^14 + 1/20922789888000*x^16 - 1/6402373705728000*x^18 + O(x^20) diff --git a/src/sage/structure/parent.pyx b/src/sage/structure/parent.pyx index 564368806c0..dccccf1bbc8 100644 --- a/src/sage/structure/parent.pyx +++ b/src/sage/structure/parent.pyx @@ -86,7 +86,7 @@ TESTS: This came up in some subtle bug once:: - sage: gp(2) + gap(3) + sage: gp(2) + gap(3) # optional - sage.libs.pari 5 """ # **************************************************************************** @@ -584,8 +584,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: k = GF(5) - sage: k._set_element_constructor() + sage: k = GF(5) # optional - sage.rings.finite_rings + sage: k._set_element_constructor() # optional - sage.rings.finite_rings """ try: _element_constructor_ = self._element_constructor_ @@ -823,7 +823,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: ZZ._repr_option('ascii_art') False - sage: MatrixSpace(ZZ, 2)._repr_option('element_ascii_art') + sage: MatrixSpace(ZZ, 2)._repr_option('element_ascii_art') # optional - sage.modules True """ if not isinstance(key, basestring): @@ -909,36 +909,36 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: MS = MatrixSpace(QQ,2,2) + sage: MS = MatrixSpace(QQ, 2, 2) # optional - sage.modules This matrix space is in fact an algebra, and in particular it is a ring, from the point of view of categories:: - sage: MS.category() + sage: MS.category() # optional - sage.modules Category of infinite finite dimensional algebras with basis over (number fields and quotient fields and metric spaces) - sage: MS in Rings() + sage: MS in Rings() # optional - sage.modules True However, its class does not inherit from the base class ``Ring``:: - sage: isinstance(MS,Ring) + sage: isinstance(MS, Ring) # optional - sage.modules False Its ``_mul_`` method is inherited from the category, and can be used to create a left or right ideal:: - sage: MS._mul_.__module__ + sage: MS._mul_.__module__ # optional - sage.modules 'sage.categories.rings' - sage: MS*MS.1 # indirect doctest + sage: MS * MS.1 # indirect doctest # optional - sage.modules Left Ideal ( [0 1] [0 0] ) of Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: MS*[MS.1,2] + sage: MS * [MS.1, 2] # optional - sage.modules Left Ideal ( [0 1] @@ -948,14 +948,14 @@ cdef class Parent(sage.structure.category_object.CategoryObject): [0 2] ) of Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: MS.1*MS + sage: MS.1 * MS # optional - sage.modules Right Ideal ( [0 1] [0 0] ) of Full MatrixSpace of 2 by 2 dense matrices over Rational Field - sage: [MS.1,2]*MS + sage: [MS.1, 2] * MS # optional - sage.modules Right Ideal ( [0 1] @@ -1004,22 +1004,22 @@ cdef class Parent(sage.structure.category_object.CategoryObject): TESTS:: - sage: ZZ^3 + sage: ZZ^3 # optional - sage.modules Ambient free module of rank 3 over the principal ideal domain Integer Ring - sage: QQ^3 + sage: QQ^3 # optional - sage.modules Vector space of dimension 3 over Rational Field - sage: QQ[x]^3 + sage: QQ['x']^3 # optional - sage.modules Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field - sage: IntegerModRing(6)^3 + sage: IntegerModRing(6)^3 # optional - sage.modules Ambient free module of rank 3 over Ring of integers modulo 6 sage: 3^ZZ Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for ^: 'Integer Ring' and '' - sage: Partitions(3)^3 + sage: Partitions(3)^3 # optional - sage.combinat sage.modules Traceback (most recent call last): ... TypeError: unsupported operand type(s) for ** or pow(): 'Partitions_n_with_category' and 'int' @@ -1129,9 +1129,9 @@ cdef class Parent(sage.structure.category_object.CategoryObject): Check that :trac:`13824` is fixed:: - sage: 4/3 in GF(3) + sage: 4/3 in GF(3) # optional - sage.rings.finite_rings False - sage: 15/50 in GF(25, 'a') + sage: 15/50 in GF(25, 'a') # optional - sage.rings.finite_rings False sage: 7/4 in Integers(4) False @@ -1194,8 +1194,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): We make an exception for zero:: - sage: V = GF(7)^7 - sage: V.coerce(0) + sage: V = GF(7)^7 # optional - sage.modules sage.rings.finite_rings + sage: V.coerce(0) # optional - sage.modules sage.rings.finite_rings (0, 0, 0, 0, 0, 0, 0) """ cdef R = parent(x) @@ -1233,7 +1233,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: VectorSpace(GF(7), 3)[:10] + sage: VectorSpace(GF(7), 3)[:10] # optional - sage.rings.finite_rings [(0, 0, 0), (1, 0, 0), (2, 0, 0), @@ -1370,29 +1370,30 @@ cdef class Parent(sage.structure.category_object.CategoryObject): 6 sage: R. = PolynomialRing(QQ) - sage: f = R.hom([5], GF(7)) + sage: f = R.hom([5], GF(7)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... - ValueError: relations do not all (canonically) map to 0 under map determined by images of generators + ValueError: relations do not all (canonically) map to 0 + under map determined by images of generators - sage: R. = PolynomialRing(GF(7)) - sage: f = R.hom([3], GF(49,'a')) - sage: f + sage: R. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: f = R.hom([3], GF(49,'a')) # optional - sage.rings.finite_rings + sage: f # optional - sage.rings.finite_rings Ring morphism: From: Univariate Polynomial Ring in x over Finite Field of size 7 To: Finite Field in a of size 7^2 Defn: x |--> 3 - sage: f(x+6) + sage: f(x + 6) # optional - sage.rings.finite_rings 2 - sage: f(x^2+1) + sage: f(x^2 + 1) # optional - sage.rings.finite_rings 3 Natural morphism:: - sage: f = ZZ.hom(GF(5)) - sage: f(7) + sage: f = ZZ.hom(GF(5)) # optional - sage.rings.finite_rings + sage: f(7) # optional - sage.rings.finite_rings 2 - sage: f + sage: f # optional - sage.rings.finite_rings Natural morphism: From: Integer Ring To: Finite Field of size 5 @@ -1677,30 +1678,30 @@ cdef class Parent(sage.structure.category_object.CategoryObject): ....: return a.parent()(D) sage: R. = QQ['x, y, z'] - sage: G = SymmetricGroup(3) - sage: act = SymmetricGroupAction(G, R) + sage: G = SymmetricGroup(3) # optional - sage.groups + sage: act = SymmetricGroupAction(G, R) # optional - sage.groups sage: t = x + 2*y + 3*z - sage: act(G((1, 2)), t) + sage: act(G((1, 2)), t) # optional - sage.groups 2*x + y + 3*z - sage: act(G((2, 3)), t) + sage: act(G((2, 3)), t) # optional - sage.groups x + 3*y + 2*z - sage: act(G((1, 2, 3)), t) + sage: act(G((1, 2, 3)), t) # optional - sage.groups 3*x + y + 2*z This should fail, since we have not registered the left action:: - sage: G((1,2)) * t + sage: G((1,2)) * t # optional - sage.groups Traceback (most recent call last): ... TypeError: ... Now let's make it work:: - sage: R._unset_coercions_used() - sage: R.register_action(act) - sage: G((1, 2)) * t + sage: R._unset_coercions_used() # optional - sage.groups + sage: R.register_action(act) # optional - sage.groups + sage: G((1, 2)) * t # optional - sage.groups 2*x + y + 3*z """ if self._coercions_used: @@ -1761,35 +1762,35 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: S3 = AlternatingGroup(3) - sage: G = SL(3, QQ) - sage: p = S3[2]; p.matrix() + sage: S3 = AlternatingGroup(3) # optional - sage.groups + sage: G = SL(3, QQ) # optional - sage.groups + sage: p = S3[2]; p.matrix() # optional - sage.groups [0 0 1] [1 0 0] [0 1 0] In general one cannot mix matrices and permutations:: - sage: G(p) + sage: G(p) # optional - sage.groups Traceback (most recent call last): ... TypeError: unable to convert (1,3,2) to a rational - sage: phi = S3.hom(lambda p: G(p.matrix()), codomain = G) - sage: phi(p) + sage: phi = S3.hom(lambda p: G(p.matrix()), codomain=G) # optional - sage.groups + sage: phi(p) # optional - sage.groups [0 0 1] [1 0 0] [0 1 0] - sage: S3._unset_coercions_used() - sage: S3.register_embedding(phi) + sage: S3._unset_coercions_used() # optional - sage.groups + sage: S3.register_embedding(phi) # optional - sage.groups By :trac:`14711`, coerce maps should be copied when using outside of the coercion system:: - sage: phi = copy(S3.coerce_embedding()); phi + sage: phi = copy(S3.coerce_embedding()); phi # optional - sage.groups Generic morphism: From: Alternating group of order 3!/2 as a permutation group To: Special Linear Group of degree 3 over Rational Field - sage: phi(p) + sage: phi(p) # optional - sage.groups [0 0 1] [1 0 0] [0 1 0] @@ -1797,11 +1798,11 @@ cdef class Parent(sage.structure.category_object.CategoryObject): This does not work since matrix groups are still old-style parents (see :trac:`14014`):: - sage: G(p) # todo: not implemented + sage: G(p) # todo: not implemented # optional - sage.groups Though one can have a permutation act on the rows of a matrix:: - sage: G(1) * p + sage: G(1) * p # optional - sage.groups [0 0 1] [1 0 0] [0 1 0] @@ -1810,29 +1811,30 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: x = QQ['x'].0 sage: t = abs(ZZ.random_element(10^6)) - sage: K = NumberField(x^2 + 2*3*7*11, "a"+str(t)) - sage: a = K.gen() - sage: K_into_MS = K.hom([a.matrix()]) - sage: K._unset_coercions_used() - sage: K.register_embedding(K_into_MS) - - sage: L = NumberField(x^2 + 2*3*7*11*19*31, "b"+str(abs(ZZ.random_element(10^6)))) - sage: b = L.gen() - sage: L_into_MS = L.hom([b.matrix()]) - sage: L._unset_coercions_used() - sage: L.register_embedding(L_into_MS) - - sage: K.coerce_embedding()(a) + sage: K = NumberField(x^2 + 2*3*7*11, "a"+str(t)) # optional - sage.rings.number_field + sage: a = K.gen() # optional - sage.rings.number_field + sage: K_into_MS = K.hom([a.matrix()]) # optional - sage.rings.number_field + sage: K._unset_coercions_used() # optional - sage.rings.number_field + sage: K.register_embedding(K_into_MS) # optional - sage.rings.number_field + + sage: L = NumberField(x^2 + 2*3*7*11*19*31, # optional - sage.rings.number_field + ....: "b" + str(abs(ZZ.random_element(10^6)))) + sage: b = L.gen() # optional - sage.rings.number_field + sage: L_into_MS = L.hom([b.matrix()]) # optional - sage.rings.number_field + sage: L._unset_coercions_used() # optional - sage.rings.number_field + sage: L.register_embedding(L_into_MS) # optional - sage.rings.number_field + + sage: K.coerce_embedding()(a) # optional - sage.rings.number_field [ 0 1] [-462 0] - sage: L.coerce_embedding()(b) + sage: L.coerce_embedding()(b) # optional - sage.rings.number_field [ 0 1] [-272118 0] - sage: a.matrix() * b.matrix() + sage: a.matrix() * b.matrix() # optional - sage.rings.number_field [-272118 0] [ 0 -462] - sage: a.matrix() * b.matrix() + sage: a.matrix() * b.matrix() # optional - sage.rings.number_field [-272118 0] [ 0 -462] """ @@ -1865,13 +1867,15 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: K. = NumberField(x^3 + x^2 + 1, embedding=1) # optional - sage.rings.number_field sage: K.coerce_embedding() # optional - sage.rings.number_field Generic morphism: - From: Number Field in a with defining polynomial x^3 + x^2 + 1 with a = -1.465571231876768? + From: Number Field in a with defining polynomial x^3 + x^2 + 1 + with a = -1.465571231876768? To: Real Lazy Field Defn: a -> -1.465571231876768? - sage: K.=NumberField(x^3+x^2+1,embedding=CC.gen()) - sage: K.coerce_embedding() + sage: K. = NumberField(x^3 + x^2 + 1, embedding=CC.gen()) # optional - sage.rings.number_field + sage: K.coerce_embedding() # optional - sage.rings.number_field Generic morphism: - From: Number Field in a with defining polynomial x^3 + x^2 + 1 with a = 0.2327856159383841? + 0.7925519925154479?*I + From: Number Field in a with defining polynomial x^3 + x^2 + 1 + with a = 0.2327856159383841? + 0.7925519925154479?*I To: Complex Lazy Field Defn: a -> 0.2327856159383841? + 0.7925519925154479?*I """ @@ -1922,11 +1926,11 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: QQ['x']._generic_convert_map(SR) + sage: QQ['x']._generic_convert_map(SR) # optional - sage.symbolic Conversion via _polynomial_ method map: From: Symbolic Ring To: Univariate Polynomial Ring in x over Rational Field - sage: GF(11)._generic_convert_map(GF(7)) + sage: GF(11)._generic_convert_map(GF(7)) # optional - sage.rings.finite_rings Conversion map: From: Finite Field of size 7 To: Finite Field of size 11 @@ -2098,13 +2102,13 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: import gc sage: _ = gc.collect() - sage: K = GF(1<<55,'t') - sage: for i in range(50): + sage: K = GF(1<<55,'t') # optional - sage.rings.finite_rings + sage: for i in range(50): # optional - sage.rings.finite_rings ....: a = K.random_element() ....: E = EllipticCurve(j=a) ....: b = K.has_coerce_map_from(E) - sage: _ = gc.collect() - sage: len([x for x in gc.get_objects() if isinstance(x,type(E))]) + sage: _ = gc.collect() # optional - sage.rings.finite_rings + sage: len([x for x in gc.get_objects() if isinstance(x, type(E))]) # optional - sage.rings.finite_rings 1 TESTS: @@ -2112,12 +2116,12 @@ cdef class Parent(sage.structure.category_object.CategoryObject): The following was fixed in :trac:`12969`:: sage: R = QQ['q,t'].fraction_field() - sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) - sage: H = Sym.macdonald().H() - sage: P = Sym.macdonald().P() - sage: m = Sym.monomial() - sage: Ht = Sym.macdonald().Ht() - sage: phi = m.coerce_map_from(P) + sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) # optional - sage.combinat + sage: H = Sym.macdonald().H() # optional - sage.combinat + sage: P = Sym.macdonald().P() # optional - sage.combinat + sage: m = Sym.monomial() # optional - sage.combinat + sage: Ht = Sym.macdonald().Ht() # optional - sage.combinat + sage: phi = m.coerce_map_from(P) # optional - sage.combinat """ return copy(self._internal_coerce_map_from(S)) @@ -2148,15 +2152,15 @@ cdef class Parent(sage.structure.category_object.CategoryObject): To: Rational Field sage: R = QQ['q,t'].fraction_field() - sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) - sage: P = Sym.macdonald().P() - sage: Ht = Sym.macdonald().Ht() - sage: Ht._internal_coerce_map_from(P) + sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) # optional - sage.combinat + sage: P = Sym.macdonald().P() # optional - sage.combinat + sage: Ht = Sym.macdonald().Ht() # optional - sage.combinat + sage: Ht._internal_coerce_map_from(P) # optional - sage.combinat (map internal to coercion system -- copy before use) Composite map: From: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald P basis To: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald Ht basis - sage: copy(Ht._internal_coerce_map_from(P)) + sage: copy(Ht._internal_coerce_map_from(P)) # optional - sage.combinat Composite map: From: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald P basis To: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald Ht basis @@ -2174,8 +2178,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): The following was fixed in :trac:`4740`:: - sage: F = GF(13) - sage: F._internal_coerce_map_from(F) is F._internal_coerce_map_from(F) + sage: F = GF(13) # optional - sage.rings.finite_rings + sage: F._internal_coerce_map_from(F) is F._internal_coerce_map_from(F) # optional - sage.rings.finite_rings True """ if not good_as_coerce_domain(S): @@ -2540,10 +2544,14 @@ cdef class Parent(sage.structure.category_object.CategoryObject): TESTS:: - sage: M = QQ['y']^3 - sage: M.get_action(ZZ['x']['y']) - Right scalar multiplication by Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Integer Ring on Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field - sage: print(M.get_action(ZZ['x'])) + sage: M = QQ['y']^3 # optional - sage.modules + sage: M.get_action(ZZ['x']['y']) # optional - sage.modules + Right scalar multiplication + by Univariate Polynomial Ring in y + over Univariate Polynomial Ring in x over Integer Ring + on Ambient free module of rank 3 over the principal ideal domain + Univariate Polynomial Ring in y over Rational Field + sage: print(M.get_action(ZZ['x'])) # optional - sage.modules None """ action = self._get_action_(S, op, self_on_left) @@ -2564,27 +2572,34 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: E = EllipticCurve([1,0]) sage: coercion_model.get_action(E, ZZ, operator.mul) - Right Integer Multiplication by Integer Ring on Elliptic Curve defined by y^2 = x^3 + x over Rational Field + Right Integer Multiplication by Integer Ring + on Elliptic Curve defined by y^2 = x^3 + x over Rational Field sage: coercion_model.get_action(ZZ, E, operator.mul) - Left Integer Multiplication by Integer Ring on Elliptic Curve defined by y^2 = x^3 + x over Rational Field + Left Integer Multiplication by Integer Ring + on Elliptic Curve defined by y^2 = x^3 + x over Rational Field sage: coercion_model.get_action(E, int, operator.mul) - Right Integer Multiplication by Set of Python objects of class 'int' on Elliptic Curve defined by y^2 = x^3 + x over Rational Field + Right Integer Multiplication by Set of Python objects of class 'int' + on Elliptic Curve defined by y^2 = x^3 + x over Rational Field sage: coercion_model.get_action(int, E, operator.mul) - Left Integer Multiplication by Set of Python objects of class 'int' on Elliptic Curve defined by y^2 = x^3 + x over Rational Field + Left Integer Multiplication by Set of Python objects of class 'int' + on Elliptic Curve defined by y^2 = x^3 + x over Rational Field :: sage: R. = CDF[] sage: coercion_model.get_action(R, ZZ, operator.pow) - Right Integer Powering by Integer Ring on Univariate Polynomial Ring in x over Complex Double Field + Right Integer Powering by Integer Ring + on Univariate Polynomial Ring in x over Complex Double Field sage: print(coercion_model.get_action(ZZ, R, operator.pow)) None sage: coercion_model.get_action(R, int, operator.pow) - Right Integer Powering by Set of Python objects of class 'int' on Univariate Polynomial Ring in x over Complex Double Field + Right Integer Powering by Set of Python objects of class 'int' + on Univariate Polynomial Ring in x over Complex Double Field sage: print(coercion_model.get_action(int, R, operator.pow)) None sage: coercion_model.get_action(R, IntegerModRing(7), operator.pow) - Right Integer Powering by Ring of integers modulo 7 on Univariate Polynomial Ring in x over Complex Double Field + Right Integer Powering by Ring of integers modulo 7 + on Univariate Polynomial Ring in x over Complex Double Field :: @@ -2791,9 +2806,9 @@ cdef class Parent(sage.structure.category_object.CategoryObject): True sage: ZZ.is_exact() True - sage: Qp(7).is_exact() + sage: Qp(7).is_exact() # optional - sage.rings.padics False - sage: Zp(7, type='capped-abs').is_exact() + sage: Zp(7, type='capped-abs').is_exact() # optional - sage.rings.padics False """ return True @@ -2806,10 +2821,14 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: [R._is_numerical() for R in [RR, CC, QQ, QuadraticField(-1)]] - [True, True, True, True] - sage: [R._is_numerical() for R in [SR, QQ['x'], QQ[['x']]]] - [False, False, False] + sage: QuadraticField(-1)._is_numerical() # optional - sage.rings.number_field + True + sage: [R._is_numerical() for R in [RR, CC, QQ]] + [True, True, True] + sage: SR._is_numerical() # optional - sage.symbolic + False + sage: [R._is_numerical() for R in [QQ['x'], QQ[['x']]]] + [False, False] sage: [R._is_numerical() for R in [RIF, RBF, CIF, CBF]] [False, False, False, False] """ @@ -2832,12 +2851,18 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: - sage: [R._is_real_numerical() for R in [RR, QQ, ZZ, RLF, QuadraticField(2)]] - [True, True, True, True, True] - sage: [R._is_real_numerical() for R in [CC, QuadraticField(-1)]] + sage: QuadraticField(2)._is_real_numerical() # optional - sage.rings.number_field + True + sage: [R._is_real_numerical() for R in [RR, QQ, ZZ, RLF]] + [True, True, True, True] + sage: QuadraticField(-1)._is_real_numerical() # optional - sage.rings.number_field + False + sage: CC._is_real_numerical() + False + sage: SR._is_real_numerical() # optional - sage.symbolic + False + sage: [R._is_real_numerical() for R in [QQ['x'], QQ[['x']]]] [False, False] - sage: [R._is_real_numerical() for R in [SR, QQ['x'], QQ[['x']]]] - [False, False, False] sage: [R._is_real_numerical() for R in [RIF, RBF, CIF, CBF]] [False, False, False, False] """ @@ -2885,7 +2910,7 @@ cdef class Set_generic(Parent): sage: bool(Set(QQ)) True - sage: bool(Set(GF(3))) + sage: bool(Set(GF(3))) # optional - sage.rings.finite_rings True """ return not (self.is_finite() and len(self) == 0) @@ -2926,9 +2951,9 @@ cdef class EltPair: Verify that :trac:`16341` has been resolved:: - sage: K. = Qq(9) # optional - sage.rings.padics - sage: E = EllipticCurve_from_j(0).base_extend(K) # optional - sage.rings.padics - sage: E.get_action(ZZ) # optional - sage.rings.padics + sage: K. = Qq(9) # optional - sage.rings.padics + sage: E = EllipticCurve_from_j(0).base_extend(K) # optional - sage.rings.padics + sage: E.get_action(ZZ) # optional - sage.rings.padics Right Integer Multiplication by Integer Ring on Elliptic Curve defined by y^2 + (1+O(3^20))*y = x^3 diff --git a/src/sage/structure/parent_gens.pyx b/src/sage/structure/parent_gens.pyx index 332ec274a42..43540c75254 100644 --- a/src/sage/structure/parent_gens.pyx +++ b/src/sage/structure/parent_gens.pyx @@ -47,14 +47,14 @@ This example illustrates generators for a free module over `\ZZ`. :: - sage: M = FreeModule(ZZ, 4) - sage: M + sage: M = FreeModule(ZZ, 4) # optional - sage.modules + sage: M # optional - sage.modules Ambient free module of rank 4 over the principal ideal domain Integer Ring - sage: M.ngens() + sage: M.ngens() # optional - sage.modules 4 - sage: M.gen(0) + sage: M.gen(0) # optional - sage.modules (1, 0, 0, 0) - sage: M.gens() + sage: M.gens() # optional - sage.modules ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)) """ @@ -240,31 +240,31 @@ cdef class ParentWithGens(ParentWithBase): 6 sage: R. = PolynomialRing(QQ) - sage: f = R.hom([5], GF(7)) + sage: f = R.hom([5], GF(7)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: relations do not all (canonically) map to 0 under map determined by images of generators - sage: R. = PolynomialRing(GF(7)) - sage: f = R.hom([3], GF(49,'a')) - sage: f + sage: R. = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings + sage: f = R.hom([3], GF(49, 'a')) # optional - sage.rings.finite_rings + sage: f # optional - sage.rings.finite_rings Ring morphism: From: Univariate Polynomial Ring in x over Finite Field of size 7 To: Finite Field in a of size 7^2 Defn: x |--> 3 - sage: f(x+6) + sage: f(x + 6) # optional - sage.rings.finite_rings 2 - sage: f(x^2+1) + sage: f(x^2 + 1) # optional - sage.rings.finite_rings 3 EXAMPLES: Natural morphism :: - sage: f = ZZ.hom(GF(5)) - sage: f(7) + sage: f = ZZ.hom(GF(5)) # optional - sage.rings.finite_rings + sage: f(7) # optional - sage.rings.finite_rings 2 - sage: f + sage: f # optional - sage.rings.finite_rings Natural morphism: From: Integer Ring To: Finite Field of size 5 @@ -280,13 +280,13 @@ cdef class ParentWithGens(ParentWithBase): You can specify a map on the base ring:: - sage: k = GF(2) - sage: R. = k[] - sage: l. = k.extension(a^3 + a^2 + 1) - sage: R. = l[] - sage: m. = l.extension(b^2 + b + a) - sage: n. = GF(2^6) - sage: m.hom([z^4 + z^3 + 1], base_map=l.hom([z^5 + z^4 + z^2])) + sage: k = GF(2) # optional - sage.rings.finite_rings + sage: R. = k[] # optional - sage.rings.finite_rings + sage: l. = k.extension(a^3 + a^2 + 1) # optional - sage.rings.finite_rings + sage: R. = l[] # optional - sage.rings.finite_rings + sage: m. = l.extension(b^2 + b + a) # optional - sage.rings.finite_rings + sage: n. = GF(2^6) # optional - sage.rings.finite_rings + sage: m.hom([z^4 + z^3 + 1], base_map=l.hom([z^5 + z^4 + z^2])) # optional - sage.rings.finite_rings Ring morphism: From: Univariate Quotient Polynomial Ring in b over Finite Field in a of size 2^3 with modulus b^2 + b + a To: Finite Field in z of size 2^6 @@ -335,7 +335,7 @@ cdef class localvars: EXAMPLES:: - sage: R. = PolynomialRing(QQ,2) + sage: R. = PolynomialRing(QQ, 2) sage: with localvars(R, 'z,w'): ....: print(x^3 + y^3 - x*y) z^3 + w^3 - z*w diff --git a/src/sage/structure/parent_old.pyx b/src/sage/structure/parent_old.pyx index 097acdd55de..db7f7bce274 100644 --- a/src/sage/structure/parent_old.pyx +++ b/src/sage/structure/parent_old.pyx @@ -13,7 +13,7 @@ TESTS: This came up in some subtle bug once:: - sage: gp(2) + gap(3) + sage: gp(2) + gap(3) # optional - sage.libs.pari 5 """ @@ -46,19 +46,19 @@ cdef class Parent(parent.Parent): TESTS:: - sage: V = VectorSpace(GF(2,'a'),2) - sage: V.list() + sage: V = VectorSpace(GF(2,'a'), 2) # optional - sage.rings.finite_rings + sage: V.list() # optional - sage.rings.finite_rings [(0, 0), (1, 0), (0, 1), (1, 1)] - sage: MatrixSpace(GF(3), 1, 1).list() + sage: MatrixSpace(GF(3), 1, 1).list() # optional - sage.rings.finite_rings [[0], [1], [2]] - sage: DirichletGroup(3).list() + sage: DirichletGroup(3).list() # optional - sage.groups [Dirichlet character modulo 3 of conductor 1 mapping 2 |--> 1, Dirichlet character modulo 3 of conductor 3 mapping 2 |--> -1] - sage: K = GF(7^6,'a') - sage: K.list()[:10] # long time + sage: K = GF(7^6,'a') # optional - sage.rings.finite_rings + sage: K.list()[:10] # long time # optional - sage.rings.finite_rings [0, 1, 2, 3, 4, 5, 6, a, a + 1, a + 2] - sage: K. = GF(4) - sage: K.list() + sage: K. = GF(4) # optional - sage.rings.finite_rings + sage: K.list() # optional - sage.rings.finite_rings [0, a, a + 1, 1] """ diff --git a/src/sage/structure/proof/proof.py b/src/sage/structure/proof/proof.py index a5a931f5675..b232225da33 100644 --- a/src/sage/structure/proof/proof.py +++ b/src/sage/structure/proof/proof.py @@ -196,10 +196,12 @@ class WithProof(): systems for a block of code, with a guarantee that it will be set back to how it was before after the block is done, even if there is an error. - EXAMPLES:: + EXAMPLES: + + This would hang "forever" if attempted with ``proof=True``:: sage: proof.arithmetic(True) - sage: with proof.WithProof('arithmetic',False): # this would hang "forever" if attempted with proof=True + sage: with proof.WithProof('arithmetic', False): # optional - sage.libs.pari ....: print((10^1000 + 453).is_prime()) ....: print(1/0) Traceback (most recent call last): diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py index 45ca7765e3d..1286d6a1114 100644 --- a/src/sage/structure/sequence.py +++ b/src/sage/structure/sequence.py @@ -45,8 +45,8 @@ special parent. This is what should happen, e.g., with finite field elements of different characteristics:: - sage: v = Sequence([GF(3)(1), GF(7)(1)]) - sage: v.universe() + sage: v = Sequence([GF(3)(1), GF(7)(1)]) # optional - sage.rings.finite_rings + sage: v.universe() # optional - sage.rings.finite_rings Category of objects You can make a list immutable with ``v.freeze()``. Assignment is @@ -201,9 +201,9 @@ def Sequence(x, universe=None, check=True, immutable=False, cr=False, cr_str=Non This example illustrates how every element of a list is taken into account when constructing a sequence.:: - sage: v = Sequence([1,7,6,GF(5)(3)]); v + sage: v = Sequence([1, 7, 6, GF(5)(3)]); v # optional - sage.rings.finite_rings [1, 2, 1, 3] - sage: v.universe() + sage: v.universe() # optional - sage.rings.finite_rings Finite Field of size 5 TESTS:: @@ -397,9 +397,9 @@ class Sequence_generic(sage.structure.sage_object.SageObject, list): :: - sage: v = Sequence([1,7,6,GF(5)(3)]); v + sage: v = Sequence([1, 7, 6, GF(5)(3)]); v # optional - sage.rings.finite_rings [1, 2, 1, 3] - sage: v.universe() + sage: v.universe() # optional - sage.rings.finite_rings Finite Field of size 5 """ @@ -674,11 +674,11 @@ def _latex_(self): r""" TESTS:: - sage: t= Sequence([sqrt(x), exp(x), x^(x-1)], universe=SR); t + sage: t= Sequence([sqrt(x), exp(x), x^(x-1)], universe=SR); t # optional - sage.symbolic [sqrt(x), e^x, x^(x - 1)] - sage: t._latex_() + sage: t._latex_() # optional - sage.symbolic '\\left[\\sqrt{x}, e^{x}, x^{x - 1}\\right]' - sage: latex(t) + sage: latex(t) # optional - sage.symbolic \left[\sqrt{x}, e^{x}, x^{x - 1}\right] """ from sage.misc.latex import list_function as list_latex_function @@ -710,9 +710,9 @@ def universe(self): EXAMPLES:: - sage: Sequence([1,2/3,-2/5]).universe() + sage: Sequence([1, 2/3, -2/5]).universe() Rational Field - sage: Sequence([1,2/3,'-2/5']).universe() + sage: Sequence([1, 2/3, '-2/5']).universe() Category of objects """ return self.__universe @@ -738,7 +738,7 @@ def set_immutable(self): EXAMPLES:: - sage: v = Sequence([1,2,3,4/5]) + sage: v = Sequence([1, 2, 3, 4/5]) sage: v[0] = 5 sage: v [5, 2, 3, 4/5] @@ -759,7 +759,7 @@ def is_immutable(self): EXAMPLES:: - sage: v = Sequence([1,2,3,4/5]) + sage: v = Sequence([1, 2, 3, 4/5]) sage: v[0] = 5 sage: v [5, 2, 3, 4/5] @@ -778,7 +778,7 @@ def is_mutable(self): """ EXAMPLES:: - sage: a = Sequence([1,2/3,-2/5]) + sage: a = Sequence([1, 2/3, -2/5]) sage: a.is_mutable() True sage: a[0] = 100 diff --git a/src/sage/structure/unique_representation.py b/src/sage/structure/unique_representation.py index 7d30c39d66c..a0174109283 100644 --- a/src/sage/structure/unique_representation.py +++ b/src/sage/structure/unique_representation.py @@ -21,13 +21,13 @@ instances constructed with the same arguments share the same memory representation. For example, calling twice:: - sage: G = SymmetricGroup(6) - sage: H = SymmetricGroup(6) + sage: G = SymmetricGroup(6) # optional - sage.groups + sage: H = SymmetricGroup(6) # optional - sage.groups to create the symmetric group on six elements gives back the same object:: - sage: G is H + sage: G is H # optional - sage.groups True This is a standard design pattern. Besides saving memory, it allows for @@ -100,9 +100,9 @@ class will by default also be used as keys for the cache:: since ``C(1)`` already is in the cache, and since the unit elements in different finite fields are all equal to the integer one, we find:: - sage: GF(5)(1) == 1 == GF(3)(1) + sage: GF(5)(1) == 1 == GF(3)(1) # optional - sage.rings.finite_rings True - sage: C(1) is C(GF(3)(1)) is C(GF(5)(1)) + sage: C(1) is C(GF(3)(1)) is C(GF(5)(1)) # optional - sage.rings.finite_rings True But ``C(2)`` is not in the cache, and the number two is not equal in different @@ -112,9 +112,9 @@ class will by default also be used as keys for the cache:: when comparing elements of *distinct* algebraic structures!!). Hence, we have:: - sage: GF(5)(2) == GF(3)(2) + sage: GF(5)(2) == GF(3)(2) # optional - sage.rings.finite_rings False - sage: C(GF(3)(2)) is C(GF(5)(2)) + sage: C(GF(3)(2)) is C(GF(5)(2)) # optional - sage.rings.finite_rings False Normalising the arguments @@ -436,14 +436,14 @@ class is directly created, then the cache is not used:: sage: isinstance(GF, sage.structure.factory.UniqueFactory) True - sage: K5 = GF(5) - sage: type(K5) + sage: K5 = GF(5) # optional - sage.rings.finite_rings + sage: type(K5) # optional - sage.rings.finite_rings - sage: K25 = GF(25, 'x') - sage: type(K25) + sage: K25 = GF(25, 'x') # optional - sage.rings.finite_rings + sage: type(K25) # optional - sage.rings.finite_rings - sage: Kp = GF(next_prime_power(1000000)^2, 'x') - sage: type(Kp) + sage: Kp = GF(next_prime_power(1000000)^2, 'x') # optional - sage.rings.finite_rings + sage: type(Kp) # optional - sage.rings.finite_rings This can be confusing to the user. Namely, the user might determine the class @@ -498,9 +498,9 @@ class :class:`~sage.misc.fast_methods.WithEqualityById`, which provides since they are equal to groups created in a totally different way, namely to subgroups:: - sage: G = SymmetricGroup(6) - sage: G3 = G.subgroup([G((1,2,3,4,5,6)),G((1,2))]) - sage: G is G3 + sage: G = SymmetricGroup(6) # optional - sage.groups + sage: G3 = G.subgroup([G((1,2,3,4,5,6)), G((1,2))]) # optional - sage.groups + sage: G is G3 # optional - sage.groups False sage: type(G) == type(G3) False @@ -1188,15 +1188,15 @@ class UniqueRepresentation(CachedRepresentation, WithEqualityById): the same memory representation), if and only if they were created using equal arguments. For example, calling twice:: - sage: f = SymmetricFunctions(QQ) - sage: g = SymmetricFunctions(QQ) + sage: f = SymmetricFunctions(QQ) # optional - sage.combinat + sage: g = SymmetricFunctions(QQ) # optional - sage.combinat to create the symmetric function algebra over `\QQ` actually gives back the same object:: - sage: f == g + sage: f == g # optional - sage.combinat True - sage: f is g + sage: f is g # optional - sage.combinat True This is a standard design pattern. It allows for sharing cached data (say @@ -1211,14 +1211,14 @@ class UniqueRepresentation(CachedRepresentation, WithEqualityById): derive from it, or make sure some of its super classes does. Also, it groups together the class and the factory in a single gadget:: - sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) + sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) # optional - sage.combinat True - sage: issubclass(SymmetricFunctions, UniqueRepresentation) + sage: issubclass(SymmetricFunctions, UniqueRepresentation) # optional - sage.combinat True This nice behaviour is not available when one just uses a factory:: - sage: isinstance(GF(7), GF) + sage: isinstance(GF(7), GF) # optional - sage.rings.finite_rings Traceback (most recent call last): ... TypeError: isinstance() arg 2 must be a type... From 2882223f5974ee2f37e68bdc73cf343f0a55a6a4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 24 Apr 2023 20:06:18 -0700 Subject: [PATCH 073/205] sage.features: Update tested Python module for feature 'sage.combinat' --- src/sage/features/sagemath.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index 27faca1d3fa..04b2e07c156 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -63,9 +63,10 @@ def __init__(self): """ # sage.combinat will be a namespace package. # Testing whether sage.combinat itself can be imported is meaningless. + # Some modules providing basic combinatorics are already included in sagemath-categories. # Hence, we test a Python module within the package. JoinFeature.__init__(self, 'sage.combinat', - [PythonModule('sage.combinat.combination')]) + [PythonModule('sage.combinat.tableau')]) class sage__geometry__polyhedron(PythonModule): From 058ff2a526c54c31aa8cff7ba8e80224e3d4fef1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 4 Jun 2023 15:25:03 -0700 Subject: [PATCH 074/205] sage.features: Define features 'sage.schemes', 'sage.modular'; add spkg information --- src/sage/categories/action.pyx | 32 ++++++------ src/sage/categories/hecke_modules.py | 10 ++-- src/sage/categories/homset.py | 12 ++--- src/sage/features/sagemath.py | 78 ++++++++++++++++++++++++---- 4 files changed, 95 insertions(+), 37 deletions(-) diff --git a/src/sage/categories/action.pyx b/src/sage/categories/action.pyx index b90d97e0f02..4637e239dce 100644 --- a/src/sage/categories/action.pyx +++ b/src/sage/categories/action.pyx @@ -432,16 +432,16 @@ cdef class PrecomposedAction(Action): We demonstrate that an example discussed on :trac:`14711` did not become a problem:: - sage: E = ModularSymbols(11).2 - sage: s = E.modular_symbol_rep() - sage: del E,s - sage: import gc - sage: _ = gc.collect() - sage: E = ModularSymbols(11).2 - sage: v = E.manin_symbol_rep() - sage: c,x = v[0] - sage: y = x.modular_symbol_rep() - sage: coercion_model.get_action(QQ, parent(y), op=operator.mul) + sage: E = ModularSymbols(11).2 # optional - sage.modular + sage: s = E.modular_symbol_rep() # optional - sage.modular + sage: del E,s # optional - sage.modular + sage: import gc # optional - sage.modular + sage: _ = gc.collect() # optional - sage.modular + sage: E = ModularSymbols(11).2 # optional - sage.modular + sage: v = E.manin_symbol_rep() # optional - sage.modular + sage: c,x = v[0] # optional - sage.modular + sage: y = x.modular_symbol_rep() # optional - sage.modular + sage: coercion_model.get_action(QQ, parent(y), op=operator.mul) # optional - sage.modular Left scalar multiplication by Rational Field on Abelian Group of all Formal Finite Sums over Rational Field with precomposition on right by Coercion map: @@ -483,12 +483,12 @@ cdef class PrecomposedAction(Action): Check that this action can be pickled (:trac:`29031`):: - sage: E = ModularSymbols(11).2 - sage: v = E.manin_symbol_rep() - sage: c,x = v[0] - sage: y = x.modular_symbol_rep() - sage: act = coercion_model.get_action(QQ, parent(y), op=operator.mul) - sage: loads(dumps(act)) is not None + sage: E = ModularSymbols(11).2 # optional - sage.modular + sage: v = E.manin_symbol_rep() # optional - sage.modular + sage: c,x = v[0] # optional - sage.modular + sage: y = x.modular_symbol_rep() # optional - sage.modular + sage: act = coercion_model.get_action(QQ, parent(y), op=operator.mul) # optional - sage.modular + sage: loads(dumps(act)) is not None # optional - sage.modular True """ return (type(self), (self._action, self.G_precomposition, self.S_precomposition)) diff --git a/src/sage/categories/hecke_modules.py b/src/sage/categories/hecke_modules.py index 9372e88c54b..130314186ac 100644 --- a/src/sage/categories/hecke_modules.py +++ b/src/sage/categories/hecke_modules.py @@ -103,7 +103,7 @@ class ParentMethods: def _Hom_(self, Y, category): r""" - Returns the homset from ``self`` to ``Y`` in the category ``category`` + Return the homset from ``self`` to ``Y`` in the category ``category`` INPUT: @@ -121,13 +121,13 @@ def _Hom_(self, Y, category): EXAMPLES:: - sage: M = ModularForms(Gamma0(7), 4) - sage: H = M._Hom_(M, category = HeckeModules(QQ)); H + sage: M = ModularForms(Gamma0(7), 4) # optional - sage.modular + sage: H = M._Hom_(M, category=HeckeModules(QQ)); H # optional - sage.modular Set of Morphisms from Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(7) of weight 4 over Rational Field to Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(7) of weight 4 over Rational Field in Category of Hecke modules over Rational Field - sage: H.__class__ + sage: H.__class__ # optional - sage.modular sage: TestSuite(H).run(skip=["_test_elements", "_test_an_element", "_test_elements_eq", ....: "_test_elements_eq_reflexive", "_test_elements_eq_transitive", @@ -142,7 +142,7 @@ def _Hom_(self, Y, category): TESTS:: - sage: H = M._Hom_(M, category = HeckeModules(GF(5))); H + sage: H = M._Hom_(M, category=HeckeModules(GF(5))); H # optional - sage.modular sage.rings.finite_rings Traceback (most recent call last): ... TypeError: Category of Hecke modules over Finite Field of size 5 diff --git a/src/sage/categories/homset.py b/src/sage/categories/homset.py index 6554c895ff4..eba755da300 100644 --- a/src/sage/categories/homset.py +++ b/src/sage/categories/homset.py @@ -592,15 +592,15 @@ class Homset(Set_generic): Conversely, homsets of non-unique parents are non-unique:: - sage: P11 = ProductProjectiveSpaces(QQ, [1, 1]) - sage: H = End(P11) - sage: loads(dumps(P11)) is ProductProjectiveSpaces(QQ, [1, 1]) + sage: P11 = ProductProjectiveSpaces(QQ, [1, 1]) # optional - sage.schemes + sage: H = End(P11) # optional - sage.schemes + sage: loads(dumps(P11)) is ProductProjectiveSpaces(QQ, [1, 1]) # optional - sage.schemes False - sage: loads(dumps(P11)) == ProductProjectiveSpaces(QQ, [1, 1]) + sage: loads(dumps(P11)) == ProductProjectiveSpaces(QQ, [1, 1]) # optional - sage.schemes True - sage: loads(dumps(H)) is H + sage: loads(dumps(H)) is H # optional - sage.schemes False - sage: loads(dumps(H)) == H + sage: loads(dumps(H)) == H # optional - sage.schemes True """ def __init__(self, X, Y, category=None, base=None, check=True): diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index 04b2e07c156..8ea01d3ab90 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -66,7 +66,8 @@ def __init__(self): # Some modules providing basic combinatorics are already included in sagemath-categories. # Hence, we test a Python module within the package. JoinFeature.__init__(self, 'sage.combinat', - [PythonModule('sage.combinat.tableau')]) + [PythonModule('sage.combinat.tableau')], + spkg='sagemath_combinat') class sage__geometry__polyhedron(PythonModule): @@ -88,7 +89,8 @@ def __init__(self): sage: isinstance(sage__geometry__polyhedron(), sage__geometry__polyhedron) True """ - PythonModule.__init__(self, 'sage.geometry.polyhedron') + PythonModule.__init__(self, 'sage.geometry.polyhedron', + spkg='sagemath_polyhedra') class sage__graphs(JoinFeature): @@ -110,7 +112,31 @@ def __init__(self): True """ JoinFeature.__init__(self, 'sage.graphs', - [PythonModule('sage.graphs.graph')]) + [PythonModule('sage.graphs.graph')], + spkg='sagemath_graphs') + + +class sage__modular(JoinFeature): + r""" + A :class:`~sage.features.Feature` describing the presence of :mod:`sage.modular`. + + EXAMPLES:: + + sage: from sage.features.sagemath import sage__modular + sage: sage__modular().is_present() # optional - sage.modular + FeatureTestResult('sage.modular', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__modular + sage: isinstance(sage__modular(), sage__modular) + True + """ + JoinFeature.__init__(self, 'sage.modular', + [PythonModule('sage.modular.modform.eisenstein_submodule')], + spkg='sagemath_schemes') class sage__groups(JoinFeature): @@ -156,7 +182,8 @@ def __init__(self): """ JoinFeature.__init__(self, 'sage.libs.flint', [PythonModule('sage.libs.flint.flint'), - PythonModule('sage.libs.arb.arith')]) + PythonModule('sage.libs.arb.arith')], + spkg='sagemath_flint') class sage__libs__ntl(JoinFeature): @@ -179,7 +206,8 @@ def __init__(self): True """ JoinFeature.__init__(self, 'sage.libs.ntl', - [PythonModule('sage.libs.ntl.convert')]) + [PythonModule('sage.libs.ntl.convert')], + spkg='sagemath_ntl') class sage__libs__pari(JoinFeature): @@ -201,7 +229,8 @@ def __init__(self): True """ JoinFeature.__init__(self, 'sage.libs.pari', - [PythonModule('sage.libs.pari.convert_sage')]) + [PythonModule('sage.libs.pari.convert_sage')], + spkg='sagemath_pari') class sage__modules(JoinFeature): @@ -223,7 +252,8 @@ def __init__(self): True """ JoinFeature.__init__(self, 'sage.modules', - [PythonModule('sage.modules.free_module')]) + [PythonModule('sage.modules.free_module')], + spkg='sagemath_modules') class sage__plot(JoinFeature): @@ -245,7 +275,8 @@ def __init__(self): True """ JoinFeature.__init__(self, 'sage.plot', - [PythonModule('sage.plot.plot')]) + [PythonModule('sage.plot.plot')], + spkg='sagemath_symbolics') class sage__rings__finite_rings(JoinFeature): @@ -357,7 +388,8 @@ def __init__(self): True """ JoinFeature.__init__(self, 'sage.rings.polynomial.pbori', - [PythonModule('sage.rings.polynomial.pbori.pbori')]) + [PythonModule('sage.rings.polynomial.pbori.pbori')], + spkg='sagemath_brial') class sage__rings__real_double(PythonModule): @@ -399,7 +431,31 @@ def __init__(self): sage: isinstance(sage__rings__real_mpfr(), sage__rings__real_mpfr) True """ - PythonModule.__init__(self, 'sage.rings.real_mpfr') + PythonModule.__init__(self, 'sage.rings.real_mpfr', + spkg='sagemath_modules') + + +class sage__schemes(JoinFeature): + r""" + A :class:`~sage.features.Feature` describing the presence of :mod:`sage.schemes`. + + EXAMPLES:: + + sage: from sage.features.sagemath import sage__schemes + sage: sage__schemes().is_present() # optional - sage.schemes + FeatureTestResult('sage.schemes', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.sagemath import sage__schemes + sage: isinstance(sage__schemes(), sage__schemes) + True + """ + JoinFeature.__init__(self, 'sage.schemes', + [PythonModule('sage.schemes.elliptic_curves.ell_generic')], + spkg="sagemath_schemes") class sage__symbolic(JoinFeature): @@ -455,6 +511,7 @@ def all_features(): sage__libs__flint(), sage__libs__ntl(), sage__libs__pari(), + sage__modular(), sage__modules(), sage__plot(), sage__rings__finite_rings(), @@ -464,4 +521,5 @@ def all_features(): sage__rings__polynomial__pbori(), sage__rings__real_double(), sage__rings__real_mpfr(), + sage__schemes(), sage__symbolic()] From 03712b380d6bd559f53ee94ea8d331ff0ad63c01 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 9 May 2023 10:34:15 +0900 Subject: [PATCH 075/205] Initial implementation of the exceptional Jordan algebra. --- src/sage/algebras/jordan_algebra.py | 718 +++++++++++++++++++++++++++- 1 file changed, 707 insertions(+), 11 deletions(-) diff --git a/src/sage/algebras/jordan_algebra.py b/src/sage/algebras/jordan_algebra.py index f5824069797..d81293f1bad 100644 --- a/src/sage/algebras/jordan_algebra.py +++ b/src/sage/algebras/jordan_algebra.py @@ -4,26 +4,30 @@ AUTHORS: - Travis Scrimshaw (2014-04-02): initial version +- Travis Scrimshaw (2023-05-09): added the 27 dimensional exceptional + Jordan algebra """ #***************************************************************************** -# Copyright (C) 2014 Travis Scrimshaw +# Copyright (C) 2014, 2023 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ #***************************************************************************** from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation from sage.structure.element import AlgebraElement +from sage.structure.richcmp import richcmp from sage.categories.magmatic_algebras import MagmaticAlgebras from sage.misc.cachefunc import cached_method from sage.structure.element import is_Matrix from sage.modules.free_module import FreeModule +from sage.matrix.constructor import matrix from sage.sets.family import Family -class JordanAlgebra(Parent, UniqueRepresentation): +class JordanAlgebra(UniqueRepresentation, Parent): r""" A Jordan algebra. @@ -63,7 +67,7 @@ class JordanAlgebra(Parent, UniqueRepresentation): (\alpha + x) \circ (\beta + y) = \underbrace{\alpha \beta + (x,y)}_{\in R} - + \underbrace{\beta x + \alpha y}_{\in M} + + \underbrace{\beta x + \alpha y}_{\in M}, where `\alpha, \beta \in R` and `x,y \in M`. @@ -71,7 +75,7 @@ class JordanAlgebra(Parent, UniqueRepresentation): Can be either an associative algebra `A` or a symmetric bilinear form given as a matrix (possibly followed by, or preceded by, a base - ring argument) + ring argument). EXAMPLES: @@ -144,13 +148,9 @@ class JordanAlgebra(Parent, UniqueRepresentation): REFERENCES: - :wikipedia:`Jordan_algebra` - - [Ja1971]_ - - [Ch2012]_ - - [McC1978]_ - - [Al1947]_ """ @staticmethod @@ -194,6 +194,9 @@ def __classcall_private__(self, arg0, arg1=None, names=None): if arg1 is None: if not is_Matrix(arg0): + from sage.algebras.octonion_algebra import OctonionAlgebra + if isinstance(arg0, OctonionAlgebra): + return ExceptionalJordanAlgebra(arg0) if arg0.base_ring().characteristic() == 2: raise ValueError("the base ring cannot have characteristic 2") return SpecialJordanAlgebra(arg0, names) @@ -209,6 +212,7 @@ def __classcall_private__(self, arg0, arg1=None, names=None): arg1.set_immutable() return JordanAlgebraSymmetricBilinear(arg0, arg1, names=names) + class SpecialJordanAlgebra(JordanAlgebra): r""" A (special) Jordan algebra `A^+` from an associative algebra `A`. @@ -572,6 +576,7 @@ def monomial_coefficients(self, copy=True): """ return self._x.monomial_coefficients(copy) + class JordanAlgebraSymmetricBilinear(JordanAlgebra): r""" A Jordan algebra given by a symmetric bilinear form `m`. @@ -694,6 +699,12 @@ def _coerce_map_from_base_ring(self): TESTS:: sage: J = JordanAlgebra(Matrix([[0, 1], [1, 1]])) + sage: J._coerce_map_from_base_ring() + Conversion map: + From: Integer Ring + To: Jordan algebra over Integer Ring given by the symmetric bilinear form: + [0 1] + [1 1] sage: J.coerce_map_from(ZZ) Coercion map: From: Integer Ring @@ -737,8 +748,8 @@ def gens(self): sage: m = matrix([[0,1],[1,1]]) sage: J = JordanAlgebra(m) - sage: J.basis() - Family (1 + (0, 0), 0 + (1, 0), 0 + (0, 1)) + sage: J.gens() + (1 + (0, 0), 0 + (1, 0), 0 + (0, 1)) """ return tuple(self.algebra_generators()) @@ -1052,3 +1063,688 @@ def bar(self): True """ return self.__class__(self.parent(), self._s, -self._v) + + +class ExceptionalJordanAlgebra(JordanAlgebra): + r""" + The exceptional `27` dimensional Jordan algebra as self-adjoint + `3 \times 3` over an octonion algebra. + + Let `\mathbf{O}` be the :class:`OctonionAlgebra` over a commutative + ring `R` of characteristic not equal to `2`. The *exceptional Jordan + algebra* `\mathfrak{h}_3(\mathbf{O})` is a `27` dimensional free + `R`-module spanned by the matrices + + .. MATH:: + + \begin{bmatrix} + \alpha & x & y \\ + x^* & \beta & z \\ + y^* & z^* & \gamma + \end{bmatrix} + + for `\alpha, \beta, \gamma \in R` and `x, y, z \in \mathbf{O}`, + with multiplication given by the usual symmetrizer operation + `X \circ Y = \frac{1}{2}(XY + YX)`. + + These are also known as *Albert algebras* due to the work of + Abraham Adrian Albert on these algebras over `\RR`. + + EXAMPLES: + + We construct an exceptional Jordan algebra over `\QQ` and perform + some basic computations:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: gens = J.gens() + sage: gens[1] + [0 0 0] + [0 1 0] + [0 0 0] + sage: gens[3] + [0 1 0] + [1 0 0] + [0 0 0] + sage: gens[1] * gens[3] + [ 0 1/2 0] + [1/2 0 0] + [ 0 0 0] + + The Lie algebra of derivations of the exceptional Jordan algebra + is isomorphic to the simple Lie algebra of type `F_4`. We verify + that we the derivation module has the correct dimension:: + + sage: len(J.derivations_basis()) # long time + 52 + sage: LieAlgebra(QQ, cartan_type='F4').dimension() + 52 + + REFERENCES: + + - :wikipedia:`Albert_algebra` + - :wikipedia:`Jordan_algebra#Examples` + - :wikipedia:`Hurwitz's_theorem_(composition_algebras)#Applications_to_Jordan_algebras` + - ``_ + """ + def __init__(self, O): + r""" + Initialize ``self``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: TestSuite(J).run() # long time + + sage: O = OctonionAlgebra(QQ, 1, -2, 9) + sage: J = JordanAlgebra(O) + sage: TestSuite(J).run() # long time + + sage: R. = GF(11)[] + sage: O = OctonionAlgebra(R, 1, x + y, 9) + sage: J = JordanAlgebra(O) + sage: TestSuite(J).run() # long time + + sage: O = OctonionAlgebra(ZZ) + sage: J = JordanAlgebra(O) + Traceback (most recent call last): + ... + ValueError: 2 must be invertible + """ + self._O = O + R = O.base_ring() + + if not R(2).is_unit(): + raise ValueError("2 must be invertible") + self._half = R(2).inverse_of_unit() + + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + Onames = list(O.variable_names()) + Onames.extend(Onames[3] + Onames[i] for i in range(3)) + self._repr_poly_ring = PolynomialRing(R, Onames) + + cat = MagmaticAlgebras(R).Unital().FiniteDimensional().WithBasis() + Parent.__init__(self, base=R, category=cat) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: JordanAlgebra(O) + Exceptional Jordan algebra constructed from Octonion algebra + over Rational Field + """ + return "Exceptional Jordan algebra constructed from {}".format(self._O) + + def _element_constructor_(self, x): + r""" + Construct an element of ``self`` from ``s``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: J(2) + [2 0 0] + [0 2 0] + [0 0 2] + sage: J([2, 3, 0, -1, O.basis()[3], 2]) + [ 2 -1 k] + [-1 3 2] + [-k 2 0] + """ + R = self.base_ring() + try: + x = R(x) + zero = self._O.zero() + return self.element_class(self, [x, x, x, zero, zero, zero]) + except (ValueError, TypeError): + pass + x = list(x) + if len(x) != 6: + raise ValueError("invalid data to construct an element") + R = self.base_ring() + for i in range(3): + x[i] = R(x[i]) + x[3+i] = self._O(x[3+i]) + return self.element_class(self, x) + + def _test_multiplication_self_adjoint(self, **options): + r""" + Test that `(XY + YX) / 2` is self-adjoint. + + EXAMPLES:: + + sage: O = OctonionAlgebra(GF(7), 1, 3, 4) + sage: J = JordanAlgebra(O) + sage: J._test_multiplication_self_adjoint() + """ + tester = self._tester(**options) + S = tester.some_elements() + data_pairs = [(0, 0), (1, 1), (2, 2), (0, 1), (0, 2), (1, 2)] + zerO = self._O.zero() + from sage.misc.misc import some_tuples + for x, y in some_tuples(S, 2, tester._max_runs): + SD = x._data + OD = y._data + X = [[SD[0], SD[3], SD[4]], + [SD[3].conjugate(), SD[1], SD[5]], + [SD[4].conjugate(), SD[5].conjugate(), SD[2]]] + Y = [[OD[0], OD[3], OD[4]], + [OD[3].conjugate(), OD[1], OD[5]], + [OD[4].conjugate(), OD[5].conjugate(), OD[2]]] + for r, c in data_pairs: + if r != c: + val = sum(X[r][i] * Y[i][c] + Y[r][i] * X[i][c] for i in range(3)) * self._half + val_opp = sum(X[c][i] * Y[i][r] + Y[c][i] * X[i][r] for i in range(3)) * self._half + tester.assertEqual(val, val_opp.conjugate()) + else: + val = sum(X[r][i] * Y[i][c] + Y[r][i] * X[i][c] for i in range(3)) * self._half + tester.assertEqual(val.imag_part(), zerO) + + @cached_method + def basis(self): + r""" + Return a basis of ``self``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: B = J.basis() + sage: B[::6] + ([1 0 0] + [0 0 0] + [0 0 0], + [ 0 k 0] + [-k 0 0] + [ 0 0 0], + [ 0 0 i] + [ 0 0 0] + [-i 0 0], + [ 0 0 lk] + [ 0 0 0] + [-lk 0 0], + [ 0 0 0] + [ 0 0 li] + [ 0 -li 0]) + sage: len(B) + 27 + """ + import itertools + R = self.base_ring() + OB = self._O.basis() + base = [R.zero()] * 3 + [self._O.zero()] * 3 + ret = [] + for i in range(3): + temp = list(base) + temp[i] = R.one() + ret.append(self.element_class(self, temp)) + for i in range(3): + for b in OB: + temp = list(base) + temp[3+i] = b + ret.append(self.element_class(self, temp)) + return Family(ret) + + algebra_generators = basis + + def gens(self): + """ + Return the generators of ``self``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: G = J.gens() + sage: G[0] + [1 0 0] + [0 0 0] + [0 0 0] + sage: G[5] + [ 0 j 0] + [-j 0 0] + [ 0 0 0] + sage: G[22] + [ 0 0 0] + [ 0 0 k] + [ 0 -k 0] + """ + return tuple(self.algebra_generators()) + + @cached_method + def zero(self): + r""" + Return the additive identity. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: J.zero() + [0 0 0] + [0 0 0] + [0 0 0] + """ + Rz = self.base_ring().zero() + Oz = self._O.zero() + return self.element_class(self, (Rz, Rz, Rz, Oz, Oz, Oz)) + + @cached_method + def one(self): + r""" + Return multiplicative identity. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: J.one() + [1 0 0] + [0 1 0] + [0 0 1] + sage: all(J.one() * b == b for b in J.basis()) + True + """ + one = self.base_ring().one() + zero = self._O.zero() + return self.element_class(self, (one, one, one, zero, zero, zero)) + + def some_elements(self): + r""" + Return some elements of ``self``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: J.some_elements() + [[6/5 0 0] + [ 0 6/5 0] + [ 0 0 6/5], + [1 0 0] + [0 1 0] + [0 0 1], + [0 0 0] + [0 0 0] + [0 0 0], + [0 0 0] + [0 1 0] + [0 0 0], + [ 0 j 0] + [-j 0 0] + [ 0 0 0], + [ 0 0 lj] + [ 0 0 0] + [-lj 0 0], + [ 0 0 0] + [ 0 1 1/2*lj] + [ 0 -1/2*lj 0], + [ 1 0 j + 2*li] + [ 0 1 0] + [-j - 2*li 0 1], + [ 1 j + lk l] + [-j - lk 0 i + lj] + [ -l -i - lj 0], + [ 1 3/2*l 2*k] + [-3/2*l 0 5/2*j] + [ -2*k -5/2*j 0]] + + sage: O = OctonionAlgebra(GF(3)) + sage: J = JordanAlgebra(O) + sage: J.some_elements() + [[-1 0 0] + [ 0 -1 0] + [ 0 0 -1], + [1 0 0] + [0 1 0] + [0 0 1], + [0 0 0] + [0 0 0] + [0 0 0], + [0 0 0] + [0 1 0] + [0 0 0], + [ 0 j 0] + [-j 0 0] + [ 0 0 0], + [ 0 0 lj] + [ 0 0 0] + [-lj 0 0], + [ 0 0 0] + [ 0 1 -lj] + [ 0 lj 0], + [ 1 0 j - li] + [ 0 1 0] + [-j + li 0 1], + [ 1 j + lk l] + [-j - lk 0 i + lj] + [ -l -i - lj 0], + [ 1 0 -k] + [ 0 0 j] + [ k -j 0]] + """ + B = self.basis() + S = [self.an_element(), self.one(), self.zero(), + B[1], B[5], B[17], B[1] + self._half*B[25], + self.one() + B[13] + 2*B[16]] + S.append(sum(B[::5])) + S.append(sum(self._half * ind * b for ind, b in enumerate(B[::7], start=2))) + return S + + class Element(AlgebraElement): + r""" + An element of an exceptional Jordan algebra. + """ + def __init__(self, parent, data): + """ + Initialize ``self``. + + TESTS:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: elt = sum(J.basis()) + sage: TestSuite(elt).run() + """ + self._data = tuple(data) + AlgebraElement.__init__(self, parent) + + def _to_print_matrix(self): + r""" + Return ``self`` as a matrix for printing. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: elt = J([2, 3, 0, -1 + O.basis()[2], O.basis()[3], -O.basis()[5] + 5*O.basis()[7]]) + sage: elt._to_print_matrix() + [ 2 j - 1 k] + [ -j - 1 3 -li + 5*lk] + [ -k li - 5*lk 0] + """ + PR = self.parent()._repr_poly_ring + gens = [PR.one()] + list(PR.gens()) + data = [PR(self._data[i]) for i in range(3)] + data.extend(PR.sum(c * g for c, g in zip(self._data[3+i].vector(), gens)) + for i in range(3)) + # add the conjugates + for i in range(1, 8): + gens[i] = -gens[i] + data.extend(PR.sum(c * g for c, g in zip(self._data[3+i].vector(), gens)) + for i in range(3)) + return matrix(PR, [[data[0], data[3], data[4]], [data[6], data[1], data[5]], [data[7], data[8], data[2]]]) + + def _repr_(self): + r""" + Return a string representation of ``self``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: J.an_element() + [6/5 0 0] + [ 0 6/5 0] + [ 0 0 6/5] + """ + return repr(self._to_print_matrix()) + + def _latex_(self): + r""" + Return a latex representation of ``self``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: latex(J.an_element()) + \left(\begin{array}{rrr} + \frac{6}{5} & 0 & 0 \\ + 0 & \frac{6}{5} & 0 \\ + 0 & 0 & \frac{6}{5} + \end{array}\right) + """ + from sage.misc.latex import latex + return latex(self._to_print_matrix()) + + def _ascii_art_(self): + r""" + Return an ascii art representation of ``self``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: ascii_art(J.an_element()) + [6/5 0 0] + [ 0 6/5 0] + [ 0 0 6/5] + """ + from sage.typeset.ascii_art import ascii_art + return ascii_art(self._to_print_matrix()) + + def _unicode_art_(self): + r""" + Return a unicode art representation of ``self``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: unicode_art(J.an_element()) + ⎛6/5 0 0⎞ + ⎜ 0 6/5 0⎟ + ⎝ 0 0 6/5⎠ + """ + from sage.typeset.unicode_art import unicode_art + return unicode_art(self._to_print_matrix()) + + def __bool__(self) -> bool: + """ + Return if ``self`` is non-zero. + + TESTS:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: all(bool(b) for b in J.basis()) + True + sage: bool(J.zero()) + False + """ + return any(d for d in self._data) + + def _richcmp_(self, other, op): + r""" + Rich comparison of ``self`` with ``other`` by ``op``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: x = sum(J.basis()[::6]) + sage: y = sum(J.basis()[::5]) + sage: x == x + True + sage: x == y + False + sage: x < y + True + sage: x != J.zero() + True + """ + return richcmp(self._data, other._data, op) + + def _add_(self, other): + """ + Add ``self`` and ``other``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: x = sum(J.basis()[::6]) + sage: y = sum(J.basis()[::5]) + sage: x + x + [ 2 2*k 2*i + 2*lk] + [ -2*k 0 2*li] + [-2*i - 2*lk -2*li 0] + sage: x + y + [ 2 j + k + lk i + l + lk] + [ -j - k - lk 0 i + li + lj] + [ -i - l - lk -i - li - lj 0] + """ + return self.__class__(self.parent(), [a + b for a, b in zip(self._data, other._data)]) + + def _neg_(self): + """ + Negate ``self``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: x = sum(J.basis()[::6]) + sage: -x + [ -1 -k -i - lk] + [ k 0 -li] + [ i + lk li 0] + """ + return self.__class__(self.parent(), [-c for c in self._data]) + + def _sub_(self, other): + r""" + Subtract ``other`` from ``self``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: x = sum(J.basis()[::6]) + sage: y = sum(J.basis()[::5]) + sage: x - x + [0 0 0] + [0 0 0] + [0 0 0] + sage: x - y + [ 0 -j + k - lk i - l + lk] + [ j - k + lk 0 -i + li - lj] + [ -i + l - lk i - li + lj 0] + """ + return self.__class__(self.parent(), [a - b for a, b in zip(self._data, other._data)]) + + def _mul_(self, other): + """ + Multiply ``self`` and ``other``. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: x = sum(J.basis()[::7]) + sage: y = sum(J.basis()[::11]) + sage: x * y + [ 1 -1/2*j + 1/2*l + 1/2 1/2*k + 1/2*lk + 1/2] + [ 1/2*j - 1/2*l + 1/2 0 -1/2*l] + [-1/2*k - 1/2*lk + 1/2 1/2*l 0] + """ + P = self.parent() + SD = self._data + OD = other._data + X = [[SD[0], SD[3], SD[4]], + [SD[3].conjugate(), SD[1], SD[5]], + [SD[4].conjugate(), SD[5].conjugate(), SD[2]]] + Y = [[OD[0], OD[3], OD[4]], + [OD[3].conjugate(), OD[1], OD[5]], + [OD[4].conjugate(), OD[5].conjugate(), OD[2]]] + # we do a simplified multiplication for the diagonal entries since + # we have, e.g., \alpha * \alpha' + (x (x')^* + x' x^* + y (y')^* + y' y^*) / 2 + ret = [X[0][0] * Y[0][0] + (X[0][1] * Y[1][0]).real_part() + (X[0][2] * Y[2][0]).real_part(), + X[1][1] * Y[1][1] + (X[1][0] * Y[0][1]).real_part() + (X[1][2] * Y[2][1]).real_part(), + X[2][2] * Y[2][2] + (X[2][0] * Y[0][2]).real_part() + (X[2][1] * Y[1][2]).real_part()] + ret += [sum(X[r][i] * Y[i][c] + Y[r][i] * X[i][c] for i in range(3)) * P._half + for r, c in [(0, 1), (0, 2), (1, 2)]] + return self.__class__(P, ret) + + def _lmul_(self, other): + r""" + Multiply ``self`` by the scalar ``other`` on the left. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: elt = sum(2 * b for b in J.basis()[::6]); elt + [ 2 2*k 2*i + 2*lk] + [ -2*k 0 2*li] + [-2*i - 2*lk -2*li 0] + sage: elt * 2 + [ 4 4*k 4*i + 4*lk] + [ -4*k 0 4*li] + [-4*i - 4*lk -4*li 0] + """ + return self.__class__(self.parent(), [c * other for c in self._data]) + + def _rmul_(self, other): + r""" + Multiply ``self`` with the scalar ``other`` by the right + action. + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: elt = sum(b * 2 for b in J.basis()[::6]); elt + [ 2 2*k 2*i + 2*lk] + [ -2*k 0 2*li] + [-2*i - 2*lk -2*li 0] + sage: (1/2) * elt + [ 1 k i + lk] + [ -k 0 li] + [-i - lk -li 0] + """ + return self.__class__(self.parent(), [other * c for c in self._data]) + + def monomial_coefficients(self, copy=True): + r""" + Return a dictionary whose keys are indices of basis elements in + the support of ``self`` and whose values are the corresponding + coefficients. + + INPUT: + + - ``copy`` -- ignored + + EXAMPLES:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: elt = sum(~QQ(ind) * b for ind, b in enumerate(J.basis()[::6], start=1)); elt + [ 1 1/2*k 1/3*i + 1/4*lk] + [ -1/2*k 0 1/5*li] + [-1/3*i - 1/4*lk -1/5*li 0] + sage: elt.monomial_coefficients() + {0: 1, 6: 1/2, 12: 1/3, 18: 1/4, 24: 1/5} + + TESTS:: + + sage: O = OctonionAlgebra(QQ) + sage: J = JordanAlgebra(O) + sage: all(b.monomial_coefficients() == {i: 1} for i,b in enumerate(J.basis())) + True + """ + ret = {} + for i in range(3): + if self._data[i]: + ret[i] = self._data[i] + mc = self._data[3+i].monomial_coefficients() + for k, coeff in mc.items(): + ret[3+i*8+k] = coeff + return ret From 6d3bc3e940b2c29feb80677f906fd057f40367b6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 4 Jun 2023 23:13:41 -0700 Subject: [PATCH 076/205] sage.coding: Doctest cosmetics, add # optional --- src/sage/coding/abstract_code.py | 52 ++-- src/sage/coding/ag_code.py | 4 +- src/sage/coding/ag_code_decoders.pyx | 2 +- src/sage/coding/bch_code.py | 19 +- src/sage/coding/binary_code.pyx | 22 +- src/sage/coding/channel.py | 7 +- src/sage/coding/code_bounds.py | 8 +- src/sage/coding/code_constructions.py | 101 ++++--- src/sage/coding/cyclic_code.py | 67 ++-- src/sage/coding/databases.py | 26 +- src/sage/coding/decoder.py | 22 +- src/sage/coding/encoder.py | 22 +- src/sage/coding/extended_code.py | 15 +- src/sage/coding/gabidulin_code.py | 16 +- src/sage/coding/goppa_code.py | 1 + src/sage/coding/grs_code.py | 37 ++- src/sage/coding/guava.py | 1 + src/sage/coding/guruswami_sudan/gs_decoder.py | 164 +++++----- .../coding/guruswami_sudan/interpolation.py | 31 +- src/sage/coding/guruswami_sudan/utils.py | 1 + src/sage/coding/hamming_code.py | 1 + src/sage/coding/information_set_decoder.py | 50 +-- src/sage/coding/kasami_codes.pyx | 2 +- src/sage/coding/linear_code.py | 285 ++++++++++-------- src/sage/coding/linear_code_no_metric.py | 83 ++--- src/sage/coding/linear_rank_metric.py | 11 +- src/sage/coding/parity_check_code.py | 1 + src/sage/coding/punctured_code.py | 72 +++-- src/sage/coding/reed_muller_code.py | 70 +++-- src/sage/coding/self_dual_codes.py | 1 + src/sage/coding/source_coding/huffman.py | 8 +- src/sage/coding/subfield_subcode.py | 9 +- src/sage/coding/two_weight_db.py | 1 + 33 files changed, 705 insertions(+), 507 deletions(-) diff --git a/src/sage/coding/abstract_code.py b/src/sage/coding/abstract_code.py index ead76be288a..ee4ee619ab0 100644 --- a/src/sage/coding/abstract_code.py +++ b/src/sage/coding/abstract_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Codes @@ -683,7 +684,8 @@ def decode_to_code(self, word, decoder_name=None, *args, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: word = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: w_err = word + vector(GF(2), (1, 0, 0, 0, 0, 0, 0)) @@ -720,7 +722,8 @@ def decode_to_message(self, word, decoder_name=None, *args, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: word = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: C.decode_to_message(word) @@ -759,7 +762,8 @@ def decoder(self, decoder_name=None, *args, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: C.decoder() Syndrome decoder for [7, 4] linear code over GF(2) handling errors of weight up to 1 @@ -790,7 +794,8 @@ def decoder(self, decoder_name=None, *args, **kwargs): sage: C.decoder('Try') Traceback (most recent call last): ... - ValueError: There is no Decoder named 'Try'. The known Decoders are: ['InformationSet', 'NearestNeighbor', 'Syndrome'] + ValueError: There is no Decoder named 'Try'. + The known Decoders are: ['InformationSet', 'NearestNeighbor', 'Syndrome'] Some decoders take extra arguments. If the user forgets to supply these, the error message attempts to be helpful:: @@ -798,11 +803,13 @@ def decoder(self, decoder_name=None, *args, **kwargs): sage: C.decoder('InformationSet') Traceback (most recent call last): ... - ValueError: Constructing the InformationSet decoder failed, possibly due to missing or incorrect parameters. + ValueError: Constructing the InformationSet decoder failed, + possibly due to missing or incorrect parameters. The constructor requires the arguments ['number_errors']. It takes the optional arguments ['algorithm']. - It accepts unspecified arguments as well. - See the documentation of sage.coding.information_set_decoder.LinearCodeInformationSetDecoder for more details. + It accepts unspecified arguments as well. See the documentation of + sage.coding.information_set_decoder.LinearCodeInformationSetDecoder + for more details. """ if not self._default_decoder_name: @@ -837,7 +844,8 @@ def decoders_available(self, classes=False): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: C.decoders_available() ['InformationSet', 'NearestNeighbor', 'Syndrome'] @@ -878,7 +886,8 @@ def encode(self, word, encoder_name=None, *args, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: word = vector((0, 1, 1, 0)) sage: C.encode(word) @@ -928,7 +937,8 @@ def encoder(self, encoder_name=None, *args, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: C.encoder() Generator matrix-based encoder for [7, 4] linear code over GF(2) @@ -944,7 +954,8 @@ def encoder(self, encoder_name=None, *args, **kwargs): ....: def field(self): ....: return self._field ....: def _repr_(self): - ....: return "%d dummy code over GF(%s)" % (self.length(), self.field().cardinality()) + ....: return "%d dummy code over GF(%s)" % (self.length(), + ....: self.field().cardinality()) sage: D = MyCodeFamily(5, GF(2)) sage: D.encoder() Traceback (most recent call last): @@ -964,7 +975,8 @@ def encoder(self, encoder_name=None, *args, **kwargs): sage: C.encoder('NonExistingEncoder') Traceback (most recent call last): ... - ValueError: There is no Encoder named 'NonExistingEncoder'. The known Encoders are: ['GeneratorMatrix', 'Systematic'] + ValueError: There is no Encoder named 'NonExistingEncoder'. + The known Encoders are: ['GeneratorMatrix', 'Systematic'] Some encoders take extra arguments. If the user incorrectly supplies these, the error message attempts to be helpful:: @@ -972,10 +984,12 @@ def encoder(self, encoder_name=None, *args, **kwargs): sage: C.encoder('Systematic', strange_parameter=True) Traceback (most recent call last): ... - ValueError: Constructing the Systematic encoder failed, possibly due to missing or incorrect parameters. - The constructor requires no arguments. - It takes the optional arguments ['systematic_positions']. - See the documentation of sage.coding.linear_code_no_metric.LinearCodeSystematicEncoder for more details. + ValueError: Constructing the Systematic encoder failed, + possibly due to missing or incorrect parameters. + The constructor requires no arguments. It takes the optional + arguments ['systematic_positions']. See the documentation of + sage.coding.linear_code_no_metric.LinearCodeSystematicEncoder + for more details. """ if not self._default_encoder_name: raise NotImplementedError("No encoder implemented for this code.") @@ -1009,7 +1023,8 @@ def encoders_available(self, classes=False): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: C.encoders_available() ['GeneratorMatrix', 'Systematic'] @@ -1051,7 +1066,8 @@ def unencode(self, c, encoder_name=None, nocheck=False, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: c = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: C.unencode(c) diff --git a/src/sage/coding/ag_code.py b/src/sage/coding/ag_code.py index 72bf5c37d5f..f705f75d476 100644 --- a/src/sage/coding/ag_code.py +++ b/src/sage/coding/ag_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.rings.finite_rings sage.schemes """ AG codes @@ -538,7 +539,8 @@ def basis_differentials(self): sage: Q, = C.places_at_infinity() sage: pls.remove(Q) sage: code = codes.DifferentialAGCode(pls, 3*Q) - sage: matrix([[w.residue(p) for p in pls] for w in code.basis_differentials()]) + sage: matrix([[w.residue(p) for p in pls] + ....: for w in code.basis_differentials()]) [ 1 0 0 0 0 a + 1 a + 1 1] [ 0 1 0 0 0 a + 1 a 0] [ 0 0 1 0 0 a 1 a] diff --git a/src/sage/coding/ag_code_decoders.pyx b/src/sage/coding/ag_code_decoders.pyx index 1ff9a5ed47b..ccd6c8c6912 100644 --- a/src/sage/coding/ag_code_decoders.pyx +++ b/src/sage/coding/ag_code_decoders.pyx @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.rings.finite_rings sage.schemes r""" Decoders for AG codes diff --git a/src/sage/coding/bch_code.py b/src/sage/coding/bch_code.py index 96d4691e554..804bae41349 100644 --- a/src/sage/coding/bch_code.py +++ b/src/sage/coding/bch_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" BCH code @@ -406,7 +407,8 @@ def grs_word_to_bch(self, c): sage: Cgrs = D.grs_code() sage: Fgrs = Cgrs.base_field() sage: b = Fgrs.gen() - sage: c = vector(Fgrs, [0, b^2 + b, 1, b^2 + b, 0, 1, 1, 1, b^2 + b, 0, 0, b^2 + b + 1, b^2 + b, 0, 1]) + sage: c = vector(Fgrs, [0, b^2 + b, 1, b^2 + b, 0, 1, 1, 1, + ....: b^2 + b, 0, 0, b^2 + b + 1, b^2 + b, 0, 1]) sage: D.grs_word_to_bch(c) (0, a, 1, a, 0, 1, 1, 1, a, 0, 0, a + 1, a, 0, 1) """ @@ -424,7 +426,8 @@ def decode_to_code(self, y): sage: a = F.gen() sage: C = codes.BCHCode(F, 15, 3, jump_size=2) sage: D = codes.decoders.BCHUnderlyingGRSDecoder(C) - sage: y = vector(F, [a, a + 1, 1, a + 1, 1, a, a + 1, a + 1, 0, 1, a + 1, 1, 1, 1, a]) + sage: y = vector(F, [a, a + 1, 1, a + 1, 1, a, a + 1, + ....: a + 1, 0, 1, a + 1, 1, 1, 1, a]) sage: D.decode_to_code(y) (a, a + 1, 1, a + 1, 1, a, a + 1, a + 1, 0, 1, a + 1, 1, 1, 1, a) sage: D.decode_to_code(y) in C @@ -438,12 +441,18 @@ def decode_to_code(self, y): [31, 6] BCH Code over GF(2) with designed distance 15 sage: D = codes.decoders.BCHUnderlyingGRSDecoder(C, "GuruswamiSudan", tau=8) sage: Dgrs = D.grs_decoder() - sage: c = vector(GF(2), [1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0]) - sage: y = vector(GF(2), [1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0]) + sage: c = vector(GF(2), [1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, + ....: 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0]) + sage: y = vector(GF(2), [1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, + ....: 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0]) sage: print (c in C and (c-y).hamming_weight() == 8) True sage: Dgrs.decode_to_code(y) - [(1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0), (1, z5^3 + z5^2 + z5 + 1, z5^4 + z5^2 + z5, z5^4 + z5^3 + z5^2 + 1, 0, 0, z5^4 + z5 + 1, 1, z5^4 + z5^2 + z5, 0, 1, z5^4 + z5, 1, 0, 1, 1, 1, 0, 0, z5^4 + z5^3 + 1, 1, 0, 1, 1, 1, 1, z5^4 + z5^3 + z5 + 1, 1, 1, 0, 0)] + [(1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, + 0, 1, 1, 0, 1, 0, 0), + (1, z5^3 + z5^2 + z5 + 1, z5^4 + z5^2 + z5, z5^4 + z5^3 + z5^2 + 1, 0, 0, + z5^4 + z5 + 1, 1, z5^4 + z5^2 + z5, 0, 1, z5^4 + z5, 1, 0, 1, 1, 1, 0, + 0, z5^4 + z5^3 + 1, 1, 0, 1, 1, 1, 1, z5^4 + z5^3 + z5 + 1, 1, 1, 0, 0)] sage: D.decode_to_code(y) == [c] True """ diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index fcd569779f9..eee87d83ef6 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Optimized low-level binary code representation @@ -92,7 +93,7 @@ def weight_dist(M): EXAMPLES:: sage: from sage.coding.binary_code import weight_dist - sage: M = Matrix(GF(2),[ + sage: M = Matrix(GF(2), [ ....: [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0], ....: [0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0], ....: [0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1], @@ -100,14 +101,14 @@ def weight_dist(M): ....: [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1]]) sage: weight_dist(M) [1, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 1] - sage: M = Matrix(GF(2),[ + sage: M = Matrix(GF(2), [ ....: [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0], ....: [0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0], ....: [0,0,0,0,0,1,0,1,0,0,0,1,1,1,1,1,1], ....: [0,0,0,1,1,0,0,0,0,1,1,0,1,1,0,1,1]]) sage: weight_dist(M) [1, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 0, 0] - sage: M=Matrix(GF(2),[ + sage: M = Matrix(GF(2), [ ....: [1,0,0,1,1,1,1,0,0,1,0,0,0,0,0,0,0], ....: [0,1,0,0,1,1,1,1,0,0,1,0,0,0,0,0,0], ....: [0,0,1,0,0,1,1,1,1,0,0,1,0,0,0,0,0], @@ -536,7 +537,7 @@ def test_expand_to_ortho_basis(B=None): TESTS:: sage: from sage.coding.binary_code import test_expand_to_ortho_basis, BinaryCode - sage: M = Matrix(GF(2), [[1,1,1,1,1,1,0,0,0,0],[0,0,1,1,1,1,1,1,1,1]]) + sage: M = Matrix(GF(2), [[1,1,1,1,1,1,0,0,0,0], [0,0,1,1,1,1,1,1,1,1]]) sage: B = BinaryCode(M) sage: B.put_in_std_form() 0 @@ -870,7 +871,7 @@ cdef class BinaryCode: EXAMPLES:: - sage: M = Matrix(GF(2), [[1,1,1,1,0,0],[0,0,1,1,1,1]]) + sage: M = Matrix(GF(2), [[1,1,1,1,0,0], [0,0,1,1,1,1]]) sage: from sage.coding.binary_code import * sage: B = BinaryCode(M) sage: B.matrix() @@ -1212,7 +1213,7 @@ cdef class BinaryCode: EXAMPLES:: sage: from sage.coding.binary_code import * - sage: M = Matrix(GF(2), [[1,1,1,1,0,0],[0,0,1,1,1,1]]) + sage: M = Matrix(GF(2), [[1,1,1,1,0,0], [0,0,1,1,1,1]]) sage: B = BinaryCode(M); B Binary [6,2] linear code, generator matrix [111100] @@ -2930,7 +2931,11 @@ cdef class PartitionStack: sage: import sage.coding.binary_code sage: from sage.coding.binary_code import * sage: P = PartitionStack(4, 8) - sage: P._dangerous_dont_use_set_ents_lvls(list(range(8)), list(range(7))+[-1], [4,7,12,11,1,9,3,0,2,5,6,8,10,13,14,15], [0]*16) + sage: P._dangerous_dont_use_set_ents_lvls( + ....: list(range(8)), + ....: list(range(7)) + [-1], + ....: [4,7,12,11,1,9,3,0,2,5,6,8,10,13,14,15], + ....: [0]*16) sage: P ({4},{7},{12},{11},{1},{9},{3},{0},{2},{5},{6},{8},{10},{13},{14},{15}) ({0},{1,2,3,4,5,6,7}) ({4},{7},{12},{11},{1},{9},{3},{0},{2},{5},{6},{8},{10},{13},{14},{15}) ({0},{1},{2,3,4,5,6,7}) @@ -3931,7 +3936,8 @@ cdef class BinaryCodeClassifier: sage: for n in range(13): ....: s = 'n=%2d : '%n ....: for k in range(1,7): - ....: s += '%3d '%len([C for C in L if C.length() == n and C.dimension() == k]) + ....: s += '%3d '%len([C for C in L + ....: if C.length() == n and C.dimension() == k]) ....: print(s) n= 0 : 0 0 0 0 0 0 n= 1 : 0 0 0 0 0 0 diff --git a/src/sage/coding/channel.py b/src/sage/coding/channel.py index ba59d756d1a..8f09e07a038 100644 --- a/src/sage/coding/channel.py +++ b/src/sage/coding/channel.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Channels @@ -582,9 +583,9 @@ def transmit_unsafe(self, message): - a couple of vectors, namely: - - the transmitted message, which is ``message`` with erroneous and erased positions - - the erasure vector, which contains ``1`` at the erased positions of the transmitted message - , 0 elsewhere. + - the transmitted message, which is ``message`` with erroneous and erased positions + - the erasure vector, which contains ``1`` at the erased positions of the transmitted message + and ``0`` elsewhere. EXAMPLES:: diff --git a/src/sage/coding/code_bounds.py b/src/sage/coding/code_bounds.py index 8e1ce61cedb..da42a63789f 100644 --- a/src/sage/coding/code_bounds.py +++ b/src/sage/coding/code_bounds.py @@ -174,16 +174,18 @@ # **************************************************************************** from sage.arith.misc import binomial, is_prime_power -from sage.libs.gap.libgap import libgap +from sage.features.gap import GapPackage from sage.misc.functional import sqrt, log +from sage.misc.lazy_import import lazy_import from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.real_double import RDF -from sage.rings.real_mpfr import RR from .delsarte_bounds import (delsarte_bound_hamming_space, delsarte_bound_additive_hamming_space) -from sage.features.gap import GapPackage + +lazy_import('sage.libs.gap.libgap', 'libgap') +lazy_import('sage.rings.real_mpfr', 'RR') def _check_n_q_d(n, q, d, field_based=True): diff --git a/src/sage/coding/code_constructions.py b/src/sage/coding/code_constructions.py index 812d5d88df9..d3a377cc27d 100644 --- a/src/sage/coding/code_constructions.py +++ b/src/sage/coding/code_constructions.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Linear code constructors that do not preserve the structural information @@ -226,28 +227,28 @@ def permutation_action(g, v): sage: V = VectorSpace(GF(3),5) sage: v = V([0,1,2,0,1]) - sage: G = SymmetricGroup(5) - sage: g = G([(1,2,3)]) - sage: permutation_action(g,v) + sage: G = SymmetricGroup(5) # optional - sage.groups + sage: g = G([(1,2,3)]) # optional - sage.groups + sage: permutation_action(g,v) # optional - sage.groups (1, 2, 0, 0, 1) - sage: g = G([()]) - sage: permutation_action(g,v) + sage: g = G([()]) # optional - sage.groups + sage: permutation_action(g,v) # optional - sage.groups (0, 1, 2, 0, 1) - sage: g = G([(1,2,3,4,5)]) - sage: permutation_action(g,v) + sage: g = G([(1,2,3,4,5)]) # optional - sage.groups + sage: permutation_action(g,v) # optional - sage.groups (1, 2, 0, 1, 0) sage: L = Sequence([1,2,3,4,5]) - sage: permutation_action(g,L) + sage: permutation_action(g,L) # optional - sage.groups [2, 3, 4, 5, 1] sage: MS = MatrixSpace(GF(3),3,7) sage: A = MS([[1,0,0,0,1,1,0],[0,1,0,1,0,1,0],[0,0,0,0,0,0,1]]) - sage: S5 = SymmetricGroup(5) - sage: g = S5([(1,2,3)]) + sage: S5 = SymmetricGroup(5) # optional - sage.groups + sage: g = S5([(1,2,3)]) # optional - sage.groups sage: A [1 0 0 0 1 1 0] [0 1 0 1 0 1 0] [0 0 0 0 0 0 1] - sage: permutation_action(g,A) + sage: permutation_action(g,A) # optional - sage.groups [0 1 0 1 0 1 0] [0 0 0 0 0 0 1] [1 0 0 0 1 1 0] @@ -255,16 +256,16 @@ def permutation_action(g, v): It also works on lists and is a "left action":: sage: v = [0,1,2,0,1] - sage: G = SymmetricGroup(5) - sage: g = G([(1,2,3)]) - sage: gv = permutation_action(g,v); gv + sage: G = SymmetricGroup(5) # optional - sage.groups + sage: g = G([(1,2,3)]) # optional - sage.groups + sage: gv = permutation_action(g,v); gv # optional - sage.groups [1, 2, 0, 0, 1] - sage: permutation_action(g,v) == g(v) + sage: permutation_action(g,v) == g(v) # optional - sage.groups True - sage: h = G([(3,4)]) - sage: gv = permutation_action(g,v) - sage: hgv = permutation_action(h,gv) - sage: hgv == permutation_action(h*g,v) + sage: h = G([(3,4)]) # optional - sage.groups + sage: gv = permutation_action(g,v) # optional - sage.groups + sage: hgv = permutation_action(h,gv) # optional - sage.groups + sage: hgv == permutation_action(h*g,v) # optional - sage.groups True AUTHORS: @@ -436,28 +437,28 @@ def ExtendedQuadraticResidueCode(n,F): INPUT: - - ``n`` - an odd prime + - ``n`` -- an odd prime - - ``F`` - a finite prime field F whose order must be a - quadratic residue modulo n. + - ``F`` -- a finite prime field whose order must be a + quadratic residue modulo `n`. OUTPUT: Returns an extended quadratic residue code. EXAMPLES:: - sage: C1 = codes.QuadraticResidueCode(7,GF(2)) + sage: C1 = codes.QuadraticResidueCode(7, GF(2)) sage: C2 = C1.extended_code() - sage: C3 = codes.ExtendedQuadraticResidueCode(7,GF(2)); C3 + sage: C3 = codes.ExtendedQuadraticResidueCode(7, GF(2)); C3 Extension of [7, 4] Cyclic Code over GF(2) sage: C2 == C3 True - sage: C = codes.ExtendedQuadraticResidueCode(17,GF(2)) + sage: C = codes.ExtendedQuadraticResidueCode(17, GF(2)) sage: C Extension of [17, 9] Cyclic Code over GF(2) - sage: C3 = codes.QuadraticResidueCodeOddPair(7,GF(2))[0] + sage: C3 = codes.QuadraticResidueCodeOddPair(7, GF(2))[0] sage: C3x = C3.extended_code() - sage: C4 = codes.ExtendedQuadraticResidueCode(7,GF(2)) + sage: C4 = codes.ExtendedQuadraticResidueCode(7, GF(2)) sage: C3x == C4 True @@ -505,28 +506,28 @@ def QuadraticResidueCode(n,F): INPUT: - - ``n`` - an odd prime + - ``n`` -- an odd prime - - ``F`` - a finite prime field F whose order must be a - quadratic residue modulo n. + - ``F`` -- a finite prime field whose order must be a + quadratic residue modulo `n`. OUTPUT: Returns a quadratic residue code. EXAMPLES:: - sage: C = codes.QuadraticResidueCode(7,GF(2)) + sage: C = codes.QuadraticResidueCode(7, GF(2)) sage: C [7, 4] Cyclic Code over GF(2) - sage: C = codes.QuadraticResidueCode(17,GF(2)) + sage: C = codes.QuadraticResidueCode(17, GF(2)) sage: C [17, 9] Cyclic Code over GF(2) - sage: C1 = codes.QuadraticResidueCodeOddPair(7,GF(2))[0] - sage: C2 = codes.QuadraticResidueCode(7,GF(2)) + sage: C1 = codes.QuadraticResidueCodeOddPair(7, GF(2))[0] + sage: C2 = codes.QuadraticResidueCode(7, GF(2)) sage: C1 == C2 True - sage: C1 = codes.QuadraticResidueCodeOddPair(17,GF(2))[0] - sage: C2 = codes.QuadraticResidueCode(17,GF(2)) + sage: C1 = codes.QuadraticResidueCodeOddPair(17, GF(2))[0] + sage: C2 = codes.QuadraticResidueCode(17, GF(2)) sage: C1 == C2 True @@ -556,16 +557,16 @@ def QuadraticResidueCodeEvenPair(n,F): sage: codes.QuadraticResidueCodeEvenPair(17, GF(2)) ([17, 8] Cyclic Code over GF(2), [17, 8] Cyclic Code over GF(2)) - sage: codes.QuadraticResidueCodeEvenPair(13,GF(9,"z")) # known bug (#25896) + sage: codes.QuadraticResidueCodeEvenPair(13, GF(9,"z")) # known bug (#25896) ([13, 6] Cyclic Code over GF(9), [13, 6] Cyclic Code over GF(9)) - sage: C1,C2 = codes.QuadraticResidueCodeEvenPair(7,GF(2)) + sage: C1,C2 = codes.QuadraticResidueCodeEvenPair(7, GF(2)) sage: C1.is_self_orthogonal() True sage: C2.is_self_orthogonal() True - sage: C3 = codes.QuadraticResidueCodeOddPair(17,GF(2))[0] - sage: C4 = codes.QuadraticResidueCodeEvenPair(17,GF(2))[1] + sage: C3 = codes.QuadraticResidueCodeOddPair(17, GF(2))[0] + sage: C4 = codes.QuadraticResidueCodeEvenPair(17, GF(2))[1] sage: C3.systematic_generator_matrix() == C4.dual_code().systematic_generator_matrix() True @@ -577,11 +578,11 @@ def QuadraticResidueCodeEvenPair(n,F): Traceback (most recent call last): ... ValueError: the argument F must be a finite field - sage: codes.QuadraticResidueCodeEvenPair(14,GF(2)) + sage: codes.QuadraticResidueCodeEvenPair(14, GF(2)) Traceback (most recent call last): ... ValueError: the argument n must be an odd prime - sage: codes.QuadraticResidueCodeEvenPair(5,GF(2)) + sage: codes.QuadraticResidueCodeEvenPair(5, GF(2)) Traceback (most recent call last): ... ValueError: the order of the finite field must be a quadratic residue modulo n @@ -641,7 +642,7 @@ def QuadraticResidueCodeOddPair(n,F): TESTS:: - sage: codes.QuadraticResidueCodeOddPair(9,GF(2)) + sage: codes.QuadraticResidueCodeOddPair(9, GF(2)) Traceback (most recent call last): ... ValueError: the argument n must be an odd prime @@ -712,10 +713,10 @@ def ToricCode(P,F): INPUT: - - ``P`` - all the integer lattice points in a polytope + - ``P`` -- all the integer lattice points in a polytope defining the toric variety. - - ``F`` - a finite field. + - ``F`` -- a finite field. OUTPUT: Returns toric code with length n = , dimension k over field @@ -723,7 +724,7 @@ def ToricCode(P,F): EXAMPLES:: - sage: C = codes.ToricCode([[0,0],[1,0],[2,0],[0,1],[1,1]],GF(7)) + sage: C = codes.ToricCode([[0,0],[1,0],[2,0],[0,1],[1,1]], GF(7)) sage: C [36, 5] linear code over GF(7) sage: C.minimum_distance() @@ -731,14 +732,16 @@ def ToricCode(P,F): sage: C.minimum_distance(algorithm="guava") # optional - gap_packages (Guava package) ... 24 - sage: C = codes.ToricCode([[-2,-2],[-1,-2],[-1,-1],[-1,0],[0,-1],[0,0],[0,1],[1,-1],[1,0]],GF(5)) + sage: C = codes.ToricCode([[-2,-2],[-1,-2],[-1,-1],[-1,0], + ....: [0,-1],[0,0],[0,1],[1,-1],[1,0]], GF(5)) sage: C [16, 9] linear code over GF(5) sage: C.minimum_distance() 6 sage: C.minimum_distance(algorithm="guava") # optional - gap_packages (Guava package) 6 - sage: C = codes.ToricCode([ [0,0],[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[3,1],[3,2],[4,1]],GF(8,"a")) + sage: C = codes.ToricCode([[0,0],[1,1],[1,2],[1,3],[1,4],[2,1], + ....: [2,2],[2,3],[3,1],[3,2],[4,1]], GF(8,"a")) sage: C [49, 11] linear code over GF(8) @@ -784,7 +787,7 @@ def WalshCode(m): [1, 0, 0, 0, 7, 0, 0, 0, 0] sage: C.minimum_distance() 4 - sage: C.minimum_distance(algorithm='gap') # check d=2^(m-1) + sage: C.minimum_distance(algorithm='gap') # check d=2^(m-1) 4 REFERENCES: diff --git a/src/sage/coding/cyclic_code.py b/src/sage/coding/cyclic_code.py index 77b72d4ba95..a87c0595273 100644 --- a/src/sage/coding/cyclic_code.py +++ b/src/sage/coding/cyclic_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Cyclic code @@ -262,7 +263,7 @@ class CyclicCode(AbstractLinearCode): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: C [7, 4] Cyclic Code over GF(2) @@ -280,7 +281,7 @@ class CyclicCode(AbstractLinearCode): sage: F = GF(16, 'a') sage: n = 15 - sage: Cc = codes.CyclicCode(length = n, field = F, D = [1,2]) + sage: Cc = codes.CyclicCode(length=n, field=F, D = [1,2]) sage: Cc [15, 13] Cyclic Code over GF(16) """ @@ -299,7 +300,7 @@ def __init__(self, generator_pol=None, length=None, code=None, check=True, sage: F. = GF(2)[] sage: n = 2 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) Traceback (most recent call last): ... ValueError: Only cyclic codes whose length and field order are coprimes are implemented. @@ -547,7 +548,7 @@ def _latex_(self): def generator_polynomial(self): r""" - Returns the generator polynomial of ``self``. + Return the generator polynomial of ``self``. EXAMPLES:: @@ -562,7 +563,7 @@ def generator_polynomial(self): def field_embedding(self): r""" - Returns the base field embedding into the splitting field. + Return the base field embedding into the splitting field. EXAMPLES:: @@ -582,7 +583,7 @@ def field_embedding(self): def defining_set(self, primitive_root=None): r""" - Returns the set of exponents of the roots of ``self``'s generator + Return the set of exponents of the roots of ``self``'s generator polynomial over the extension field. Of course, it depends on the choice of the primitive root of the splitting field. @@ -674,7 +675,7 @@ def defining_set(self, primitive_root=None): def primitive_root(self): r""" - Returns the primitive root of the splitting field that is used + Return the primitive root of the splitting field that is used to build the defining set of the code. If it has not been specified by the user, it is set by default with the @@ -692,7 +693,8 @@ def primitive_root(self): sage: F = GF(16, 'a') sage: n = 15 sage: a = F.gen() - sage: Cc = codes.CyclicCode(length = n, field = F, D = [1,2], primitive_root = a^2 + 1) + sage: Cc = codes.CyclicCode(length=n, field=F, D=[1,2], + ....: primitive_root=a^2 + 1) sage: Cc.primitive_root() a^2 + 1 """ @@ -716,7 +718,7 @@ def check_polynomial(self): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: h = C.check_polynomial() sage: h == (x**n - 1)/C.generator_polynomial() True @@ -739,7 +741,7 @@ def parity_check_matrix(self): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: C.parity_check_matrix() [1 0 1 1 1 0 0] [0 1 0 1 1 1 0] @@ -776,14 +778,14 @@ def bch_bound(self, arithmetic=False): sage: F = GF(16, 'a') sage: n = 15 sage: D = [14,1,2,11,12] - sage: C = codes.CyclicCode(field = F, length = n, D = D) + sage: C = codes.CyclicCode(field=F, length=n, D = D) sage: C.bch_bound() (3, (1, 1)) sage: F = GF(16, 'a') sage: n = 15 sage: D = [14,1,2,11,12] - sage: C = codes.CyclicCode(field = F, length = n, D = D) + sage: C = codes.CyclicCode(field=F, length=n, D = D) sage: C.bch_bound(True) (4, (2, 12)) """ @@ -829,7 +831,7 @@ class CyclicCodePolynomialEncoder(Encoder): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: E Polynomial-style encoder for [7, 4] Cyclic Code over GF(2) @@ -842,7 +844,7 @@ def __init__(self, code): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: E Polynomial-style encoder for [7, 4] Cyclic Code over GF(2) @@ -861,7 +863,7 @@ def __eq__(self, other): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E1 = codes.encoders.CyclicCodePolynomialEncoder(C) sage: E2 = codes.encoders.CyclicCodePolynomialEncoder(C) sage: E1 == E2 @@ -879,7 +881,7 @@ def _repr_(self): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: E Polynomial-style encoder for [7, 4] Cyclic Code over GF(2) @@ -895,7 +897,7 @@ def _latex_(self): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: latex(E) \textnormal{Polynomial-style encoder for }[7, 4] \textnormal{ Cyclic Code over } \Bold{F}_{2} @@ -920,7 +922,7 @@ def encode(self, p): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: m = x ** 2 + 1 sage: E.encode(m) @@ -952,7 +954,7 @@ def unencode_nocheck(self, c): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: c = vector(GF(2), (1, 1, 1, 0, 0, 1, 0)) sage: E.unencode_nocheck(c) @@ -972,7 +974,7 @@ def message_space(self): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodePolynomialEncoder(C) sage: E.message_space() Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X) @@ -1003,7 +1005,7 @@ class CyclicCodeVectorEncoder(Encoder): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: E Vector-style encoder for [7, 4] Cyclic Code over GF(2) @@ -1017,7 +1019,7 @@ def __init__(self, code): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: E Vector-style encoder for [7, 4] Cyclic Code over GF(2) @@ -1036,7 +1038,7 @@ def __eq__(self, other): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E1 = codes.encoders.CyclicCodeVectorEncoder(C) sage: E2 = codes.encoders.CyclicCodeVectorEncoder(C) sage: E1 == E2 @@ -1054,7 +1056,7 @@ def _repr_(self): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: E Vector-style encoder for [7, 4] Cyclic Code over GF(2) @@ -1070,7 +1072,7 @@ def _latex_(self): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: latex(E) \textnormal{Vector-style encoder for }[7, 4] \textnormal{ Cyclic Code over } \Bold{F}_{2} @@ -1095,7 +1097,7 @@ def encode(self, m): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: m = vector(GF(2), (1, 0, 1, 0)) sage: E.encode(m) @@ -1132,7 +1134,7 @@ def unencode_nocheck(self, c): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: c = vector(GF(2), (1, 1, 1, 0, 0, 1, 0)) sage: E.unencode_nocheck(c) @@ -1155,7 +1157,7 @@ def generator_matrix(self): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: E.generator_matrix() [1 1 0 1 0 0 0] @@ -1180,7 +1182,7 @@ def message_space(self): sage: F. = GF(2)[] sage: n = 7 sage: g = x ** 3 + x + 1 - sage: C = codes.CyclicCode(generator_pol = g, length = n) + sage: C = codes.CyclicCode(generator_pol=g, length=n) sage: E = codes.encoders.CyclicCodeVectorEncoder(C) sage: E.message_space() Vector space of dimension 4 over Finite Field of size 2 @@ -1288,7 +1290,8 @@ def bch_decoder(self): sage: C = codes.CyclicCode(field=GF(16), length=15, D=[14, 1, 2, 11, 12]) sage: D = codes.decoders.CyclicCodeSurroundingBCHDecoder(C) sage: D.bch_decoder() - Decoder through the underlying GRS code of [15, 12] BCH Code over GF(16) with designed distance 4 + Decoder through the underlying GRS code of [15, 12] BCH Code + over GF(16) with designed distance 4 """ return self._bch_decoder @@ -1302,7 +1305,9 @@ def decode_to_code(self, y): sage: C = codes.CyclicCode(field=F, length=15, D=[14, 1, 2, 11, 12]) sage: a = F.gen() sage: D = codes.decoders.CyclicCodeSurroundingBCHDecoder(C) - sage: y = vector(F, [0, a^3, a^3 + a^2 + a, 1, a^2 + 1, a^3 + a^2 + 1, a^3 + a^2 + a, a^3 + a^2 + a, a^2 + a, a^2 + 1, a^2 + a + 1, a^3 + 1, a^2, a^3 + a, a^3 + a]) + sage: y = vector(F, [0, a^3, a^3 + a^2 + a, 1, a^2 + 1, a^3 + a^2 + 1, + ....: a^3 + a^2 + a, a^3 + a^2 + a, a^2 + a, a^2 + 1, + ....: a^2 + a + 1, a^3 + 1, a^2, a^3 + a, a^3 + a]) sage: D.decode_to_code(y) in C True """ diff --git a/src/sage/coding/databases.py b/src/sage/coding/databases.py index ee753504f8b..9fd3b43485b 100644 --- a/src/sage/coding/databases.py +++ b/src/sage/coding/databases.py @@ -1,9 +1,13 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Access functions to online databases for coding theory """ -from sage.libs.gap.libgap import libgap from sage.features.gap import GapPackage +from sage.misc.lazy_import import lazy_import + +lazy_import('sage.libs.gap.libgap', 'libgap') + +del lazy_import # Do not put any global imports here since this module is accessible as # sage.codes.databases. @@ -142,8 +146,8 @@ def best_linear_code_in_codetables_dot_de(n, k, F, verbose=False): last modified: 2002-03-20 - This function raises an ``IOError`` if an error occurs downloading data or - parsing it. It raises a ``ValueError`` if the ``q`` input is invalid. + This function raises an :class:`IOError` if an error occurs downloading data or + parsing it. It raises a :class:`ValueError` if the ``q`` input is invalid. AUTHORS: @@ -184,22 +188,22 @@ def self_orthogonal_binary_codes(n, k, b=2, parent=None, BC=None, equal=False, INPUT: - - ``n`` - Integer, maximal length + - ``n`` -- Integer, maximal length - - ``k`` - Integer, maximal dimension + - ``k`` -- Integer, maximal dimension - - ``b`` - Integer, requires that the generators all have weight divisible + - ``b`` -- Integer, requires that the generators all have weight divisible by ``b`` (if ``b=2``, all self-orthogonal codes are generated, and if ``b=4``, all doubly even codes are generated). Must be an even positive integer. - - ``parent`` - Used in recursion (default: ``None``) + - ``parent``- - Used in recursion (default: ``None``) - - ``BC`` - Used in recursion (default: ``None``) + - ``BC`` -- Used in recursion (default: ``None``) - - ``equal`` - If ``True`` generates only [n, k] codes (default: ``False``) + - ``equal`` -- If ``True``, generates only [n, k] codes (default: ``False``) - - ``in_test`` - Used in recursion (default: ``None``) + - ``in_test`` -- Used in recursion (default: ``None``) EXAMPLES: diff --git a/src/sage/coding/decoder.py b/src/sage/coding/decoder.py index 8a8e6496f74..2f92bb5c9b8 100644 --- a/src/sage/coding/decoder.py +++ b/src/sage/coding/decoder.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Decoders @@ -237,7 +238,8 @@ def decode_to_code(self, r): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: word = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: word in C @@ -261,7 +263,8 @@ def connected_encoder(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: D = C.decoder() sage: D.connected_encoder() @@ -287,7 +290,8 @@ def decode_to_message(self, r): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: word = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: w_err = word + vector(GF(2), (1, 0, 0, 0, 0, 0, 0)) @@ -304,7 +308,8 @@ def code(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: D = C.decoder() sage: D.code() @@ -318,7 +323,8 @@ def message_space(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: D = C.decoder() sage: D.message_space() @@ -332,7 +338,8 @@ def input_space(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: D = C.decoder() sage: D.input_space() @@ -352,7 +359,8 @@ def decoding_radius(self, **kwargs): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: D = codes.decoders.LinearCodeSyndromeDecoder(C) sage: D.decoding_radius() diff --git a/src/sage/coding/encoder.py b/src/sage/coding/encoder.py index ba1070633fd..177b3e50e58 100644 --- a/src/sage/coding/encoder.py +++ b/src/sage/coding/encoder.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Encoders @@ -143,7 +144,8 @@ def encode(self, word): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: word = vector(GF(2), (0, 1, 1, 0)) sage: E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C) @@ -156,7 +158,8 @@ def encode(self, word): sage: E.encode(word) Traceback (most recent call last): ... - ValueError: The value to encode must be in Vector space of dimension 4 over Finite Field of size 2 + ValueError: The value to encode must be in + Vector space of dimension 4 over Finite Field of size 2 """ M = self.message_space() if word not in M: @@ -215,7 +218,8 @@ def unencode(self, c, nocheck=False): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: c = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: c in C @@ -299,7 +303,8 @@ def unencode_nocheck(self, c): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: c = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) sage: c in C @@ -332,7 +337,8 @@ def code(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: E = C.encoder() sage: E.code() == C @@ -348,7 +354,8 @@ def message_space(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: E = C.encoder() sage: E.message_space() @@ -368,7 +375,8 @@ def generator_matrix(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: E = C.encoder() sage: E.generator_matrix() diff --git a/src/sage/coding/extended_code.py b/src/sage/coding/extended_code.py index 6065d4c2c96..3ea5adbfe49 100644 --- a/src/sage/coding/extended_code.py +++ b/src/sage/coding/extended_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Extended code @@ -298,7 +299,8 @@ class ExtendedCodeOriginalCodeDecoder(Decoder): sage: Ce = codes.ExtendedCode(C) sage: D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce) sage: D - 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) + 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): @@ -385,7 +387,8 @@ def decode_to_code(self, y, **kwargs): sage: Ce = codes.ExtendedCode(C) sage: D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce) sage: c = Ce.random_element() - sage: Chan = channels.StaticErrorRateChannel(Ce.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(Ce.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: y in Ce False @@ -396,10 +399,12 @@ def decode_to_code(self, y, **kwargs): sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) sage: Ce = codes.ExtendedCode(C) - sage: Dgrs = C.decoder('GuruswamiSudan', tau = 4) - sage: D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce, original_decoder = Dgrs) + sage: Dgrs = C.decoder('GuruswamiSudan', tau=4) + sage: D = codes.decoders.ExtendedCodeOriginalCodeDecoder(Ce, + ....: original_decoder=Dgrs) sage: c = Ce.random_element() - sage: Chan = channels.StaticErrorRateChannel(Ce.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(Ce.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: y in Ce False diff --git a/src/sage/coding/gabidulin_code.py b/src/sage/coding/gabidulin_code.py index b6d2e2bac4d..0ba1d13ec41 100644 --- a/src/sage/coding/gabidulin_code.py +++ b/src/sage/coding/gabidulin_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Gabidulin Code @@ -499,7 +500,8 @@ def generator_matrix(self): sage: Fqm = GF(2^9) sage: Fq = GF(2^3) sage: C = codes.GabidulinCode(Fqm, 3, 3, Fq) - sage: list(C.generator_matrix().row(1)) == [C.evaluation_points()[i]**(2**3) for i in range(3)] + sage: (list(C.generator_matrix().row(1)) + ....: == [C.evaluation_points()[i]**(2**3) for i in range(3)]) True """ from functools import reduce @@ -543,7 +545,8 @@ class GabidulinPolynomialEvaluationEncoder(Encoder): sage: z9 = Fqm.gen() sage: p = (z9^6 + z9^2 + z9 + 1)*x + z9^7 + z9^5 + z9^4 + z9^2 sage: vector(p.multi_point_evaluation(C.evaluation_points())) - doctest:...: FutureWarning: This class/method/function is marked as experimental. It, its functionality or its interface might change without a formal deprecation. + doctest:...: FutureWarning: This class/method/function is marked as experimental. + It, its functionality or its interface might change without a formal deprecation. See https://github.com/sagemath/sage/issues/13215 for details. (z9^7 + z9^6 + z9^5 + z9^4 + z9 + 1, z9^6 + z9^5 + z9^3 + z9) @@ -554,13 +557,15 @@ class GabidulinPolynomialEvaluationEncoder(Encoder): sage: C = codes.GabidulinCode(Fqm, 2, 2, Fq) sage: E = codes.encoders.GabidulinPolynomialEvaluationEncoder(C) sage: E - Polynomial evaluation style encoder for [2, 2, 1] linear Gabidulin code over GF(16)/GF(4) + Polynomial evaluation style encoder for + [2, 2, 1] linear Gabidulin code over GF(16)/GF(4) Alternatively, we can construct the encoder from ``C`` directly:: sage: E = C.encoder("PolynomialEvaluation") sage: E - Polynomial evaluation style encoder for [2, 2, 1] linear Gabidulin code over GF(16)/GF(4) + Polynomial evaluation style encoder for + [2, 2, 1] linear Gabidulin code over GF(16)/GF(4) """ def __init__(self, code): @@ -655,7 +660,8 @@ def message_space(self): sage: C = codes.GabidulinCode(Fqm, 4, 4, Fq) sage: E = codes.encoders.GabidulinPolynomialEvaluationEncoder(C) sage: E.message_space() - Ore Polynomial Ring in x over Finite Field in z20 of size 5^20 twisted by z20 |--> z20^(5^4) + Ore Polynomial Ring in x over Finite Field in z20 of size 5^20 + twisted by z20 |--> z20^(5^4) """ C = self.code() return C.base_field()['x', C.twisting_homomorphism()] diff --git a/src/sage/coding/goppa_code.py b/src/sage/coding/goppa_code.py index fbfa74462c4..fffd3fd080f 100644 --- a/src/sage/coding/goppa_code.py +++ b/src/sage/coding/goppa_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Goppa code diff --git a/src/sage/coding/grs_code.py b/src/sage/coding/grs_code.py index d86c61c254e..3ec7ee30092 100644 --- a/src/sage/coding/grs_code.py +++ b/src/sage/coding/grs_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Reed-Solomon codes and Generalized Reed-Solomon codes @@ -64,9 +65,6 @@ from sage.misc.functional import symbolic_sum from sage.misc.misc_c import prod -from sage.functions.other import binomial -from sage.symbolic.ring import SR - from .linear_code import AbstractLinearCode from .encoder import Encoder from .decoder import Decoder, DecodingError @@ -516,7 +514,7 @@ def weight_distribution(self): sage: F = GF(11) sage: n, k = 10, 5 sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k) - sage: C.weight_distribution() + sage: C.weight_distribution() # optional - sage.symbolic [1, 0, 0, 0, 0, 0, 2100, 6000, 29250, 61500, 62200] TESTS: @@ -525,13 +523,16 @@ def weight_distribution(self): sage: F = GF(7) sage: C = codes.GeneralizedReedSolomonCode(F.list(), 3) - sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time + sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time # optional - sage.symbolic True sage: F = GF(8) sage: C = codes.GeneralizedReedSolomonCode(F.list(), 3) - sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time + sage: C.weight_distribution() == super(codes.GeneralizedReedSolomonCode, C).weight_distribution() # long time # optional - sage.symbolic True """ + from sage.symbolic.ring import SR + from sage.functions.other import binomial + d = self.minimum_distance() n = self.length() q = self.base_ring().order() @@ -987,7 +988,8 @@ def encode(self, p): sage: E.encode(p) Traceback (most recent call last): ... - ValueError: The value to encode must be in Univariate Polynomial Ring in x over Finite Field of size 11 + ValueError: The value to encode must be in + Univariate Polynomial Ring in x over Finite Field of size 11 TESTS: @@ -1277,7 +1279,8 @@ def decode_to_message(self, r): sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k) sage: D = codes.decoders.GRSBerlekampWelchDecoder(C) sage: c = C.random_element() - sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: D.connected_encoder().unencode(c) == D.decode_to_message(y) True @@ -1338,7 +1341,8 @@ def decode_to_code(self, r): sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k) sage: D = codes.decoders.GRSBerlekampWelchDecoder(C) sage: c = C.random_element() - sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: c == D.decode_to_code(y) True @@ -1660,7 +1664,8 @@ def decode_to_message(self, r): sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k) sage: D = codes.decoders.GRSGaoDecoder(C) sage: c = C.random_element() - sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: D.connected_encoder().unencode(c) == D.decode_to_message(y) True @@ -1721,7 +1726,8 @@ def decode_to_code(self, r): sage: C = codes.GeneralizedReedSolomonCode(F.list()[:n], k) sage: D = codes.decoders.GRSGaoDecoder(C) sage: c = C.random_element() - sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: c == D.decode_to_code(y) True @@ -1927,7 +1933,8 @@ def decode_to_message(self, word_and_erasure_vector): sage: D = codes.decoders.GRSErrorErasureDecoder(C) sage: c = C.random_element() sage: n_era = randint(0, C.minimum_distance() - 2) - sage: Chan = channels.ErrorErasureChannel(C.ambient_space(), D.decoding_radius(n_era), n_era) + sage: Chan = channels.ErrorErasureChannel(C.ambient_space(), + ....: D.decoding_radius(n_era), n_era) sage: y = Chan(c) sage: D.connected_encoder().unencode(c) == D.decode_to_message(y) True @@ -2272,7 +2279,8 @@ def decode_to_code(self, r): sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k) sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C) sage: c = C.random_element() - sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: c == D.decode_to_code(y) True @@ -2346,7 +2354,8 @@ def decode_to_message(self, r): sage: C = codes.GeneralizedReedSolomonCode(F.list()[1:n+1], k) sage: D = codes.decoders.GRSKeyEquationSyndromeDecoder(C) sage: c = C.random_element() - sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(C.ambient_space(), + ....: D.decoding_radius()) sage: y = Chan(c) sage: D.connected_encoder().unencode(c) == D.decode_to_message(y) True diff --git a/src/sage/coding/guava.py b/src/sage/coding/guava.py index 26d94e068f3..ee0aa849e46 100644 --- a/src/sage/coding/guava.py +++ b/src/sage/coding/guava.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.libs.gap sage.modules sage.rings.finite_rings r""" Constructions of generator matrices using the GUAVA package for GAP diff --git a/src/sage/coding/guruswami_sudan/gs_decoder.py b/src/sage/coding/guruswami_sudan/gs_decoder.py index 830d49238dc..85f9fb2327c 100644 --- a/src/sage/coding/guruswami_sudan/gs_decoder.py +++ b/src/sage/coding/guruswami_sudan/gs_decoder.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Guruswami-Sudan decoder for (Generalized) Reed-Solomon codes @@ -36,7 +37,7 @@ def n_k_params(C, n_k): r""" - Internal helper function for the GRSGuruswamiSudanDecoder class for allowing to + Internal helper function for the :class:`GRSGuruswamiSudanDecoder` class for allowing to specify either a GRS code `C` or the length and dimensions `n, k` directly, in all the static functions. @@ -60,13 +61,13 @@ def n_k_params(C, n_k): sage: n_k_params(None, (10, 5)) (10, 5) sage: C = codes.GeneralizedReedSolomonCode(GF(11).list()[:10], 5) - sage: n_k_params(C,None) + sage: n_k_params(C, None) (10, 5) sage: n_k_params(None,None) Traceback (most recent call last): ... ValueError: Please provide either the code or its length and dimension - sage: n_k_params(C,(12, 2)) + sage: n_k_params(C, (12, 2)) Traceback (most recent call last): ... ValueError: Please provide only the code or its length and dimension @@ -155,16 +156,16 @@ class GRSGuruswamiSudanDecoder(Decoder): Guruswami-Sudan algorithm to correct. - ``parameters`` -- (default: ``None``) a pair of integers, where: - - the first integer is the multiplicity parameter, and - - the second integer is the list size parameter. + - the first integer is the multiplicity parameter, and + - the second integer is the list size parameter. - ``interpolation_alg`` -- (default: ``None``) the interpolation algorithm that will be used. The following possibilities are currently available: - * ``"LinearAlgebra"`` -- uses a linear system solver. - * ``"LeeOSullivan"`` -- uses Lee O'Sullivan method based on row reduction of a matrix - * ``None`` -- one of the above will be chosen based on the size of the - code and the parameters. + * ``"LinearAlgebra"`` -- uses a linear system solver. + * ``"LeeOSullivan"`` -- uses Lee O'Sullivan method based on row reduction of a matrix + * ``None`` -- one of the above will be chosen based on the size of the + code and the parameters. You can also supply your own function to perform the interpolation. See NOTE section for details on the signature of this function. @@ -172,12 +173,12 @@ class GRSGuruswamiSudanDecoder(Decoder): - ``root_finder`` -- (default: ``None``) the rootfinding algorithm that will be used. The following possibilities are currently available: - * ``"Alekhnovich"`` -- uses Alekhnovich's algorithm. + * ``"Alekhnovich"`` -- uses Alekhnovich's algorithm. - * ``"RothRuckenstein"`` -- uses Roth-Ruckenstein algorithm. + * ``"RothRuckenstein"`` -- uses Roth-Ruckenstein algorithm. - * ``None`` -- one of the above will be chosen based on the size of the - code and the parameters. + * ``None`` -- one of the above will be chosen based on the size of the + code and the parameters. You can also supply your own function to perform the interpolation. See NOTE section for details on the signature of this function. @@ -201,38 +202,40 @@ class GRSGuruswamiSudanDecoder(Decoder): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau = 97) - sage: D - Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) decoding 97 errors with parameters (1, 2) + sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau=97); D + Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) + decoding 97 errors with parameters (1, 2) One can specify multiplicity and list size instead of ``tau``:: - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters = (1,2)) - sage: D - Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) decoding 97 errors with parameters (1, 2) + sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters=(1,2)); D + Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) + decoding 97 errors with parameters (1, 2) One can pass a method as ``root_finder`` (works also for ``interpolation_alg``):: sage: from sage.coding.guruswami_sudan.gs_decoder import roth_ruckenstein_root_finder sage: rf = roth_ruckenstein_root_finder - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters = (1,2), root_finder = rf) - sage: D - Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) decoding 97 errors with parameters (1, 2) + sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters=(1,2), + ....: root_finder=rf); D + Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) + decoding 97 errors with parameters (1, 2) If one wants to use the native Sage algorithms for the root finding step, one can directly pass the string given in the ``Input`` block of this class. This works for ``interpolation_alg`` as well:: - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters = (1,2), root_finder="RothRuckenstein") - sage: D - Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) decoding 97 errors with parameters (1, 2) + sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, parameters=(1,2), + ....: root_finder="RothRuckenstein"); D + Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) + decoding 97 errors with parameters (1, 2) Actually, we can construct the decoder from ``C`` directly:: - sage: D = C.decoder("GuruswamiSudan", tau = 97) - sage: D - Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) decoding 97 errors with parameters (1, 2) + sage: D = C.decoder("GuruswamiSudan", tau=97); D + Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) + decoding 97 errors with parameters (1, 2) """ ####################### static methods ############################### @@ -254,8 +257,8 @@ def parameters_given_tau(tau, C = None, n_k = None): OUTPUT: - ``(s, l)`` -- a pair of integers, where: - - ``s`` is the multiplicity parameter, and - - ``l`` is the list size parameter. + - ``s`` is the multiplicity parameter, and + - ``l`` is the list size parameter. .. NOTE:: @@ -264,23 +267,25 @@ def parameters_given_tau(tau, C = None, n_k = None): EXAMPLES:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: tau, n, k = 97, 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) + sage: GSD.parameters_given_tau(tau, n_k=(n, k)) (1, 2) Another example with a bigger decoding radius:: sage: tau, n, k = 118, 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) + sage: GSD.parameters_given_tau(tau, n_k=(n, k)) (47, 89) Choosing a decoding radius which is too large results in an errors:: sage: tau = 200 - sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) + sage: GSD.parameters_given_tau(tau, n_k=(n, k)) Traceback (most recent call last): ... - ValueError: The decoding radius must be less than the Johnson radius (which is 118.66) + ValueError: The decoding radius must be less than + the Johnson radius (which is 118.66) """ n,k = n_k_params(C, n_k) @@ -332,27 +337,28 @@ def guruswami_sudan_decoding_radius(C = None, n_k = None, l = None, s = None): OUTPUT: - ``(tau, (s, l))`` -- where - - ``tau`` is the obtained decoding radius, and - - ``s, ell`` are the multiplicity parameter, respectively list size - parameter giving this radius. + - ``tau`` is the obtained decoding radius, and + - ``s, ell`` are the multiplicity parameter, respectively list size + parameter giving this radius. EXAMPLES:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: n, k = 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k)) + sage: GSD.guruswami_sudan_decoding_radius(n_k=(n, k)) (118, (47, 89)) One parameter can be restricted at a time:: sage: n, k = 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k), s=3) + sage: GSD.guruswami_sudan_decoding_radius(n_k=(n, k), s=3) (109, (3, 5)) - sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k), l=7) + sage: GSD.guruswami_sudan_decoding_radius(n_k=(n, k), l=7) (111, (4, 7)) The function can also just compute the decoding radius given the parameters:: - sage: codes.decoders.GRSGuruswamiSudanDecoder.guruswami_sudan_decoding_radius(n_k = (n, k), s=2, l=6) + sage: GSD.guruswami_sudan_decoding_radius(n_k=(n, k), s=2, l=6) (92, (2, 6)) """ n,k = n_k_params(C, n_k) @@ -364,7 +370,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)) @@ -423,8 +429,8 @@ def _suitable_parameters_given_tau(tau, C = None, n_k = None): OUTPUT: - ``(s, l)`` -- a pair of integers, where: - - ``s`` is the multiplicity parameter, and - - ``l`` is the list size parameter. + - ``s`` is the multiplicity parameter, and + - ``l`` is the list size parameter. .. NOTE:: @@ -436,31 +442,32 @@ def _suitable_parameters_given_tau(tau, C = None, n_k = None): The following is an example where the parameters are optimal:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: tau = 98 sage: n, k = 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder._suitable_parameters_given_tau(tau, n_k = (n, k)) + sage: GSD._suitable_parameters_given_tau(tau, n_k=(n, k)) (2, 3) - sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) + sage: GSD.parameters_given_tau(tau, n_k=(n, k)) (2, 3) This is an example where they are not:: sage: tau = 97 sage: n, k = 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder._suitable_parameters_given_tau(tau, n_k = (n, k)) + sage: GSD._suitable_parameters_given_tau(tau, n_k=(n, k)) (2, 3) - sage: codes.decoders.GRSGuruswamiSudanDecoder.parameters_given_tau(tau, n_k = (n, k)) + sage: GSD.parameters_given_tau(tau, n_k=(n, k)) (1, 2) We can provide a GRS code instead of `n` and `k` directly:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: codes.decoders.GRSGuruswamiSudanDecoder._suitable_parameters_given_tau(tau, C = C) + sage: GSD._suitable_parameters_given_tau(tau, C=C) (2, 3) Another one with a bigger ``tau``:: - sage: codes.decoders.GRSGuruswamiSudanDecoder._suitable_parameters_given_tau(118, C = C) + sage: GSD._suitable_parameters_given_tau(118, C=C) (47, 89) """ n,k = n_k_params(C, n_k) @@ -497,21 +504,22 @@ def gs_satisfactory(tau, s, l, C = None, n_k = None): EXAMPLES:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: tau, s, l = 97, 1, 2 sage: n, k = 250, 70 - sage: codes.decoders.GRSGuruswamiSudanDecoder.gs_satisfactory(tau, s, l, n_k = (n, k)) + sage: GSD.gs_satisfactory(tau, s, l, n_k=(n, k)) True One can also pass a GRS code:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: codes.decoders.GRSGuruswamiSudanDecoder.gs_satisfactory(tau, s, l, C = C) + sage: GSD.gs_satisfactory(tau, s, l, C=C) True Another example where ``s`` and ``l`` does not satisfy the equation:: sage: tau, s, l = 118, 47, 80 - sage: codes.decoders.GRSGuruswamiSudanDecoder.gs_satisfactory(tau, s, l, n_k = (n, k)) + sage: GSD.gs_satisfactory(tau, s, l, n_k=(n, k)) False If one provides both ``C`` and ``n_k`` an exception is returned:: @@ -519,14 +527,14 @@ def gs_satisfactory(tau, s, l, C = None, n_k = None): sage: tau, s, l = 97, 1, 2 sage: n, k = 250, 70 sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: codes.decoders.GRSGuruswamiSudanDecoder.gs_satisfactory(tau, s, l, C = C, n_k = (n, k)) + sage: GSD.gs_satisfactory(tau, s, l, C=C, n_k=(n, k)) Traceback (most recent call last): ... ValueError: Please provide only the code or its length and dimension Same if one provides none of these:: - sage: codes.decoders.GRSGuruswamiSudanDecoder.gs_satisfactory(tau, s, l) + sage: GSD.gs_satisfactory(tau, s, l) Traceback (most recent call last): ... ValueError: Please provide either the code or its length and dimension @@ -541,8 +549,9 @@ def __init__(self, code, tau = None, parameters = None, interpolation_alg = None If neither ``tau`` nor ``parameters`` is given, an exception is returned:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C) + sage: D = GSD(C) Traceback (most recent call last): ... ValueError: Specify either tau or parameters @@ -551,7 +560,7 @@ def __init__(self, code, tau = None, parameters = None, interpolation_alg = None an exception is returned:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau = 97, interpolation_alg = 42) + sage: D = GSD(C, tau=97, interpolation_alg=42) Traceback (most recent call last): ... ValueError: Please provide a method or one of the allowed strings for interpolation_alg @@ -559,7 +568,7 @@ def __init__(self, code, tau = None, parameters = None, interpolation_alg = None Same thing for ``root_finder``:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau = 97, root_finder = "FortyTwo") + sage: D = GSD(C, tau=97, root_finder="FortyTwo") Traceback (most recent call last): ... ValueError: Please provide a method or one of the allowed strings for root_finder @@ -568,7 +577,7 @@ def __init__(self, code, tau = None, parameters = None, interpolation_alg = None error message is returned:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau = 142, parameters=(1, 2)) + sage: D = GSD(C, tau=142, parameters=(1, 2)) Traceback (most recent call last): ... ValueError: Impossible parameters for the Guruswami-Sudan algorithm @@ -576,7 +585,7 @@ def __init__(self, code, tau = None, parameters = None, interpolation_alg = None If ``code`` is not a GRS code, an error is raised:: sage: C = codes.random_linear_code(GF(11), 10, 4) - sage: codes.decoders.GRSGuruswamiSudanDecoder(C, tau = 2) + sage: GSD(C, tau=2) Traceback (most recent call last): ... ValueError: code has to be a generalized Reed-Solomon code @@ -622,7 +631,7 @@ def _repr_(self): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D Guruswami-Sudan decoder for [250, 70, 181] Reed-Solomon Code over GF(251) decoding 97 errors with parameters (1, 2) """ @@ -635,7 +644,7 @@ def _latex_(self): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: latex(D) \textnormal{Guruswami-Sudan decoder for } [250, 70, 181] \textnormal{ Reed-Solomon Code over } \Bold{F}_{251}\textnormal{ decoding }97\textnormal{ errors with parameters }(1, 2) """ @@ -648,8 +657,8 @@ def __eq__(self, other): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D1 = C.decoder("GuruswamiSudan", tau = 97) - sage: D2 = C.decoder("GuruswamiSudan", tau = 97) + sage: D1 = C.decoder("GuruswamiSudan", tau=97) + sage: D2 = C.decoder("GuruswamiSudan", tau=97) sage: D1.__eq__(D2) True """ @@ -673,7 +682,7 @@ def interpolation_algorithm(self): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D.interpolation_algorithm() """ @@ -691,7 +700,7 @@ def rootfinding_algorithm(self): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D.rootfinding_algorithm() """ @@ -704,7 +713,7 @@ def parameters(self): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D.parameters() (1, 2) """ @@ -717,7 +726,7 @@ def multiplicity(self): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D.multiplicity() 1 """ @@ -730,7 +739,7 @@ def list_size(self): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D.list_size() 2 """ @@ -749,8 +758,9 @@ def decode_to_message(self, r): EXAMPLES:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: C = codes.GeneralizedReedSolomonCode(GF(17).list()[:15], 6) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau=5) + sage: D = GSD(C, tau=5) sage: F. = GF(17)[] sage: m = 13*x^4 + 7*x^3 + 10*x^2 + 14*x + 3 sage: c = D.connected_encoder().encode(m) @@ -769,7 +779,7 @@ def decode_to_message(self, r): does not fit the allowed signature, an exception will be raised:: sage: C = codes.GeneralizedReedSolomonCode(GF(17).list()[:15], 6) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau=5, root_finder=next_prime) + sage: D = GSD(C, tau=5, root_finder=next_prime) sage: F. = GF(17)[] sage: m = 9*x^5 + 10*x^4 + 9*x^3 + 7*x^2 + 15*x + 2 sage: c = D.connected_encoder().encode(m) @@ -777,7 +787,8 @@ def decode_to_message(self, r): sage: m in D.decode_to_message(r) Traceback (most recent call last): ... - ValueError: The provided root-finding algorithm has a wrong signature. See the documentation of `codes.decoders.GRSGuruswamiSudanDecoder.rootfinding_algorithm()` for details + ValueError: The provided root-finding algorithm has a wrong signature. + See the documentation of `GSD.rootfinding_algorithm()` for details """ return [self.connected_encoder().unencode(c) for c in self.decode_to_code(r)] @@ -792,8 +803,9 @@ def decode_to_code(self, r): EXAMPLES:: + sage: GSD = codes.decoders.GRSGuruswamiSudanDecoder sage: C = codes.GeneralizedReedSolomonCode(GF(17).list()[:15], 6) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau=5) + sage: D = GSD(C, tau=5) sage: c = vector(GF(17), [3,13,12,0,0,7,5,1,8,11,1,9,4,12,14]) sage: c in C True @@ -811,7 +823,7 @@ def decode_to_code(self, r): Check that :trac:`21347` is fixed:: sage: C = codes.GeneralizedReedSolomonCode(GF(13).list()[:10], 3) - sage: D = codes.decoders.GRSGuruswamiSudanDecoder(C, tau = 4) + sage: D = GSD(C, tau=4) sage: c = vector(GF(13), [6, 8, 2, 1, 5, 1, 2, 8, 6, 9]) sage: e = vector(GF(13), [1, 0, 0, 1, 1, 0, 0, 1, 0, 1]) sage: D.decode_to_code(c+e) @@ -852,14 +864,14 @@ def decoding_radius(self): EXAMPLES:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", tau = 97) + sage: D = C.decoder("GuruswamiSudan", tau=97) sage: D.decoding_radius() 97 An example where tau is not one of the inputs to the constructor:: sage: C = codes.GeneralizedReedSolomonCode(GF(251).list()[:250], 70) - sage: D = C.decoder("GuruswamiSudan", parameters = (2,4)) + sage: D = C.decoder("GuruswamiSudan", parameters=(2,4)) sage: D.decoding_radius() 105 """ diff --git a/src/sage/coding/guruswami_sudan/interpolation.py b/src/sage/coding/guruswami_sudan/interpolation.py index af150b460c6..0b49c80b347 100644 --- a/src/sage/coding/guruswami_sudan/interpolation.py +++ b/src/sage/coding/guruswami_sudan/interpolation.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings """ Interpolation algorithms for the Guruswami-Sudan decoder @@ -240,8 +241,8 @@ def gs_interpolation_linalg(points, tau, parameters, wy): - ``tau`` -- an integer, the number of errors one wants to decode. - ``parameters`` -- (default: ``None``) a pair of integers, where: - - the first integer is the multiplicity parameter of Guruswami-Sudan algorithm and - - the second integer is the list size parameter. + - the first integer is the multiplicity parameter of Guruswami-Sudan algorithm and + - the second integer is the list size parameter. - ``wy`` -- an integer, the `y`-weight, where we seek ``Q`` of low ``(1,wy)`` weighted degree. @@ -253,12 +254,14 @@ def gs_interpolation_linalg(points, tau, parameters, wy): sage: from sage.coding.guruswami_sudan.interpolation import gs_interpolation_linalg sage: F = GF(11) - sage: points = [(F(x),F(y)) for (x,y) in [(0, 5), (1, 1), (2, 4), (3, 6), (4, 3), (5, 3)]] + sage: points = [(F(x), F(y)) + ....: for (x, y) in [(0, 5), (1, 1), (2, 4), (3, 6), (4, 3), (5, 3)]] sage: tau = 3 sage: params = (2, 4) sage: wy = 1 sage: Q = gs_interpolation_linalg(points, tau, params, wy); Q - 4*x^5 - 4*x^4*y - 2*x^2*y^3 - x*y^4 + 3*x^4 - 4*x^2*y^2 + 5*y^4 - x^3 + x^2*y + 5*x*y^2 - 5*y^3 + 3*x*y - 2*y^2 + x - 4*y + 1 + 4*x^5 - 4*x^4*y - 2*x^2*y^3 - x*y^4 + 3*x^4 - 4*x^2*y^2 + 5*y^4 - x^3 + x^2*y + + 5*x*y^2 - 5*y^3 + 3*x*y - 2*y^2 + x - 4*y + 1 We verify that the interpolation polynomial has a zero of multiplicity at least 2 in each point:: @@ -286,7 +289,7 @@ def gs_interpolation_linalg(points, tau, parameters, wy): def lee_osullivan_module(points, parameters, wy): r""" - Returns the analytically straight-forward basis for the `\GF q[x]` module + Return the analytically straight-forward basis for the `\GF q[x]` module containing all interpolation polynomials, as according to Lee and O'Sullivan. @@ -309,8 +312,8 @@ def lee_osullivan_module(points, parameters, wy): ``(xi,yi)`` being a root of ``Q`` with multiplicity ``s``. - ``parameters`` -- (default: ``None``) a pair of integers, where: - - the first integer is the multiplicity parameter `s` of Guruswami-Sudan algorithm and - - the second integer is the list size parameter. + - the first integer is the multiplicity parameter `s` of Guruswami-Sudan algorithm and + - the second integer is the list size parameter. - ``wy`` -- an integer, the `y`-weight, where we seek ``Q`` of low ``(1,wy)`` weighted degree. @@ -319,8 +322,8 @@ def lee_osullivan_module(points, parameters, wy): sage: from sage.coding.guruswami_sudan.interpolation import lee_osullivan_module sage: F = GF(11) - sage: points = [(F(0), F(2)), (F(1), F(5)), (F(2), F(0)), (F(3), F(4)), (F(4), F(9))\ - , (F(5), F(1)), (F(6), F(9)), (F(7), F(10))] + sage: points = [(F(0), F(2)), (F(1), F(5)), (F(2), F(0)), (F(3), F(4)), + ....: (F(4), F(9)), (F(5), F(1)), (F(6), F(9)), (F(7), F(10))] sage: params = (1, 1) sage: wy = 1 sage: lee_osullivan_module(points, params, wy) @@ -363,8 +366,8 @@ def gs_interpolation_lee_osullivan(points, tau, parameters, wy): - ``tau`` -- an integer, the number of errors one wants to decode. - ``parameters`` -- (default: ``None``) a pair of integers, where: - - the first integer is the multiplicity parameter of Guruswami-Sudan algorithm and - - the second integer is the list size parameter. + - the first integer is the multiplicity parameter of Guruswami-Sudan algorithm and + - the second integer is the list size parameter. - ``wy`` -- an integer, the `y`-weight, where we seek ``Q`` of low ``(1,wy)`` weighted degree. @@ -373,13 +376,13 @@ def gs_interpolation_lee_osullivan(points, tau, parameters, wy): sage: from sage.coding.guruswami_sudan.interpolation import gs_interpolation_lee_osullivan sage: F = GF(11) - sage: points = [(F(0), F(2)), (F(1), F(5)), (F(2), F(0)), (F(3), F(4)), (F(4), F(9))\ - , (F(5), F(1)), (F(6), F(9)), (F(7), F(10))] + sage: points = [(F(0), F(2)), (F(1), F(5)), (F(2), F(0)), (F(3), F(4)), + ....: (F(4), F(9)), (F(5), F(1)), (F(6), F(9)), (F(7), F(10))] sage: tau = 1 sage: params = (1, 1) sage: wy = 1 sage: Q = gs_interpolation_lee_osullivan(points, tau, params, wy) - sage: Q / Q.lc() # make monic + sage: Q / Q.lc() # make monic x^3*y + 2*x^3 - x^2*y + 5*x^2 + 5*x*y - 5*x + 2*y - 4 """ from .utils import _degree_of_vector diff --git a/src/sage/coding/guruswami_sudan/utils.py b/src/sage/coding/guruswami_sudan/utils.py index d53637d933f..d899bd0e12e 100644 --- a/src/sage/coding/guruswami_sudan/utils.py +++ b/src/sage/coding/guruswami_sudan/utils.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Guruswami-Sudan utility methods diff --git a/src/sage/coding/hamming_code.py b/src/sage/coding/hamming_code.py index cf355c2431f..4d63c0409c4 100644 --- a/src/sage/coding/hamming_code.py +++ b/src/sage/coding/hamming_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Hamming codes diff --git a/src/sage/coding/information_set_decoder.py b/src/sage/coding/information_set_decoder.py index fb4612fa69b..3f28a0bcd06 100644 --- a/src/sage/coding/information_set_decoder.py +++ b/src/sage/coding/information_set_decoder.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Information-set decoding for linear codes @@ -96,7 +96,8 @@ class InformationSetAlgorithm(SageObject): sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm sage: LeeBrickellISDAlgorithm(codes.GolayCode(GF(2)), (0,4)) - ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 4 errors + ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) + decoding up to 4 errors A minimal working example of how to sub-class:: @@ -112,7 +113,8 @@ class InformationSetAlgorithm(SageObject): ....: # decoding algorithm here ....: raise DecodingError("I failed") sage: MinimalISD(codes.GolayCode(GF(2)), (0,4)) - ISD Algorithm (MinimalISD) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 4 errors + 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): @@ -388,11 +390,13 @@ class LeeBrickellISDAlgorithm(InformationSetAlgorithm): sage: C = codes.GolayCode(GF(2)) sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm sage: A = LeeBrickellISDAlgorithm(C, (0,4)); A - ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 4 errors + ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) + decoding up to 4 errors sage: C = codes.GolayCode(GF(2)) 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 + 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): r""" @@ -525,7 +529,8 @@ def calibrate(self): sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm sage: C = codes.GolayCode(GF(2)) sage: A = LeeBrickellISDAlgorithm(C, (0,3)); A - ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 3 errors + ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) + decoding up to 3 errors sage: A.calibrate() sage: A.parameters() #random {'search_size': 1} @@ -535,7 +540,8 @@ def calibrate(self): If we specify the parameter at construction time, calibrate does not override this choice:: sage: A = LeeBrickellISDAlgorithm(C, (0,3), search_size=2); A - ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding up to 3 errors + ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) + decoding up to 3 errors sage: A.parameters() {'search_size': 2} sage: A.calibrate() @@ -693,16 +699,19 @@ class LinearCodeInformationSetDecoder(Decoder): sage: C = codes.GolayCode(GF(3)) sage: D = C.decoder("InformationSet", 2); D - Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors You can specify which algorithm you wish to use, and you should do so in order to pass special parameters to it:: sage: C = codes.GolayCode(GF(3)) sage: D2 = C.decoder("InformationSet", 2, algorithm="Lee-Brickell", search_size=2); D2 - Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors sage: D2.algorithm() - ISD Algorithm (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + ISD Algorithm (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors sage: D2.algorithm().parameters() {'search_size': 2} @@ -711,7 +720,8 @@ class LinearCodeInformationSetDecoder(Decoder): sage: C.decoder("InformationSet", 2, algorithm="NoSuchThing") Traceback (most recent call last): ... - ValueError: Unknown ISD algorithm 'NoSuchThing'. The known algorithms are ['Lee-Brickell']. + ValueError: Unknown ISD algorithm 'NoSuchThing'. + The known algorithms are ['Lee-Brickell']. You can also construct an ISD algorithm separately and pass that. This is mostly useful if you write your own ISD algorithms:: @@ -719,7 +729,8 @@ class LinearCodeInformationSetDecoder(Decoder): sage: from sage.coding.information_set_decoder import LeeBrickellISDAlgorithm sage: A = LeeBrickellISDAlgorithm(C, (0, 2)) sage: D = C.decoder("InformationSet", 2, algorithm=A); D - Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors When passing an already constructed ISD algorithm, you can't also pass parameters to the ISD algorithm when constructing the decoder:: @@ -727,22 +738,26 @@ class LinearCodeInformationSetDecoder(Decoder): sage: C.decoder("InformationSet", 2, algorithm=A, search_size=2) Traceback (most recent call last): ... - ValueError: ISD algorithm arguments are not allowed when supplying a constructed ISD algorithm + ValueError: ISD algorithm arguments are not allowed + when supplying a constructed ISD algorithm We can also information-set decode non-binary codes:: sage: C = codes.GolayCode(GF(3)) sage: D = C.decoder("InformationSet", 2); D - Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors There are two other ways to access this class:: sage: D = codes.decoders.LinearCodeInformationSetDecoder(C, 2); D - Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors sage: from sage.coding.information_set_decoder import LinearCodeInformationSetDecoder sage: D = LinearCodeInformationSetDecoder(C, 2); D - Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) decoding up to 2 errors + Information-set decoder (Lee-Brickell) for [12, 6, 6] Extended Golay code over GF(3) + decoding up to 2 errors """ def __init__(self, code, number_errors, algorithm=None, **kwargs): r""" @@ -889,7 +904,8 @@ def algorithm(self): sage: C = codes.GolayCode(GF(2)) sage: D = C.decoder("InformationSet", (2,4), "Lee-Brickell") sage: D.algorithm() - ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) decoding between 2 and 4 errors + ISD Algorithm (Lee-Brickell) for [24, 12, 8] Extended Golay code over GF(2) + decoding between 2 and 4 errors """ return self._algorithm diff --git a/src/sage/coding/kasami_codes.pyx b/src/sage/coding/kasami_codes.pyx index 8212ae29ded..b14eada8436 100644 --- a/src/sage/coding/kasami_codes.pyx +++ b/src/sage/coding/kasami_codes.pyx @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Kasami code diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index b03ef5116ba..2e98ea967e3 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: sage.modules sage.rings.finite_rings r""" Generic structures for linear codes over the Hamming metric @@ -217,12 +217,11 @@ class should inherit from this class. Also ``AbstractLinearCode`` should never from sage.combinat.subset import Subsets from sage.cpython.string import bytes_to_str from sage.features.gap import GapPackage -from sage.groups.perm_gps.permgroup_named import SymmetricGroup -from sage.groups.perm_gps.permgroup import PermutationGroup from sage.interfaces.gap import gap from sage.matrix.matrix_space import MatrixSpace from sage.misc.cachefunc import cached_method from sage.misc.functional import is_even +from sage.misc.lazy_import import lazy_import from sage.misc.misc_c import prod from sage.misc.randstate import current_randstate from sage.modules.free_module import VectorSpace @@ -233,6 +232,10 @@ class should inherit from this class. Also ``AbstractLinearCode`` should never from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import QQ +lazy_import('sage.groups.perm_gps.permgroup_named', 'SymmetricGroup') +lazy_import('sage.groups.perm_gps.permgroup', 'PermutationGroup') + + # ***************************************************************************** # coding theory functions # ***************************************************************************** @@ -374,7 +377,8 @@ def __init__(self, base_field, length, default_encoder_name, default_decoder_nam sage: class MyCodeFamily(sage.coding.linear_code.AbstractLinearCode): ....: def __init__(self, field, length, dimension, generator_matrix): - ....: sage.coding.linear_code.AbstractLinearCode.__init__(self,field, length, "GeneratorMatrix", "Syndrome") + ....: super().__init__(self, field, length, + ....: "GeneratorMatrix", "Syndrome") ....: self._dimension = dimension ....: self._generator_matrix = generator_matrix ....: def generator_matrix(self): @@ -445,11 +449,11 @@ def automorphism_group_gens(self, equivalence="semilinear"): - ``equivalence`` (optional) -- which defines the acting group, either - * ``permutational`` + * ``"permutational"`` - * ``linear`` + * ``"linear"`` - * ``semilinear`` + * ``"semilinear"`` OUTPUT: @@ -466,30 +470,55 @@ def automorphism_group_gens(self, equivalence="semilinear"): 0 sage: C = codes.HammingCode(GF(4, 'z'), 3) sage: C.automorphism_group_gens() - ([((1, 1, 1, z, z + 1, 1, 1, 1, 1, z + 1, z, z, z + 1, z + 1, z + 1, 1, z + 1, z, z, 1, z); (1,13,14,20)(2,21,8,18,7,16,19,15)(3,10,5,12,17,9,6,4), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z + 1), - ((z, 1, z, z, z, z + 1, z, z, z, z, z, z, z + 1, z, z, z, z, z + 1, z, z, z); (1,11,5,12,3,19)(2,8)(6,18,13)(7,17,15)(9,10,14,16,20,21), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z + 1), - ((z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z); (), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z)], + ([((1, 1, 1, z, z + 1, 1, 1, 1, 1, z + 1, z, z, z + 1, z + 1, + z + 1, 1, z + 1, z, z, 1, z); + (1,13,14,20)(2,21,8,18,7,16,19,15)(3,10,5,12,17,9,6,4), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z + 1), + ((z, 1, z, z, z, z + 1, z, z, z, z, z, z, z + 1, z, z, z, + z, z + 1, z, z, z); + (1,11,5,12,3,19)(2,8)(6,18,13)(7,17,15)(9,10,14,16,20,21), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z + 1), + ((z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z); + (), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z)], 362880) sage: C.automorphism_group_gens(equivalence="linear") - ([((z, 1, z + 1, z + 1, 1, z + 1, z, 1, z + 1, z + 1, 1, z, 1, z + 1, z, 1, z, 1, z + 1, 1, 1); (1,12,11,10,6,8,9,20,13,21,5,14,3,16,17,19,7,4,2,15,18), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z), - ((z + 1, z + 1, z + 1, z, 1, 1, z, z, 1, z + 1, z, 1, 1, z, 1, z + 1, z, z + 1, z + 1, 1, z); (1,3,18,2,17,6,19)(4,15,13,20,7,14,16)(5,11,8,21,12,9,10), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z), - ((z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1); (), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z)], + ([((z, 1, z + 1, z + 1, 1, z + 1, z, 1, z + 1, z + 1, 1, z, 1, z + 1, + z, 1, z, 1, z + 1, 1, 1); + (1,12,11,10,6,8,9,20,13,21,5,14,3,16,17,19,7,4,2,15,18), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z), + ((z + 1, z + 1, z + 1, z, 1, 1, z, z, 1, z + 1, z, 1, 1, z, 1, z + 1, + z, z + 1, z + 1, 1, z); + (1,3,18,2,17,6,19)(4,15,13,20,7,14,16)(5,11,8,21,12,9,10), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z), + ((z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, + z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1); + (), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z)], 181440) sage: C.automorphism_group_gens(equivalence="permutational") - ([((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (1,11)(3,10)(4,9)(5,7)(12,21)(14,20)(15,19)(16,17), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z), - ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (2,18)(3,19)(4,10)(5,16)(8,13)(9,14)(11,21)(15,20), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z), - ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (1,19)(3,17)(4,21)(5,20)(7,14)(9,12)(10,16)(11,15), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z), - ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (2,13)(3,14)(4,20)(5,11)(8,18)(9,19)(10,15)(16,21), Ring endomorphism of Finite Field in z of size 2^2 - Defn: z |--> z)], + ([((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + (1,11)(3,10)(4,9)(5,7)(12,21)(14,20)(15,19)(16,17), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z), + ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + (2,18)(3,19)(4,10)(5,16)(8,13)(9,14)(11,21)(15,20), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z), + ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + (1,19)(3,17)(4,21)(5,20)(7,14)(9,12)(10,16)(11,15), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z), + ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); + (2,13)(3,14)(4,20)(5,11)(8,18)(9,19)(10,15)(16,21), + Ring endomorphism of Finite Field in z of size 2^2 + Defn: z |--> z)], 64) """ aut_group_can_label = self._canonize(equivalence) @@ -717,11 +746,11 @@ def canonical_representative(self, equivalence="semilinear"): - ``equivalence`` (optional) -- which defines the acting group, either - * ``permutational`` + * ``"permutational"`` - * ``linear`` + * ``"linear"`` - * ``semilinear`` + * ``"semilinear"`` OUTPUT: @@ -892,7 +921,8 @@ def covering_radius(self): sage: C.covering_radius() # optional - gap_packages (Guava package) Traceback (most recent call last): ... - NotImplementedError: the GAP algorithm that Sage is using is limited to computing with fields of size at most 256 + NotImplementedError: the GAP algorithm that Sage is using + is limited to computing with fields of size at most 256 """ from sage.libs.gap.libgap import libgap GapPackage("guava", spkg="gap_packages").require() @@ -919,7 +949,7 @@ def divisor(self): sage: C = codes.GolayCode(GF(2)) sage: C.divisor() # Type II self-dual 4 - sage: C = codes.QuadraticResidueCodeEvenPair(17,GF(2))[0] + sage: C = codes.QuadraticResidueCodeEvenPair(17, GF(2))[0] sage: C.divisor() 2 """ @@ -952,7 +982,7 @@ def is_projective(self): A non-projective code:: - sage: C = codes.LinearCode(matrix(GF(2),[[1,0,1],[1,1,1]])) + sage: C = codes.LinearCode(matrix(GF(2), [[1,0,1],[1,1,1]])) sage: C.is_projective() False """ @@ -1065,23 +1095,23 @@ def product_code(self, other): Note that the two codes have to be over the same field. - EXAMPLES:: - - sage: C = codes.HammingCode(GF(2), 3) - sage: C - [7, 4] Hamming Code over GF(2) - sage: D = codes.ReedMullerCode(GF(2), 2, 2) - sage: D - Binary Reed-Muller Code of order 2 and number of variables 2 - sage: A = C.product_code(D) - sage: A - [28, 16] linear code over GF(2) - sage: A.length() == C.length()*D.length() - True - sage: A.dimension() == C.dimension()*D.dimension() - True - sage: A.minimum_distance() == C.minimum_distance()*D.minimum_distance() - True + EXAMPLES:: + + sage: C = codes.HammingCode(GF(2), 3) + sage: C + [7, 4] Hamming Code over GF(2) + sage: D = codes.ReedMullerCode(GF(2), 2, 2) + sage: D + Binary Reed-Muller Code of order 2 and number of variables 2 + sage: A = C.product_code(D) + sage: A + [28, 16] linear code over GF(2) + sage: A.length() == C.length()*D.length() + True + sage: A.dimension() == C.dimension()*D.dimension() + True + sage: A.minimum_distance() == C.minimum_distance()*D.minimum_distance() + True """ G1 = self.generator_matrix() @@ -1102,29 +1132,29 @@ def construction_x(self, other, aux): The method will then return a `[n+n_a, k_1, d_a+d_1]` linear code. - EXAMPLES:: - - sage: C = codes.BCHCode(GF(2),15,7) - sage: C - [15, 5] BCH Code over GF(2) with designed distance 7 - sage: D = codes.BCHCode(GF(2),15,5) - sage: D - [15, 7] BCH Code over GF(2) with designed distance 5 - sage: C.is_subcode(D) - True - sage: C.minimum_distance() - 7 - sage: D.minimum_distance() - 5 - sage: aux = codes.HammingCode(GF(2),2) - sage: aux = aux.dual_code() - sage: aux.minimum_distance() - 2 - sage: Cx = D.construction_x(C,aux) - sage: Cx - [18, 7] linear code over GF(2) - sage: Cx.minimum_distance() - 7 + EXAMPLES:: + + sage: C = codes.BCHCode(GF(2),15,7) + sage: C + [15, 5] BCH Code over GF(2) with designed distance 7 + sage: D = codes.BCHCode(GF(2),15,5) + sage: D + [15, 7] BCH Code over GF(2) with designed distance 5 + sage: C.is_subcode(D) + True + sage: C.minimum_distance() + 7 + sage: D.minimum_distance() + 5 + sage: aux = codes.HammingCode(GF(2),2) + sage: aux = aux.dual_code() + sage: aux.minimum_distance() + 2 + sage: Cx = D.construction_x(C,aux) + sage: Cx + [18, 7] linear code over GF(2) + sage: Cx.minimum_distance() + 7 """ if not other.is_subcode(self): raise ValueError("%s is not a subcode of %s" % (self, other)) @@ -1150,12 +1180,12 @@ def construction_x(self, other, aux): def extended_code(self): r""" - Return `self` as an extended code. + Return ``self`` as an extended code. See documentation of :class:`sage.coding.extended_code.ExtendedCode` for details. - EXAMPLES:: + EXAMPLES:: sage: C = codes.HammingCode(GF(4,'a'), 3) sage: C @@ -1245,14 +1275,14 @@ def is_permutation_equivalent(self,other,algorithm=None): EXAMPLES:: sage: P. = PolynomialRing(GF(2),"x") - sage: g = x^3+x+1 - sage: C1 = codes.CyclicCode(length = 7, generator_pol = g); C1 + sage: g = x^3 + x + 1 + sage: C1 = codes.CyclicCode(length=7, generator_pol=g); C1 [7, 4] Cyclic Code over GF(2) sage: C2 = codes.HammingCode(GF(2), 3); C2 [7, 4] Hamming Code over GF(2) sage: C1.is_permutation_equivalent(C2) True - sage: C1.is_permutation_equivalent(C2,algorithm="verbose") + sage: C1.is_permutation_equivalent(C2, algorithm="verbose") (True, (3,4)(5,7,6)) sage: C1 = codes.random_linear_code(GF(2), 10, 5) sage: C2 = codes.random_linear_code(GF(3), 10, 5) @@ -1342,9 +1372,9 @@ def minimum_distance(self, algorithm=None): If ``algorithm`` is provided, then the minimum distance will be recomputed even if there is a stored value from a previous run.:: - sage: C.minimum_distance(algorithm="gap") + sage: C.minimum_distance(algorithm="gap") # optional - sage.libs.gap 3 - sage: libgap.SetAllInfoLevels(0) # to suppress extra info messages + sage: libgap.SetAllInfoLevels(0) # to suppress extra info messages # optional - sage.libs.gap sage: C.minimum_distance(algorithm="guava") # optional - gap_packages (Guava package) ... 3 @@ -1474,10 +1504,11 @@ def module_composition_factors(self, gp): EXAMPLES:: sage: MS = MatrixSpace(GF(2),4,8) - sage: G = MS([[1,0,0,0,1,1,1,0],[0,1,1,1,0,0,0,0],[0,0,0,0,0,0,0,1],[0,0,0,0,0,1,0,0]]) + sage: G = MS([[1,0,0,0,1,1,1,0], [0,1,1,1,0,0,0,0], + ....: [0,0,0,0,0,0,0,1], [0,0,0,0,0,1,0,0]]) sage: C = LinearCode(G) sage: gp = C.permutation_automorphism_group() - sage: C.module_composition_factors(gp) + sage: C.module_composition_factors(gp) # optional - sage.libs.gap [ rec( IsIrreducible := true, IsOverFiniteField := true, @@ -1535,15 +1566,16 @@ def permutation_automorphism_group(self, algorithm="partition"): EXAMPLES:: sage: MS = MatrixSpace(GF(2),4,8) - sage: G = MS([[1,0,0,0,1,1,1,0],[0,1,1,1,0,0,0,0],[0,0,0,0,0,0,0,1],[0,0,0,0,0,1,0,0]]) + sage: G = MS([[1,0,0,0,1,1,1,0], [0,1,1,1,0,0,0,0], + ....: [0,0,0,0,0,0,0,1], [0,0,0,0,0,1,0,0]]) sage: C = LinearCode(G) sage: C [8, 4] linear code over GF(2) - sage: G = C.permutation_automorphism_group() - sage: G.order() + sage: G = C.permutation_automorphism_group() # optional - sage.groups + sage: G.order() # optional - sage.groups 144 - sage: GG = C.permutation_automorphism_group("codecan") - sage: GG == G + sage: GG = C.permutation_automorphism_group("codecan") # optional - sage.groups + sage: GG == G # optional - sage.groups True A less easy example involves showing that the permutation @@ -1553,42 +1585,44 @@ def permutation_automorphism_group(self, algorithm="partition"): :: sage: C = codes.GolayCode(GF(3)) - sage: M11 = MathieuGroup(11) - sage: M11.order() + sage: M11 = MathieuGroup(11) # optional - sage.groups + sage: M11.order() # optional - sage.groups 7920 - sage: G = C.permutation_automorphism_group() # long time (6s on sage.math, 2011) - sage: G.is_isomorphic(M11) # long time + sage: G = C.permutation_automorphism_group() # long time (6s on sage.math, 2011) # optional - sage.groups + sage: G.is_isomorphic(M11) # long time # optional - sage.groups True - sage: GG = C.permutation_automorphism_group("codecan") # long time - sage: GG == G # long time + sage: GG = C.permutation_automorphism_group("codecan") # long time # optional - sage.groups + sage: GG == G # long time # optional - sage.groups True Other examples:: sage: C = codes.GolayCode(GF(2)) - sage: G = C.permutation_automorphism_group() - sage: G.order() + sage: G = C.permutation_automorphism_group() # optional - sage.groups + sage: G.order() # optional - sage.groups 244823040 sage: C = codes.HammingCode(GF(2), 5) - sage: G = C.permutation_automorphism_group() - sage: G.order() + sage: G = C.permutation_automorphism_group() # optional - sage.groups + sage: G.order() # optional - sage.groups 9999360 sage: C = codes.HammingCode(GF(3), 2); C [4, 2] Hamming Code over GF(3) - sage: C.permutation_automorphism_group(algorithm="partition") + sage: C.permutation_automorphism_group(algorithm="partition") # optional - sage.groups Permutation Group with generators [(1,3,4)] sage: C = codes.HammingCode(GF(4,"z"), 2); C [5, 3] Hamming Code over GF(4) - sage: G = C.permutation_automorphism_group(algorithm="partition"); G + sage: G = C.permutation_automorphism_group(algorithm="partition"); G # optional - sage.groups Permutation Group with generators [(1,3)(4,5), (1,4)(3,5)] - sage: GG = C.permutation_automorphism_group(algorithm="codecan") # long time - sage: GG == G # long time + sage: GG = C.permutation_automorphism_group(algorithm="codecan") # long time, optional - sage.groups + sage: GG == G # long time, optional - sage.groups True - sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_packages (Guava package) + sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_packages (Guava package) sage.groups Permutation Group with generators [(1,3)(4,5), (1,4)(3,5)] sage: C = codes.GolayCode(GF(3), True) - sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_packages (Guava package) - Permutation Group with generators [(5,7)(6,11)(8,9)(10,12), (4,6,11)(5,8,12)(7,10,9), (3,4)(6,8)(9,11)(10,12), (2,3)(6,11)(8,12)(9,10), (1,2)(5,10)(7,12)(8,9)] + sage: C.permutation_automorphism_group(algorithm="gap") # optional - gap_packages (Guava package) sage.groups + Permutation Group with generators + [(5,7)(6,11)(8,9)(10,12), (4,6,11)(5,8,12)(7,10,9), (3,4)(6,8)(9,11)(10,12), + (2,3)(6,11)(8,12)(9,10), (1,2)(5,10)(7,12)(8,9)] However, the option ``algorithm="gap+verbose"``, will print out:: @@ -1683,7 +1717,7 @@ def punctured(self, L): INPUT: - - ``L`` - List of positions to puncture + - ``L`` -- List of positions to puncture OUTPUT: @@ -1808,7 +1842,7 @@ def weight_distribution(self, algorithm=None): [7, 4] Hamming Code over GF(2) sage: C.weight_distribution(algorithm="leon") # optional - gap_packages (Guava package) [1, 0, 0, 7, 7, 0, 0, 1] - sage: C.weight_distribution(algorithm="gap") + sage: C.weight_distribution(algorithm="gap") # optional - sage.libs.gap [1, 0, 0, 7, 7, 0, 0, 1] sage: C.weight_distribution(algorithm="binary") [1, 0, 0, 7, 7, 0, 0, 1] @@ -1826,7 +1860,6 @@ def weight_distribution(self, algorithm=None): True """ - from sage.libs.gap.libgap import libgap if algorithm is None: if self.base_ring().order() == 2: algorithm = "binary" @@ -1835,6 +1868,7 @@ def weight_distribution(self, algorithm=None): F = self.base_ring() n = self.length() if algorithm=="gap": + from sage.libs.gap.libgap import libgap Gmat = self.generator_matrix() q = self.base_ring().order() z = 0*libgap.Z(q)*([0]*self.length()) # GAP zero vector @@ -1848,6 +1882,7 @@ def weight_distribution(self, algorithm=None): raise NotImplementedError("The algorithm 'leon' is only implemented for q = 2,3,5,7.") # The GAP command DirectoriesPackageLibrary tells the location of the latest # version of the Guava libraries, so gives us the location of the Guava binaries too. + from sage.libs.gap.libgap import libgap guava_bin_dir = libgap.DirectoriesPackagePrograms("guava")[0].Filename("").sage() input = _dump_code_in_leon_format(self) + "::code" lines = subprocess.check_output([os.path.join(guava_bin_dir, 'wtdist'), input]) @@ -1894,15 +1929,15 @@ def weight_enumerator(self, names=None, bivariate=True): This is the bivariate, homogeneous polynomial in `x` and `y` whose coefficient to `x^i y^{n-i}` is the number of codewords of `self` of - Hamming weight `i`. Here, `n` is the length of `self`. + Hamming weight `i`. Here, `n` is the length of ``self``. INPUT: - - ``names`` - (default: ``"xy"``) The names of the variables in the + - ``names`` -- (default: ``"xy"``) The names of the variables in the homogeneous polynomial. Can be given as a single string of length 2, or a single string with a comma, or as a tuple or list of two strings. - - ``bivariate`` - (default: `True`) Whether to return a bivariate, + - ``bivariate`` -- (default: `True`) Whether to return a bivariate, homogeneous polynomial or just a univariate polynomial. If set to ``False``, then ``names`` will be interpreted as a single variable name and default to ``"x"``. @@ -1956,7 +1991,7 @@ def zeta_polynomial(self, name="T"): INPUT: - - ``name`` - String, variable name (default: ``"T"``) + - ``name`` -- String, variable name (default: ``"T"``) OUTPUT: @@ -2467,7 +2502,8 @@ def generator_matrix(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: E = codes.encoders.LinearCodeGeneratorMatrixEncoder(C) sage: E.generator_matrix() @@ -2527,7 +2563,9 @@ class LinearCodeSyndromeDecoder(Decoder): EXAMPLES:: - sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2],[0,1,0,2,2,0,1,1,0],[0,0,1,0,2,2,2,1,2]]) + sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2], + ....: [0,1,0,2,2,0,1,1,0], + ....: [0,0,1,0,2,2,2,1,2]]) sage: C = LinearCode(G) sage: D = codes.decoders.LinearCodeSyndromeDecoder(C) sage: D @@ -2831,7 +2869,7 @@ def _build_lookup_table(self): def decode_to_code(self, r): r""" - Corrects the errors in ``word`` and returns a codeword. + Correct the errors in ``word`` and return a codeword. INPUT: @@ -2872,11 +2910,13 @@ def maximum_error_weight(self): Return the maximal number of errors a received word can have and for which ``self`` is guaranteed to return a most likely codeword. - Same as ``self.decoding_radius``. + Same as :meth:`decoding_radius`. EXAMPLES:: - sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2],[0,1,0,2,2,0,1,1,0],[0,0,1,0,2,2,2,1,2]]) + sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2], + ....: [0,1,0,2,2,0,1,1,0], + ....: [0,0,1,0,2,2,2,1,2]]) sage: C = LinearCode(G) sage: D = codes.decoders.LinearCodeSyndromeDecoder(C) sage: D.maximum_error_weight() @@ -2891,7 +2931,9 @@ def decoding_radius(self): EXAMPLES:: - sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2],[0,1,0,2,2,0,1,1,0],[0,0,1,0,2,2,2,1,2]]) + sage: G = Matrix(GF(3), [[1,0,0,1,0,1,0,1,2], + ....: [0,1,0,2,2,0,1,1,0], + ....: [0,0,1,0,2,2,2,1,2]]) sage: C = LinearCode(G) sage: D = codes.decoders.LinearCodeSyndromeDecoder(C) sage: D.decoding_radius() @@ -2905,7 +2947,8 @@ def syndrome_table(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: D = codes.decoders.LinearCodeSyndromeDecoder(C) sage: D.syndrome_table() @@ -3000,7 +3043,8 @@ def decode_to_code(self, r): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: D = codes.decoders.LinearCodeNearestNeighborDecoder(C) sage: word = vector(GF(2), (1, 1, 0, 0, 1, 1, 0)) @@ -3023,7 +3067,8 @@ def decoding_radius(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: D = codes.decoders.LinearCodeNearestNeighborDecoder(C) sage: D.decoding_radius() diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index bb70d6a74c5..0de2b9db8cc 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Generic structures for linear codes of any metric @@ -199,7 +200,8 @@ def base_field(self): EXAMPLES:: - sage: G = Matrix(GF(2), [[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: G = Matrix(GF(2), [[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: C = LinearCode(G) sage: C.base_field() Finite Field of size 2 @@ -233,7 +235,7 @@ def generator_matrix(self, encoder_name=None, **kwargs): EXAMPLES:: - sage: G = matrix(GF(3),2,[1,-1,1,-1,1,1]) + sage: G = matrix(GF(3), 2, [1,-1,1,-1,1,1]) sage: code = LinearCode(G) sage: code.generator_matrix() [1 2 1] @@ -304,7 +306,7 @@ def dimension(self): EXAMPLES:: - sage: G = matrix(GF(2),[[1,0,0],[1,1,0]]) + sage: G = matrix(GF(2), [[1,0,0], [1,1,0]]) sage: C = LinearCode(G) sage: C.dimension() 2 @@ -379,7 +381,8 @@ def gens(self): sage: C = codes.HammingCode(GF(2), 3) sage: C.gens() - [(1, 0, 0, 0, 0, 1, 1), (0, 1, 0, 0, 1, 0, 1), (0, 0, 1, 0, 1, 1, 0), (0, 0, 0, 1, 1, 1, 1)] + [(1, 0, 0, 0, 0, 1, 1), (0, 1, 0, 0, 1, 0, 1), + (0, 0, 1, 0, 1, 1, 0), (0, 0, 0, 1, 1, 1, 1)] """ return self.generator_matrix().rows() @@ -905,7 +908,8 @@ def is_permutation_automorphism(self,g): sage: C.is_permutation_automorphism(g) 0 sage: MS = MatrixSpace(GF(2),4,8) - sage: G = MS([[1,0,0,0,1,1,1,0],[0,1,1,1,0,0,0,0],[0,0,0,0,0,0,0,1],[0,0,0,0,0,1,0,0]]) + sage: G = MS([[1,0,0,0,1,1,1,0], [0,1,1,1,0,0,0,0], + ....: [0,0,0,0,0,0,0,1], [0,0,0,0,0,1,0,0]]) sage: C = LinearCode(G) sage: S8 = SymmetricGroup(8) sage: g = S8("(2,3)") @@ -933,7 +937,8 @@ def permuted_code(self, p): sage: C = codes.HammingCode(GF(2), 3) sage: G = C.permutation_automorphism_group(); G - Permutation Group with generators [(4,5)(6,7), (4,6)(5,7), (2,3)(6,7), (2,4)(3,5), (1,2)(5,6)] + Permutation Group with generators + [(4,5)(6,7), (4,6)(5,7), (2,3)(6,7), (2,4)(3,5), (1,2)(5,6)] sage: g = G("(2,3)(6,7)") sage: Cg = C.permuted_code(g) sage: Cg @@ -1000,7 +1005,7 @@ def is_self_orthogonal(self): sage: C.is_self_orthogonal() False sage: C = codes.QuasiQuadraticResidueCode(11) # optional - gap_packages (Guava package) - sage: C.is_self_orthogonal() # optional - gap_packages (Guava package) + sage: C.is_self_orthogonal() # optional - gap_packages (Guava package) True """ return self.is_subcode(self.dual_code()) @@ -1060,31 +1065,32 @@ class LinearCodeSystematicEncoder(Encoder): The following demonstrates the basic usage of :class:`LinearCodeSystematicEncoder`:: - sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0,0],\ - [1,0,0,1,1,0,0,0],\ - [0,1,0,1,0,1,0,0],\ - [1,1,0,1,0,0,1,1]]) - sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) - sage: E.generator_matrix() - [1 0 0 0 0 1 1 1] - [0 1 0 0 1 0 1 1] - [0 0 1 0 1 1 0 0] - [0 0 0 1 1 1 1 1] - sage: E2 = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[5,4,3,2]) - sage: E2.generator_matrix() - [1 0 0 0 0 1 1 1] - [0 1 0 0 1 0 1 1] - [1 1 0 1 0 0 1 1] - [1 1 1 0 0 0 0 0] + sage: LCSE = codes.encoders.LinearCodeSystematicEncoder + sage: G = Matrix(GF(2), [[1,1,1,0,0,0,0,0],\ + [1,0,0,1,1,0,0,0],\ + [0,1,0,1,0,1,0,0],\ + [1,1,0,1,0,0,1,1]]) + sage: C = LinearCode(G) + sage: E = LCSE(C) + sage: E.generator_matrix() + [1 0 0 0 0 1 1 1] + [0 1 0 0 1 0 1 1] + [0 0 1 0 1 1 0 0] + [0 0 0 1 1 1 1 1] + sage: E2 = LCSE(C, systematic_positions=[5,4,3,2]) + sage: E2.generator_matrix() + [1 0 0 0 0 1 1 1] + [0 1 0 0 1 0 1 1] + [1 1 0 1 0 0 1 1] + [1 1 1 0 0 0 0 0] An error is raised if one specifies systematic positions which do not form an information set:: - sage: E3 = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[0,1,6,7]) - Traceback (most recent call last): - ... - ValueError: systematic_positions are not an information set + sage: E3 = LCSE(C, systematic_positions=[0,1,6,7]) + Traceback (most recent call last): + ... + ValueError: systematic_positions are not an information set We exemplify how to use :class:`LinearCodeSystematicEncoder` as the default @@ -1092,7 +1098,7 @@ class LinearCodeSystematicEncoder(Encoder): sage: class DualRepetitionCode(sage.coding.linear_code.AbstractLinearCode): ....: def __init__(self, field, length): - ....: sage.coding.linear_code.AbstractLinearCode.__init__(self,field, length, "Systematic", "Syndrome") + ....: super().__init__(self,f ield, length, "Systematic", "Syndrome") ....: ....: def parity_check_matrix(self): ....: return Matrix(self.base_field(), [1]*self.length()) @@ -1112,7 +1118,7 @@ class LinearCodeSystematicEncoder(Encoder): sage: class BadCodeFamily(sage.coding.linear_code.AbstractLinearCode): ....: def __init__(self, field, length): - ....: sage.coding.linear_code.AbstractLinearCode.__init__(self, field, length, "Systematic", "Syndrome") + ....: super().__init__(self, field, length, "Systematic", "Syndrome") ....: ....: def _repr_(self): ....: return "I am a badly defined code" @@ -1120,7 +1126,8 @@ class LinearCodeSystematicEncoder(Encoder): sage: BadCodeFamily(GF(3), 5).generator_matrix() Traceback (most recent call last): ... - ValueError: a parity check matrix must be specified if LinearCodeSystematicEncoder is the default encoder + ValueError: a parity check matrix must be specified + if LinearCodeSystematicEncoder is the default encoder """ def __init__(self, code, systematic_positions=None): @@ -1212,12 +1219,13 @@ def generator_matrix(self): EXAMPLES:: + sage: LCSE = codes.encoders.LinearCodeSystematicEncoder sage: G = Matrix(GF(2), [[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: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E = LCSE(C) sage: E.generator_matrix() [1 0 0 0 0 1 1] [0 1 0 0 1 0 1] @@ -1226,7 +1234,7 @@ def generator_matrix(self): We can ask for different systematic positions:: - sage: E2 = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[5,4,3,2]) + sage: E2 = LCSE(C, systematic_positions=[5,4,3,2]) sage: E2.generator_matrix() [1 0 0 0 0 1 1] [0 1 0 0 1 0 1] @@ -1240,7 +1248,7 @@ def generator_matrix(self): [0,0,1,0,0,1,0],\ [0,0,1,0,1,0,1]]) sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E = LCSE(C) sage: E.generator_matrix() [1 1 0 0 0 1 0] [0 0 1 0 0 1 0] @@ -1313,12 +1321,13 @@ def systematic_positions(self): EXAMPLES:: + sage: LCSE = codes.encoders.LinearCodeSystematicEncoder sage: G = Matrix(GF(2), [[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: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E = LCSE(C) sage: E.systematic_positions() (0, 1, 2, 3) @@ -1329,7 +1338,7 @@ def systematic_positions(self): [0,0,1,0,0,1,0],\ [0,0,1,0,1,0,1]]) sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C) + sage: E = LCSE(C) sage: E.systematic_positions() (0, 2, 4, 6) @@ -1351,7 +1360,7 @@ def systematic_positions(self): [0,1,0,0],\ [0,0,1,1]]) sage: C = LinearCode(G) - sage: E = codes.encoders.LinearCodeSystematicEncoder(C, systematic_positions=[0,1,3]) + sage: E = LCSE(C, systematic_positions=[0,1,3]) sage: E.systematic_positions() (0, 1, 3) """ diff --git a/src/sage/coding/linear_rank_metric.py b/src/sage/coding/linear_rank_metric.py index 78db1b8c602..a432538d012 100644 --- a/src/sage/coding/linear_rank_metric.py +++ b/src/sage/coding/linear_rank_metric.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Generic structures for linear codes over the rank metric @@ -391,9 +391,11 @@ def __init__(self, base_field, sub_field, length, default_encoder_name, sage: from sage.coding.linear_rank_metric import AbstractLinearRankMetricCode sage: class RankRepetitionCode(AbstractLinearRankMetricCode): ....: def __init__(self, base_field, sub_field, length): - ....: sage.coding.linear_rank_metric.AbstractLinearRankMetricCode.__init__(self, base_field, sub_field, length, "GeneratorMatrix", "NearestNeighbor") + ....: super().__init__(self, base_field, sub_field, length, + ....: "GeneratorMatrix", "NearestNeighbor") ....: beta = base_field.gen() - ....: self._generator_matrix = matrix(base_field, [[ beta^i for i in range(length) ]]) + ....: self._generator_matrix = matrix(base_field, + ....: [[beta^i for i in range(length)]]) ....: def generator_matrix(self): ....: return self._generator_matrix ....: def _repr_(self): @@ -436,7 +438,8 @@ def __init__(self, base_field, sub_field, length, default_encoder_name, sage: C.parent() sage: C.category() - Category of facade finite dimensional vector spaces with basis over Finite Field in z3 of size 2^3 + Category of facade finite dimensional vector spaces with basis + over Finite Field in z3 of size 2^3 And any method that works on rank metric linear codes works for our new dummy code:: diff --git a/src/sage/coding/parity_check_code.py b/src/sage/coding/parity_check_code.py index 880de2c00fd..9a0836db9de 100644 --- a/src/sage/coding/parity_check_code.py +++ b/src/sage/coding/parity_check_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Parity-check code diff --git a/src/sage/coding/punctured_code.py b/src/sage/coding/punctured_code.py index 0c85dddbd77..429e651ef7e 100644 --- a/src/sage/coding/punctured_code.py +++ b/src/sage/coding/punctured_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Punctured code @@ -278,7 +279,9 @@ def encode(self, m, original_encode=False, encoder_name=None, **kwargs): EXAMPLES:: - sage: M = matrix(GF(7), [[1, 0, 0, 0, 3, 4, 6], [0, 1, 0, 6, 1, 6, 4], [0, 0, 1, 5, 2, 2, 4]]) + sage: M = matrix(GF(7), [[1, 0, 0, 0, 3, 4, 6], + ....: [0, 1, 0, 6, 1, 6, 4], + ....: [0, 0, 1, 5, 2, 2, 4]]) sage: C_original = LinearCode(M) sage: Cp = codes.PuncturedCode(C_original, 2) sage: m = vector(GF(7), [1, 3, 5]) @@ -348,7 +351,8 @@ class PuncturedCodePuncturedMatrixEncoder(Encoder): sage: Cp = codes.PuncturedCode(C, 3) sage: E = codes.encoders.PuncturedCodePuncturedMatrixEncoder(Cp) sage: E - Punctured matrix-based encoder for the Puncturing of [11, 5] linear code over GF(7) on position(s) [3] + Punctured matrix-based encoder for the + Puncturing of [11, 5] linear code over GF(7) on position(s) [3] """ def __init__(self, code): @@ -435,18 +439,18 @@ class PuncturedCodeOriginalCodeDecoder(Decoder): - ``strategy`` -- (default: ``None``) the strategy used to decode. The available strategies are: - * ``'error-erasure'`` -- uses an error-erasure decoder over the original code if available, - fails otherwise. + * ``'error-erasure'`` -- uses an error-erasure decoder over the original code if available, + fails otherwise. - * ``'random-values'`` -- fills the punctured positions with random elements - in ``code``'s base field and tries to decode using - the default decoder of the original code + * ``'random-values'`` -- fills the punctured positions with random elements + in ``code``'s base field and tries to decode using + the default decoder of the original code - * ``'try-all'`` -- fills the punctured positions with every possible combination of - symbols until decoding succeeds, or until every combination have been tried + * ``'try-all'`` -- fills the punctured positions with every possible combination of + symbols until decoding succeeds, or until every combination have been tried - * ``None`` -- uses ``error-erasure`` if an error-erasure decoder is available, - switch to ``random-values`` behaviour otherwise + * ``None`` -- uses ``error-erasure`` if an error-erasure decoder is available, + switch to ``random-values`` behaviour otherwise - ``original_decoder`` -- (default: ``None``) the decoder that will be used over the original code. It has to be a decoder object over the original code. @@ -456,33 +460,35 @@ class PuncturedCodeOriginalCodeDecoder(Decoder): - ``**kwargs`` -- all extra arguments are forwarded to original code's decoder - EXAMPLES:: + EXAMPLES:: - sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) - sage: Cp = codes.PuncturedCode(C, 3) - sage: codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp) - Decoder of Puncturing of [15, 7, 9] Reed-Solomon Code over GF(16) on position(s) [3] through Error-Erasure decoder for [15, 7, 9] Reed-Solomon Code over GF(16) + sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) + sage: Cp = codes.PuncturedCode(C, 3) + sage: codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp) + Decoder of Puncturing of [15, 7, 9] Reed-Solomon Code over GF(16) on position(s) [3] + through Error-Erasure decoder for [15, 7, 9] Reed-Solomon Code over GF(16) - As seen above, if all optional are left blank, and if an error-erasure decoder is - available, it will be chosen as the original decoder. - Now, if one forces ``strategy `` to ``'try-all'`` or ``'random-values'``, the - default decoder of the original code will be chosen, even if an error-erasure is available:: + As seen above, if all optional are left blank, and if an error-erasure decoder is + available, it will be chosen as the original decoder. + Now, if one forces ``strategy `` to ``'try-all'`` or ``'random-values'``, the + default decoder of the original code will be chosen, even if an error-erasure is available:: - sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) - sage: Cp = codes.PuncturedCode(C, 3) - sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp, strategy="try-all") - sage: "error-erasure" in D.decoder_type() - False + sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) + sage: Cp = codes.PuncturedCode(C, 3) + sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp, strategy="try-all") + sage: "error-erasure" in D.decoder_type() + False - And if one fills ``original_decoder`` and ``strategy`` fields with contradictory - elements, the ``original_decoder`` takes precedence:: + And if one fills ``original_decoder`` and ``strategy`` fields with contradictory + elements, the ``original_decoder`` takes precedence:: - sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) - sage: Cp = codes.PuncturedCode(C, 3) - sage: Dor = C.decoder("Gao") - sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp, original_decoder = Dor, strategy="error-erasure") - sage: D.original_decoder() == Dor - True + sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) + sage: Cp = codes.PuncturedCode(C, 3) + sage: Dor = C.decoder("Gao") + sage: D = codes.decoders.PuncturedCodeOriginalCodeDecoder(Cp, original_decoder=Dor, + ....: strategy="error-erasure") + sage: D.original_decoder() == Dor + True """ def __init__(self, code, strategy = None, original_decoder = None, **kwargs): diff --git a/src/sage/coding/reed_muller_code.py b/src/sage/coding/reed_muller_code.py index 457f90bdab9..45784cbf956 100644 --- a/src/sage/coding/reed_muller_code.py +++ b/src/sage/coding/reed_muller_code.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Reed-Muller code @@ -145,7 +146,7 @@ def ReedMullerCode(base_field, order, num_of_var): - ``base_field`` -- The finite field `F` over which the code is built. - ``order`` -- The order of the Reed-Muller Code, which is the maximum - degree of the polynomial to be used in the code. + degree of the polynomial to be used in the code. - ``num_of_var`` -- The number of variables used in polynomial. @@ -436,7 +437,7 @@ def __init__(self, order, num_of_var): def order(self): r""" - Returns the order of ``self``. Order is the maximum degree of the polynomial used in the Reed-Muller code. + Return the order of ``self``. Order is the maximum degree of the polynomial used in the Reed-Muller code. EXAMPLES:: @@ -448,7 +449,7 @@ def order(self): def number_of_variables(self): r""" - Returns the number of variables of the polynomial ring used in ``self``. + Return the number of variables of the polynomial ring used in ``self``. EXAMPLES:: @@ -460,7 +461,8 @@ def number_of_variables(self): def minimum_distance(self): r""" - Returns the minimum distance of ``self``. + Return the minimum distance of ``self``. + The minimum distance of a binary Reed-Muller code of order `d` and number of variables `m` is `q^{m-d}` EXAMPLES:: @@ -473,7 +475,7 @@ def minimum_distance(self): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -486,7 +488,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -542,21 +544,24 @@ class ReedMullerVectorEncoder(Encoder): EXAMPLES:: - sage: C1=codes.ReedMullerCode(GF(2), 2, 4) - sage: E1=codes.encoders.ReedMullerVectorEncoder(C1) + sage: C1 = codes.ReedMullerCode(GF(2), 2, 4) + sage: E1 = codes.encoders.ReedMullerVectorEncoder(C1) sage: E1 - Evaluation vector-style encoder for Binary Reed-Muller Code of order 2 and number of variables 4 - sage: C2=codes.ReedMullerCode(GF(3), 2, 2) - sage: E2=codes.encoders.ReedMullerVectorEncoder(C2) + Evaluation vector-style encoder for + Binary Reed-Muller Code of order 2 and number of variables 4 + sage: C2 = codes.ReedMullerCode(GF(3), 2, 2) + sage: E2 = codes.encoders.ReedMullerVectorEncoder(C2) sage: E2 - Evaluation vector-style encoder for Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3 + Evaluation vector-style encoder for + Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3 Actually, we can construct the encoder from ``C`` directly:: sage: C=codes.ReedMullerCode(GF(2), 2, 4) sage: E = C.encoder("EvaluationVector") sage: E - Evaluation vector-style encoder for Binary Reed-Muller Code of order 2 and number of variables 4 + Evaluation vector-style encoder for + Binary Reed-Muller Code of order 2 and number of variables 4 """ def __init__(self, code): @@ -629,7 +634,7 @@ def __eq__(self, other): @cached_method def generator_matrix(self): r""" - Returns a generator matrix of ``self`` + Return a generator matrix of ``self`` EXAMPLES:: @@ -663,7 +668,7 @@ def generator_matrix(self): def points(self): r""" - Returns the points of `F^m`, where `F` is base field and `m` is the number of variables, in order of which polynomials are evaluated on. + Return the points of `F^m`, where `F` is base field and `m` is the number of variables, in order of which polynomials are evaluated on. EXAMPLES:: @@ -705,34 +710,38 @@ class ReedMullerPolynomialEncoder(Encoder): - ``code`` -- The associated code of this encoder. - -``polynomial_ring`` -- (default:``None``) The polynomial ring from which the message is chosen. - If this is set to ``None``, a polynomial ring in `x` will be built - from the code parameters. + - ``polynomial_ring`` -- (default:``None``) The polynomial ring from which the message is chosen. + If this is set to ``None``, a polynomial ring in `x` will be built + from the code parameters. EXAMPLES:: - sage: C1=codes.ReedMullerCode(GF(2), 2, 4) - sage: E1=codes.encoders.ReedMullerPolynomialEncoder(C1) + sage: C1 = codes.ReedMullerCode(GF(2), 2, 4) + sage: E1 = codes.encoders.ReedMullerPolynomialEncoder(C1) sage: E1 - Evaluation polynomial-style encoder for Binary Reed-Muller Code of order 2 and number of variables 4 - sage: C2=codes.ReedMullerCode(GF(3), 2, 2) - sage: E2=codes.encoders.ReedMullerPolynomialEncoder(C2) + Evaluation polynomial-style encoder for + Binary Reed-Muller Code of order 2 and number of variables 4 + sage: C2 = codes.ReedMullerCode(GF(3), 2, 2) + sage: E2 = codes.encoders.ReedMullerPolynomialEncoder(C2) sage: E2 - Evaluation polynomial-style encoder for Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3 + Evaluation polynomial-style encoder for + Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3 We can also pass a predefined polynomial ring:: - sage: R=PolynomialRing(GF(3), 2, 'y') - sage: C=codes.ReedMullerCode(GF(3), 2, 2) - sage: E=codes.encoders.ReedMullerPolynomialEncoder(C, R) + sage: R = PolynomialRing(GF(3), 2, 'y') + sage: C = codes.ReedMullerCode(GF(3), 2, 2) + sage: E = codes.encoders.ReedMullerPolynomialEncoder(C, R) sage: E - Evaluation polynomial-style encoder for Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3 + Evaluation polynomial-style encoder for + Reed-Muller Code of order 2 and 2 variables over Finite Field of size 3 Actually, we can construct the encoder from ``C`` directly:: sage: E = C1.encoder("EvaluationPolynomial") sage: E - Evaluation polynomial-style encoder for Binary Reed-Muller Code of order 2 and number of variables 4 + Evaluation polynomial-style encoder for + Binary Reed-Muller Code of order 2 and number of variables 4 """ def __init__(self, code, polynomial_ring=None): @@ -861,7 +870,8 @@ def encode(self, p): sage: E.encode(p) Traceback (most recent call last): ... - ValueError: The value to encode must be in Multivariate Polynomial Ring in x0, x1 over Finite Field of size 3 + ValueError: The value to encode must be in + Multivariate Polynomial Ring in x0, x1 over Finite Field of size 3 """ M = self.message_space() if p not in M: diff --git a/src/sage/coding/self_dual_codes.py b/src/sage/coding/self_dual_codes.py index 4fa7960e4df..eb250b66e67 100644 --- a/src/sage/coding/self_dual_codes.py +++ b/src/sage/coding/self_dual_codes.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.groups sage.modules r""" Enumerating binary self-dual codes diff --git a/src/sage/coding/source_coding/huffman.py b/src/sage/coding/source_coding/huffman.py index 59f16555e3a..c8d5258ff3a 100644 --- a/src/sage/coding/source_coding/huffman.py +++ b/src/sage/coding/source_coding/huffman.py @@ -235,7 +235,7 @@ def __init__(self, source): Feeding anything else than a string or a dictionary:: - sage: Huffman(Graph()) + sage: Huffman(Graph()) # optional - sage.graphs Traceback (most recent call last): ... ValueError: Input must be either a string or a dictionary. @@ -510,9 +510,9 @@ def tree(self): sage: from sage.coding.source_coding.huffman import Huffman sage: str = "Sage is my most favorite general purpose computer algebra system" sage: h = Huffman(str) - sage: T = h.tree(); T + sage: T = h.tree(); T # optional - sage.graphs Digraph on 39 vertices - sage: T.show(figsize=[20,20]) + sage: T.show(figsize=[20,20]) # optional - sage.graphs sage.plot """ from sage.graphs.digraph import DiGraph @@ -543,7 +543,7 @@ def _generate_edges(self, tree, parent="", bit=""): sage: from sage.coding.source_coding.huffman import Huffman sage: H = Huffman("Sage") - sage: T = H.tree() + sage: T = H.tree() # optional - sage.graphs sage: T.edges(sort=True, labels=None) # indirect doctest [('0', 'S: 00'), ('0', 'a: 01'), ('1', 'e: 10'), ('1', 'g: 11'), ('root', '0'), ('root', '1')] """ diff --git a/src/sage/coding/subfield_subcode.py b/src/sage/coding/subfield_subcode.py index b3861707d6b..e45a9c41a81 100644 --- a/src/sage/coding/subfield_subcode.py +++ b/src/sage/coding/subfield_subcode.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Subfield subcode @@ -282,7 +283,8 @@ class SubfieldSubcodeOriginalCodeDecoder(Decoder): sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'aa').list()[:13], 5) sage: Cs = codes.SubfieldSubcode(C, GF(4, 'a')) sage: codes.decoders.SubfieldSubcodeOriginalCodeDecoder(Cs) - 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) + 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): @@ -296,7 +298,7 @@ def __init__(self, code, original_decoder = None, **kwargs): sage: Cs = codes.SubfieldSubcode(C, GF(4, 'a')) sage: Cbis = codes.GeneralizedReedSolomonCode(GF(16, 'aa').list()[:9], 5) sage: D = Cbis.decoder() - sage: codes.decoders.SubfieldSubcodeOriginalCodeDecoder(Cs, original_decoder = D) + sage: codes.decoders.SubfieldSubcodeOriginalCodeDecoder(Cs, original_decoder=D) Traceback (most recent call last): ... ValueError: original_decoder must have the original code as associated code @@ -368,7 +370,8 @@ def decode_to_code(self, y): sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'aa').list()[:13], 5) sage: Cs = codes.SubfieldSubcode(C, GF(4, 'a')) sage: D = codes.decoders.SubfieldSubcodeOriginalCodeDecoder(Cs) - sage: Chan = channels.StaticErrorRateChannel(Cs.ambient_space(), D.decoding_radius()) + sage: Chan = channels.StaticErrorRateChannel(Cs.ambient_space(), + ....: D.decoding_radius()) sage: c = Cs.random_element() sage: y = Chan(c) sage: c == D.decode_to_code(y) diff --git a/src/sage/coding/two_weight_db.py b/src/sage/coding/two_weight_db.py index 1fb1f90ad84..44695300f33 100644 --- a/src/sage/coding/two_weight_db.py +++ b/src/sage/coding/two_weight_db.py @@ -1,3 +1,4 @@ +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Database of two-weight codes From 1744ae9b93e33fcfd2b5fcef18acccd333e84271 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 4 Jun 2023 23:30:15 -0700 Subject: [PATCH 077/205] More # optional - sage.schemes sage.modular --- src/sage/categories/hecke_modules.py | 2 +- src/sage/categories/modules_with_basis.py | 2 +- src/sage/misc/cachefunc.pyx | 5 ++- src/sage/misc/latex.py | 4 +- src/sage/misc/lazy_import.pyx | 4 +- src/sage/modules/module.pyx | 48 ++++++++++++++--------- 6 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/sage/categories/hecke_modules.py b/src/sage/categories/hecke_modules.py index 130314186ac..ae3d638b06b 100644 --- a/src/sage/categories/hecke_modules.py +++ b/src/sage/categories/hecke_modules.py @@ -129,7 +129,7 @@ def _Hom_(self, Y, category): in Category of Hecke modules over Rational Field sage: H.__class__ # optional - sage.modular - sage: TestSuite(H).run(skip=["_test_elements", "_test_an_element", "_test_elements_eq", + sage: TestSuite(H).run(skip=["_test_elements", "_test_an_element", "_test_elements_eq", # optional - sage.modular ....: "_test_elements_eq_reflexive", "_test_elements_eq_transitive", ....: "_test_elements_eq_symmetric", "_test_elements_neq", "_test_some_elements", ....: "_test_zero", "_test_additive_associativity", diff --git a/src/sage/categories/modules_with_basis.py b/src/sage/categories/modules_with_basis.py index 9f31917cf22..85a0d50239a 100644 --- a/src/sage/categories/modules_with_basis.py +++ b/src/sage/categories/modules_with_basis.py @@ -165,7 +165,7 @@ def _call_(self, x): If ``x`` itself is not a module with basis, but there is a canonical one associated to it, the latter is returned:: - sage: CQ(AbelianVariety(Gamma0(37))) # indirect doctest # optional - sage.modules + sage: CQ(AbelianVariety(Gamma0(37))) # indirect doctest # optional - sage.modular sage.modules Vector space of dimension 4 over Rational Field """ try: diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx index bf6aafdc2a7..6693a5be8b4 100644 --- a/src/sage/misc/cachefunc.pyx +++ b/src/sage/misc/cachefunc.pyx @@ -3707,8 +3707,9 @@ class disk_cached_function: sage: dir = tmp_dir() sage: @disk_cached_function(dir) ....: def foo(x): return ModularSymbols(x) - sage: foo(389) - Modular Symbols space of dimension 65 for Gamma_0(389) of weight 2 with sign 0 over Rational Field + sage: foo(389) # optional - sage.modular + Modular Symbols space of dimension 65 for Gamma_0(389) of weight 2 + with sign 0 over Rational Field """ return DiskCachedFunction(f, self._dir, memory_cache=self._memory_cache, key=self._key) diff --git a/src/sage/misc/latex.py b/src/sage/misc/latex.py index c915ae00e2f..e4ada89f9e8 100644 --- a/src/sage/misc/latex.py +++ b/src/sage/misc/latex.py @@ -2068,9 +2068,9 @@ def repr_lincomb(symbols, coeffs): Verify that :trac:`17299` (latex representation of modular symbols) is fixed:: - sage: x = EllipticCurve('64a1').modular_symbol_space(sign=1).basis()[0] + sage: x = EllipticCurve('64a1').modular_symbol_space(sign=1).basis()[0] # optional - sage.schemes sage: from sage.misc.latex import repr_lincomb - sage: latex(x.modular_symbol_rep()) + sage: latex(x.modular_symbol_rep()) # optional - sage.schemes \left\{\frac{-3}{11}, \frac{-1}{4}\right\} - \left\{\frac{3}{13}, \frac{1}{4}\right\} Verify that it works when the symbols are numbers:: diff --git a/src/sage/misc/lazy_import.pyx b/src/sage/misc/lazy_import.pyx index d4a6c12ed5a..ada787afa22 100644 --- a/src/sage/misc/lazy_import.pyx +++ b/src/sage/misc/lazy_import.pyx @@ -1150,7 +1150,7 @@ def get_star_imports(module_name): sage: from sage.misc.lazy_import import get_star_imports sage: 'get_star_imports' in get_star_imports('sage.misc.lazy_import') True - sage: 'EllipticCurve' in get_star_imports('sage.schemes.all') + sage: 'EllipticCurve' in get_star_imports('sage.schemes.all') # optional - sage.schemes True TESTS:: @@ -1164,7 +1164,7 @@ def get_star_imports(module_name): sage: import sage.misc.lazy_import_cache as cache sage: cache.get_cache_file = (lambda: cache_file) sage: lazy.star_imports = None - sage: lazy.get_star_imports('sage.schemes.all') + sage: lazy.get_star_imports('sage.schemes.all') # optional - sage.schemes doctest:...: UserWarning: star_imports cache is corrupted [...] sage: os.remove(cache_file) diff --git a/src/sage/modules/module.pyx b/src/sage/modules/module.pyx index 180222b8b18..20c51d19079 100644 --- a/src/sage/modules/module.pyx +++ b/src/sage/modules/module.pyx @@ -186,7 +186,9 @@ cdef class Module(Parent): EXAMPLES:: - sage: sage.modular.modform.space.ModularFormsSpace(Gamma0(11), 2, DirichletGroup(1)[0], QQ).change_ring(GF(7)) + sage: from sage.modular.modform.space import ModularFormsSpace # optional - sage.modular + sage: ModularFormsSpace(Gamma0(11), 2, # optional - sage.modular sage.rings.finite_rings + ....: DirichletGroup(1)[0], QQ).change_ring(GF(7)) Traceback (most recent call last): ... NotImplementedError: the method change_ring() has not yet been implemented @@ -216,26 +218,31 @@ cdef class Module(Parent): TESTS:: - sage: N = ModularForms(6, 4) - sage: N.base_extend(CyclotomicField(7)) - Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) of weight 4 over Cyclotomic Field of order 7 and degree 6 - - sage: m = ModularForms(DirichletGroup(13).0^2,2); m - Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 6 and degree 2 - sage: m.base_extend(CyclotomicField(12)) - Modular Forms space of dimension 3, character [zeta6] and weight 2 over Cyclotomic Field of order 12 and degree 4 - - sage: chi = DirichletGroup(109, CyclotomicField(3)).0 - sage: S3 = CuspForms(chi, 2) - sage: S9 = S3.base_extend(CyclotomicField(9)) - sage: S9 - Cuspidal subspace of dimension 8 of Modular Forms space of dimension 10, character [zeta3 + 1] and weight 2 over Cyclotomic Field of order 9 and degree 6 - sage: S9.has_coerce_map_from(S3) # not implemented + sage: N = ModularForms(6, 4) # optional - sage.modular + sage: N.base_extend(CyclotomicField(7)) # optional - sage.modular sage.rings.number_field + Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(6) + of weight 4 over Cyclotomic Field of order 7 and degree 6 + + sage: m = ModularForms(DirichletGroup(13).0^2,2); m # optional - sage.modular sage.rings.number_field + Modular Forms space of dimension 3, character [zeta6] and weight 2 + over Cyclotomic Field of order 6 and degree 2 + sage: m.base_extend(CyclotomicField(12)) # optional - sage.modular sage.rings.number_field + Modular Forms space of dimension 3, character [zeta6] and weight 2 + over Cyclotomic Field of order 12 and degree 4 + + sage: chi = DirichletGroup(109, CyclotomicField(3)).0 # optional - sage.modular sage.rings.number_field + sage: S3 = CuspForms(chi, 2) # optional - sage.modular sage.rings.number_field + sage: S9 = S3.base_extend(CyclotomicField(9)); S9 # optional - sage.modular sage.rings.number_field + Cuspidal subspace of dimension 8 of + Modular Forms space of dimension 10, character [zeta3 + 1] and weight 2 + over Cyclotomic Field of order 9 and degree 6 + sage: S9.has_coerce_map_from(S3) # not implemented # optional - sage.modular sage.rings.number_field True - sage: S9.base_extend(CyclotomicField(3)) + sage: S9.base_extend(CyclotomicField(3)) # optional - sage.modular sage.rings.number_field Traceback (most recent call last): ... - TypeError: Base extension of self (over 'Cyclotomic Field of order 9 and degree 6') to ring 'Cyclotomic Field of order 3 and degree 2' not defined. + TypeError: Base extension of self (over 'Cyclotomic Field of order 9 and degree 6') + to ring 'Cyclotomic Field of order 3 and degree 2' not defined. """ if R.has_coerce_map_from(self.base_ring()): @@ -252,7 +259,10 @@ cdef class Module(Parent): sage: from sage.modules.module import Module sage: M = Module(ZZ) sage: M.endomorphism_ring() - Set of Morphisms from to in Category of modules over Integer Ring + Set of Morphisms + from + to + in Category of modules over Integer Ring """ from sage.categories.homset import End return End(self) From abe201e3d38f1b2ea3b7ad67bafce77a15012aac Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 4 Jun 2023 23:40:39 -0700 Subject: [PATCH 078/205] src/sage/coding/guruswami_sudan/gs_decoder.py: Fix doc markup --- src/sage/coding/guruswami_sudan/gs_decoder.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/coding/guruswami_sudan/gs_decoder.py b/src/sage/coding/guruswami_sudan/gs_decoder.py index 85f9fb2327c..3cf03781c2e 100644 --- a/src/sage/coding/guruswami_sudan/gs_decoder.py +++ b/src/sage/coding/guruswami_sudan/gs_decoder.py @@ -337,7 +337,9 @@ def guruswami_sudan_decoding_radius(C = None, n_k = None, l = None, s = None): OUTPUT: - ``(tau, (s, l))`` -- where + - ``tau`` is the obtained decoding radius, and + - ``s, ell`` are the multiplicity parameter, respectively list size parameter giving this radius. From 77dc5715d096422164d5253b0234c28928896461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 4 Jun 2023 17:20:28 +0200 Subject: [PATCH 079/205] fix some pep8 warnings in modform_hecketriangle --- .../modform_hecketriangle/abstract_ring.py | 20 +-- .../modform_hecketriangle/abstract_space.py | 14 +-- .../modform_hecketriangle/analytic_type.py | 19 +-- .../modform_hecketriangle/constructor.py | 4 +- .../modular/modform_hecketriangle/functors.py | 64 ++++------ .../modform_hecketriangle/graded_ring.py | 14 ++- .../graded_ring_element.py | 85 ++++++------- .../hecke_triangle_groups.py | 113 ++++++++--------- .../series_constructor.py | 10 +- .../modular/modform_hecketriangle/space.py | 116 +++++++++--------- .../modular/modform_hecketriangle/subspace.py | 5 +- 11 files changed, 221 insertions(+), 243 deletions(-) diff --git a/src/sage/modular/modform_hecketriangle/abstract_ring.py b/src/sage/modular/modform_hecketriangle/abstract_ring.py index f863fd718c7..f2b0e77d920 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_ring.py +++ b/src/sage/modular/modform_hecketriangle/abstract_ring.py @@ -7,14 +7,14 @@ """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013-2014 Jonas Jermann # # 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/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.algebras.free_algebra import FreeAlgebra from sage.misc.cachefunc import cached_method @@ -79,12 +79,12 @@ def __init__(self, group, base_ring, red_hom, n): False """ - #from graded_ring import canonical_parameters - #(group, base_ring, red_hom, n) = canonical_parameters(group, base_ring, red_hom, n) + # from graded_ring import canonical_parameters + # (group, base_ring, red_hom, n) = canonical_parameters(group, base_ring, red_hom, n) - #if (not group.is_arithmetic() and base_ring.characteristic()>0): + # if (not group.is_arithmetic() and base_ring.characteristic()>0): # raise NotImplementedError - #if (base_ring.characteristic().divides(2*group.n()*(group.n()-2))): + # if (base_ring.characteristic().divides(2*group.n()*(group.n()-2))): # raise NotImplementedError if (base_ring.characteristic() > 0): @@ -1903,7 +1903,7 @@ def EisensteinSeries(self, k=None): if n == infinity: raise NotImplementedError("In the case n=infinity, the Eisenstein series is not unique and more parameters are required.") - if (k is None): + if k is None: try: if not self.is_homogeneous(): raise TypeError(None) @@ -1911,10 +1911,10 @@ def EisensteinSeries(self, k=None): if k < 0: raise TypeError(None) k = 2*ZZ(k/2) - #if self.ep() != ZZ(-1)**ZZ(k/2): + # if self.ep() != ZZ(-1)**ZZ(k/2): # raise TypeError except TypeError: - k = ZZ(0) + k = ZZ.zero() try: if k < 0: diff --git a/src/sage/modular/modform_hecketriangle/abstract_space.py b/src/sage/modular/modform_hecketriangle/abstract_space.py index 11ed594308e..fcff2fdedae 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_space.py +++ b/src/sage/modular/modform_hecketriangle/abstract_space.py @@ -82,11 +82,11 @@ def __init__(self, group, base_ring, k, ep, n): sage: MF.is_homogeneous() True """ - #from space import canonical_parameters - #(group, base_ring, k, ep, n) = canonical_parameters(group, base_ring, k, ep, n) + # from space import canonical_parameters + # (group, base_ring, k, ep, n) = canonical_parameters(group, base_ring, k, ep, n) super().__init__(group=group, base_ring=base_ring, red_hom=True, n=n) - #self.register_embedding(self.hom(lambda f: f.parent().graded_ring()(f), codomain=self.graded_ring())) + # self.register_embedding(self.hom(lambda f: f.parent().graded_ring()(f), codomain=self.graded_ring())) self._weight = k self._ep = ep @@ -966,7 +966,7 @@ def Faber_pol(self, m, order_1=ZZ(0), fix_d=False, d_num_prec=None): J_qexp = self.J_inv().q_expansion(prec=order_inf - m, fix_d=fix_d, d_num_prec=d_num_prec) # The precision could be infinity, otherwise we could do this: - #assert(temp_reminder.prec() == 1) + # assert temp_reminder.prec() == 1 temp_reminder = (1 / simple_qexp / q**(-m)).add_bigoh(1) fab_pol = q.parent()([]) @@ -1108,7 +1108,7 @@ def faber_pol(self, m, order_1=ZZ(0), fix_d=False, d_num_prec=None): j_qexp = self.j_inv().q_expansion(prec=order_inf - m, fix_d=fix_d, d_num_prec=d_num_prec) # The precision could be infinity, otherwise we could do this: - #assert(temp_reminder.prec() == 1) + # assert temp_reminder.prec() == 1 temp_reminder = (1 / simple_qexp / q**(-m)).add_bigoh(1) fab_pol = q.parent()([]) @@ -1120,8 +1120,8 @@ def faber_pol(self, m, order_1=ZZ(0), fix_d=False, d_num_prec=None): temp_reminder -= temp_coeff*j_qexp**temp_exp # The first term is zero only up to numerical errors, # so we manually have to remove it - if (not d.parent().is_exact()): - temp_reminder=temp_reminder.truncate_neg(-temp_exp+1) + if not d.parent().is_exact(): + temp_reminder = temp_reminder.truncate_neg(-temp_exp+1) return fab_pol.polynomial() diff --git a/src/sage/modular/modform_hecketriangle/analytic_type.py b/src/sage/modular/modform_hecketriangle/analytic_type.py index 68adb2c513f..7b2618991df 100644 --- a/src/sage/modular/modform_hecketriangle/analytic_type.py +++ b/src/sage/modular/modform_hecketriangle/analytic_type.py @@ -11,14 +11,14 @@ """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013-2014 Jonas Jermann # # 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. # https://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** from sage.sets.set import Set from sage.combinat.posets.posets import Poset, FinitePoset @@ -68,7 +68,7 @@ class AnalyticTypeElement(LatticePosetElement): """ # We use the same constructor as LatticePosetElement - #def __init__(self, poset, element, vertex): + # def __init__(self, poset, element, vertex): # super().__init__(poset, element, vertex) def _repr_(self): @@ -437,14 +437,14 @@ def __init__(self): zero """ # We (arbitrarily) choose to model by inclusion instead of restriction - P_elements = [ "cusp", "holo", "weak", "mero", "quasi"] + P_elements = ["cusp", "holo", "weak", "mero", "quasi"] P_relations = [["cusp", "holo"], ["holo", "weak"], ["weak", "mero"]] self._base_poset = Poset([P_elements, P_relations], cover_relations=True, linear_extension=True, facade=False) L = self._base_poset.order_ideals_lattice() - H = L._hasse_diagram.relabel({i:x for i,x in enumerate(L._elements)}, + H = L._hasse_diagram.relabel({i: x for i, x in enumerate(L._elements)}, inplace=False) FiniteLatticePoset.__init__(self, hasse_diagram=H, elements=L._elements, category=L.category(), @@ -527,19 +527,20 @@ def _element_constructor_(self, element): if isinstance(element, str): element = [element] if isinstance(element, (list, tuple)): - element = Set(self._base_poset.order_ideal([self._base_poset(s) for s in element])) + element = Set(self._base_poset.order_ideal([self._base_poset(s) + for s in element])) return super()._element_constructor_(element) - #res = self.first() - #for element in args: + # res = self.first() + # for element in args: # if type(element)==str: # element=[element] # if isinstance(element,list) or isinstance(element,tuple): # element = Set(self._base_poset.order_ideal([self._base_poset(s) for s in element])) # element = super()._element_constructor_(element) # res += element - #return res + # return res def base_poset(self): r""" diff --git a/src/sage/modular/modform_hecketriangle/constructor.py b/src/sage/modular/modform_hecketriangle/constructor.py index 2caae3a8d7e..9471394bea1 100644 --- a/src/sage/modular/modform_hecketriangle/constructor.py +++ b/src/sage/modular/modform_hecketriangle/constructor.py @@ -7,14 +7,14 @@ """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013-2014 Jonas Jermann # # 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. # https://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ diff --git a/src/sage/modular/modform_hecketriangle/functors.py b/src/sage/modular/modform_hecketriangle/functors.py index 989f7b8e30e..f06615c823f 100644 --- a/src/sage/modular/modform_hecketriangle/functors.py +++ b/src/sage/modular/modform_hecketriangle/functors.py @@ -20,16 +20,17 @@ from sage.rings.rational_field import QQ from sage.rings.infinity import infinity -from sage.categories.functor import Functor -from sage.categories.pushout import ConstructionFunctor -from sage.categories.sets_cat import Sets -from sage.structure.parent import Parent +from sage.categories.functor import Functor +from sage.categories.pushout import ConstructionFunctor +from sage.categories.sets_cat import Sets +from sage.structure.parent import Parent +from sage.structure.unique_representation import UniqueRepresentation from sage.categories.commutative_additive_groups import CommutativeAdditiveGroups -from sage.categories.rings import Rings +from sage.categories.rings import Rings -from .constructor import FormsSpace, FormsRing -from .abstract_space import FormsSpace_abstract -from .subspace import SubSpaceForms +from .constructor import FormsSpace, FormsRing +from .abstract_space import FormsSpace_abstract +from .subspace import SubSpaceForms def _get_base_ring(ring, var_name="d"): @@ -77,16 +78,16 @@ def _get_base_ring(ring, var_name="d"): True """ - #from sage.rings.fraction_field import is_FractionField + # from sage.rings.fraction_field import is_FractionField from sage.rings.polynomial.polynomial_ring import is_PolynomialRing from sage.categories.pushout import FractionField as FractionFieldFunctor base_ring = ring - #if (is_FractionField(base_ring)): + # if (is_FractionField(base_ring)): # base_ring = base_ring.base() if (base_ring.construction() and base_ring.construction()[0] == FractionFieldFunctor()): base_ring = base_ring.construction()[1] - if (is_PolynomialRing(base_ring) and base_ring.ngens()==1 and base_ring.variable_name()==var_name): + if (is_PolynomialRing(base_ring) and base_ring.ngens() == 1 and base_ring.variable_name() == var_name): base_ring = base_ring.base() if (base_ring.construction() and base_ring.construction()[0] == FractionFieldFunctor()): base_ring = base_ring.construction()[1] @@ -325,13 +326,9 @@ def __eq__(self, other): sage: ss_functor1 == ss_functor2 False """ - - if (type(self) is type(other) and - self._ambient_space_functor == other._ambient_space_functor and - self._generators == other._generators): - return True - else: - return False + return (type(self) is type(other) and + self._ambient_space_functor == other._ambient_space_functor and + self._generators == other._generators) class FormsSpaceFunctor(ConstructionFunctor): @@ -514,15 +511,11 @@ def __eq__(self, other): sage: functor1 == functor2 False """ - - if (type(self) is type(other) and - self._group == other._group and - self._analytic_type == other._analytic_type and - self._k == other._k and - self._ep == other._ep): - return True - else: - return False + return (type(self) is type(other) and + self._group == other._group and + self._analytic_type == other._analytic_type and + self._k == other._k and + self._ep == other._ep) class FormsRingFunctor(ConstructionFunctor): @@ -703,17 +696,12 @@ def __eq__(self, other): sage: functor1 == functor2 False """ - - if (type(self) is type(other) and - self._group == other._group and - self._analytic_type == other._analytic_type and - self._red_hom == other._red_hom): - return True - else: - return False + return (type(self) is type(other) and + self._group == other._group and + self._analytic_type == other._analytic_type and + self._red_hom == other._red_hom) -from sage.structure.unique_representation import UniqueRepresentation class BaseFacade(Parent, UniqueRepresentation): r""" BaseFacade of a ring. @@ -754,11 +742,10 @@ def __init__(self, ring): sage: CC.has_coerce_map_from(BaseFacade(ZZ)) True """ - Parent.__init__(self, facade=ring, category=Rings()) self._ring = _get_base_ring(ring) # The BaseFacade(R) coerces/embeds into R, used in pushout - self.register_embedding(self.Hom(self._ring,Sets())(lambda x: x)) + self.register_embedding(self.Hom(self._ring, Sets())(lambda x: x)) def __repr__(self): r""" @@ -770,5 +757,4 @@ def __repr__(self): sage: BaseFacade(ZZ) BaseFacade(Integer Ring) """ - return "BaseFacade({})".format(self._ring) diff --git a/src/sage/modular/modform_hecketriangle/graded_ring.py b/src/sage/modular/modform_hecketriangle/graded_ring.py index 4d75538817e..f7153493aac 100644 --- a/src/sage/modular/modform_hecketriangle/graded_ring.py +++ b/src/sage/modular/modform_hecketriangle/graded_ring.py @@ -6,15 +6,14 @@ - Jonas Jermann (2013): initial version """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013-2014 Jonas Jermann # # 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/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.rings.integer_ring import ZZ from sage.rings.infinity import infinity @@ -119,6 +118,7 @@ def __init__(self, group, base_ring, red_hom, n): CommutativeAlgebra.__init__(self, base_ring=base_ring, category=CommutativeAlgebras(base_ring)) self._analytic_type = self.AT(["quasi", "mero"]) + class QuasiWeakModularFormsRing(FormsRing_abstract, CommutativeAlgebra, UniqueRepresentation): r""" Graded ring of (Hecke) quasi weakly holomorphic modular forms @@ -178,6 +178,7 @@ def __init__(self, group, base_ring, red_hom, n): CommutativeAlgebra.__init__(self, base_ring=base_ring, category=CommutativeAlgebras(base_ring)) self._analytic_type = self.AT(["quasi", "weak"]) + class QuasiModularFormsRing(FormsRing_abstract, CommutativeAlgebra, UniqueRepresentation): r""" Graded ring of (Hecke) quasi modular forms @@ -237,6 +238,7 @@ def __init__(self, group, base_ring, red_hom, n): CommutativeAlgebra.__init__(self, base_ring=base_ring, category=CommutativeAlgebras(base_ring)) self._analytic_type = self.AT(["quasi", "holo"]) + class QuasiCuspFormsRing(FormsRing_abstract, CommutativeAlgebra, UniqueRepresentation): r""" Graded ring of (Hecke) quasi cusp forms @@ -296,6 +298,7 @@ def __init__(self, group, base_ring, red_hom, n): CommutativeAlgebra.__init__(self, base_ring=base_ring, category=CommutativeAlgebras(base_ring)) self._analytic_type = self.AT(["quasi", "cusp"]) + class MeromorphicModularFormsRing(FormsRing_abstract, CommutativeAlgebra, UniqueRepresentation): r""" Graded ring of (Hecke) meromorphic modular forms @@ -355,6 +358,7 @@ def __init__(self, group, base_ring, red_hom, n): CommutativeAlgebra.__init__(self, base_ring=base_ring, category=CommutativeAlgebras(base_ring)) self._analytic_type = self.AT(["mero"]) + class WeakModularFormsRing(FormsRing_abstract, CommutativeAlgebra, UniqueRepresentation): r""" Graded ring of (Hecke) weakly holomorphic modular forms @@ -414,6 +418,7 @@ def __init__(self, group, base_ring, red_hom, n): CommutativeAlgebra.__init__(self, base_ring=base_ring, category=CommutativeAlgebras(base_ring)) self._analytic_type = self.AT(["weak"]) + class ModularFormsRing(FormsRing_abstract, CommutativeAlgebra, UniqueRepresentation): r""" Graded ring of (Hecke) modular forms @@ -472,6 +477,7 @@ def __init__(self, group, base_ring, red_hom, n): CommutativeAlgebra.__init__(self, base_ring=base_ring, category=CommutativeAlgebras(base_ring)) self._analytic_type = self.AT(["holo"]) + class CuspFormsRing(FormsRing_abstract, CommutativeAlgebra, UniqueRepresentation): r""" Graded ring of (Hecke) cusp forms diff --git a/src/sage/modular/modform_hecketriangle/graded_ring_element.py b/src/sage/modular/modform_hecketriangle/graded_ring_element.py index f96ce2ee7dc..92981f2f52e 100644 --- a/src/sage/modular/modform_hecketriangle/graded_ring_element.py +++ b/src/sage/modular/modform_hecketriangle/graded_ring_element.py @@ -6,15 +6,14 @@ - Jonas Jermann (2013): initial version """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013-2014 Jonas Jermann # # 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/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.functions.log import exp from sage.geometry.hyperbolic_space.hyperbolic_interface import HyperbolicPlane @@ -194,15 +193,14 @@ def _rat_repr(self): sage: QuasiModularForms(n=infinity, k=10)(x*(x-y^2)*z)._rat_repr() '-E4*f_i^2*E2 + E4^2*E2' """ - - if (self.hecke_n() == infinity): + if self.hecke_n() == infinity: with localvars(self.parent()._pol_ring, "E4, f_i, E2, d"): pol_str = str(self._rat) else: with localvars(self.parent()._pol_ring, "f_rho, f_i, E2, d"): pol_str = str(self._rat) - return "{}".format(pol_str) + return pol_str def _qexp_repr(self): r""" @@ -426,10 +424,9 @@ def degree(self): sage: ModularForms(n=infinity).f_rho().degree() (0, 1) """ + return (self._weight, self._ep) - return (self._weight,self._ep) - - def is_modular(self): + def is_modular(self) -> bool: r""" Return whether ``self`` (resp. its homogeneous components) transform like modular forms. @@ -450,7 +447,6 @@ def is_modular(self): sage: QuasiModularForms(n=infinity).f_inf().is_modular() True """ - return not (self.AT("quasi") <= self._analytic_type) def is_weakly_holomorphic(self): @@ -642,7 +638,7 @@ def denominator(self): new_parent = self.parent().extend_type("holo", ring=True).reduce_type(["holo", "quasi"]) return new_parent(res).reduce() - def _add_(self,other): + def _add_(self, other): r""" Return the sum of ``self`` and ``other``. @@ -718,10 +714,9 @@ def _add_(self,other): sage: el.parent() ModularFormsRing(n=+Infinity) over Integer Ring """ + return self.parent()(self._rat + other._rat) - return self.parent()(self._rat+other._rat) - - def _sub_(self,other): + def _sub_(self, other): r""" Return the difference of ``self`` and ``other``. @@ -774,9 +769,8 @@ def _sub_(self,other): sage: el.parent() ModularFormsRing(n=+Infinity) over Integer Ring """ - - #reduce at the end? See example "sage: ((E4+E6)-E6).parent()" - return self.parent()(self._rat-other._rat) + # reduce at the end? See example "sage: ((E4+E6)-E6).parent()" + return self.parent()(self._rat - other._rat) def _neg_(self): r""" @@ -802,7 +796,7 @@ def _neg_(self): """ return self.parent()(-self._rat) - def _mul_(self,other): + def _mul_(self, other): r""" Return the product of ``self`` and ``other``. @@ -879,13 +873,12 @@ def _mul_(self,other): sage: el.parent() QuasiModularForms(n=+Infinity, k=8, ep=1) over Integer Ring """ - - res = self.parent().rat_field()(self._rat*other._rat) + res = self.parent().rat_field()(self._rat * other._rat) new_parent = self.parent().extend_type(ring=True) # The product of two homogeneous elements is homogeneous return new_parent(res).reduce() - def _div_(self,other): + def _div_(self, other): r""" Return the division of ``self`` by ``other``. @@ -965,8 +958,7 @@ def _div_(self,other): sage: el.parent() QuasiMeromorphicModularForms(n=+Infinity, k=0, ep=1) over Integer Ring """ - - res = self.parent().rat_field()(self._rat/other._rat) + res = self.parent().rat_field()(self._rat / other._rat) new_parent = self.parent().extend_type("mero", ring=True) # The division of two homogeneous elements is homogeneous return new_parent(res).reduce() @@ -1001,7 +993,7 @@ def sqrt(self): """ res = self._rat.sqrt() assert res.parent() is self.parent().rat_field() - #new_parent = self.parent().extend_type(ring=True) + # new_parent = self.parent().extend_type(ring=True) # The sqrt of a homogeneous element is homogeneous if it exists new_parent = self.parent().extend_type(ring=True) return new_parent(res).reduce() @@ -1094,20 +1086,19 @@ def diff_op(self, op, new_parent=None): sage: E2.diff_op(ran_op) E4*E2 + 1 """ - - (x,y,z,d) = self.parent().rat_field().gens() - (X,Y,Z,dX,dY,dZ) = self.parent().diff_alg().gens() + x, y, z, d = self.parent().rat_field().gens() + X, Y, Z, dX, dY, dZ = self.parent().diff_alg().gens() L = op.monomials() new_rat = 0 for mon in L: mon_summand = self._rat - mon_summand = mon_summand.derivative(x,mon.degree(dX)) - mon_summand = mon_summand.derivative(y,mon.degree(dY)) - mon_summand = mon_summand.derivative(z,mon.degree(dZ)) + mon_summand = mon_summand.derivative(x, mon.degree(dX)) + mon_summand = mon_summand.derivative(y, mon.degree(dY)) + mon_summand = mon_summand.derivative(z, mon.degree(dZ)) mon_summand *= x**(mon.degree(X)) mon_summand *= y**(mon.degree(Y)) mon_summand *= z**(mon.degree(Z)) - new_rat += op.monomial_coefficient(mon)*mon_summand + new_rat += op.monomial_coefficient(mon) * mon_summand res = self.parent().rat_field()(new_rat) if (new_parent is None): new_parent = self.parent().extend_type(["quasi", "mero"], ring=True) @@ -1350,7 +1341,7 @@ def order_at(self, tau=infinity): R = self.parent().pol_ring() numerator = R(rat.numerator()) denom = R(rat.denominator()) - (x,y,z,d) = R.gens() + x, y, z, d = R.gens() n = self.hecke_n() if (tau == i): @@ -1379,7 +1370,7 @@ def order_at(self, tau=infinity): try: while (f_pol.divides(numerator)): numerator = numerator.quo_rem(f_pol)[0] - #numerator /= f_pol + # numerator /= f_pol numerator = R(numerator) order_f += 1 except TypeError: @@ -1387,7 +1378,7 @@ def order_at(self, tau=infinity): try: while (f_pol.divides(denom)): denom = denom.quo_rem(f_pol)[0] - #denom /= f_pol + # denom /= f_pol denom = R(denom) order_f -= 1 except TypeError: @@ -1395,11 +1386,11 @@ def order_at(self, tau=infinity): return order_f else: - if (tau != infinity): + if tau != infinity: raise NotImplementedError("Only the order at infinity is supported for non-homogeneous or quasi forms!") - num_val = prec_num_bound = 1 #(self.parent()._prec/ZZ(2)).ceil() - denom_val = prec_denom_bound = 1 #(self.parent()._prec/ZZ(2)).ceil() + num_val = prec_num_bound = 1 # (self.parent()._prec/ZZ(2)).ceil() + denom_val = prec_denom_bound = 1 # (self.parent()._prec/ZZ(2)).ceil() while (num_val >= prec_num_bound): prec_num_bound *= 2 @@ -1408,7 +1399,7 @@ def order_at(self, tau=infinity): prec_denom_bound *= 2 denom_val = self.denominator().q_expansion(prec=prec_denom_bound, fix_prec=True).valuation() - return (num_val-denom_val) + return num_val - denom_val def as_ring_element(self): r""" @@ -1521,7 +1512,7 @@ def full_reduce(self): return self.reduced_parent()(self._rat) - #precision is actually accuracy, maybe add "real precision" meaning number of rel. coef + # precision is actually accuracy, maybe add "real precision" meaning number of rel. coef @cached_method def _q_expansion_cached(self, prec, fix_d, subs_d, d_num_prec, fix_prec=False): """ @@ -1574,7 +1565,7 @@ def _q_expansion_cached(self, prec, fix_d, subs_d, d_num_prec, fix_prec=False): qexp = self._rat.subs(x=X, y=Y, z=Z, d=formal_d) qexp = (qexp + O(formal_q**prec)).parent()(qexp) - qexp = qexp(formal_q/formal_d) + qexp = qexp(formal_q / formal_d) cur_prec = qexp.prec() if (subs_d): @@ -1820,12 +1811,12 @@ def q_expansion_vector(self, min_exp=None, max_exp=None, prec=None, **kwargs): qexp = self.q_expansion(prec=prec, **kwargs) - if (min_exp is None): + if min_exp is None: min_exp = qexp.valuation() else: min_exp = ZZ(min_exp) - return vector([qexp[m] for m in range(min_exp, max_exp +1)]) + return vector([qexp[m] for m in range(min_exp, max_exp + 1)]) def evaluate(self, tau, prec=None, num_prec=None, check=False): r""" @@ -2182,16 +2173,16 @@ def evaluate(self, tau, prec=None, num_prec=None, check=False): return q_exp.laurent_polynomial()(exp((2 * pi * i).n(num_prec) / self.group().lam() * w)) * aut_factor else: return q_exp.polynomial()(exp((2 * pi * i).n(num_prec) / self.group().lam() * w)) * aut_factor - elif (self._rat == z): + elif self._rat == z: E2 = self.parent().graded_ring().E2().reduce(force=True) (A, w) = self.group().get_FD(tau) aut_factor = E2.parent().aut_factor(A, w) E2_wvalue = E2.q_expansion_fixed_d(prec=prec, d_num_prec=num_prec).polynomial()(exp((2 * pi * i).n(num_prec) / self.group().lam() * w)) if (self.hecke_n() == infinity): - E2_cor_term = 4 * self.group().lam() / (2*pi*i).n(num_prec) * A.c() * (A.c()*w + A.d()) + E2_cor_term = 4 * self.group().lam() / (2 * pi * i).n(num_prec) * A.c() * (A.c() * w + A.d()) else: - E2_cor_term = 4 * self.group().lam() / (2*pi*i).n(num_prec) * self.hecke_n() / (self.hecke_n()-2) * A.c() * (A.c()*w + A.d()) - return E2_wvalue*aut_factor + E2_cor_term + E2_cor_term = 4 * self.group().lam() / (2 * pi * i).n(num_prec) * self.hecke_n() / (self.hecke_n() - 2) * A.c() * (A.c() * w + A.d()) + return E2_wvalue * aut_factor + E2_cor_term else: f_i = self.parent().graded_ring().f_i() E2 = self.parent().graded_ring().E2() diff --git a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py index d84bb365745..a0e3afbd9d6 100644 --- a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py +++ b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py @@ -19,7 +19,7 @@ from sage.arith.misc import divisors from sage.functions.gamma import psi1 from sage.functions.log import exp -from sage.functions.trig import cos, sec +from sage.functions.trig import sec from sage.groups.matrix_gps.finitely_generated import FinitelyGeneratedMatrixGroup_generic from sage.matrix.constructor import matrix from sage.misc.cachefunc import cached_method @@ -31,12 +31,14 @@ from sage.rings.number_field.number_field import NumberField from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.qqbar import AA, AlgebraicField +from sage.rings.universal_cyclotomic_field import E from sage.rings.rational_field import QQ from sage.structure.unique_representation import UniqueRepresentation from sage.symbolic.constants import pi from .hecke_triangle_group_element import HeckeTriangleGroupElement, cyclic_representative, coerce_AA + class HeckeTriangleGroup(FinitelyGeneratedMatrixGroup_generic, UniqueRepresentation): r""" @@ -56,11 +58,11 @@ def __classcall__(cls, n=3): sage: HeckeTriangleGroup(QQ(3)) == HeckeTriangleGroup(int(3)) True """ - if (n == infinity): + if n == infinity: n = infinity else: n = ZZ(n) - if (n < 3): + if n < 3: raise AttributeError("n has to be infinity or an Integer >= 3.") return super().__classcall__(cls, n) @@ -95,12 +97,12 @@ def __init__(self, n): if n in [3, infinity]: self._base_ring = ZZ - self._lam = ZZ(1) if n == 3 else ZZ(2) + self._lam = ZZ.one() if n == 3 else ZZ(2) else: - lam_symbolic = 2 * cos(pi / n) + lam_symbolic = coerce_AA(E(2 * n) + ~E(2 * n)) K = NumberField(self.lam_minpoly(), 'lam', - embedding=coerce_AA(lam_symbolic)) - #self._base_ring = K.order(K.gens()) + embedding=lam_symbolic) + # self._base_ring = K.order(K.gens()) self._base_ring = K.maximal_order() self._lam = self._base_ring.gen(1) @@ -167,9 +169,9 @@ def element_repr_method(self, method=None): if method is None: return self._element_repr_method elif method in ["default", "basic", "block", "conj"]: - self._element_repr_method=method + self._element_repr_method = method else: - raise ValueError("The specified method {} is not supported!").format(method) + raise ValueError(f"the specified method {method} is not supported") def one(self): r""" @@ -205,8 +207,12 @@ def lam_minpoly(self): x - 2 """ # TODO: Write an explicit (faster) implementation - lam_symbolic = 2 * cos(pi / self._n) - return coerce_AA(lam_symbolic).minpoly() + n = self._n + if n == infinity: + lam_symbolic = QQ(2) + else: + lam_symbolic = E(2 * n) + ~E(2 * n) + return lam_symbolic.minpoly() def base_ring(self): r""" @@ -304,9 +310,9 @@ def rho(self): # TODO: maybe rho should be replaced by -rhobar # Also we could use NumberFields... if self._n == infinity: - return coerce_AA(1) + return AA.one() else: - rho = AlgebraicField()(exp(pi / self._n * I)) + rho = AlgebraicField()(E(2 * self._n)) rho.simplify() return rho @@ -332,11 +338,12 @@ def alpha(self): sage: HeckeTriangleGroup(infinity).alpha() 1/4 """ - return ZZ(1) / ZZ(2) * (ZZ(1) / ZZ(2) - ZZ(1) / self._n) + return QQ((1, 2)) * (QQ((1, 2)) - ZZ.one() / self._n) def beta(self): r""" Return the parameter ``beta`` of ``self``. + This is the second parameter of the hypergeometric series used in the calculation of the Hauptmodul of ``self``. @@ -356,7 +363,7 @@ def beta(self): sage: HeckeTriangleGroup(infinity).beta() 1/4 """ - return ZZ(1)/ZZ(2) * (ZZ(1)/ZZ(2) + ZZ(1)/self._n) + return QQ((1, 2)) * (QQ((1, 2)) + ZZ.one() / self._n) # We use cached method here to create unique instances of basic matrices # (major performance gain) @@ -540,17 +547,18 @@ def dvalue(self): """ n = self._n if n == 3: - return ZZ(1)/ZZ(2**6*3**3) - elif n == 4: - return ZZ(1)/ZZ(2**8) - elif n == 6: - return ZZ(1)/ZZ(2**2*3**3) - elif n == infinity: - return ZZ(1)/ZZ(2**6) - else: - return exp(-ZZ(2)*psi1(ZZ(1)) + psi1(ZZ(1)-self.alpha())+psi1(ZZ(1)-self.beta()) - pi*sec(pi/self._n)) - - def is_arithmetic(self): + return 1 / ZZ(2**6*3**3) + if n == 4: + return 1 / ZZ(2**8) + if n == 6: + return 1 / ZZ(2**2*3**3) + if n == infinity: + return 1 / ZZ(2**6) + # reference for this formula ? + return exp(-ZZ(2)*psi1(ZZ.one()) + psi1(ZZ.one()-self.alpha()) + + psi1(ZZ.one()-self.beta()) - pi*sec(pi/self._n)) + + def is_arithmetic(self) -> bool: r""" Return True if ``self`` is an arithmetic subgroup. @@ -625,20 +633,20 @@ def get_FD(self, z): A = ID w = z - while (abs(w) < ZZ(1) or abs(w.real()) > self.lam()/ZZ(2)): - if (abs(w) < ZZ(1)): + while abs(w) < ZZ.one() or abs(w.real()) > self.lam() / ZZ(2): + if abs(w) < ZZ.one(): w = self.S().acton(w) A = S*A - while (w.real() >= self.lam()/ZZ(2)): + while w.real() >= self.lam() / ZZ(2): w = TI.acton(w) A = TI*A - while (w.real() < -self.lam()/ZZ(2)): + while w.real() < -self.lam() / ZZ(2): w = T.acton(w) A = T*A - if (w.real() == self.lam()/ZZ(2)): + if w.real() == self.lam() / ZZ(2): w = TI.acton(w) A = TI*A - if (abs(w) == ZZ(1) and w.real() > ZZ(0)): + if abs(w) == ZZ.one() and w.real() > ZZ.zero(): w = S.acton(w) A = S*A @@ -715,12 +723,12 @@ def root_extension_field(self, D): L = K.extension(x**2 - D, 'e') - #e = AA(D).sqrt() - #emb = L.hom([e]) - #L._unset_embedding() - #L.register_embedding(emb) + # e = AA(D).sqrt() + # emb = L.hom([e]) + # L._unset_embedding() + # L.register_embedding(emb) - #return NumberField(L.absolute_polynomial(), 'e', structure=AbsoluteFromRelative(L), embedding=(???)) + # return NumberField(L.absolute_polynomial(), 'e', structure=AbsoluteFromRelative(L), embedding=(???)) return L # We cache this method for performance reasons (it is repeatedly reused) @@ -869,7 +877,9 @@ def _elliptic_conj_reps(self): self._conj_prim[D] = [] self._conj_prim[D].append(self.S()) - other_reps = [self.U()**k for k in range(-((self.n()-1)/2).floor(), (self.n()/2).floor() + 1) if k not in [0,1]] + other_reps = [self.U()**k + for k in range(-(self.n() - 1) // 2, self.n() // 2 + 1) + if k not in [0, 1]] for v in other_reps: D = v.discriminant() @@ -877,7 +887,7 @@ def _elliptic_conj_reps(self): self._conj_nonprim[D] = [] self._conj_nonprim[D].append(v) - def _conjugacy_representatives(self, max_block_length=ZZ(0), D=None): + def _conjugacy_representatives(self, max_block_length=0, D=None): r""" Store conjugacy representatives up to block length ``max_block_length`` (a non-negative integer, default: 0) @@ -944,12 +954,12 @@ def _conjugacy_representatives(self, max_block_length=ZZ(0), D=None): sage: G.element_repr_method("default") """ - from sage.combinat.partition import OrderedPartitions from sage.combinat.combinat import tuples if D is not None: - max_block_length = max(coerce_AA(0), coerce_AA((D + 4)/(self.lam()**2))).sqrt().floor() + max_block_length = max(AA.zero(), + coerce_AA((D + 4)/(self.lam()**2))).sqrt().floor() else: try: max_block_length = ZZ(max_block_length) @@ -959,7 +969,7 @@ def _conjugacy_representatives(self, max_block_length=ZZ(0), D=None): raise ValueError("max_block_length must be a non-negative integer!") if not hasattr(self, "_max_block_length"): - self._max_block_length = ZZ(0) + self._max_block_length = ZZ.zero() self._conj_block = {} self._conj_nonprim = {} self._conj_prim = {} @@ -1018,7 +1028,7 @@ def is_cycle_of_length(seq, n): keep = False # But: Do we maybe want powers of V(n-1)?? # For now we exclude the parabolic cases... - elif ex[0] == self.n()-1: + elif ex[0] == self.n() - 1: keep = False if keep: @@ -1028,18 +1038,11 @@ def is_cycle_of_length(seq, n): for el in self._conj_block[t_ZZ]: group_el = prod([self.V(el[k][0])**el[k][1] for k in range(len(el))]) - #if el != group_el.conjugacy_type(): - # raise AssertionError("This shouldn't happen!") - D = group_el.discriminant() - if coerce_AA(D) < 0: - raise AssertionError("This shouldn't happen!") - if coerce_AA(D) == 0: - raise AssertionError("This shouldn't happen!") - #continue + assert coerce_AA(D) > 0 # The primitive cases - #if group_el.is_primitive(): + # if group_el.is_primitive(): if not ((len(el) == 1 and el[0][1] > 1) or is_cycle(el)): if D not in self._conj_prim: self._conj_prim[D] = [] @@ -1129,7 +1132,7 @@ def class_representatives(self, D, primitive=True): if not primitive and D in self._conj_nonprim: L += self._conj_nonprim[D] - if len(L) == 0: + if not L: raise ValueError("D = {} is not a{} discriminant for {}".format(D, " primitive" if primitive else "", self)) else: return L @@ -1220,9 +1223,9 @@ def is_discriminant(self, D, primitive=True): sage: G.is_discriminant(2) False """ - self._conjugacy_representatives(0) - t_bound = max(coerce_AA(0), coerce_AA((D + 4)/(self.lam()**2))).sqrt().floor() + t_bound = max(AA.zero(), + coerce_AA((D + 4) / (self.lam()**2))).sqrt().floor() for t in range(self._max_block_length + 1, t_bound + 1): self._conjugacy_representatives(t) diff --git a/src/sage/modular/modform_hecketriangle/series_constructor.py b/src/sage/modular/modform_hecketriangle/series_constructor.py index 7bd6e256c31..dc2cd792a6b 100644 --- a/src/sage/modular/modform_hecketriangle/series_constructor.py +++ b/src/sage/modular/modform_hecketriangle/series_constructor.py @@ -11,14 +11,14 @@ ``J_inv_ZZ`` is the main function used to determine all Fourier expansions. """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013-2014 Jonas Jermann # # 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/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.arith.misc import bernoulli, sigma, rising_factorial from sage.misc.cachefunc import cached_method @@ -369,17 +369,15 @@ def G_inv_ZZ(self): sage: MFSeriesConstructor(group=infinity, prec=3).G_inv_ZZ() q^-1 - 1/8 - 59/1024*q + O(q^2) """ - n = self.hecke_n() # Note that G_inv is not a weakly holomorphic form (because of the behavior at -1) - if (n == infinity): + if n == infinity: q = self._series_ring.gen() temp_expr = (self.J_inv_ZZ()/self.f_inf_ZZ()*q**2).power_series() return 1/q*self.f_i_ZZ()*(temp_expr.log()/2).exp() elif (ZZ(2).divides(n)): return self.f_i_ZZ()*(self.f_rho_ZZ()**(ZZ(n/ZZ(2))))/self.f_inf_ZZ() else: - #return self._qseries_ring([]) raise ValueError("G_inv doesn't exist for n={}.".format(self.hecke_n())) @cached_method diff --git a/src/sage/modular/modform_hecketriangle/space.py b/src/sage/modular/modform_hecketriangle/space.py index 1edab742412..662f1035794 100644 --- a/src/sage/modular/modform_hecketriangle/space.py +++ b/src/sage/modular/modform_hecketriangle/space.py @@ -6,15 +6,14 @@ - Jonas Jermann (2013): initial version """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013-2014 Jonas Jermann # # 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/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ @@ -29,6 +28,7 @@ from .hecke_triangle_groups import HeckeTriangleGroup from .abstract_space import FormsSpace_abstract + def canonical_parameters(group, base_ring, k, ep, n=None): r""" Return a canonical version of the parameters. @@ -42,11 +42,10 @@ def canonical_parameters(group, base_ring, k, ep, n=None): sage: canonical_parameters(infinity, ZZ, 2, int(-1)) (Hecke triangle group for n = +Infinity, Integer Ring, 2, -1, +Infinity) """ - - if not (n is None): + if n is not None: group = n - if (group == infinity): + if group == infinity: group = HeckeTriangleGroup(infinity) else: try: @@ -56,16 +55,16 @@ def canonical_parameters(group, base_ring, k, ep, n=None): n = group.n() k = QQ(k) - if (ep is None): - if (n == infinity): - ep = (-1)**(k/ZZ(2)) - elif (ZZ(2).divides(n)): + if ep is None: + if n == infinity: + ep = (-1)**(k / 2) + elif ZZ(2).divides(n): ep = (-1)**(k*ZZ(n-2)/ZZ(4)) else: ep = (-1)**(k*ZZ(n-2)/ZZ(2)) ep = ZZ(ep) - if (n == infinity): + if n == infinity: num = (k-(1-ep)) / ZZ(4) else: num = (k-(1-ep)*n/(n-2)) * (n-2) / ZZ(4) @@ -73,7 +72,7 @@ def canonical_parameters(group, base_ring, k, ep, n=None): try: num = ZZ(num) except TypeError: - raise ValueError("Invalid or non-occurring weight k={}, ep={}!".format(k,ep)) + raise ValueError(f"Invalid or non-occurring weight k={k}, ep={ep}!") return (group, base_ring, k, ep, n) @@ -119,10 +118,10 @@ def __init__(self, group, base_ring, k, ep, n): sage: MF.ambient_space() == MF True """ - FormsSpace_abstract.__init__(self, group=group, base_ring=base_ring, k=k, ep=ep, n=n) Module.__init__(self, base=base_ring) - self._analytic_type=self.AT(["quasi", "mero"]) + self._analytic_type = self.AT(["quasi", "mero"]) + class QuasiWeakModularForms(FormsSpace_abstract, Module, UniqueRepresentation): r""" @@ -166,10 +165,10 @@ def __init__(self, group, base_ring, k, ep, n): sage: MF.is_ambient() True """ - FormsSpace_abstract.__init__(self, group=group, base_ring=base_ring, k=k, ep=ep, n=n) Module.__init__(self, base=base_ring) - self._analytic_type=self.AT(["quasi", "weak"]) + self._analytic_type = self.AT(["quasi", "weak"]) + class QuasiModularForms(FormsSpace_abstract, Module, UniqueRepresentation): r""" @@ -216,7 +215,7 @@ def __init__(self, group, base_ring, k, ep, n): FormsSpace_abstract.__init__(self, group=group, base_ring=base_ring, k=k, ep=ep, n=n) Module.__init__(self, base=base_ring) - self._analytic_type=self.AT(["quasi", "holo"]) + self._analytic_type = self.AT(["quasi", "holo"]) self._module = FreeModule(self.coeff_ring(), self.dimension()) @cached_method @@ -310,29 +309,29 @@ def coordinate_vector(self, v): sage: el2 == MF.element_from_coordinates(el2.coordinate_vector()) True """ - - (x,y,z,d) = self.pol_ring().gens() + x, y, z, d = self.pol_ring().gens() k = self._weight - rmax = QQ(k / ZZ(2)).floor() + rmax = (QQ(k) / 2).floor() partlist = v.rat().numerator().polynomial(z).list() denom = self.coeff_ring()(v.rat().denominator()) - partlist = [part/denom for part in partlist] - parts = partlist + [0]*(rmax + 1 - len(partlist)) + partlist = [part / denom for part in partlist] + parts = partlist + [0] * (rmax + 1 - len(partlist)) E2 = self.E2() coord_vector = [] - for r in range(ZZ(0), rmax + 1): - gens = [v/E2**r for v in self.quasi_part_gens(r)] + for r in range(rmax + 1): + gens = [v / E2**r for v in self.quasi_part_gens(r)] - if len(gens) > 0: + if gens: ambient_space = self.graded_ring().reduce_type("holo", degree=(gens[0].weight(), gens[0].ep())) subspace = ambient_space.subspace(gens) vector_part_in_subspace = subspace(parts[r]) - coord_part = [v for v in vector_part_in_subspace.coordinate_vector() ] + coord_part = [v for v in vector_part_in_subspace.coordinate_vector()] coord_vector += coord_part return self._module(vector(self.coeff_ring(), coord_vector)) + class QuasiCuspForms(FormsSpace_abstract, Module, UniqueRepresentation): r""" Module of (Hecke) quasi cusp forms @@ -381,7 +380,7 @@ def __init__(self, group, base_ring, k, ep, n): FormsSpace_abstract.__init__(self, group=group, base_ring=base_ring, k=k, ep=ep, n=n) Module.__init__(self, base=base_ring) - self._analytic_type=self.AT(["quasi", "cusp"]) + self._analytic_type = self.AT(["quasi", "cusp"]) self._module = FreeModule(self.coeff_ring(), self.dimension()) @cached_method @@ -482,29 +481,29 @@ def coordinate_vector(self, v): sage: el2 == MF.element_from_coordinates(el2.coordinate_vector()) True """ - - (x,y,z,d) = self.pol_ring().gens() + x, y, z, d = self.pol_ring().gens() k = self._weight - rmax = QQ(k / ZZ(2)).floor() + rmax = (QQ(k) / 2).floor() partlist = v.rat().numerator().polynomial(z).list() denom = self.coeff_ring()(v.rat().denominator()) - partlist = [part/denom for part in partlist] - parts = partlist + [0]*(rmax + 1 - len(partlist)) + partlist = [part / denom for part in partlist] + parts = partlist + [0] * (rmax + 1 - len(partlist)) E2 = self.E2() coord_vector = [] - for r in range(ZZ(0), rmax + 1): - gens = [v/E2**r for v in self.quasi_part_gens(r)] + for r in range(rmax + 1): + gens = [v / E2**r for v in self.quasi_part_gens(r)] - if len(gens) > 0: + if gens: ambient_space = self.graded_ring().reduce_type("cusp", degree=(gens[0].weight(), gens[0].ep())) subspace = ambient_space.subspace(gens) vector_part_in_subspace = subspace(parts[r]) - coord_part = [v for v in vector_part_in_subspace.coordinate_vector() ] + coord_part = [v for v in vector_part_in_subspace.coordinate_vector()] coord_vector += coord_part return self._module(vector(self.coeff_ring(), coord_vector)) + class MeromorphicModularForms(FormsSpace_abstract, Module, UniqueRepresentation): r""" Module of (Hecke) meromorphic modular forms @@ -550,7 +549,8 @@ def __init__(self, group, base_ring, k, ep, n): FormsSpace_abstract.__init__(self, group=group, base_ring=base_ring, k=k, ep=ep, n=n) Module.__init__(self, base=base_ring) - self._analytic_type=self.AT(["mero"]) + self._analytic_type = self.AT(["mero"]) + class WeakModularForms(FormsSpace_abstract, Module, UniqueRepresentation): r""" @@ -592,10 +592,10 @@ def __init__(self, group, base_ring, k, ep, n): sage: MF in MF.category() True """ - FormsSpace_abstract.__init__(self, group=group, base_ring=base_ring, k=k, ep=ep, n=n) Module.__init__(self, base=base_ring) - self._analytic_type=self.AT(["weak"]) + self._analytic_type = self.AT(["weak"]) + class ModularForms(FormsSpace_abstract, Module, UniqueRepresentation): r""" @@ -679,8 +679,7 @@ def gens(self): sage: ModularForms(n=infinity, k=4).gens() [1 + 240*q^2 + 2160*q^4 + O(q^5), q - 8*q^2 + 28*q^3 - 64*q^4 + O(q^5)] """ - - return [ self.F_basis(m) for m in range(self.dimension()) ] + return [self.F_basis(m) for m in range(self.dimension())] @cached_method def dimension(self): @@ -699,8 +698,7 @@ def dimension(self): sage: ModularForms(n=infinity, k=8).dimension() 3 """ - - return max(self._l1+1, ZZ(0)) + return max(self._l1 + 1, ZZ.zero()) @cached_method def coordinate_vector(self, v): @@ -750,6 +748,7 @@ def coordinate_vector(self, v): vec = v.q_expansion_vector(min_exp=0, max_exp=self.degree() - 1) return self._module(vec) + class CuspForms(FormsSpace_abstract, Module, UniqueRepresentation): r""" Module of (Hecke) cusp forms @@ -795,10 +794,9 @@ def __init__(self, group, base_ring, k, ep, n): sage: MF.is_ambient() True """ - FormsSpace_abstract.__init__(self, group=group, base_ring=base_ring, k=k, ep=ep, n=n) Module.__init__(self, base=base_ring) - self._analytic_type=self.AT(["cusp"]) + self._analytic_type = self.AT(["cusp"]) self._module = FreeModule(self.coeff_ring(), self.dimension()) @cached_method @@ -822,9 +820,9 @@ def gens(self): sage: MF = CuspForms(n=infinity, k=8, ep=1) sage: MF.gen(0) == MF.E4()*MF.f_inf() True - """ - - return [ self.F_basis(m, order_1=ZZ(1)) for m in range(1, self.dimension() + 1) ] + """ + return [self.F_basis(m, order_1=ZZ.one()) + for m in range(1, self.dimension() + 1)] @cached_method def dimension(self): @@ -843,11 +841,9 @@ def dimension(self): sage: CuspForms(n=infinity, k=8).dimension() 1 """ - - if (self.hecke_n() == infinity): - return max(self._l1-1, ZZ(0)) - else: - return max(self._l1, ZZ(0)) + if self.hecke_n() == infinity: + return max(self._l1 - 1, ZZ.zero()) + return max(self._l1, ZZ.zero()) @cached_method def coordinate_vector(self, v): @@ -902,6 +898,7 @@ def coordinate_vector(self, v): vec = v.q_expansion_vector(min_exp=1, max_exp=self.degree()) return self._module(vec) + class ZeroForm(FormsSpace_abstract, Module, UniqueRepresentation): r""" Zero Module for the zero form for the given group, base ring @@ -952,7 +949,7 @@ def __init__(self, group, base_ring, k, ep, n): FormsSpace_abstract.__init__(self, group=group, base_ring=base_ring, k=k, ep=ep, n=n) Module.__init__(self, base=base_ring) - self._analytic_type=self.AT([]) + self._analytic_type = self.AT([]) self._module = FreeModule(self.coeff_ring(), self.dimension()) def _change_degree(self, k, ep): @@ -977,7 +974,8 @@ def _change_degree(self, k, ep): sage: MF._change_degree(14, -1) ZeroForms(n=3, k=14, ep=-1) over Integer Ring """ - return ZeroForm(group=self.group(), base_ring=self.base_ring(), k=k, ep=ep) + return ZeroForm(group=self.group(), base_ring=self.base_ring(), + k=k, ep=ep) @cached_method def gens(self): @@ -991,7 +989,6 @@ def gens(self): sage: ZeroForm(6, CC, 3, -1).gens() [] """ - return [] @cached_method @@ -1006,7 +1003,6 @@ def dimension(self): sage: ZeroForm(6, CC, 3, -1).dimension() 0 """ - return 0 @cached_method @@ -1038,6 +1034,4 @@ def coordinate_vector(self, v): sage: vec.parent() == MF.module() True """ - - vec = [] - return self._module(vector(self.coeff_ring(), vec)) + return self._module(vector(self.coeff_ring(), [])) diff --git a/src/sage/modular/modform_hecketriangle/subspace.py b/src/sage/modular/modform_hecketriangle/subspace.py index 332546aee15..f89d42affd8 100644 --- a/src/sage/modular/modform_hecketriangle/subspace.py +++ b/src/sage/modular/modform_hecketriangle/subspace.py @@ -43,7 +43,6 @@ def canonical_parameters(ambient_space, basis, check=True): (q + 30*q^2 + 333*q^3 + 1444*q^4 + O(q^5), 1 + 26208*q^3 + 530712*q^4 + O(q^5))) """ - if check: coord_matrix = matrix([ambient_space(v).ambient_coordinate_vector() for v in basis]) pivots = coord_matrix.transpose().pivots() @@ -55,6 +54,7 @@ def canonical_parameters(ambient_space, basis, check=True): return (ambient_space, basis) + def ModularFormsSubSpace(*args, **kwargs): r""" Create a modular forms subspace generated by the supplied arguments if possible. @@ -203,7 +203,6 @@ def __init__(self, ambient_space, basis, check): sage: subspace.gens() [q + 24*q^2 + O(q^3), q - 24*q^2 + O(q^3), q - 8*q^2 + O(q^3)] """ - FormsSpace_abstract.__init__(self, group=ambient_space.group(), base_ring=ambient_space.base_ring(), k=ambient_space.weight(), ep=ambient_space.ep(), n=ambient_space.hecke_n()) Module.__init__(self, base=ambient_space.base_ring()) @@ -213,7 +212,7 @@ def __init__(self, ambient_space, basis, check): self._gens = [self._element_constructor_(v) for v in basis] self._module = ambient_space._module.submodule([ambient_space.coordinate_vector(v) for v in basis]) # TODO: get the analytic type from the basis - #self._analytic_type=self.AT(["quasi", "mero"]) + # self._analytic_type=self.AT(["quasi", "mero"]) self._analytic_type = ambient_space._analytic_type def _repr_(self): From a30af3fee5d25fced2665c609e025d4646dbb2e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 5 Jun 2023 12:19:17 +0200 Subject: [PATCH 080/205] fix doctest and some care for the doc --- .../hecke_triangle_groups.py | 91 ++++++++++--------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py index a0e3afbd9d6..cd51bda2b9d 100644 --- a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py +++ b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py @@ -25,7 +25,6 @@ from sage.misc.cachefunc import cached_method from sage.misc.latex import latex from sage.misc.misc_c import prod -from sage.rings.imaginary_unit import I from sage.rings.infinity import infinity from sage.rings.integer_ring import ZZ from sage.rings.number_field.number_field import NumberField @@ -42,7 +41,7 @@ class HeckeTriangleGroup(FinitelyGeneratedMatrixGroup_generic, UniqueRepresentation): r""" - Hecke triangle group (2, n, infinity). + Hecke triangle group `(2, n, \infty)`. """ Element = HeckeTriangleGroupElement @@ -262,7 +261,6 @@ def n(self): """ return self._n - # TODO: rename this to a more descriptive lambda in a later update/patch def lam(self): r""" Return the parameter ``lambda`` of ``self``, @@ -319,6 +317,7 @@ def rho(self): def alpha(self): r""" Return the parameter ``alpha`` of ``self``. + This is the first parameter of the hypergeometric series used in the calculation of the Hauptmodul of ``self``. @@ -479,12 +478,13 @@ def V(self, j): INPUT: - ``j`` -- Any integer. To get the usual representatives - ``j`` should range from ``1`` to ``self.n()-1``. + ``j`` should range from ``1`` to ``self.n()-1``. OUTPUT: The corresponding matrix/element. - The matrix is parabolic if ``j`` is congruent to +-1 modulo ``self.n()``. + + The matrix is parabolic if ``j`` is congruent to `\pm 1` modulo ``self.n()``. It is elliptic if ``j`` is congruent to 0 modulo ``self.n()``. It is hyperbolic otherwise. @@ -560,7 +560,7 @@ def dvalue(self): def is_arithmetic(self) -> bool: r""" - Return True if ``self`` is an arithmetic subgroup. + Return ``True`` if ``self`` is an arithmetic subgroup. EXAMPLES:: @@ -654,9 +654,9 @@ def get_FD(self, z): return (AI, A.acton(z)) - def in_FD(self, z): + def in_FD(self, z) -> bool: r""" - Returns ``True`` if ``z`` lies in the (strict) fundamental + Return ``True`` if ``z`` lies in the (strict) fundamental domain of ``self``. EXAMPLES:: @@ -677,7 +677,7 @@ def root_extension_field(self, D): INPUT: - ``D`` -- An element of the base ring of ``self`` - corresponding to a discriminant. + corresponding to a discriminant. OUTPUT: @@ -744,17 +744,17 @@ def root_extension_embedding(self, D, K=None): INPUT: - ``D`` -- An element of the base ring of ``self`` - corresponding to a discriminant. + corresponding to a discriminant. - ``K`` -- A field to which we want the (correct) embedding. - If ``K=None`` (default) then ``AlgebraicField()`` is - used for positive ``D`` and ``AlgebraicRealField()`` - otherwise. + If ``K=None`` (default) then ``AlgebraicField()`` is + used for positive ``D`` and ``AlgebraicRealField()`` + otherwise. OUTPUT: The corresponding embedding if it was found. - Otherwise a ValueError is raised. + Otherwise a ``ValueError`` is raised. EXAMPLES:: @@ -878,7 +878,8 @@ def _elliptic_conj_reps(self): self._conj_prim[D].append(self.S()) other_reps = [self.U()**k - for k in range(-(self.n() - 1) // 2, self.n() // 2 + 1) + for k in range(-((self.n() - 1) / 2).floor(), + self.n() // 2 + 1) if k not in [0, 1]] for v in other_reps: @@ -984,8 +985,8 @@ def _conjugacy_representatives(self, max_block_length=0, D=None): # # We set it here to ensure that 0 is enlisted as a discriminant... # - self._conj_prim[ZZ(0)] = [] - self._conj_prim[ZZ(0)].append(self.V(self.n()-1)) + self._conj_prim[ZZ.zero()] = [] + self._conj_prim[ZZ.zero()].append(self.V(self.n()-1)) self._elliptic_conj_reps() @@ -1066,10 +1067,10 @@ def class_representatives(self, D, primitive=True): INPUT: - ``D`` -- An element of the base ring corresponding - to a valid discriminant. + to a valid discriminant. - ``primitive`` -- If ``True`` (default) then only primitive - representatives are considered. + representatives are considered. EXAMPLES:: @@ -1151,10 +1152,10 @@ def class_number(self, D, primitive=True): INPUT: - ``D`` -- An element of the base ring corresponding - to a valid discriminant. + to a valid discriminant. - ``primitive`` -- If ``True`` (default) then only primitive - elements are considered. + elements are considered. EXAMPLES:: @@ -1191,9 +1192,9 @@ def class_number(self, D, primitive=True): else: return num - def is_discriminant(self, D, primitive=True): + def is_discriminant(self, D, primitive=True) -> bool: r""" - Returns whether ``D`` is a discriminant of an element of ``self``. + Return whether ``D`` is a discriminant of an element of ``self``. Note: Checking that something isn't a discriminant takes much longer than checking for valid discriminants. @@ -1203,7 +1204,7 @@ def is_discriminant(self, D, primitive=True): - ``D`` -- An element of the base ring. - ``primitive`` -- If ``True`` (default) then only primitive - elements are considered. + elements are considered. OUTPUT: @@ -1243,22 +1244,22 @@ def is_discriminant(self, D, primitive=True): def list_discriminants(self, D, primitive=True, hyperbolic=True, incomplete=False): r""" - Returns a list of all discriminants up to some upper bound ``D``. + Return a list of all discriminants up to some upper bound ``D``. INPUT: - ``D`` -- An element/discriminant of the base ring or - more generally an upper bound for the discriminant. + more generally an upper bound for the discriminant. - ``primitive`` -- If ``True`` (default) then only primitive - discriminants are listed. + discriminants are listed. - ``hyperbolic`` -- If ``True`` (default) then only positive - discriminants are listed. + discriminants are listed. - - ``incomplete`` -- If ``True`` (default: ``False``) then all (also higher) - discriminants which were gathered so far are listed - (however there might be missing discriminants inbetween). + - ``incomplete`` -- If ``True`` (default: ``False``) then all + (also higher) discriminants which were gathered so far are listed + (however there might be missing discriminants inbetween). OUTPUT: @@ -1287,17 +1288,18 @@ def list_discriminants(self, D, primitive=True, hyperbolic=True, incomplete=Fals else: max_D = coerce_AA(D) - L = [] if hyperbolic: - L += [key for key in self._conj_prim if coerce_AA(key) > 0 and coerce_AA(key) <= max_D] + L = [key for key in self._conj_prim if 0 < coerce_AA(key) <= max_D] else: - L += [key for key in self._conj_prim if coerce_AA(key) <= max_D] + L = [key for key in self._conj_prim if coerce_AA(key) <= max_D] if not primitive: if hyperbolic: - L += [key for key in self._conj_nonprim if coerce_AA(key) > 0 and coerce_AA(key) <= max_D and key not in L] + L += [key for key in self._conj_nonprim + if 0 < coerce_AA(key) <= max_D and key not in L] else: - L += [key for key in self._conj_nonprim if coerce_AA(key) <= max_D and key not in L] + L += [key for key in self._conj_nonprim + if coerce_AA(key) <= max_D and key not in L] return sorted(L, key=coerce_AA) @@ -1305,10 +1307,11 @@ def list_discriminants(self, D, primitive=True, hyperbolic=True, incomplete=Fals def reduced_elements(self, D): r""" Return all reduced (primitive) elements of discriminant ``D``. - Also see the element method ``is_reduced()`` for more information. + + Also see the element method :meth:`is_reduced` for more information. - ``D`` -- An element of the base ring corresponding - to a valid discriminant. + to a valid discriminant. EXAMPLES:: @@ -1341,6 +1344,7 @@ def reduced_elements(self, D): def simple_elements(self, D): r""" Return all simple elements of discriminant ``D``. + Also see the element method ``is_simple()`` for more information. - ``D`` -- An element of the base ring corresponding @@ -1371,16 +1375,19 @@ def simple_elements(self, D): def rational_period_functions(self, k, D): r""" Return a list of basic rational period functions of weight ``k`` for discriminant ``D``. - The list is expected to be a generating set for all rational period functions of the - given weight and discriminant (unknown). + + The list is expected to be a generating set for all rational + period functions of the given weight and discriminant (unknown). The method assumes that ``D > 0``. + Also see the element method `rational_period_function` for more information. - - ``k`` -- An even integer, the desired weight of the rational period functions. + - ``k`` -- An even integer, the desired weight + of the rational period functions. - ``D`` -- An element of the base ring corresponding - to a valid discriminant. + to a valid discriminant. EXAMPLES:: From a12b961a6ef4aee8bc8321998bf9a8253cddbdcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 5 Jun 2023 14:45:18 +0200 Subject: [PATCH 081/205] little refreshment of code in Weyl groups --- src/sage/combinat/root_system/weyl_group.py | 98 ++++++++++----------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/src/sage/combinat/root_system/weyl_group.py b/src/sage/combinat/root_system/weyl_group.py index 6842f0467fa..079f0f8475e 100644 --- a/src/sage/combinat/root_system/weyl_group.py +++ b/src/sage/combinat/root_system/weyl_group.py @@ -185,7 +185,7 @@ def WeylGroup(x, prefix=None, implementation='matrix'): TESTS:: sage: TestSuite(WeylGroup(["A",3])).run() - sage: TestSuite(WeylGroup(["A",3,1])).run() # long time + sage: TestSuite(WeylGroup(["A",2,1])).run() # long time sage: W = WeylGroup(['A',3,1]) sage: s = W.simple_reflections() @@ -199,7 +199,7 @@ def WeylGroup(x, prefix=None, implementation='matrix'): """ if implementation == "permutation": return WeylGroup_permutation(x, prefix) - elif implementation != "matrix": + if implementation != "matrix": raise ValueError("invalid implementation") if x in RootLatticeRealizations: @@ -230,6 +230,10 @@ def __init__(self, domain, prefix): sage: cm = CartanMatrix([[2,-5,0],[-2,2,-1],[0,-1,2]]) sage: W = WeylGroup(cm) sage: TestSuite(W).run() # long time + + TESTS:: + + sage: W = WeylGroup(SymmetricGroup(1)) """ self._domain = domain if self.cartan_type().is_affine(): @@ -247,7 +251,10 @@ def __init__(self, domain, prefix): gens_matrix = [self.morphism_matrix(self.domain().simple_reflection(i)) for i in self.index_set()] from sage.libs.gap.libgap import libgap - libgap_group = libgap.Group(gens_matrix) + if not gens_matrix: + libgap_group = libgap.Group([], 1) + else: + libgap_group = libgap.Group(gens_matrix) degree = ZZ(self.domain().dimension()) ring = self.domain().base_ring() FinitelyGeneratedMatrixGroup_gap.__init__( @@ -284,8 +291,9 @@ def index_set(self): # Should be implemented in (morphisms of) modules with basis def morphism_matrix(self, f): - return matrix(self.domain().base_ring(), [f(b).to_vector() - for b in self.domain().basis()]).transpose() + return matrix(self.domain().base_ring(), + [f(b).to_vector() + for b in self.domain().basis()]).transpose() def from_morphism(self, f): return self._element_constructor_(self.morphism_matrix(f)) @@ -396,10 +404,10 @@ def _repr_(self): sage: WeylGroup(['A', 3, 1]) Weyl Group of type ['A', 3, 1] (as a matrix group acting on the root space) """ - return "Weyl Group of type %s (as a matrix group acting on the %s)" % (self.cartan_type(), - self._domain._name_string(capitalize=False, - base_ring=False, - type=False)) + domain = self._domain._name_string(capitalize=False, + base_ring=False, + type=False) + return "Weyl Group of type %s (as a matrix group acting on the %s)" % (self.cartan_type(), domain) def character_table(self): """ @@ -504,19 +512,19 @@ def long_element_hardcoded(self): sage: all(WeylGroup(t).long_element() == WeylGroup(t).long_element_hardcoded() for t in types) # long time (17s on sage.math, 2011) True """ - type = self.cartan_type() - if type[0] == 'D' and type[1] % 2: + typ = self.cartan_type() + if typ[0] == 'D' and typ[1] % 2: l = [-1 for i in range(self.n - 1)] l.append(1) m = diagonal_matrix(QQ, l) - elif type[0] == 'A': + elif typ[0] == 'A': l = [0 for k in range((self.n)**2)] for k in range(self.n - 1, (self.n)**2 - 1, self.n - 1): l[k] = 1 m = matrix(QQ, self.n, l) - elif type[0] == 'E': - if type[1] == 6: - half = ZZ(1) / ZZ(2) + elif typ[0] == 'E': + if typ[1] == 6: + half = QQ((1, 2)) l = [[-half, -half, -half, half, 0, 0, 0, 0], [-half, -half, half, -half, 0, 0, 0, 0], [-half, half, -half, -half, 0, 0, 0, 0], @@ -528,15 +536,15 @@ def long_element_hardcoded(self): m = matrix(QQ, 8, l) else: raise NotImplementedError("not implemented yet for this type") - elif type[0] == 'G': - third = ZZ(1) / ZZ(3) - twothirds = ZZ(2) / ZZ(3) + elif typ[0] == 'G': + third = QQ((1, 3)) + twothirds = QQ((2, 3)) l = [[-third, twothirds, twothirds], [twothirds, -third, twothirds], [twothirds, twothirds, -third]] m = matrix(QQ, 3, l) else: - m = diagonal_matrix([-1 for i in range(self.n)]) + m = diagonal_matrix([-1 for _ in range(self.n)]) return self(m) def classical(self): @@ -643,9 +651,9 @@ def __repr__(self): Parabolic Subgroup of the Weyl Group of type ['C', 4, 1]^* (as a matrix group acting on the coweight lattice) """ return "Parabolic Subgroup of the Weyl Group of type %s (as a matrix group acting on the %s)" % (self.domain().cartan_type(), - self._domain._name_string(capitalize=False, - base_ring=False, - type=False)) + self._domain._name_string(capitalize=False, + base_ring=False, + type=False)) def weyl_group(self, prefix="hereditary"): """ @@ -740,15 +748,14 @@ def _repr_(self): """ if self._parent._prefix is None: return MatrixGroupElement_gap._repr_(self) - else: - redword = self.reduced_word() - if len(redword) == 0: - return "1" - else: - ret = "" - for i in redword[:-1]: - ret += "%s%d*" % (self._parent._prefix, i) - return ret + "%s%d" % (self._parent._prefix, redword[-1]) + + redword = self.reduced_word() + if len(redword) == 0: + return "1" + + ret = "".join("%s%d*" % (self._parent._prefix, i) + for i in redword[:-1]) + return ret + "%s%d" % (self._parent._prefix, redword[-1]) def _latex_(self): r""" @@ -771,13 +778,12 @@ def _latex_(self): """ if self._parent._prefix is None: return MatrixGroupElement_gap._latex_(self) - else: - redword = self.reduced_word() - if not redword: - return "1" - else: - return "".join("%s_{%d}" % (self._parent._prefix, i) - for i in redword) + + redword = self.reduced_word() + if not redword: + return "1" + + return "".join("%s_{%d}" % (self._parent._prefix, i) for i in redword) def __eq__(self, other): """ @@ -849,7 +855,7 @@ def action(self, v): # Descents # ####################################################################### - def has_descent(self, i, positive=False, side="right"): + def has_descent(self, i, positive=False, side="right") -> bool: """ Test if ``self`` has a descent at position ``i``. @@ -911,13 +917,12 @@ def has_descent(self, i, positive=False, side="right"): else: use_rho = side == "left" - if use_rho is not (side == "left"): - self = ~self + element = self if use_rho is (side == "left") else ~self if use_rho: - s = self.action(L.rho()).scalar(L.alphacheck()[i]) >= 0 + s = element.action(L.rho()).scalar(L.alphacheck()[i]) >= 0 else: - s = self.action(L.alpha()[i]).is_positive_root() + s = element.action(L.alpha()[i]).is_positive_root() return s is positive @@ -967,12 +972,7 @@ def apply_simple_reflection(self, i, side="right"): s = self.parent().simple_reflections() if side == "right": return self * s[i] - else: - return s[i] * self - -# TODO -# The methods first_descent, descents, reduced_word appear almost verbatim in -# root_lattice_realizations and need to be factored out! + return s[i] * self def to_permutation(self): """ From c7183415f4857ffce8ac92a67d49558c35ad69f9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 07:41:42 -0700 Subject: [PATCH 082/205] Fix up super in doctests --- src/sage/coding/linear_code.py | 2 +- src/sage/coding/linear_code_no_metric.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index 2e98ea967e3..d1d311c4388 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -377,7 +377,7 @@ def __init__(self, base_field, length, default_encoder_name, default_decoder_nam sage: class MyCodeFamily(sage.coding.linear_code.AbstractLinearCode): ....: def __init__(self, field, length, dimension, generator_matrix): - ....: super().__init__(self, field, length, + ....: super().__init__(field, length, ....: "GeneratorMatrix", "Syndrome") ....: self._dimension = dimension ....: self._generator_matrix = generator_matrix diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index 0de2b9db8cc..490165b928c 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -1098,7 +1098,7 @@ class LinearCodeSystematicEncoder(Encoder): sage: class DualRepetitionCode(sage.coding.linear_code.AbstractLinearCode): ....: def __init__(self, field, length): - ....: super().__init__(self,f ield, length, "Systematic", "Syndrome") + ....: super().__init__(field, length, "Systematic", "Syndrome") ....: ....: def parity_check_matrix(self): ....: return Matrix(self.base_field(), [1]*self.length()) @@ -1118,7 +1118,7 @@ class LinearCodeSystematicEncoder(Encoder): sage: class BadCodeFamily(sage.coding.linear_code.AbstractLinearCode): ....: def __init__(self, field, length): - ....: super().__init__(self, field, length, "Systematic", "Syndrome") + ....: super().__init__(field, length, "Systematic", "Syndrome") ....: ....: def _repr_(self): ....: return "I am a badly defined code" From 94ebfeb4594a047bce2a9595606704dc02d9a603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 5 Jun 2023 16:55:43 +0200 Subject: [PATCH 083/205] detail --- src/sage/combinat/root_system/weyl_group.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/root_system/weyl_group.py b/src/sage/combinat/root_system/weyl_group.py index 079f0f8475e..49880e9c340 100644 --- a/src/sage/combinat/root_system/weyl_group.py +++ b/src/sage/combinat/root_system/weyl_group.py @@ -650,10 +650,10 @@ def __repr__(self): sage: RootSystem(['C',4,1]).coweight_lattice().weyl_group().classical() Parabolic Subgroup of the Weyl Group of type ['C', 4, 1]^* (as a matrix group acting on the coweight lattice) """ - return "Parabolic Subgroup of the Weyl Group of type %s (as a matrix group acting on the %s)" % (self.domain().cartan_type(), - self._domain._name_string(capitalize=False, - base_ring=False, - type=False)) + domain = self._domain._name_string(capitalize=False, + base_ring=False, + type=False) + return "Parabolic Subgroup of the Weyl Group of type %s (as a matrix group acting on the %s)" % (self.domain().cartan_type(), domain) def weyl_group(self, prefix="hereditary"): """ From e4d25fb91ad92aa9a465b5786f48fa32a60693b7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 08:04:45 -0700 Subject: [PATCH 084/205] 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 1f18999733198277e282161e6c45abb7ad155e90 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 09:05:11 -0700 Subject: [PATCH 085/205] src/sage/coding/code_bounds.py: Move import into method --- src/sage/coding/code_bounds.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/coding/code_bounds.py b/src/sage/coding/code_bounds.py index da42a63789f..659455408e3 100644 --- a/src/sage/coding/code_bounds.py +++ b/src/sage/coding/code_bounds.py @@ -185,7 +185,6 @@ delsarte_bound_additive_hamming_space) lazy_import('sage.libs.gap.libgap', 'libgap') -lazy_import('sage.rings.real_mpfr', 'RR') def _check_n_q_d(n, q, d, field_based=True): @@ -397,6 +396,7 @@ def plotkin_upper_bound(n,q,d, algorithm=None): return int(d/( d - t*n)) elif d < t*n + 1: fact = (d-1) / t + from sage.rings.real_mpfr import RR if RR(fact)==RR(int(fact)): fact = int(fact) + 1 return int(d/( d - t * fact)) * q**(n - fact) From f4a6ca069587a4132c5efa995f9ec6358b39d547 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 10:18:15 -0700 Subject: [PATCH 086/205] .github/workflows/doc-build.yml: Build incrementally --- .github/workflows/build.yml | 3 ++- .github/workflows/doc-build.yml | 40 +++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ceb2af231ca..a9db05e9641 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,10 +46,11 @@ jobs: set -ex git config --global user.email "ci-sage@example.com" git config --global user.name "Build & Test workflow" + git config --global --add safe.directory $(pwd) # If actions/checkout downloaded our source tree using the GitHub REST API # instead of with git (because do not have git installed in our image), # we first make the source tree a repo. - if [ ! -d .git ]; then git config --global --add safe.directory $(pwd) && git init && git add -A && git commit --quiet -m "new"; fi + if [ ! -d .git ]; then git init && git add -A && git commit --quiet -m "new"; fi # Tag this state of the source tree "new". This is what we want to build and test. git tag -f new # Our container image contains a source tree in /sage with a full build of Sage. diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 4be22210eee..2d0c2303829 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -19,25 +19,51 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Prepare + - name: Update system packages run: | - apt-get update && apt-get install -y zip - # Reuse built SAGE_LOCAL contained in the Docker image - ./bootstrap - ./configure --enable-build-as-root --prefix=/sage/local --with-sage-venv --enable-download-from-upstream-url + apt-get update && apt-get install -y git zip - name: Build - run: make doc-html + run: | + set -ex + git config --global user.email "ci-sage@example.com" + git config --global user.name "Build & Test workflow" + git config --global --add safe.directory $(pwd) + # If actions/checkout downloaded our source tree using the GitHub REST API + # instead of with git (because do not have git installed in our image), + # we first make the source tree a repo. + if [ ! -d .git ]; then git init && git add -A && git commit --quiet -m "new"; fi + # Tag this state of the source tree "new". This is what we want to build and test. + git tag -f new + # Our container image contains a source tree in /sage with a full build of Sage. + # But /sage is not a git repository. + # We make /sage a worktree whose index is at tag "new". + # We then commit the current sources and set the tag "old". (This keeps all mtimes unchanged.) + # Then we update worktree and index with "git reset --hard new". + # (This keeps mtimes of unchanged files unchanged and mtimes of changed files newer than unchanged files.) + # Finally we reset the index to "old". (This keeps all mtimes unchanged.) + # The changed files now show up as uncommitted changes. + git worktree add --detach worktree-image + rm -rf /sage/.git && mv worktree-image/.git /sage/ + rm -rf worktree-image && ln -s /sage worktree-image + (cd worktree-image && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) + # Keep track of changes to built HTML + (cd /sage/local/share/doc/sage/html && git init && git add -A && git commit -m "old") + # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. + (cd worktree-image && ./bootstrap && make doc-html) env: MAKE: make -j2 SAGE_NUM_THREADS: 2 - name: Copy docs run: | + mkdir -p ./docs + # Create changelog + (cd /sage/local/share/doc/sage/html/en && git diff --name-only && rm -rf .git) | tee ./docs/CHANGES.txt + sed -E 's,(.*),

\1,' ./docs/CHANGES.txt > .docs/CHANGES.html # For some reason the deploy step below cannot find /sage/... # So copy everything from there to local folder # We also need to replace the symlinks because netlify is not following them - mkdir -p ./docs cp -r -L /sage/local/share/doc/sage/html/en/* ./docs # Zip everything for increased performance zip -r docs.zip docs 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 087/205] 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 1bc06a524989ae9163786976d70e7ed54663fbc5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 12:08:20 -0700 Subject: [PATCH 088/205] sage.coding: More docstring cosmetics --- src/sage/coding/abstract_code.py | 18 ++++----- src/sage/coding/channel.py | 52 +++++++++++++------------- src/sage/coding/linear_code.py | 63 ++++++++++++++++---------------- 3 files changed, 66 insertions(+), 67 deletions(-) diff --git a/src/sage/coding/abstract_code.py b/src/sage/coding/abstract_code.py index ee4ee619ab0..0eb3c061190 100644 --- a/src/sage/coding/abstract_code.py +++ b/src/sage/coding/abstract_code.py @@ -152,9 +152,9 @@ class AbstractCode(Parent): To implement a code, you need to: - - inherit from AbstractCode + - inherit from :class:`AbstractCode` - - call AbstractCode ``__init__`` method in the subclass constructor. + - call :class:`AbstractCode` ``__init__`` method in the subclass constructor. Example: ``super().__init__(length, "EncoderName", "DecoderName", "metric")``. "EncoderName" and "DecoderName" are set to ``None`` by default, a generic code class such as AbstractCode does @@ -197,7 +197,7 @@ class AbstractCode(Parent): ``MyDecoderClass``. - As AbstractCode is not designed to be implemented, it does not have any + As the class :class:`AbstractCode` is not designed to be instantiated, it does not have any representation methods. You should implement ``_repr_`` and ``_latex_`` methods in the subclass. """ @@ -227,7 +227,7 @@ def __init__(self, length, default_encoder_name=None, EXAMPLES: - The following example demonstrates how to use subclass `AbstractCode` + The following example demonstrates how to use a subclass of ``AbstractCode`` for representing a new family of codes:: sage: from sage.coding.abstract_code import AbstractCode @@ -666,7 +666,7 @@ def add_encoder(self, name, encoder): def decode_to_code(self, word, decoder_name=None, *args, **kwargs): r""" - Corrects the errors in ``word`` and returns a codeword. + Correct the errors in ``word`` and returns a codeword. INPUT: @@ -837,10 +837,10 @@ def decoders_available(self, classes=False): INPUT: - ``classes`` -- (default: ``False``) if ``classes`` is set to ``True``, - return instead a ``dict`` mapping available decoder name to the + return instead a :class:`dict` mapping available decoder name to the associated decoder class. - OUTPUT: a list of strings, or a `dict` mapping strings to classes. + OUTPUT: a list of strings, or a :class:`dict` mapping strings to classes. EXAMPLES:: @@ -1016,10 +1016,10 @@ def encoders_available(self, classes=False): INPUT: - ``classes`` -- (default: ``False``) if ``classes`` is set to ``True``, - return instead a ``dict`` mapping available encoder name to the + return instead a :class:`dict` mapping available encoder name to the associated encoder class. - OUTPUT: a list of strings, or a `dict` mapping strings to classes. + OUTPUT: a list of strings, or a :class:`dict` mapping strings to classes. EXAMPLES:: diff --git a/src/sage/coding/channel.py b/src/sage/coding/channel.py index 8f09e07a038..f467521fe95 100644 --- a/src/sage/coding/channel.py +++ b/src/sage/coding/channel.py @@ -148,9 +148,9 @@ class Channel(SageObject): This abstract class provides the following parameters: - - ``input_space`` -- the space of the words to transmit + - ``input_space`` -- the space of the words to transmit - - ``output_space`` -- the space of the transmitted words + - ``output_space`` -- the space of the transmitted words """ def __init__(self, input_space, output_space): @@ -278,7 +278,7 @@ def transmit_unsafe(self, message): Return ``message``, modified accordingly with the algorithm of the channel it was transmitted through. - This method does not check if ``message`` belongs to the input space of``self``. + This method does not check if ``message`` belongs to the input space of ``self``. This is an abstract method which should be reimplemented in all the subclasses of Channel. @@ -310,7 +310,7 @@ class StaticErrorRateChannel(Channel): EXAMPLES: - We construct a StaticErrorRateChannel which adds 2 errors + We construct a :class:`StaticErrorRateChannel` which adds 2 errors to any transmitted message:: sage: n_err = 2 @@ -368,7 +368,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -384,12 +384,12 @@ def _latex_(self): def transmit_unsafe(self, message): r""" - Returns ``message`` with as many errors as ``self._number_errors`` in it. + Return ``message`` with as many errors as ``self._number_errors`` in it. If ``self._number_errors`` was passed as a tuple for the number of errors, it will pick a random integer between the bounds of the tuple and use it as the number of errors. - This method does not check if ``message`` belongs to the input space of``self``. + This method does not check if ``message`` belongs to the input space of ``self``. INPUT: @@ -430,7 +430,7 @@ def transmit_unsafe(self, message): def number_errors(self): r""" - Returns the number of errors created by ``self``. + Return the number of errors created by ``self``. EXAMPLES:: @@ -447,7 +447,7 @@ class ErrorErasureChannel(Channel): Channel which adds errors and erases several positions in any message it transmits. The output space of this channel is a Cartesian product - between its input space and a VectorSpace of the same dimension over GF(2) + between its input space and a VectorSpace of the same dimension over `\GF{2}`. INPUT: @@ -523,7 +523,7 @@ def __init__(self, space, number_errors, number_erasures): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -542,7 +542,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -561,7 +561,7 @@ def _latex_(self): def transmit_unsafe(self, message): r""" - Returns ``message`` with as many errors as ``self._number_errors`` in it, and as many erasures + Return ``message`` with as many errors as ``self._number_errors`` in it, and as many erasures as ``self._number_erasures`` in it. If ``self._number_errors`` was passed as an tuple for the number of errors, it will @@ -573,7 +573,7 @@ def transmit_unsafe(self, message): the received message will always contains exactly as many errors and erasures as expected. - This method does not check if ``message`` belongs to the input space of``self``. + This method does not check if ``message`` belongs to the input space of ``self``. INPUT: @@ -618,7 +618,7 @@ def transmit_unsafe(self, message): def number_errors(self): r""" - Returns the number of errors created by ``self``. + Return the number of errors created by ``self``. EXAMPLES:: @@ -631,7 +631,7 @@ def number_errors(self): def number_erasures(self): r""" - Returns the number of erasures created by ``self``. + Return the number of erasures created by ``self``. EXAMPLES:: @@ -645,10 +645,10 @@ def number_erasures(self): class QarySymmetricChannel(Channel): r""" - The q-ary symmetric, memoryless communication channel. + The `q`-ary symmetric, memoryless communication channel. Given an alphabet `\Sigma` with `|\Sigma| = q` and an error probability - `\epsilon`, a q-ary symmetric channel sends an element of `\Sigma` into the + `\epsilon`, a `q`-ary symmetric channel sends an element of `\Sigma` into the same element with probability `1 - \epsilon`, and any one of the other `q - 1` elements with probability `\frac{\epsilon}{q - 1}`. This implementation operates over vectors in `\Sigma^n`, and "transmits" each element of the @@ -666,13 +666,13 @@ class QarySymmetricChannel(Channel): INPUT: - ``space`` -- the input and output space of the channel. It has to be - `GF(q)^n` for some finite field `GF(q)`. + `\GF{q}^n` for some finite field `\GF{q}`. - ``epsilon`` -- the transmission error probability of the individual elements. EXAMPLES: - We construct a QarySymmetricChannel which corrupts 30% of all transmitted + We construct a :class:`QarySymmetricChannel` which corrupts 30% of all transmitted symbols:: sage: epsilon = 0.3 @@ -714,7 +714,7 @@ def __init__(self, space, epsilon): def __repr__(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -729,7 +729,7 @@ def __repr__(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -744,10 +744,10 @@ def _latex_(self): def transmit_unsafe(self, message): r""" - Returns ``message`` where each of the symbols has been changed to another from the alphabet with + Return ``message`` where each of the symbols has been changed to another from the alphabet with probability :meth:`error_probability`. - This method does not check if ``message`` belongs to the input space of``self``. + This method does not check if ``message`` belongs to the input space of ``self``. INPUT: @@ -777,7 +777,7 @@ def transmit_unsafe(self, message): def error_probability(self): r""" - Returns the error probability of a single symbol transmission of + Return the error probability of a single symbol transmission of ``self``. EXAMPLES:: @@ -791,7 +791,7 @@ def error_probability(self): def probability_of_exactly_t_errors(self, t): r""" - Returns the probability ``self`` has to return + Return the probability ``self`` has to return exactly ``t`` errors. INPUT: @@ -811,7 +811,7 @@ def probability_of_exactly_t_errors(self, t): def probability_of_at_most_t_errors(self, t): r""" - Returns the probability ``self`` has to return + Return the probability ``self`` has to return at most ``t`` errors. INPUT: diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index d1d311c4388..754b97c25dc 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -298,9 +298,9 @@ class AbstractLinearCode(AbstractLinearCodeNoMetric): To implement a linear code, you need to: - - inherit from AbstractLinearCode + - inherit from :class:`AbstractLinearCode` - - call AbstractLinearCode ``__init__`` method in the subclass constructor. Example: + - call :class:`AbstractLinearCode` ``__init__`` method in the subclass constructor. Example: ``super().__init__(base_field, length, "EncoderName", "DecoderName")``. By doing that, your subclass will have its ``length`` parameter initialized and will be properly set as a member of the category framework. @@ -328,7 +328,7 @@ class AbstractLinearCode(AbstractLinearCodeNoMetric): ``MyNewCodeClass`` will be able to use instances of ``MyDecoderClass``. - As AbstractLinearCode is not designed to be implemented, it does not have any representation + As the class :class:`AbstractLinearCode` is not designed to be instantiated, it does not have any representation methods. You should implement ``_repr_`` and ``_latex_`` methods in the subclass. .. NOTE:: @@ -578,7 +578,7 @@ def assmus_mattson_designs(self, t, mode=None): `C=C^*` in this case, so this info is extraneous). The test fails to produce 6-designs (ie, the hypotheses of the theorem fail to hold, not that the 6-designs definitely don't exist). The command - assmus_mattson_designs(C,5,mode="verbose") returns the same value + ``assmus_mattson_designs(C,5,mode="verbose")`` returns the same value but prints out more detailed information. The second example below illustrates the blocks of the 5-(24, 8, 1) @@ -588,17 +588,14 @@ def assmus_mattson_designs(self, t, mode=None): sage: C = codes.GolayCode(GF(2)) # example 1 sage: C.assmus_mattson_designs(5) - ['weights from C: ', - [8, 12, 16, 24], - 'designs from C: ', - [[5, (24, 8, 1)], [5, (24, 12, 48)], [5, (24, 16, 78)], [5, (24, 24, 1)]], - 'weights from C*: ', - [8, 12, 16], - 'designs from C*: ', - [[5, (24, 8, 1)], [5, (24, 12, 48)], [5, (24, 16, 78)]]] + ['weights from C: ', [8, 12, 16, 24], + 'designs from C: ', [[5, (24, 8, 1)], [5, (24, 12, 48)], [5, (24, 16, 78)], + [5, (24, 24, 1)]], + 'weights from C*: ', [8, 12, 16], + 'designs from C*: ', [[5, (24, 8, 1)], [5, (24, 12, 48)], [5, (24, 16, 78)]]] sage: C.assmus_mattson_designs(6) 0 - sage: X = range(24) # example 2 + sage: X = range(24) # example 2 sage: blocks = [c.support() for c in C if c.hamming_weight()==8]; len(blocks) # long time computation 759 """ @@ -648,7 +645,7 @@ def binomial_moment(self, i): where `k_S` is the dimension of the shortened code `C_{J-S}`, `J=[1,2,...,n]`. (The normalized binomial moment is - `b_i(C) = \binom(n,d+i)^{-1}B_{d+i}(C)`.) In other words, `C_{J-S}` + `b_i(C) = \binom{n}{d+i})^{-1}B_{d+i}(C)`.) In other words, `C_{J-S}` is isomorphic to the subcode of C of codewords supported on S. EXAMPLES:: @@ -746,11 +743,11 @@ def canonical_representative(self, equivalence="semilinear"): - ``equivalence`` (optional) -- which defines the acting group, either - * ``"permutational"`` + * ``"permutational"`` - * ``"linear"`` + * ``"linear"`` - * ``"semilinear"`` + * ``"semilinear"`` OUTPUT: @@ -1353,9 +1350,11 @@ def minimum_distance(self, algorithm=None): INPUT: - ``algorithm`` -- (default: ``None``) the name of the algorithm to use - to perform minimum distance computation. If set to ``None``, - GAP methods will be used. ``algorithm`` can be: - - ``"Guava"``, which will use optional GAP package Guava + to perform minimum distance computation. ``algorithm`` can be: + + - ``None``, to use GAP methods (but not Guava) + + - ``"Guava"``, to use the optional GAP package Guava OUTPUT: @@ -1782,7 +1781,7 @@ def shortened(self, L): INPUT: - - ``L`` - Subset of `\{1,...,n\}`, where `n` is the length of this code + - ``L`` -- Subset of `\{1,...,n\}`, where `n` is the length of this code OUTPUT: @@ -1808,8 +1807,8 @@ def weight_distribution(self, algorithm=None): INPUT: - - ``algorithm`` - (optional, default: ``None``) If set to ``"gap"``, - call GAP. If set to `"leon"`, call the option GAP package GUAVA and + - ``algorithm`` -- (optional, default: ``None``) If set to ``"gap"``, + call GAP. If set to ``"leon"``, call the option GAP package GUAVA and call a function therein by Jeffrey Leon (see warning below). If set to ``"binary"``, use an algorithm optimized for binary codes. The default is to use ``"binary"`` for binary codes and ``"gap"`` otherwise. @@ -1820,7 +1819,7 @@ def weight_distribution(self, algorithm=None): .. WARNING:: - Specifying ``algorithm = "leon"`` sometimes prints a traceback + Specifying ``algorithm="leon"`` sometimes prints a traceback related to a stack smashing error in the C library. The result appears to be computed correctly, however. It appears to run much faster than the GAP algorithm in small examples and much slower than @@ -1848,11 +1847,11 @@ def weight_distribution(self, algorithm=None): [1, 0, 0, 7, 7, 0, 0, 1] sage: C = codes.HammingCode(GF(3), 3); C [13, 10] Hamming Code over GF(3) - sage: C.weight_distribution() == C.weight_distribution(algorithm="leon") # optional - gap_packages (Guava package) + sage: C.weight_distribution() == C.weight_distribution(algorithm="leon") # optional - gap_packages (Guava package) True sage: C = codes.HammingCode(GF(5), 2); C [6, 4] Hamming Code over GF(5) - sage: C.weight_distribution() == C.weight_distribution(algorithm="leon") # optional - gap_packages (Guava package) + sage: C.weight_distribution() == C.weight_distribution(algorithm="leon") # optional - gap_packages (Guava package) True sage: C = codes.HammingCode(GF(7), 2); C [8, 6] Hamming Code over GF(7) @@ -1904,7 +1903,7 @@ def weight_distribution(self, algorithm=None): def support(self): r""" Return the set of indices `j` where `A_j` is nonzero, where - `A_j` is the number of codewords in `self` of Hamming weight `j`. + `A_j` is the number of codewords in ``self`` of Hamming weight `j`. OUTPUT: @@ -1928,7 +1927,7 @@ def weight_enumerator(self, names=None, bivariate=True): Return the weight enumerator polynomial of ``self``. This is the bivariate, homogeneous polynomial in `x` and `y` whose - coefficient to `x^i y^{n-i}` is the number of codewords of `self` of + coefficient to `x^i y^{n-i}` is the number of codewords of ``self`` of Hamming weight `i`. Here, `n` is the length of ``self``. INPUT: @@ -1937,7 +1936,7 @@ def weight_enumerator(self, names=None, bivariate=True): homogeneous polynomial. Can be given as a single string of length 2, or a single string with a comma, or as a tuple or list of two strings. - - ``bivariate`` -- (default: `True`) Whether to return a bivariate, + - ``bivariate`` -- (default: ``True``) Whether to return a bivariate, homogeneous polynomial or just a univariate polynomial. If set to ``False``, then ``names`` will be interpreted as a single variable name and default to ``"x"``. @@ -2003,9 +2002,9 @@ def zeta_polynomial(self, name="T"): sage: C.zeta_polynomial() 2/5*T^2 + 2/5*T + 1/5 sage: C = codes.databases.best_linear_code_in_guava(6,3,GF(2)) # optional - gap_packages (Guava package) - sage: C.minimum_distance() # optional - gap_packages (Guava package) + sage: C.minimum_distance() # optional - gap_packages (Guava package) 3 - sage: C.zeta_polynomial() # optional - gap_packages (Guava package) + sage: C.zeta_polynomial() # optional - gap_packages (Guava package) 2/5*T^2 + 2/5*T + 1/5 sage: C = codes.HammingCode(GF(2), 4) sage: C.zeta_polynomial() @@ -2198,7 +2197,7 @@ class LinearCode(AbstractLinearCode): minimum distance, will use generic, slow algorithms. If you are looking for constructing a code from a more specific family, see - if the family has been implemented by investigating `codes.`. These + if the family has been implemented by investigating ``codes.``. These more specific classes use properties particular to that family to allow faster algorithms, and could also have family-specific methods. 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 089/205] 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 d6cacb80a79267e5f1e64f48af43ac545d13a525 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 12:51:06 -0700 Subject: [PATCH 090/205] sage.coding: Even more docstring cosmetics --- src/sage/coding/bch_code.py | 32 ++++---- src/sage/coding/bounds_catalog.py | 8 +- src/sage/coding/channels_catalog.py | 6 +- src/sage/coding/codes_catalog.py | 6 +- src/sage/coding/cyclic_code.py | 2 +- src/sage/coding/decoder.py | 4 +- src/sage/coding/decoders_catalog.py | 7 +- src/sage/coding/encoders_catalog.py | 6 +- src/sage/coding/grs_code.py | 28 +++---- src/sage/coding/hamming_code.py | 2 +- src/sage/coding/kasami_codes.pyx | 18 ++-- src/sage/coding/linear_code_no_metric.py | 18 ++-- src/sage/coding/linear_rank_metric.py | 100 +++++++++++------------ src/sage/coding/parity_check_code.py | 4 +- src/sage/coding/reed_muller_code.py | 61 +++++++------- 15 files changed, 144 insertions(+), 158 deletions(-) diff --git a/src/sage/coding/bch_code.py b/src/sage/coding/bch_code.py index 804bae41349..40fa088354a 100644 --- a/src/sage/coding/bch_code.py +++ b/src/sage/coding/bch_code.py @@ -2,7 +2,7 @@ r""" BCH code -Let `F = GF(q)` and `\Phi` be the splitting field of `x^{n} - 1` over `F`, with +Let `F = \GF{q}` and `\Phi` be the splitting field of `x^{n} - 1` over `F`, with `n` a positive integer. Let also `\alpha` be an element of multiplicative order `n` in `\Phi`. Finally, let `b, \delta, \ell` be integers such that `0 \le b \le n`, `1 \le \delta \le n` and `\alpha^\ell` generates the multiplicative @@ -52,7 +52,7 @@ class BCHCode(CyclicCode): splitting field. It has to be of multiplicative order ``length`` over this field. If the splitting field is not ``field``, it also has to be a polynomial in ``zx``, where ``x`` is the degree of the extension field. - For instance, over `GF(16)`, it has to be a polynomial in ``z4``. + For instance, over `\GF{16}`, it has to be a polynomial in ``z4``. - ``offset`` -- (default: ``1``) the first element in the defining set @@ -80,7 +80,7 @@ class BCHCode(CyclicCode): sage: C.generator_polynomial() x^8 + x^7 + x^6 + x^4 + 1 - BCH codes are cyclic, and can be interfaced into the CyclicCode class. + BCH codes are cyclic, and can be interfaced into the :class:`CyclicCode` class. The smallest GRS code which contains a given BCH code can also be computed, and these two codes may be equal:: @@ -159,7 +159,7 @@ def __eq__(self, other): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -173,7 +173,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -187,7 +187,7 @@ def _latex_(self): def jump_size(self): r""" - Returns the jump size between two consecutive elements of the defining + Return the jump size between two consecutive elements of the defining set of ``self``. EXAMPLES:: @@ -200,7 +200,7 @@ def jump_size(self): def offset(self): r""" - Returns the offset which was used to compute the elements in + Return the offset which was used to compute the elements in the defining set of ``self``. EXAMPLES:: @@ -213,7 +213,7 @@ def offset(self): def designed_distance(self): r""" - Returns the designed distance of ``self``. + Return the designed distance of ``self``. EXAMPLES:: @@ -225,7 +225,7 @@ def designed_distance(self): def bch_to_grs(self): r""" - Returns the underlying GRS code from which ``self`` was derived. + Return the underlying GRS code from which ``self`` was derived. EXAMPLES:: @@ -287,7 +287,7 @@ def __init__(self, code, grs_decoder="KeyEquationSyndrome", **kwargs): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -300,7 +300,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -314,7 +314,7 @@ def _latex_(self): def grs_code(self): r""" - Returns the underlying GRS code of :meth:`sage.coding.decoder.Decoder.code`. + Return the underlying GRS code of :meth:`sage.coding.decoder.Decoder.code`. .. NOTE:: @@ -367,7 +367,7 @@ def grs_code(self): def grs_decoder(self): r""" - Returns the decoder used to decode words of :meth:`grs_code`. + Return the decoder used to decode words of :meth:`grs_code`. EXAMPLES:: @@ -380,7 +380,7 @@ def grs_decoder(self): def bch_word_to_grs(self, c): r""" - Returns ``c`` converted as a codeword of :meth:`grs_code`. + Return ``c`` converted as a codeword of :meth:`grs_code`. EXAMPLES:: @@ -398,7 +398,7 @@ def bch_word_to_grs(self, c): def grs_word_to_bch(self, c): r""" - Returns ``c`` converted as a codeword of :meth:`sage.coding.decoder.Decoder.code`. + Return ``c`` converted as a codeword of :meth:`sage.coding.decoder.Decoder.code`. EXAMPLES:: @@ -473,7 +473,7 @@ def decode_to_code(self, y): def decoding_radius(self): r""" - Returns maximal number of errors that ``self`` can decode. + Return maximal number of errors that ``self`` can decode. EXAMPLES:: diff --git a/src/sage/coding/bounds_catalog.py b/src/sage/coding/bounds_catalog.py index 25d422afee7..aa4c2dd9996 100644 --- a/src/sage/coding/bounds_catalog.py +++ b/src/sage/coding/bounds_catalog.py @@ -1,15 +1,13 @@ r""" Index of bounds on the parameters of codes -The ``codes.bounds`` object may be used to access the bounds that Sage can compute. +The :obj:`codes.bounds` object may be used to access the bounds that Sage can compute. {INDEX_OF_FUNCTIONS} -.. NOTE:: +To import these names into the global namespace, use:: - To import these names into the global namespace, use: - - sage: from sage.coding.bounds_catalog import * + sage: from sage.coding.bounds_catalog import * """ from sage.misc.lazy_import import lazy_import as _lazy_import _lazy_import("sage.coding.code_bounds", ["codesize_upper_bound", diff --git a/src/sage/coding/channels_catalog.py b/src/sage/coding/channels_catalog.py index ed3aa0ce6c2..b121fe847d8 100644 --- a/src/sage/coding/channels_catalog.py +++ b/src/sage/coding/channels_catalog.py @@ -9,11 +9,9 @@ - :class:`channel.QarySymmetricChannel ` - :class:`channel.StaticErrorRateChannel ` -.. NOTE:: +To import these names into the global namespace, use:: - To import these names into the global namespace, use: - - sage: from sage.coding.channels_catalog import * + sage: from sage.coding.channels_catalog import * """ #***************************************************************************** diff --git a/src/sage/coding/codes_catalog.py b/src/sage/coding/codes_catalog.py index 9535d364ce7..96021d5fdd3 100644 --- a/src/sage/coding/codes_catalog.py +++ b/src/sage/coding/codes_catalog.py @@ -57,11 +57,9 @@ :meth:`~sage.coding.extended_code.ExtendedCode` @ Extended codes :meth:`~sage.coding.punctured_code.PuncturedCode` @ Puncturedcodes -.. NOTE:: +To import these names into the global namespace, use:: - To import these names into the global namespace, use: - - sage: from sage.coding.codes_catalog import * + sage: from sage.coding.codes_catalog import * """ #***************************************************************************** diff --git a/src/sage/coding/cyclic_code.py b/src/sage/coding/cyclic_code.py index a87c0595273..38894321459 100644 --- a/src/sage/coding/cyclic_code.py +++ b/src/sage/coding/cyclic_code.py @@ -257,7 +257,7 @@ class CyclicCode(AbstractLinearCode): EXAMPLES: - We can construct a CyclicCode object using three different methods. + We can construct a :class:`CyclicCode` object using three different methods. First (1), we provide a generator polynomial and a code length:: sage: F. = GF(2)[] diff --git a/src/sage/coding/decoder.py b/src/sage/coding/decoder.py index 2f92bb5c9b8..94fc99cdeef 100644 --- a/src/sage/coding/decoder.py +++ b/src/sage/coding/decoder.py @@ -107,7 +107,7 @@ def decoder_type(cls): sage: codes.decoders.LinearCodeSyndromeDecoder.decoder_type() {'dynamic', 'hard-decision'} - We can also call it on a instance of a Decoder class:: + We can also call it on a instance of a :class:`Decoder` class:: sage: G = Matrix(GF(2), [[1, 0, 0, 1], [0, 1, 1, 1]]) sage: C = LinearCode(G) @@ -223,7 +223,7 @@ def __ne__(self, other): def decode_to_code(self, r): r""" - Correct the errors in ``r`` and returns a codeword. + Correct the errors in ``r`` and return a codeword. This is a default implementation which assumes that the method :meth:`decode_to_message` has been implemented, else it returns an exception. diff --git a/src/sage/coding/decoders_catalog.py b/src/sage/coding/decoders_catalog.py index a95912e51b6..a9f2417880e 100644 --- a/src/sage/coding/decoders_catalog.py +++ b/src/sage/coding/decoders_catalog.py @@ -12,6 +12,7 @@ - :class:`extended_code.ExtendedCodeOriginalCodeDecoder ` **Subfield subcode decoder** + - :class:`subfield_subcode.SubfieldSubcodeOriginalCodeDecoder ` **Generalized Reed-Solomon code decoders** @@ -45,11 +46,9 @@ - :class:`ag_code_decoders.EvaluationAGCodeUniqueDecoder ` - :class:`ag_code_decoders.DifferentialAGCodeUniqueDecoder ` -.. NOTE:: - - To import these names into the global namespace, use: +To import these names into the global namespace, use:: - sage: from sage.coding.decoders_catalog import * + sage: from sage.coding.decoders_catalog import * """ #***************************************************************************** # Copyright (C) 2009 David Joyner diff --git a/src/sage/coding/encoders_catalog.py b/src/sage/coding/encoders_catalog.py index 9435f72ee33..e6ac68267fd 100644 --- a/src/sage/coding/encoders_catalog.py +++ b/src/sage/coding/encoders_catalog.py @@ -26,11 +26,9 @@ - :class:`punctured_code.PuncturedCodePuncturedMatrixEncoder ` -.. NOTE:: +To import these names into the global namespace, use:: - To import these names into the global namespace, use: - - sage: from sage.coding.encoders_catalog import * + sage: from sage.coding.encoders_catalog import * """ #***************************************************************************** # Copyright (C) 2009 David Joyner diff --git a/src/sage/coding/grs_code.py b/src/sage/coding/grs_code.py index 3ec7ee30092..851ef91faf2 100644 --- a/src/sage/coding/grs_code.py +++ b/src/sage/coding/grs_code.py @@ -8,9 +8,9 @@ .. MATH:: - \{ f(\alpha_1), \ldots, f(\alpha_n) \mid f \in F[x], \deg f < k \} + \{ (f(\alpha_1), \ldots, f(\alpha_n)) \mid f \in F[x], \deg f < k \} -An RS code is often called "classical" if `alpha_i = \alpha^{i-1}` and `\alpha` +An RS code is often called "classical" if `\alpha_i = \alpha^{i-1}` and `\alpha` is a primitive `n`'th root of unity. More generally, given also `n` "column multipliers" `\beta_1, \dots, \beta_n`, @@ -19,7 +19,7 @@ .. MATH:: - \{ (\beta_1 f(\alpha_1), \ldots, \beta_n f(\alpha_n) + \{ (\beta_1 f(\alpha_1), \ldots, \beta_n f(\alpha_n)) \mid f \in F[x], \deg f < k \} Here is a list of all content related to GRS codes: @@ -665,13 +665,13 @@ class GRSEvaluationVectorEncoder(Encoder): .. MATH:: - p = \Sigma_{i=1}^{m} m_i \times x^i. + p = \Sigma_{i=1}^{m} m_i x^i. The encoding of `m` will be the following codeword: .. MATH:: - (\beta_1 \times p(\alpha_1), \dots, \beta_n \times p(\alpha_n)). + (\beta_1 p(\alpha_1), \dots, \beta_n p(\alpha_n)). INPUT: @@ -768,7 +768,7 @@ def generator_matrix(self): .. MATH:: - G = [g_{i,j}], g_{i,j} = \beta_j \times \alpha_{j}^{i}. + G = [g_{i,j}], g_{i,j} = \beta_j \alpha_{j}^{i}. This matrix is a Vandermonde matrix. @@ -807,7 +807,7 @@ class GRSEvaluationPolynomialEncoder(Encoder): .. MATH:: - (\beta_1 \times p(\alpha_1), \dots, \beta_n \times p(\alpha_n)). + (\beta_1 p(\alpha_1), \dots, \beta_n p(\alpha_n)). INPUT: @@ -1543,7 +1543,7 @@ def _partial_xgcd(self, a, b, PolRing): Performs an Euclidean algorithm on ``a`` and ``b`` until a remainder has degree less than `\frac{n+k}{2}`, `n` being the dimension of the code, `k` its dimension, and returns `(r, s)` such that in the step - just before termination, `r = a\times s + b\times t`. + just before termination, `r = a s + b t`. INPUT: @@ -1899,11 +1899,11 @@ def decode_to_message(self, word_and_erasure_vector): INPUT: - - word_and_erasure_vector -- a tuple whose: + - ``word_and_erasure_vector`` -- a tuple whose: * first element is an element of the ambient space of the code * second element is a vector over `\GF{2}` whose length is the - same as the code's + same as the code's, containing erasure positions .. NOTE:: @@ -1915,12 +1915,6 @@ def decode_to_message(self, word_and_erasure_vector): In either case, if ``r`` is not a codeword, the output is unspecified. - INPUT: - - - ``word_and_erasure_vector`` -- a pair of vectors, where - first element is a codeword of ``self`` and second element - is a vector of GF(2) containing erasure positions - OUTPUT: - a vector of ``self`` message space @@ -2140,7 +2134,7 @@ def _partial_xgcd(self, a, b, PolRing): Performs an Euclidean algorithm on ``a`` and ``b`` until a remainder has degree less than `\frac{n+k}{2}`, `n` being the dimension of the code, `k` its dimension, and returns `(r, t)` such that in the step - just before termination, `r = a\times s + b\times t`. + just before termination, `r = a s + b t`. INPUT: diff --git a/src/sage/coding/hamming_code.py b/src/sage/coding/hamming_code.py index 4d63c0409c4..5209a0c3754 100644 --- a/src/sage/coding/hamming_code.py +++ b/src/sage/coding/hamming_code.py @@ -2,7 +2,7 @@ r""" Hamming codes -Given an integer `r` and a field `F`, such that `F=GF(q)`, the `[n, k, d]` code +Given an integer `r` and a field `F`, such that `F=\GF{q}`, the `[n, k, d]` code with length `n=\frac{q^{r}-1}{q-1}`, dimension `k=\frac{q^{r}-1}{q-1} - r` and minimum distance `d=3` is called the Hamming Code of order `r`. diff --git a/src/sage/coding/kasami_codes.pyx b/src/sage/coding/kasami_codes.pyx index b14eada8436..ea89cd8b172 100644 --- a/src/sage/coding/kasami_codes.pyx +++ b/src/sage/coding/kasami_codes.pyx @@ -9,10 +9,10 @@ The extended Kasami code with parameters `(s,t)` is defined as .. MATH:: - \{ v \in GF(2)^s \mid - \sum_{a \in GF(s)} v_a = - \sum_{a \in GF(s)} a v_a = - \sum_{a \in GF(s)} a^{t+1} v_a = 0 \} + \{ v \in \GF{2}^s \mid + \sum_{a \in \GF{s}} v_a = + \sum_{a \in \GF{s}} a v_a = + \sum_{a \in \GF{s}} a^{t+1} v_a = 0 \} It follows that these are subfield subcodes of the code having those three @@ -73,10 +73,10 @@ class KasamiCode(AbstractLinearCode): .. MATH:: - \{ v \in GF(2)^s \mid - \sum_{a \in GF(s)} v_a = - \sum_{a \in GF(s)} a v_a = - \sum_{a \in GF(s)} a^{t+1} v_a = 0 \} + \{ v \in \GF{2}^s \mid + \sum_{a \in \GF{s}} v_a = + \sum_{a \in \GF{s}} a v_a = + \sum_{a \in \GF{s}} a^{t+1} v_a = 0 \} The only valid parameters `s,t` are given by the below, where `q` is a power of 2: @@ -294,7 +294,7 @@ class KasamiCode(AbstractLinearCode): We build the parity check matrix given by the three equations that the codewords must satisfy. Then we generate the parity check matrix - over `GF(2)` and from this the obtain the generator matrix for the + over `\GF{2}` and from this the obtain the generator matrix for the extended Kasami codes. For the Kasami codes, we truncate the last column. diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index 490165b928c..97db593fb4b 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -77,7 +77,7 @@ class AbstractLinearCodeNoMetric(AbstractCode, Module): :class:`sage.coding.linear_code.LinearCode`. - As AbstractLinearCodeNoMetric is not designed to be implemented, it does not + As the class :class:`AbstractLinearCodeNoMetric` is not designed to be instantiated, it does not have any representation methods. You should implement ``_repr_`` and ``_latex_`` methods in the subclass. @@ -662,8 +662,8 @@ def information_set(self): EXAMPLES:: - sage: G = matrix(GF(3),2,[1,2,0,\ - 2,1,1]) + sage: G = matrix(GF(3),2,[1,2,0, + ....: 2,1,1]) sage: code = LinearCode(G) sage: code.systematic_generator_matrix() [1 2 0] @@ -680,7 +680,7 @@ def is_information_set(self, positions): INPUT: - A list of positions, i.e. integers in the range 0 to `n-1` where `n` - is the length of `self`. + is the length of ``self``. OUTPUT: @@ -689,8 +689,8 @@ def is_information_set(self, positions): EXAMPLES:: - sage: G = matrix(GF(3),2,[1,2,0,\ - 2,1,1]) + sage: G = matrix(GF(3),2,[1,2,0, + ....: 2,1,1]) sage: code = LinearCode(G) sage: code.is_information_set([0,1]) False @@ -898,8 +898,8 @@ def is_subcode(self, other): def is_permutation_automorphism(self,g): r""" - Return `1` if `g` is an element of `S_n` (`n` = length of self) and - if `g` is an automorphism of self. + Return `1` if `g` is an element of `S_n` (`n` = length of ``self``) and + if `g` is an automorphism of ``self``. EXAMPLES:: @@ -1058,7 +1058,7 @@ class LinearCodeSystematicEncoder(Encoder): the range 0 to `n-1` where `n` is the length of the code and `k` its dimension. The 0th symbol of a message will then be at position ``systematic_positions[0]``, the 1st index at position - ``systematic_positions[1]``, etc. A ``ValueError`` is raised at + ``systematic_positions[1]``, etc. A :class:`ValueError` is raised at construction time if the supplied indices do not form an information set. EXAMPLES: diff --git a/src/sage/coding/linear_rank_metric.py b/src/sage/coding/linear_rank_metric.py index a432538d012..04669af5024 100644 --- a/src/sage/coding/linear_rank_metric.py +++ b/src/sage/coding/linear_rank_metric.py @@ -7,10 +7,10 @@ In coding theory, the most common metric is the Hamming metric, where distance between two codewords is given by the number of positions in which they differ. -An alternative to this is the rank metric. Take two fields, `F_q` and `F_{q^m}`, +An alternative to this is the rank metric. Take two fields, `\GF{q}` and `\GF{q^m}`, and define a code `C` to be a set of vectors of length `n` with entries from -`F_{q^m}`. Let `c` be a codeword. We can represent it as an `m \times n` matrix -`M` over `F_q`. +`\GF{q^m}`. Let `c` be a codeword. We can represent it as an `m \times n` matrix +`M` over `\GF{q}`. A detailed description on the relationship between the two representations can be found in :meth:`sage.coding.linear_rank_metric.to_matrix_representation` @@ -22,9 +22,9 @@ representation of `c`. This module allows representing rank metric codes which are linear over the -big field `F_{q^m}`, i.e. the usual linearity condition when the codewords are +big field `\GF{q^m}`, i.e. the usual linearity condition when the codewords are considered in vector form. One can also consider rank metric codes which are -only linear over `F_q`, but these are not currently supported in SageMath. +only linear over `\GF{q}`, but these are not currently supported in SageMath. Note that linear rank metric codes per the definition of this file are mathematically just linear block codes, and so could be considered as a @@ -127,28 +127,28 @@ def to_matrix_representation(v, sub_field=None, basis=None): Return a matrix representation of ``v`` over ``sub_field`` in terms of ``basis``. - Let `(b_1, b_2, \ldots, b_m)`, `b_i \in GF(q^m)`, be a basis of `GF(q^m)` as - a vector space over `GF(q)`. Take an element `x \in GF(q^m)`. We can write + Let `(b_1, b_2, \ldots, b_m)`, `b_i \in GF(q^m)`, be a basis of `\GF{q^m}` as + a vector space over `\GF{q}`. Take an element `x \in \GF{q^m}`. We can write `x` as `x = u_1 b_1 + u_2 b_2 + \ldots u_m b_m`, where `u_i \in GF(q)`. This - way we can represent an element from `GF(q^m)` as a vector of length `m` - over `GF(q)`. + way we can represent an element from `\GF{q^m}` as a vector of length `m` + over `\GF{q}`. - Given a vector ``v`` of length `n` over some field `F_{q^m}`, we can + Given a vector ``v`` of length `n` over some field `\GF{q^m}`, we can represent each entry as a vector of length `m`, yielding an `m \times n` matrix over ``sub_field``. In case ``sub_field`` is not given, we take the - prime subfield `F_p` of `F_{q^m}`. + prime subfield `\GF{p}` of `\GF{q^m}`. INPUT: - - ``v`` -- a vector over some field `F_{q^m}` + - ``v`` -- a vector over some field `\GF{q^m}` - - ``sub_field`` -- (default: ``None``) a sub field of `F_{q^m}`. If not - specified, it is the prime subfield `F_p` of `F_{q^m}`. + - ``sub_field`` -- (default: ``None``) a sub field of `\GF{q^m}`. If not + specified, it is the prime subfield `\GF{p}` of `\GF{q^m}`. - - ``basis`` -- (default: ``None``) a basis of `F_{q^m}` as a vector space over + - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over ``sub_field``. If not specified, given that `q = p^s`, let `1,\beta,\ldots,\beta^{sm}` be the power basis that SageMath uses to - represent `F_{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. + represent `\GF{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. EXAMPLES:: @@ -181,25 +181,25 @@ def from_matrix_representation(w, base_field=None, basis=None): Return a vector representation of a matrix ``w`` over ``base_field`` in terms of ``basis``. - Given an `m \times n` matrix over `F_q` and some ``basis`` of `F_{q^m}` - over `F_q`, we can represent each of its columns as an element of `F_{q^m}`, - yielding a vector of length `n` over `F_q`. + Given an `m \times n` matrix over `\GF{q}` and some ``basis`` of `\GF{q^m}` + over `\GF{q}`, we can represent each of its columns as an element of `\GF{q^m}`, + yielding a vector of length `n` over `\GF{q}`. - In case ``base_field`` is not given, we take `F_{q^m}`, the field extension of - `F_q` of degree `m`, the number of rows of ``w``. + In case ``base_field`` is not given, we take `\GF{q^m}`, the field extension of + `\GF{q}` of degree `m`, the number of rows of ``w``. INPUT: - - ``w`` -- a matrix over some field `F_q` + - ``w`` -- a matrix over some field `\GF{q}` - - ``base_field`` -- (default: ``None``) an extension field of `F_q`. If not - specified, it is the field `F_{q^m}`, where `m` is the number of rows of + - ``base_field`` -- (default: ``None``) an extension field of `\GF{q}`. If not + specified, it is the field `\GF{q^m}`, where `m` is the number of rows of ``w``. - - ``basis`` -- (default: ``None``) a basis of `F_{q^m}` as a vector space over - ``F_q``. If not specified, given that `q = p^s`, let + - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over + ``\GF{q}``. If not specified, given that `q = p^s`, let `1,\beta,\ldots,\beta^{sm}` be the power basis that SageMath uses to - represent `F_{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. + represent `\GF{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. EXAMPLES:: @@ -229,20 +229,20 @@ def rank_weight(c, sub_field=None, basis=None): r""" Return the rank of ``c`` as a matrix over ``sub_field``. - If ``c`` is a vector over some field `F_{q^m}`, the function converts it - into a matrix over `F_q`. + If ``c`` is a vector over some field `\GF{q^m}`, the function converts it + into a matrix over `\GF{q}`. INPUT: - - ``c`` -- a vector over some field `F_{q^m}`; or a matrix over `F_q` + - ``c`` -- a vector over some field `\GF{q^m}`; or a matrix over `\GF{q}` - - ``sub_field`` -- (default: ``None``) a sub field of `F_{q^m}`. If not - specified, it is the prime subfield `F_p` of `F_{q^m}`. + - ``sub_field`` -- (default: ``None``) a sub field of `\GF{q^m}`. If not + specified, it is the prime subfield `\GF{p}` of `\GF{q^m}`. - - ``basis`` -- (default: ``None``) a basis of `F_{q^m}` as a vector space over + - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over ``sub_field``. If not specified, given that `q = p^s`, let `1,\beta,\ldots,\beta^{sm}` be the power basis that SageMath uses to - represent `F_{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. + represent `\GF{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. EXAMPLES:: @@ -260,26 +260,26 @@ def rank_distance(a, b, sub_field=None, basis=None): r""" Return the rank of ``a`` - ``b`` as a matrix over ``sub_field``. - Take two vectors ``a``, ``b`` over some field `F_{q^m}`. This function - converts them to matrices over `F_q` and calculates the rank of their + Take two vectors ``a``, ``b`` over some field `\GF{q^m}`. This function + converts them to matrices over `\GF{q}` and calculates the rank of their difference. - If ``sub_field`` is not specified, we take the prime subfield `F_q` of - `F_{q^m}`. + If ``sub_field`` is not specified, we take the prime subfield `\GF{q}` of + `\GF{q^m}`. INPUT: - - ``a`` -- a vector over some field `F_{q^m}` + - ``a`` -- a vector over some field `\GF{q^m}` - - ``b`` -- a vector over some field `F_{q^m}` + - ``b`` -- a vector over some field `\GF{q^m}` - - ``sub_field`` -- (default: ``None``) a sub field of `F_{q^m}`. If not - specified, it is the prime subfield `F_p` of `F_{q^m}`. + - ``sub_field`` -- (default: ``None``) a sub field of `\GF{q^m}`. If not + specified, it is the prime subfield `\GF{p}` of `\GF{q^m}`. - - ``basis`` -- (default: ``None``) a basis of `F_{q^m}` as a vector space over + - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over ``sub_field``. If not specified, given that `q = p^s`, let `1,\beta,\ldots,\beta^{sm}` be the power basis that SageMath uses to - represent `F_{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. + represent `\GF{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. EXAMPLES:: @@ -377,10 +377,10 @@ def __init__(self, base_field, sub_field, length, default_encoder_name, - ``default_decoder_name`` -- the name of the default decoder of ``self`` - - ``basis`` -- (default: ``None``) a basis of `F_{q^m}` as a vector space over + - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over ``sub_field``. If not specified, given that `q = p^s`, let `1,\beta,\ldots,\beta^{sm}` be the power basis that SageMath uses to - represent `F_{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. + represent `\GF{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. EXAMPLES: @@ -512,8 +512,8 @@ def field_extension(self): r""" Return the field extension of ``self``. - Let ``base_field`` be some field `F_{q^m}` and ``sub_field`` `F_{q}`. - This function returns the vector space of dimension `m` over `F_{q}`. + Let ``base_field`` be some field `\GF{q^m}` and ``sub_field`` `\GF{q}`. + This function returns the vector space of dimension `m` over `\GF{q}`. EXAMPLES:: @@ -677,10 +677,10 @@ def __init__(self, generator, sub_field=None, basis=None): - ``sub_field`` -- (default: ``None``) the sub field of ``self``, if not specified, it is the prime field of ``base_field`` - - ``basis`` -- (default: ``None``) a basis of `F_{q^m}` as a vector space over + - ``basis`` -- (default: ``None``) a basis of `\GF{q^m}` as a vector space over ``sub_field``. If not specified, given that `q = p^s`, let `1,\beta,\ldots,\beta^{sm}` be the power basis that SageMath uses to - represent `F_{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. + represent `\GF{q^m}`. The default basis is then `1,\beta,\ldots,\beta^{m-1}`. EXAMPLES:: diff --git a/src/sage/coding/parity_check_code.py b/src/sage/coding/parity_check_code.py index 9a0836db9de..03f23bcc17f 100644 --- a/src/sage/coding/parity_check_code.py +++ b/src/sage/coding/parity_check_code.py @@ -6,8 +6,8 @@ parity check to ensure that the sum of the digits in a transmitted word is even. -A parity-check code of dimension `k` over `F_q` is the set: -`\{(m_1, m_2, \dots, m_k, - \Sigma_{i=1}^k m_i) \mid (m_1, m_2, \dots, m_k) \in F_q^k\}` +A parity-check code of dimension `k` over `\GF{q}` is the set: +`\{(m_1, m_2, \dots, m_k, - \Sigma_{i=1}^k m_i) \mid (m_1, m_2, \dots, m_k) \in \GF{q}^k\}` REFERENCE: diff --git a/src/sage/coding/reed_muller_code.py b/src/sage/coding/reed_muller_code.py index 45784cbf956..e40c50a8062 100644 --- a/src/sage/coding/reed_muller_code.py +++ b/src/sage/coding/reed_muller_code.py @@ -45,7 +45,7 @@ def _binomial_sum(n, k): r""" - Returns the sum of all binomials `\binom{n}{i}`, + Return the sum of all binomials `\binom{n}{i}`, with `i` ranging from `0` to `k` and including `k`. INPUT: @@ -68,7 +68,7 @@ def _binomial_sum(n, k): def _multivariate_polynomial_interpolation(evaluation, order, polynomial_ring): r""" - Returns `f \in \GF{q}[X_1,...,X_m]` such that `f(\mathbf a) = v[i(\mathbf a)]` + Return `f \in \GF{q}[X_1,...,X_m]` such that `f(\mathbf a) = v[i(\mathbf a)]` for all `\mathbf a \in \GF{q^m}`, where `v \in \GF{q}^{q^m}` is a given vector of evaluations, and `i(a)` is a specific ordering of `\GF{q^m}` (see below for details) @@ -133,7 +133,7 @@ def _interpolate(evaluation, num_of_var, order): def ReedMullerCode(base_field, order, num_of_var): r""" - Returns a Reed-Muller code. + Return a Reed-Muller code. A Reed-Muller Code of order `r` and number of variables `m` over a finite field `F` is the set: @@ -192,7 +192,7 @@ def ReedMullerCode(base_field, order, num_of_var): class QAryReedMullerCode(AbstractLinearCode): r""" - Representation of a q-ary Reed-Muller code. + Representation of a `q`-ary Reed-Muller code. For details on the definition of Reed-Muller codes, refer to :meth:`ReedMullerCode`. @@ -201,7 +201,7 @@ class QAryReedMullerCode(AbstractLinearCode): It is better to use the aforementioned method rather than calling this class directly, as :meth:`ReedMullerCode` creates either - a binary or a q-ary Reed-Muller code according to the arguments it receives. + a binary or a `q`-ary Reed-Muller code according to the arguments it receives. INPUT: @@ -272,7 +272,7 @@ def __init__(self, base_field, order, num_of_var): def order(self): r""" - Returns the order of ``self``. + Return the order of ``self``. Order is the maximum degree of the polynomial used in the Reed-Muller code. @@ -288,7 +288,7 @@ def order(self): def number_of_variables(self): r""" - Returns the number of variables of the polynomial ring used in ``self``. + Return the number of variables of the polynomial ring used in ``self``. EXAMPLES:: @@ -302,9 +302,9 @@ def number_of_variables(self): def minimum_distance(self): r""" - Returns the minimum distance between two words in ``self``. + Return the minimum distance between two words in ``self``. - The minimum distance of a q-ary Reed-Muller code with order `d` and number of variables `m` is `(q-d)q^{m-1}` + The minimum distance of a `q`-ary Reed-Muller code with order `d` and number of variables `m` is `(q-d)q^{m-1}` EXAMPLES:: @@ -321,7 +321,7 @@ def minimum_distance(self): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -336,7 +336,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -381,7 +381,7 @@ class BinaryReedMullerCode(AbstractLinearCode): It is better to use the aforementioned method rather than calling this class directly, as :meth:`ReedMullerCode` creates either - a binary or a q-ary Reed-Muller code according to the arguments it receives. + a binary or a `q`-ary Reed-Muller code according to the arguments it receives. INPUT: @@ -523,11 +523,11 @@ class ReedMullerVectorEncoder(Encoder): dimension `k` over some finite field `F`. Let those variables be `(x_1, x_2, \dots, x_m)`. We order the monomials by lowest power on lowest index variables. If we have three monomials - `x_1 \times x_2`, `x_1 \times x_2^2` and `x_1^2 \times x_2`, the ordering is: - `x_1 \times x_2 < x_1 \times x_2^2 < x_1^2 \times x_2` + `x_1 x_2`, `x_1 x_2^2` and `x_1^2 x_2`, the ordering is: + `x_1 x_2 < x_1 x_2^2 < x_1^2 x_2` Let now `(v_1,v_2,\ldots,v_k)` be a vector of `F`, which corresponds to the polynomial - `f = \Sigma^{k}_{i=1} v_i \times x_i`. + `f = \Sigma^{k}_{i=1} v_i x_i`. Let `(\beta_1, \beta_2, \ldots, \beta_q)` be the elements of `F` ordered as they are returned by Sage when calling ``F.list()``. @@ -535,8 +535,9 @@ class ReedMullerVectorEncoder(Encoder): The aforementioned polynomial `f` is encoded as: `(f(\alpha_{11},\alpha_{12},\ldots,\alpha_{1m}),f(\alpha_{21},\alpha_{22},\ldots, - \alpha_{2m}),\ldots,f(\alpha_{q^m1},\alpha_{q^m2},\ldots,\alpha_{q^mm}`, with - `\alpha_{ij}=\beta_{i \ mod \ q^j} \forall (i,j)` + \alpha_{2m}),\ldots,f(\alpha_{q^m1},\alpha_{q^m2},\ldots,\alpha_{q^mm}))` + + with `\alpha_{ij}=\beta_{i \bmod{q^j}} \forall (i,j)` INPUT: @@ -587,7 +588,7 @@ def __init__(self, code): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -601,7 +602,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -691,8 +692,8 @@ class ReedMullerPolynomialEncoder(Encoder): dimension `k` over some finite field `F`. Let those variables be `(x_1, x_2, \dots, x_m)`. We order the monomials by lowest power on lowest index variables. If we have three monomials - `x_1 \times x_2`, `x_1 \times x_2^2` and `x_1^2 \times x_2`, the ordering is: - `x_1 \times x_2 < x_1 \times x_2^2 < x_1^2 \times x_2` + `x_1 x_2`, `x_1 x_2^2` and `x_1^2 x_2`, the ordering is: + `x_1 x_2 < x_1 x_2^2 < x_1^2 x_2` Let now `f` be a polynomial of the multivariate polynomial ring `F[x_1, \dots, x_m]`. @@ -702,9 +703,9 @@ class ReedMullerPolynomialEncoder(Encoder): The aforementioned polynomial `f` is encoded as: `(f(\alpha_{11},\alpha_{12},\ldots,\alpha_{1m}),f(\alpha_{21},\alpha_{22},\ldots, - \alpha_{2m}),\ldots,f(\alpha_{q^m1},\alpha_{q^m2},\ldots,\alpha_{q^mm}`, with - `\alpha_{ij}=\beta_{i \ mod \ q^j} \forall (i,j)` + \alpha_{2m}),\ldots,f(\alpha_{q^m1},\alpha_{q^m2},\ldots,\alpha_{q^mm}))` + with `\alpha_{ij}=\beta_{i \bmod{q^j}} \forall (i,j)` INPUT: @@ -785,7 +786,7 @@ def __init__(self, code, polynomial_ring=None): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -799,7 +800,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -855,7 +856,7 @@ def encode(self, p): True If a polynomial with good monomial degree but wrong monomial - degree is given,an error is raised:: + degree is given, an error is raised:: sage: p = x0^2*x1 sage: E.encode(p) @@ -885,7 +886,7 @@ def encode(self, p): def unencode_nocheck(self, c): r""" - Returns the message corresponding to the codeword ``c``. + Return the message corresponding to the codeword ``c``. Use this method with caution: it does not check if ``c`` belongs to the code, and if this is not the case, the output is @@ -931,7 +932,7 @@ def unencode_nocheck(self, c): def message_space(self): r""" - Returns the message space of ``self`` + Return the message space of ``self`` EXAMPLES:: @@ -945,7 +946,7 @@ def message_space(self): def polynomial_ring(self): r""" - Returns the polynomial ring associated with ``self`` + Return the polynomial ring associated with ``self`` EXAMPLES:: @@ -959,7 +960,7 @@ def polynomial_ring(self): def points(self): r""" - Returns the evaluation points in the appropriate order as used by ``self`` when + Return the evaluation points in the appropriate order as used by ``self`` when encoding a message. EXAMPLES:: From 29a3ae096e91f602be479c20216cd4929d4b0fa1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 15:58:52 -0700 Subject: [PATCH 091/205] 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 7d9af59d6667fef4c12d0ed06eeed445c7997f61 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 16:42:25 -0700 Subject: [PATCH 092/205] Fix up git acrobatics --- .github/workflows/build.yml | 3 ++- .github/workflows/doc-build.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a9db05e9641..2abe99d8aae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -64,7 +64,8 @@ jobs: git worktree add --detach worktree-image rm -rf /sage/.git && mv worktree-image/.git /sage/ rm -rf worktree-image && ln -s /sage worktree-image - (cd worktree-image && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) + if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi + (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. # We run tests with "sage -t --new"; this only tests the uncommitted changes. (cd worktree-image && ./bootstrap && make build && ./sage -t --new -p2) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 2d0c2303829..fc69756a557 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -46,7 +46,8 @@ jobs: git worktree add --detach worktree-image rm -rf /sage/.git && mv worktree-image/.git /sage/ rm -rf worktree-image && ln -s /sage worktree-image - (cd worktree-image && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) + if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi + (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) # Keep track of changes to built HTML (cd /sage/local/share/doc/sage/html && git init && git add -A && git commit -m "old") # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. From a0e18d9c62e4d5f688afac505e0ffdf9c59763cf Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 16:42:34 -0700 Subject: [PATCH 093/205] 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 36b9484ef9017070263d3a5db9c1c3bdf1e5d050 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 16:42:57 -0700 Subject: [PATCH 094/205] .github/workflows/doc-publish.yml: Show link to CHANGES.html --- .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..b7acc9b0a48 100644 --- a/.github/workflows/doc-publish.yml +++ b/.github/workflows/doc-publish.yml @@ -72,7 +72,7 @@ jobs: header: preview-comment recreate: true message: | - [Documentation preview for this PR](${{ steps.deploy-netlify.outputs.NETLIFY_URL }}) (built with commit ${{ steps.source-run-info.outputs.sourceHeadSha }}) is ready! :tada: + [Documentation preview for this PR](${{ steps.deploy-netlify.outputs.NETLIFY_URL }}) (built with commit ${{ steps.source-run-info.outputs.sourceHeadSha }}; [changes](${{ steps.deploy-netlify.outputs.NETLIFY_URL }}/CHANGES.html)) is ready! :tada: - name: Update deployment status PR check uses: myrotvorets/set-commit-status-action@1.1.6 From 5d13d8ff43180254fe8c5b467b6a81f4b90aca1b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 18:14:07 -0700 Subject: [PATCH 095/205] .github/workflows/doc-build.yml: Normalize Sage version in output before comparing --- .github/workflows/doc-build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index fc69756a557..7e8448ab515 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -49,7 +49,7 @@ jobs: if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) # Keep track of changes to built HTML - (cd /sage/local/share/doc/sage/html && git init && git add -A && git commit -m "old") + (cd /sage/local/share/doc/sage/html && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && git add -A && git commit -m "old") # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. (cd worktree-image && ./bootstrap && make doc-html) env: @@ -60,8 +60,8 @@ jobs: run: | mkdir -p ./docs # Create changelog - (cd /sage/local/share/doc/sage/html/en && git diff --name-only && rm -rf .git) | tee ./docs/CHANGES.txt - sed -E 's,(.*),

\1,' ./docs/CHANGES.txt > .docs/CHANGES.html + (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git diff --name-only && rm -rf .git) | tee ./docs/CHANGES.txt + sed -E 's,(.*),

\1,' ./docs/CHANGES.txt > ./docs/CHANGES.html # For some reason the deploy step below cannot find /sage/... # So copy everything from there to local folder # We also need to replace the symlinks because netlify is not following them From 45787c0146864f52bd176b6789069d4a26da8a04 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 20:01:31 -0700 Subject: [PATCH 096/205] sage.coding: Final round of docstring cosmetics --- src/sage/coding/binary_code.pyx | 53 ++++++------ src/sage/coding/code_bounds.py | 80 +++++++++---------- src/sage/coding/code_constructions.py | 34 ++++---- .../coding/codecan/autgroup_can_label.pyx | 24 +++--- src/sage/coding/codecan/codecan.pyx | 14 ++-- src/sage/coding/cyclic_code.py | 57 +++++++------ src/sage/coding/delsarte_bounds.py | 27 ++++--- src/sage/coding/extended_code.py | 26 +++--- src/sage/coding/grs_code.py | 2 +- src/sage/coding/guava.py | 4 +- src/sage/coding/guruswami_sudan/gs_decoder.py | 33 ++++---- .../coding/guruswami_sudan/interpolation.py | 20 ++--- src/sage/coding/information_set_decoder.py | 8 +- src/sage/coding/kasami_codes.pyx | 4 +- src/sage/coding/linear_rank_metric.py | 8 +- src/sage/coding/punctured_code.py | 36 ++++----- src/sage/coding/reed_muller_code.py | 4 +- src/sage/coding/self_dual_codes.py | 79 +++++++++--------- src/sage/coding/source_coding/huffman.py | 18 ++--- src/sage/coding/subfield_subcode.py | 24 +++--- 20 files changed, 281 insertions(+), 274 deletions(-) diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index eee87d83ef6..d1f3553bae0 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -2,10 +2,10 @@ r""" Optimized low-level binary code representation -Some computations with linear binary codes. Fix a basis for `GF(2)^n`. -A linear binary code is a linear subspace of `GF(2)^n`, together with +Some computations with linear binary codes. Fix a basis for `\GF{2}^n`. +A linear binary code is a linear subspace of `\GF{2}^n`, together with this choice of basis. A permutation `g \in S_n` of the fixed basis -gives rise to a permutation of the vectors, or words, in `GF(2)^n`, +gives rise to a permutation of the vectors, or words, in `\GF{2}^n`, sending `(w_i)` to `(w_{g(i)})`. The permutation automorphism group of the code `C` is the set of permutations of the basis that bijectively map `C` to itself. Note that if `g` is such a permutation, then @@ -16,7 +16,7 @@ map `C` to itself. Note that if `g` is such a permutation, then Over other fields, it is also required that the map be linear, which as per above boils down to scalar multiplication. However, over -`GF(2),` the only scalars are 0 and 1, so the linearity condition has +`\GF{2},` the only scalars are 0 and 1, so the linearity condition has trivial effect. AUTHOR: @@ -88,7 +88,7 @@ cdef int *hamming_weights(): def weight_dist(M): """ - Computes the weight distribution of the row space of M. + Computes the weight distribution of the row space of `M`. EXAMPLES:: @@ -156,34 +156,34 @@ def weight_dist(M): return L def test_word_perms(t_limit=5.0): - """ - Tests the WordPermutation structs for at least t_limit seconds. + r""" + Test the :class:`WordPermutation` structs for at least ``t_limit`` seconds. These are structures written in pure C for speed, and are tested from this function, which performs the following tests: - 1. Tests create_word_perm, which creates a WordPermutation from a Python - list L representing a permutation i --> L[i]. Takes a random word and + 1. Tests :func:`create_word_perm`, which creates a :class:`WordPermutation` from a Python + list `L` representing a permutation `i \mapsto L[i]`. Takes a random word and permutes it by a random list permutation, and tests that the result agrees with doing it the slow way. - 1b. Tests create_array_word_perm, which creates a WordPermutation from a + 1b. Tests :func:`create_array_word_perm`, which creates a :class:`WordPermutation` from a C array. Does the same as above. - 2. Tests create_comp_word_perm, which creates a WordPermutation as a - composition of two WordPermutations. Takes a random word and + 2. Tests :func:`create_comp_word_perm`, which creates a :class:`WordPermutation` as a + composition of two :class:`WordPermutation` objects. Takes a random word and two random permutations, and tests that the result of permuting by the composition is correct. - 3. Tests create_inv_word_perm and create_id_word_perm, which create a - WordPermutation as the inverse and identity permutations, resp. + 3. Tests :func:`create_inv_word_perm` and :func:`create_id_word_perm`, which create a + :class:`WordPermutation` as the inverse and identity permutations, resp. Takes a random word and a random permutation, and tests that the result permuting by the permutation and its inverse in either order, and permuting by the identity both return the original word. .. NOTE:: - The functions permute_word_by_wp and dealloc_word_perm are implicitly + The functions :func:`permute_word_by_wp` and :func:`dealloc_word_perm` are implicitly involved in each of the above tests. TESTS:: @@ -525,7 +525,7 @@ def test_expand_to_ortho_basis(B=None): INPUT: - - B -- a BinaryCode in standard form + - ``B`` -- a :class:`BinaryCode` in standard form OUTPUT: @@ -866,8 +866,8 @@ cdef class BinaryCode: def matrix(self): """ - Returns the generator matrix of the BinaryCode, i.e. the code is the - rowspace of B.matrix(). + Returns the generator matrix of the :class:`BinaryCode`, i.e. the code is the + rowspace of ``B.matrix()``. EXAMPLES:: @@ -2879,7 +2879,8 @@ cdef class PartitionStack: sage: import sage.coding.binary_code sage: from sage.coding.binary_code import * - sage: M = Matrix(GF(2), [[1,1,1,1,0,0,0,0],[0,0,1,1,1,1,0,0],[0,0,0,0,1,1,1,1],[1,0,1,0,1,0,1,0]]) + sage: M = Matrix(GF(2), [[1,1,1,1,0,0,0,0], [0,0,1,1,1,1,0,0], + ....: [0,0,0,0,1,1,1,1], [1,0,1,0,1,0,1,0]]) sage: B = BinaryCode(M) sage: P = PartitionStack(4, 8) sage: P._refine(0, [[0,0],[1,0]], B) @@ -3169,12 +3170,12 @@ cdef class BinaryCodeClassifier: def _aut_gp_and_can_label(self, CC, verbosity=0): """ - Compute the automorphism group and canonical label of the code CC. + Compute the automorphism group and canonical label of the code ``CC``. INPUT: - - CC - a BinaryCode object - - verbosity -- a nonnegative integer + - ``CC`` -- a BinaryCode object + - ``verbosity`` -- a nonnegative integer OUTPUT: a tuple, (gens, labeling, size, base) @@ -3901,15 +3902,15 @@ cdef class BinaryCodeClassifier: def generate_children(self, BinaryCode B, int n, int d=2): """ - Use canonical augmentation to generate children of the code B. + Use canonical augmentation to generate children of the code `B`. INPUT: - - B -- a BinaryCode + - ``B`` -- a :class:`BinaryCode` - - n -- limit on the degree of the code + - ``n`` -- limit on the degree of the code - - d -- test whether new vector has weight divisible by d. If d==4, this + - ``d`` -- test whether new vector has weight divisible by `d`. If `d=4`, this ensures that all doubly-even canonically augmented children are generated. diff --git a/src/sage/coding/code_bounds.py b/src/sage/coding/code_bounds.py index 659455408e3..706bcb2cb34 100644 --- a/src/sage/coding/code_bounds.py +++ b/src/sage/coding/code_bounds.py @@ -94,11 +94,11 @@ Sage, you can determine the best known estimates for this number in 2 ways: -1. Indirectly, using best_known_linear_code_www(n, k, F), - which connects to the website http://www.codetables.de by Markus Grassl; +1. Indirectly, using ``best_known_linear_code_www(n, k, F)``, + which connects to the website http://www.codetables.de by Markus Grassl; -2. codesize_upper_bound(n,d,q), dimension_upper_bound(n,d,q), - and best_known_linear_code(n, k, F). +2. ``codesize_upper_bound(n,d,q)``, ``dimension_upper_bound(n,d,q)``, + and ``best_known_linear_code(n, k, F)``. The output of :func:`best_known_linear_code`, :func:`best_known_linear_code_www`, or :func:`dimension_upper_bound` would @@ -108,52 +108,52 @@ This module implements: -- codesize_upper_bound(n,d,q), for the best known (as of May, - 2006) upper bound A(n,d) for the size of a code of length n, - minimum distance d over a field of size q. +- ``codesize_upper_bound(n,d,q)``, for the best known (as of May, + 2006) upper bound `A(n,d)` for the size of a code of length `n`, + minimum distance `d` over a field of size `q`. -- dimension_upper_bound(n,d,q), an upper bound +- ``dimension_upper_bound(n,d,q)``, an upper bound `B(n,d)=B_q(n,d)` for the dimension of a linear code of - length n, minimum distance d over a field of size q. + length `n`, minimum distance `d` over a field of size `q`. -- gilbert_lower_bound(n,q,d), a lower bound for number of - elements in the largest code of min distance d in +- ``gilbert_lower_bound(n,q,d)``, a lower bound for number of + elements in the largest code of min distance `d` in `\GF{q}^n`. -- gv_info_rate(n,delta,q), `log_q(GLB)/n`, where GLB is - the Gilbert lower bound and delta = d/n. +- ``gv_info_rate(n,delta,q)``, `log_q(GLB)/n`, where GLB is + the Gilbert lower bound and `\delta = d/n`. -- gv_bound_asymp(delta,q), asymptotic analog of Gilbert lower +- ``gv_bound_asymp(delta,q)``, asymptotic analog of Gilbert lower bound. -- plotkin_upper_bound(n,q,d) +- ``plotkin_upper_bound(n,q,d)`` -- plotkin_bound_asymp(delta,q), asymptotic analog of Plotkin +- ``plotkin_bound_asymp(delta,q)``, asymptotic analog of Plotkin bound. -- griesmer_upper_bound(n,q,d) +- ``griesmer_upper_bound(n,q,d)`` -- elias_upper_bound(n,q,d) +- ``elias_upper_bound(n,q,d)`` -- elias_bound_asymp(delta,q), asymptotic analog of Elias bound. +- ``elias_bound_asymp(delta,q)``, asymptotic analog of Elias bound. -- hamming_upper_bound(n,q,d) +- ``hamming_upper_bound(n,q,d)` -- hamming_bound_asymp(delta,q), asymptotic analog of Hamming +- ``hamming_bound_asymp(delta,q)``, asymptotic analog of Hamming bound. -- singleton_upper_bound(n,q,d) +- ``singleton_upper_bound(n,q,d)`` -- singleton_bound_asymp(delta,q), asymptotic analog of Singleton +- ``singleton_bound_asymp(delta,q)``, asymptotic analog of Singleton bound. -- mrrw1_bound_asymp(delta,q), "first" asymptotic +- ``mrrw1_bound_asymp(delta,q)``, "first" asymptotic McEliese-Rumsey-Rodemich-Welsh bound for the information rate. - Delsarte (a.k.a. Linear Programming (LP)) upper bounds. PROBLEM: In this module we shall typically either (a) seek bounds -on k, given n, d, q, (b) seek bounds on R, delta, q (assuming n is +on `k`, given `n`, `d`, `q`, (b) seek bounds on `R`, `\delta`, `q` (assuming `n` is "infinity"). .. TODO:: @@ -234,19 +234,19 @@ def codesize_upper_bound(n, d, q, algorithm=None): This function computes the minimum value of the upper bounds of Singleton, Hamming, Plotkin, and Elias. - If algorithm="gap" then this returns the best known upper - bound `A(n,d)=A_q(n,d)` for the size of a code of length n, - minimum distance d over a field of size q. The function first - checks for trivial cases (like d=1 or n=d), and if the value + If ``algorithm="gap"``, then this returns the best known upper + bound `A(n,d)=A_q(n,d)` for the size of a code of length `n`, + minimum distance `d` over a field of size `q`. The function first + checks for trivial cases (like `d=1` or `n=d`), and if the value is in the built-in table. Then it calculates the minimum value of the upper bound using the algorithms of Singleton, Hamming, Johnson, Plotkin and Elias. If the code is binary, `A(n, 2\ell-1) = A(n+1,2\ell)`, so the function takes the minimum of the values obtained from all algorithms for the parameters `(n, 2\ell-1)` and `(n+1, 2\ell)`. This - wraps GUAVA's (i.e. GAP's package Guava) UpperBound( n, d, q ). + wraps GUAVA's (i.e. GAP's package Guava) ``UpperBound(n, d, q)``. - If algorithm="LP" then this returns the Delsarte (a.k.a. Linear + If ``algorithm="LP"``, then this returns the Delsarte (a.k.a. Linear Programming) upper bound. EXAMPLES:: @@ -303,7 +303,7 @@ def dimension_upper_bound(n, d, q, algorithm=None): dimension of a linear code of length n, minimum distance d over a field of size q. - Parameter "algorithm" has the same meaning as in :func:`codesize_upper_bound` + Parameter ``algorithm`` has the same meaning as in :func:`codesize_upper_bound` EXAMPLES:: @@ -464,7 +464,7 @@ def elias_upper_bound(n,q,d,algorithm=None): Return the Elias upper bound for number of elements in the largest code of minimum distance `d` in `\GF{q}^n`, cf. [HP2003]_. - If the method is "gap", it wraps GAP's ``UpperBoundElias``. + If ``algorithm="gap"``, it wraps GAP's ``UpperBoundElias``. EXAMPLES:: @@ -499,8 +499,8 @@ def hamming_upper_bound(n,q,d): Return the Hamming upper bound. Return the Hamming upper bound for number of elements in the - largest code of length n and minimum distance d over alphabet - of size q. + largest code of length `n` and minimum distance `d` over alphabet + of size `q`. The Hamming bound (also known as the sphere packing bound) returns an upper bound on the size of a code of length `n`, minimum distance @@ -518,7 +518,7 @@ def hamming_upper_bound(n,q,d): where `M` is the maximum number of codewords and `V(n,e)` is - equal to the contents of a ball of radius e. This bound is useful + equal to the contents of a ball of radius `e`. This bound is useful for small values of `d`. Codes for which equality holds are called perfect. See e.g. [HP2003]_. @@ -536,7 +536,7 @@ def singleton_upper_bound(n, q, d): Return the Singleton upper bound. Return the Singleton upper bound for number of elements in a - largest code of minimum distance d in `\GF{q}^n`. + largest code of minimum distance `d` in `\GF{q}^n`. This bound is based on the shortening of codes. By shortening an `(n, M, d)` code `d-1` times, an `(n-d+1,M,1)` code @@ -582,9 +582,9 @@ def entropy(x, q=2): INPUT: - - ``x`` - real number in the interval `[0, 1]`. + - ``x`` -- real number in the interval `[0, 1]`. - - ``q`` - (default: 2) integer greater than 1. This is the base of the + - ``q`` -- (default: 2) integer greater than 1. This is the base of the logarithm. EXAMPLES:: @@ -623,7 +623,7 @@ def entropy(x, q=2): def entropy_inverse(x, q=2): """ - Find the inverse of the ``q``-ary entropy function at the point ``x``. + Find the inverse of the `q`-ary entropy function at the point ``x``. INPUT: diff --git a/src/sage/coding/code_constructions.py b/src/sage/coding/code_constructions.py index d3a377cc27d..abd1d3170d9 100644 --- a/src/sage/coding/code_constructions.py +++ b/src/sage/coding/code_constructions.py @@ -217,11 +217,13 @@ def _lift2smallest_field(a): def permutation_action(g, v): r""" - Returns permutation of rows g\*v. Works on lists, matrices, + Returns permutation of rows `g * v`. + + Works on lists, matrices, sequences and vectors (by permuting coordinates). The code requires - switching from i to i+1 (and back again) since the SymmetricGroup - is, by convention, the symmetric group on the "letters" 1, 2, ..., - n (not 0, 1, ..., n-1). + switching from `i` to `i+1` (and back again) since the :class:`SymmetricGroup` + is, by convention, the symmetric group on the "letters" `1`, `2`, ..., + `n` (not `0`, `1`, ..., `n-1`). EXAMPLES:: @@ -497,10 +499,10 @@ def QuadraticResidueCode(n,F): A quadratic residue code (or QR code) is a cyclic code whose generator polynomial is the product of the polynomials `x-\alpha^i` (`\alpha` is a primitive - `n^{th}` root of unity; `i` ranges over the set of + `n`'th root of unity; `i` ranges over the set of quadratic residues modulo `n`). - See QuadraticResidueCodeEvenPair and QuadraticResidueCodeOddPair + See :class:`QuadraticResidueCodeEvenPair` and :class:`QuadraticResidueCodeOddPair` for a more general construction. INPUT: @@ -542,12 +544,12 @@ def QuadraticResidueCodeEvenPair(n,F): Quadratic residue codes of a given odd prime length and base ring either don't exist at all or occur as 4-tuples - a pair of "odd-like" codes and a pair of "even-like" codes. If `n > 2` is prime - then (Theorem 6.6.2 in [HP2003]_) a QR code exists over `GF(q)` iff q is a + then (Theorem 6.6.2 in [HP2003]_) a QR code exists over `\GF{q}` iff q is a quadratic residue mod `n`. They are constructed as "even-like" duadic codes associated the - splitting (Q,N) mod n, where Q is the set of non-zero quadratic - residues and N is the non-residues. + splitting `(Q,N)` mod `n`, where `Q` is the set of non-zero quadratic + residues and `N` is the non-residues. EXAMPLES:: @@ -608,12 +610,12 @@ def QuadraticResidueCodeOddPair(n,F): Quadratic residue codes of a given odd prime length and base ring either don't exist at all or occur as 4-tuples - a pair of "odd-like" codes and a pair of "even-like" codes. If n 2 is prime - then (Theorem 6.6.2 in [HP2003]_) a QR code exists over GF(q) iff q is a - quadratic residue mod n. + then (Theorem 6.6.2 in [HP2003]_) a QR code exists over `\GF{q} iff `q` is a + quadratic residue mod `n`. They are constructed as "odd-like" duadic codes associated the - splitting (Q,N) mod n, where Q is the set of non-zero quadratic - residues and N is the non-residues. + splitting `(Q,N)` mod `n`, where `Q` is the set of non-zero quadratic + residues and `N` is the non-residues. EXAMPLES:: @@ -700,13 +702,13 @@ def ToricCode(P,F): .. MATH:: - \mathrm{eval_T} : V \rightarrow F^n, + \operatorname{eval}_T : V \rightarrow F^n, where `x^e` is the multi-index notation (`x=(x_1,...,x_d)`, `e=(e_1,...,e_d)`, and `x^e = x_1^{e_1}...x_d^{e_d}`), where - `eval_T (f(x)) = (f(t_1),...,f(t_n))`, and where + `\operatorname{eval}_T (f(x)) = (f(t_1),...,f(t_n))`, and where `T=\{t_1,...,t_n\}`. This function returns the toric codes discussed in [Joy2004]_. @@ -745,7 +747,7 @@ def ToricCode(P,F): sage: C [49, 11] linear code over GF(8) - This is in fact a [49,11,28] code over GF(8). If you type next + This is in fact a [49,11,28] code over `\GF{8}`. If you type next ``C.minimum_distance()`` and wait overnight (!), you should get 28. diff --git a/src/sage/coding/codecan/autgroup_can_label.pyx b/src/sage/coding/codecan/autgroup_can_label.pyx index c83b9264e44..c3a11c07e81 100644 --- a/src/sage/coding/codecan/autgroup_can_label.pyx +++ b/src/sage/coding/codecan/autgroup_can_label.pyx @@ -137,21 +137,21 @@ class LinearCodeAutGroupCanLabel: There are several notions of equivalence for linear codes: Let `C`, `D` be linear codes of length `n` and dimension `k`. - `C` and `D` are said to be + The codes `C` and `D` are said to be - - permutational equivalent, if there is some permutation `\pi \in S_n` - such that `(c_{\pi(0)}, \ldots, c_{\pi(n-1)}) \in D` for all `c \in C`. + - permutational equivalent, if there is some permutation `\pi \in S_n` + such that `(c_{\pi(0)}, \ldots, c_{\pi(n-1)}) \in D` for all `c \in C`. - - linear equivalent, if there is some permutation `\pi \in S_n` and a - vector `\phi \in {\GF{q}^*}^n` of units of length `n` such that - `(c_{\pi(0)} \phi_0^{-1}, \ldots, c_{\pi(n-1)} \phi_{n-1}^{-1}) \in D` - for all `c \in C`. + - linear equivalent, if there is some permutation `\pi \in S_n` and a + vector `\phi \in {\GF{q}^*}^n` of units of length `n` such that + `(c_{\pi(0)} \phi_0^{-1}, \ldots, c_{\pi(n-1)} \phi_{n-1}^{-1}) \in D` + for all `c \in C`. - - semilinear equivalent, if there is some permutation `\pi \in S_n`, a - vector `\phi` of units of length `n` and a field automorphism `\alpha` - such that - `(\alpha(c_{\pi(0)}) \phi_0^{-1}, \ldots, \alpha( c_{\pi(n-1)}) \phi_{n-1}^{-1} ) \in D` - for all `c \in C`. + - semilinear equivalent, if there is some permutation `\pi \in S_n`, a + vector `\phi` of units of length `n` and a field automorphism `\alpha` + such that + `(\alpha(c_{\pi(0)}) \phi_0^{-1}, \ldots, \alpha( c_{\pi(n-1)}) \phi_{n-1}^{-1} ) \in D` + for all `c \in C`. These are group actions. This class provides an algorithm that will compute a unique representative `D` in the orbit of the given linear code `C`. diff --git a/src/sage/coding/codecan/codecan.pyx b/src/sage/coding/codecan/codecan.pyx index 90f1fc76194..b0709155b57 100644 --- a/src/sage/coding/codecan/codecan.pyx +++ b/src/sage/coding/codecan/codecan.pyx @@ -110,10 +110,10 @@ cdef class InnerGroup: Those stabilizers can be stored as triples: - - ``rank`` - an integer in `\{0, \ldots, k\}` - - ``row_partition`` - a partition of `\{0, \ldots, k-1\}` with - discrete cells for all integers `i \geq rank`. - - ``frob_pow`` an integer in `\{0, \ldots, r-1\}` if `q = p^r` + - ``rank`` -- an integer in `\{0, \ldots, k\}` + - ``row_partition`` -- a partition of `\{0, \ldots, k-1\}` with + discrete cells for all integers `i` `\geq` ``rank``. + - ``frob_pow`` -- an integer `s` in `\{0, \ldots, r-1\}` if `q = p^r` The group `G_{\Pi^{(I)}(x)}` contains all elements `(A, \varphi, \alpha) \in G`, where @@ -126,8 +126,8 @@ cdef class InnerGroup: - The support of the columns given by `i \in I` intersect exactly one cell of the partition. The entry `\varphi_i` is equal to the entries of the corresponding diagonal entry of `A`. - - `\alpha` is a power of `\tau^{frob_pow}`, where `\tau` denotes the - Frobenius automorphism of the finite field `\GF{q}`. + - `\alpha` is a power of `\tau^s`, where `\tau` denotes the + Frobenius automorphism of the finite field `\GF{q}` and `s` = ``frob_pow``. See [Feu2009]_ for more details. """ @@ -143,8 +143,8 @@ cdef class InnerGroup: * "semilinear" -- full group * "linear" -- no field automorphisms, i.e. `G = (GL(k,q) \times \GF{q}^n )` * "permutational -- no field automorphisms and no column multiplications - i.e. `G = GL(k,q)` + - ``transporter`` (optional) -- set to an element of the group :class:`sage.groups.semimonomial_transformations.semimonomial_transformation_group.SemimonomialTransformationGroup` if you would like to modify this element simultaneously diff --git a/src/sage/coding/cyclic_code.py b/src/sage/coding/cyclic_code.py index 38894321459..342b40d45c9 100644 --- a/src/sage/coding/cyclic_code.py +++ b/src/sage/coding/cyclic_code.py @@ -51,7 +51,7 @@ def find_generator_polynomial(code, check=True): r""" - Returns a possible generator polynomial for ``code``. + Return a possible generator polynomial for ``code``. If the code is cyclic, the generator polynomial is the gcd of all the polynomial forms of the codewords. Conversely, if this gcd exactly @@ -96,7 +96,7 @@ def find_generator_polynomial(code, check=True): def _to_complete_list(poly, length): r""" - Returns the vector of length exactly ``length`` corresponding to the + Return the vector of length exactly ``length`` corresponding to the coefficients of the provided polynomial. If needed, zeros are added. INPUT: @@ -123,7 +123,7 @@ def _to_complete_list(poly, length): def bch_bound(n, D, arithmetic=False): r""" - Returns the BCH bound obtained for a cyclic code of length ``n`` and + Return the BCH bound obtained for a cyclic code of length ``n`` and defining set ``D``. Consider a cyclic code `C`, with defining set `D`, length `n`, and minimum @@ -213,7 +213,7 @@ class CyclicCode(AbstractLinearCode): r""" Representation of a cyclic code. - We propose three different ways to create a new CyclicCode, either by + We propose three different ways to create a new :class:`CyclicCode`, either by providing: - the generator polynomial and the length (1) @@ -225,7 +225,7 @@ class CyclicCode(AbstractLinearCode): cyclic codes such that its length `n` and field order `q` are coprimes. Depending on which behaviour you want, you need to specify the names of the - arguments to CyclicCode. See EXAMPLES section below for details. + arguments to :class:`CyclicCode`. See EXAMPLES section below for details. INPUT: @@ -466,7 +466,7 @@ def __init__(self, generator_pol=None, length=None, code=None, check=True, def __contains__(self, word): r""" - Returns ``True`` if ``word`` belongs to ``self``, ``False`` otherwise. + Return ``True`` if ``word`` belongs to ``self``, ``False`` otherwise. INPUT: @@ -514,7 +514,7 @@ def __eq__(self, other): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -531,7 +531,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -707,7 +707,7 @@ def primitive_root(self): @cached_method def check_polynomial(self): r""" - Returns the check polynomial of ``self``. + Return the check polynomial of ``self``. Let `C` be a cyclic code of length `n` and `g` its generator polynomial. The following: `h = \frac{x^n - 1}{g(x)}` is called `C`'s @@ -731,7 +731,7 @@ def check_polynomial(self): @cached_method def parity_check_matrix(self): r""" - Returns the parity check matrix of ``self``. + Return the parity check matrix of ``self``. The parity check matrix of a linear code `C` corresponds to the generator matrix of the dual code of `C`. @@ -757,7 +757,7 @@ def parity_check_matrix(self): def bch_bound(self, arithmetic=False): r""" - Returns the BCH bound of ``self`` which is a bound on ``self`` + Return the BCH bound of ``self`` which is a bound on ``self`` minimum distance. See :meth:`sage.coding.cyclic_code.bch_bound` for details. @@ -793,7 +793,7 @@ def bch_bound(self, arithmetic=False): def surrounding_bch_code(self): r""" - Returns the surrounding BCH code of ``self``. + Return the surrounding BCH code of ``self``. EXAMPLES:: @@ -820,7 +820,7 @@ class CyclicCodePolynomialEncoder(Encoder): and let `g` be its generator polynomial. This encoder encodes any polynomial `p \in F[x]_{2: - f = R(C0.sd_zeta_polynomial()) - print([n,i,[z[0].abs() for z in f.roots()]]) - + sage: R = PolynomialRing(CC,"T") # not tested + sage: T = R.gen() # not tested + sage: for n in [4,6,8,10,12,14,16,18,20,22]: # not tested + ....: C = self_dual_binary_codes(n); m = len(C["%s"%n].keys()) + ....: for i in range(m): + ....: C0 = C["%s"%n]["%s"%i]["code"] + ....: if C0.minimum_distance()>2: + ....: f = R(C0.sd_zeta_polynomial()) + ....: print([n,i,[z[0].abs() for z in f.roots()]]) You should get lists of numbers equal to 0.707106781186548. Here's a rather naive construction of self-dual codes in the binary case: -For even m, let A_m denote the mxm matrix over GF(2) given by adding +For even `m`, let `A_m` denote the `m\times m` matrix over `\GF{2}` given by adding the all 1's matrix to the identity matrix (in -``MatrixSpace(GF(2),m,m)`` of course). If M_1, ..., M_r are square -matrices, let `diag(M_1,M_2,...,M_r)` denote the"block diagonal" -matrix with the `M_i` 's on the diagonal and 0's elsewhere. Let +``MatrixSpace(GF(2),m,m)`` of course). If `M_1, ..., M_r` are square +matrices, let `diag(M_1,M_2,...,M_r)` denote the "block diagonal" +matrix with the matrices `M_i` on the diagonal and 0's elsewhere. Let `C(m_1,...,m_r,s)` denote the linear code with generator matrix having block form `G = (I, A)`, where `A = diag(A_{m_1},A_{m_2},...,A_{m_r},I_s)`, for some -(even) `m_i` 's and `s`, where +(even) `m_i`'s and `s`, where `m_1+m_2+...+m_r+s=n/2`. Note: Such codes `C(m_1,...,m_r,s)` are SD. @@ -256,25 +255,25 @@ def _H8(): def self_dual_binary_codes(n): r""" - Returns the dictionary of inequivalent binary self dual codes of length n. + Return the dictionary of inequivalent binary self dual codes of length `n`. - For n=4 even, returns the sd codes of a given length, up to (perm) + For `n=4` even, returns the sd codes of a given length, up to (perm) equivalence, the (perm) aut gp, and the type. - The number of inequiv "diagonal" sd binary codes in the database of + The number of inequivalent "diagonal" sd binary codes in the database of length n is ("diagonal" is defined by the conjecture above) is the - same as the restricted partition number of n, where only integers - from the set 1,4,6,8,... are allowed. This is the coefficient of + same as the restricted partition number of `n`, where only integers + from the set 1, 4, 6, 8, ... are allowed. This is the coefficient of `x^n` in the series expansion `(1-x)^{-1}\prod_{2^\infty (1-x^{2j})^{-1}}`. Typing the - command f = (1-x)(-1)\*prod([(1-x(2\*j))(-1) for j in range(2,18)]) + command ``f = (1-x)(-1)\*prod([(1-x(2\*j))(-1) for j in range(2,18)])`` into Sage, we obtain for the coeffs of `x^4`, `x^6`, ... [1, 1, 2, 2, 3, 3, 5, 5, 7, 7, 11, 11, 15, 15, 22, 22, 30, 30, 42, 42, 56, 56, 77, 77, 101, 101, 135, 135, 176, 176, 231] These numbers grow too slowly to account for all the sd codes (see Huffman+Pless' Table 9.1, referenced above). In fact, in - Table 9.10 of [HP2003]_, the number B_n of inequivalent sd binary codes - of length n is given:: + Table 9.10 of [HP2003]_, the number `B_n` of inequivalent sd binary codes + of length `n` is given:: n 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 B_n 1 1 1 2 2 3 4 7 9 16 25 55 103 261 731 @@ -289,7 +288,7 @@ def self_dual_binary_codes(n): True sage: C["10"]["1"]["code"] == C["10"]["1"]["code"].dual_code() True - sage: len(C["10"].keys()) # number of inequiv sd codes of length 10 + sage: len(C["10"].keys()) # number of inequiv sd codes of length 10 2 sage: C = codes.databases.self_dual_binary_codes(12) sage: C["12"]["0"]["code"] == C["12"]["0"]["code"].dual_code() diff --git a/src/sage/coding/source_coding/huffman.py b/src/sage/coding/source_coding/huffman.py index c8d5258ff3a..1bdf176509e 100644 --- a/src/sage/coding/source_coding/huffman.py +++ b/src/sage/coding/source_coding/huffman.py @@ -102,15 +102,15 @@ class Huffman(SageObject): - ``source`` -- can be either - - A string from which the Huffman encoding should be created. - - - A dictionary that associates to each symbol of an alphabet a numeric - value. If we consider the frequency of each alphabetic symbol, then - ``source`` is considered as the frequency table of the alphabet with - each numeric (non-negative integer) value being the number of - occurrences of a symbol. The numeric values can also represent weights - of the symbols. In that case, the numeric values are not necessarily - integers, but can be real numbers. + - A string from which the Huffman encoding should be created. + + - A dictionary that associates to each symbol of an alphabet a numeric + value. If we consider the frequency of each alphabetic symbol, then + ``source`` is considered as the frequency table of the alphabet with + each numeric (non-negative integer) value being the number of + occurrences of a symbol. The numeric values can also represent weights + of the symbols. In that case, the numeric values are not necessarily + integers, but can be real numbers. In order to construct a Huffman code for an alphabet, we use exactly one of the following methods: diff --git a/src/sage/coding/subfield_subcode.py b/src/sage/coding/subfield_subcode.py index e45a9c41a81..c4f8b984941 100644 --- a/src/sage/coding/subfield_subcode.py +++ b/src/sage/coding/subfield_subcode.py @@ -114,7 +114,7 @@ def __eq__(self, other): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -128,7 +128,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -142,7 +142,7 @@ def _latex_(self): def dimension(self): r""" - Returns the dimension of ``self``. + Return the dimension of ``self``. EXAMPLES:: @@ -155,7 +155,7 @@ def dimension(self): def dimension_upper_bound(self): r""" - Returns an upper bound for the dimension of ``self``. + Return an upper bound for the dimension of ``self``. EXAMPLES:: @@ -168,7 +168,7 @@ def dimension_upper_bound(self): def dimension_lower_bound(self): r""" - Returns a lower bound for the dimension of ``self``. + Return a lower bound for the dimension of ``self``. EXAMPLES:: @@ -185,7 +185,7 @@ def dimension_lower_bound(self): def original_code(self): r""" - Returns the original code of ``self``. + Return the original code of ``self``. EXAMPLES:: @@ -198,7 +198,7 @@ def original_code(self): def embedding(self): r""" - Returns the field embedding between the base field of ``self`` and + Return the field embedding between the base field of ``self`` and the base field of its original code. EXAMPLES:: @@ -216,7 +216,7 @@ def embedding(self): @cached_method def parity_check_matrix(self): r""" - Returns a parity check matrix of ``self``. + Return a parity check matrix of ``self``. EXAMPLES:: @@ -320,7 +320,7 @@ def __init__(self, code, original_decoder = None, **kwargs): def _repr_(self): r""" - Returns a string representation of ``self``. + Return a string representation of ``self``. EXAMPLES:: @@ -334,7 +334,7 @@ def _repr_(self): def _latex_(self): r""" - Returns a latex representation of ``self``. + Return a latex representation of ``self``. EXAMPLES:: @@ -348,7 +348,7 @@ def _latex_(self): def original_decoder(self): r""" - Returns the decoder over the original code that will be used to decode words of + Return the decoder over the original code that will be used to decode words of :meth:`sage.coding.decoder.Decoder.code`. EXAMPLES:: @@ -402,7 +402,7 @@ def decode_to_code(self, y): def decoding_radius(self, **kwargs): r""" - Returns maximal number of errors ``self`` can decode. + Return the maximal number of errors ``self`` can decode. INPUT: From 2384f1db20bf565d5724b4a5f4a19a298a939f0e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 20:18:29 -0700 Subject: [PATCH 097/205] .github/workflows/doc-build.yml: Fix path --- .github/workflows/doc-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 7e8448ab515..d099445d6e0 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -49,7 +49,7 @@ jobs: if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) # Keep track of changes to built HTML - (cd /sage/local/share/doc/sage/html && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && git add -A && git commit -m "old") + (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && git add -A && git commit -m "old") # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. (cd worktree-image && ./bootstrap && make doc-html) env: From f40fa16c7d7c0cec09224e7ddc9c31272192cdf5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 20:29:46 -0700 Subject: [PATCH 098/205] .github/workflows/doc-build.yml: Ignore some generated files for diff --- .github/workflows/doc-build.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index d099445d6e0..1964c6b79f2 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -49,7 +49,7 @@ jobs: if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) # Keep track of changes to built HTML - (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && git add -A && git commit -m "old") + (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && (echo ".buildinfo"; echo ".inv") > .gitignore; git add -A && git commit -m "old") # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. (cd worktree-image && ./bootstrap && make doc-html) env: @@ -58,9 +58,11 @@ jobs: - name: Copy docs run: | + set -ex mkdir -p ./docs # Create changelog - (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git diff --name-only && rm -rf .git) | tee ./docs/CHANGES.txt + (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git diff --name-only) | tee ./docs/CHANGES.txt + (cd /sage/local/share/doc/sage/html/en && git diff; rm -rf .git) | head -n400 sed -E 's,(.*),

\1,' ./docs/CHANGES.txt > ./docs/CHANGES.html # For some reason the deploy step below cannot find /sage/... # So copy everything from there to local folder From 29fce00171f368fb0d6b39399c0ca28726dfeed4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 15:58:52 -0700 Subject: [PATCH 099/205] 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 100/205] 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 c865882d4f4e5babd2edbd1bbeb2da94a0a12ac2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 6 Jun 2023 09:24:47 -0700 Subject: [PATCH 101/205] sage -t --new: Handle '# sage.doctest: optional' directives --- src/sage/doctest/control.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index c2e9f927e05..abaa33f6239 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -866,11 +866,12 @@ def all_doc_sources(): data = line.strip().split(' ') status, filename = data[0], data[-1] if (set(status).issubset("MARCU") - and filename.startswith("src/sage") - and (filename.endswith(".py") or - filename.endswith(".pyx") or - filename.endswith(".rst"))): - self.files.append(os.path.relpath(opj(SAGE_ROOT,filename))) + and filename.startswith("src/sage") + and (filename.endswith(".py") or + filename.endswith(".pyx") or + filename.endswith(".rst")) + and not skipfile(opj(SAGE_ROOT, filename), self.options.optional)): + self.files.append(os.path.relpath(opj(SAGE_ROOT, filename))) def expand_files_into_sources(self): r""" From c03926444cb1ed39645b129413db074b810239e7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 6 Jun 2023 10:06:37 -0700 Subject: [PATCH 102/205] src/sage/coding/code_constructions.py: Make some docstrings raw --- src/sage/coding/code_constructions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/coding/code_constructions.py b/src/sage/coding/code_constructions.py index abd1d3170d9..946bb0112a0 100644 --- a/src/sage/coding/code_constructions.py +++ b/src/sage/coding/code_constructions.py @@ -540,7 +540,7 @@ def QuadraticResidueCode(n,F): return QuadraticResidueCodeOddPair(n,F)[0] def QuadraticResidueCodeEvenPair(n,F): - """ + r""" Quadratic residue codes of a given odd prime length and base ring either don't exist at all or occur as 4-tuples - a pair of "odd-like" codes and a pair of "even-like" codes. If `n > 2` is prime @@ -606,7 +606,7 @@ def QuadraticResidueCodeEvenPair(n,F): def QuadraticResidueCodeOddPair(n,F): - """ + r""" Quadratic residue codes of a given odd prime length and base ring either don't exist at all or occur as 4-tuples - a pair of "odd-like" codes and a pair of "even-like" codes. If n 2 is prime From 21c524072fe0ef3f5dfeab3367d4cefbc6eb45ed Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 6 Jun 2023 12:01:59 -0700 Subject: [PATCH 103/205] build/pkgs/{ecl,maxima}: Make info an order-only dependency --- build/pkgs/ecl/dependencies | 2 +- build/pkgs/ecl/dependencies_order_only | 1 + build/pkgs/maxima/dependencies | 2 +- build/pkgs/maxima/dependencies_order_only | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 build/pkgs/ecl/dependencies_order_only create mode 100644 build/pkgs/maxima/dependencies_order_only diff --git a/build/pkgs/ecl/dependencies b/build/pkgs/ecl/dependencies index 51a953403e9..cda6316bf5a 100644 --- a/build/pkgs/ecl/dependencies +++ b/build/pkgs/ecl/dependencies @@ -1,4 +1,4 @@ -$(MP_LIBRARY) readline gc libffi info +$(MP_LIBRARY) readline gc libffi ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/ecl/dependencies_order_only b/build/pkgs/ecl/dependencies_order_only new file mode 100644 index 00000000000..55021245387 --- /dev/null +++ b/build/pkgs/ecl/dependencies_order_only @@ -0,0 +1 @@ +info diff --git a/build/pkgs/maxima/dependencies b/build/pkgs/maxima/dependencies index 55c7e0d8d14..fffb89e2050 100644 --- a/build/pkgs/maxima/dependencies +++ b/build/pkgs/maxima/dependencies @@ -1,4 +1,4 @@ -ecl info +ecl ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/maxima/dependencies_order_only b/build/pkgs/maxima/dependencies_order_only new file mode 100644 index 00000000000..55021245387 --- /dev/null +++ b/build/pkgs/maxima/dependencies_order_only @@ -0,0 +1 @@ +info From 60c2357d68fc124185a48edfc63de519234f726e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 6 Jun 2023 21:19:32 +0200 Subject: [PATCH 104/205] fix in libgap.Group --- src/sage/combinat/root_system/weyl_group.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/root_system/weyl_group.py b/src/sage/combinat/root_system/weyl_group.py index 49880e9c340..0a4be1eb38f 100644 --- a/src/sage/combinat/root_system/weyl_group.py +++ b/src/sage/combinat/root_system/weyl_group.py @@ -252,7 +252,7 @@ def __init__(self, domain, prefix): for i in self.index_set()] from sage.libs.gap.libgap import libgap if not gens_matrix: - libgap_group = libgap.Group([], 1) + libgap_group = libgap.Group([], matrix(ZZ, 1, 1, [1])) else: libgap_group = libgap.Group(gens_matrix) degree = ZZ(self.domain().dimension()) From eb0ef342fb9810a17b350040573209566ce9f444 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 6 Jun 2023 12:33:27 -0700 Subject: [PATCH 105/205] .github/workflows/doc-build.yml: Fall back to non-incremental build&docbuild on error --- .github/workflows/build.yml | 9 ++++++--- .github/workflows/doc-build.yml | 20 +++++++++++++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2abe99d8aae..e65542d5cf1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,9 +39,8 @@ jobs: eval $(sage-print-system-package-command auto update) eval $(sage-print-system-package-command auto --spkg --yes --no-install-recommends install git) - - name: Incremental build and test - if: always() && steps.prepare.outcome == 'success' - id: incremental + - name: Add prebuilt tree as a worktree + id: worktree run: | set -ex git config --global user.email "ci-sage@example.com" @@ -66,6 +65,10 @@ jobs: rm -rf worktree-image && ln -s /sage worktree-image if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) + + - name: Incremental build and test + id: incremental + run: | # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. # We run tests with "sage -t --new"; this only tests the uncommitted changes. (cd worktree-image && ./bootstrap && make build && ./sage -t --new -p2) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 1964c6b79f2..9215c2f4898 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -23,7 +23,8 @@ jobs: run: | apt-get update && apt-get install -y git zip - - name: Build + - name: Add prebuilt tree as a worktree + id: worktree run: | set -ex git config --global user.email "ci-sage@example.com" @@ -50,13 +51,29 @@ jobs: (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) # Keep track of changes to built HTML (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && (echo ".buildinfo"; echo ".inv") > .gitignore; git add -A && git commit -m "old") + + - name: Incremental build + id: incremental + run: | # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. (cd worktree-image && ./bootstrap && make doc-html) env: MAKE: make -j2 SAGE_NUM_THREADS: 2 + - name: Build (fallback to non-incremental) + id: build + if: always() && steps.worktree.outcome == 'success' && steps.incremental.outcome != 'success' + run: | + set -ex + (cd worktree-image && ./bootstrap && make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage && ./config.status && make doc-html) + env: + MAKE: make -j2 + SAGE_NUM_THREADS: 2 + - name: Copy docs + id: copy + if: always() && (steps.incremental.outcome == 'success' || steps.build.outcome == 'success') run: | set -ex mkdir -p ./docs @@ -72,6 +89,7 @@ jobs: zip -r docs.zip docs - name: Upload docs + if: always() && steps.copy.outcome == 'success' uses: actions/upload-artifact@v3 with: name: docs From bf36b61a56bd3d2b525c107a6db8dff820adbb69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 6 Jun 2023 22:08:48 +0200 Subject: [PATCH 106/205] fix for trivial group --- src/sage/groups/group.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/groups/group.pyx b/src/sage/groups/group.pyx index 36f18d701b2..3635c0a1481 100644 --- a/src/sage/groups/group.pyx +++ b/src/sage/groups/group.pyx @@ -216,7 +216,7 @@ cdef class Group(Parent): f0*f1*f2*f3 """ from sage.misc.misc_c import prod - return prod(self.gens()) + return self.prod(self.gens()) def quotient(self, H, **kwds): """ From a423367223d9367608ff520064098457bfa2470f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 6 Jun 2023 16:38:28 -0700 Subject: [PATCH 107/205] .github/workflows/build.yml: Also do the main test in worktree-image --- .github/workflows/build.yml | 47 +++++++++++++++++++-------------- .github/workflows/doc-build.yml | 10 ++++--- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e65542d5cf1..af3d797f73a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,49 +66,55 @@ jobs: if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) - - name: Incremental build and test + - name: Incremental build and test --new id: incremental run: | # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. # We run tests with "sage -t --new"; this only tests the uncommitted changes. - (cd worktree-image && ./bootstrap && make build && ./sage -t --new -p2) + ./bootstrap && make build && ./sage -t --new -p2 + working-directory: ./worktree-image env: MAKE: make -j2 SAGE_NUM_THREADS: 2 - name: Configure new tree - if: always() && steps.prepare.outcome == 'success' + if: always() && steps.worktree.outcome == 'success' run: | # Reuse built SAGE_LOCAL contained in the Docker image ./bootstrap ./configure --enable-build-as-root --prefix=/sage/local --with-sage-venv --enable-editable --enable-download-from-upstream-url - name: Build and test modularized distributions - if: always() && steps.prepare.outcome == 'success' + if: always() && steps.worktree.outcome == 'success' run: make V=0 tox && make pypi-wheels + working-directory: ./worktree-image env: MAKE: make -j2 SAGE_NUM_THREADS: 2 - name: Set up node to install pyright - if: always() && steps.prepare.outcome == 'success' + if: always() && steps.worktree.outcome == 'success' uses: actions/setup-node@v3 with: node-version: '12' - name: Install pyright - if: always() && steps.prepare.outcome == 'success' + if: always() && steps.worktree.outcome == 'success' # Fix to v232 due to bug https://github.com/microsoft/pyright/issues/3239 run: npm install -g pyright@1.1.232 - name: Static code check with pyright - if: always() && steps.prepare.outcome == 'success' - run: pyright - - - name: Build + if: always() && steps.worktree.outcome == 'success' + run: pyright + working-directory: ./worktree-image + + - name: Build (fallback to non-incremental) id: build - if: always() && steps.prepare.outcome == 'success' - run: make build + if: always() && steps.worktree.outcome == 'success' && steps.incremental.outcome != 'success' + run: | + set -ex + ./bootstrap && make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage && ./config.status && make build + working-directory: ./worktree-image env: MAKE: make -j2 SAGE_NUM_THREADS: 2 @@ -118,27 +124,28 @@ jobs: run: | ../sage -python -m pip install coverage pytest-xdist ../sage -python -m coverage run -m pytest -c tox.ini --doctest-modules || true - working-directory: ./src + working-directory: ./worktree-image/src env: # Increase the length of the lines in the "short summary" COLUMNS: 120 - - name: Test - if: always() && steps.build.outcome == 'success' + - name: Test --all --long + if: always() && (steps.incremental.outcome == 'success' || steps.build.outcome == 'success') run: | ../sage -python -m pip install coverage ../sage -python -m coverage run ./bin/sage-runtests --all --long -p2 --random-seed=286735480429121101562228604801325644303 - working-directory: ./src + working-directory: ./worktree-image/src - name: Prepare coverage results - if: always() && steps.build.outcome == 'success' + if: always() && (steps.incremental.outcome == 'success' || steps.build.outcome == 'success') run: | ./venv/bin/python3 -m coverage combine src/.coverage/ ./venv/bin/python3 -m coverage xml find . -name *coverage* - + working-directory: ./worktree-image + - name: Upload coverage to codecov - if: always() && steps.build.outcome == 'success' + if: always() && (steps.incremental.outcome == 'success' || steps.build.outcome == 'success') uses: codecov/codecov-action@v3 with: - files: ./coverage.xml + files: ./worktree-image/coverage.xml diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 9215c2f4898..97bc2b943f4 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -52,21 +52,23 @@ jobs: # Keep track of changes to built HTML (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && (echo ".buildinfo"; echo ".inv") > .gitignore; git add -A && git commit -m "old") - - name: Incremental build + - name: Incremental build and docbuild id: incremental run: | # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. - (cd worktree-image && ./bootstrap && make doc-html) + ./bootstrap && make doc-html + working-directory: ./worktree-image env: MAKE: make -j2 SAGE_NUM_THREADS: 2 - - name: Build (fallback to non-incremental) + - name: Build and docbuild (fallback to non-incremental) id: build if: always() && steps.worktree.outcome == 'success' && steps.incremental.outcome != 'success' run: | set -ex - (cd worktree-image && ./bootstrap && make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage && ./config.status && make doc-html) + ./bootstrap && make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage && ./config.status && make doc-html + working-directory: ./worktree-image env: MAKE: make -j2 SAGE_NUM_THREADS: 2 From 506db04ace018706f9692d597bac1a4349ef95ac Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 6 Jun 2023 17:10:56 -0700 Subject: [PATCH 108/205] .github/workflows/build.yml: Remove an obsolete step --- .github/workflows/build.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index af3d797f73a..2116ef2d515 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -77,13 +77,6 @@ jobs: MAKE: make -j2 SAGE_NUM_THREADS: 2 - - name: Configure new tree - if: always() && steps.worktree.outcome == 'success' - run: | - # Reuse built SAGE_LOCAL contained in the Docker image - ./bootstrap - ./configure --enable-build-as-root --prefix=/sage/local --with-sage-venv --enable-editable --enable-download-from-upstream-url - - name: Build and test modularized distributions if: always() && steps.worktree.outcome == 'success' run: make V=0 tox && make pypi-wheels From 9e3afe3e5e239a8d3f55ec912bc91228157d6d58 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 6 Jun 2023 17:43:18 -0700 Subject: [PATCH 109/205] .github/workflows/docker.yml: Remove defunct steps that refer to Trac --- .github/workflows/docker.yml | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index bf21a83cc60..aa276e590fe 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -105,7 +105,7 @@ on: default: "$BUILD_TAG" type: string # - # For use in upstream CIs + # For use in upstream CIs. sage_trac_* are now ignored and will be removed later. # upstream_artifact: required: false @@ -163,21 +163,6 @@ jobs: sudo apt-get --fix-broken --yes remove $(dpkg-query -f '${Package}\n' -W | grep -E '^(ghc-|google-cloud-sdk|google-chrome|firefox|mysql-server|dotnet-sdk|hhvm|mono)') || echo "(error ignored)" df -h if: inputs.free_disk_space - - name: Check out git-trac-command - uses: actions/checkout@v3 - with: - repository: sagemath/git-trac-command - path: git-trac-command - if: inputs.sage_trac_git != '' - - name: Check out SageMath from trac.sagemath.org - shell: bash {0} - # Random sleep and retry to limit the load on trac.sagemath.org - run: | - git config --global user.email "ci-sage@example.com" - git config --global user.name "ci-sage workflow" - if [ ! -d .git ]; then git init; fi; git remote add trac ${{ inputs.sage_trac_git }} && x=1 && while [ $x -le 5 ]; do x=$(( $x + 1 )); sleep $(( $RANDOM % 60 + 1 )); if git-trac-command/git-trac fetch ${{ inputs.sage_trac_ticket }}; then git merge FETCH_HEAD || echo "(ignored)"; exit 0; fi; sleep 40; done; exit 1 - if: inputs.sage_trac_git != '' - - name: Download upstream artifact uses: actions/download-artifact@v3 with: From 41490d9e5af75d67735c09937f05c7adddd59cd2 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Wed, 7 Jun 2023 11:08:57 +0800 Subject: [PATCH 110/205] 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 9f30a8dae7ace441c536d77b8af32d17521ef7d4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 6 Jun 2023 21:08:23 -0700 Subject: [PATCH 111/205] .github/workflows/doc-build.yml: Include diff in zip --- .github/workflows/doc-build.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 97bc2b943f4..a94916f37d7 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -80,9 +80,11 @@ jobs: set -ex mkdir -p ./docs # Create changelog + echo '## Preview of CHANGES.html' (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git diff --name-only) | tee ./docs/CHANGES.txt - (cd /sage/local/share/doc/sage/html/en && git diff; rm -rf .git) | head -n400 - sed -E 's,(.*),

\1,' ./docs/CHANGES.txt > ./docs/CHANGES.html + (cd /sage/local/share/doc/sage/html/en && git diff; rm -rf .git) > ./docs/html.diff + echo '## Preview of html.diff'; head -n 400 ./docs/html.diff + (echo '

HTML diff'; sed -E 's,(.*),

\1,' ./docs/CHANGES.txt) > ./docs/CHANGES.html # For some reason the deploy step below cannot find /sage/... # So copy everything from there to local folder # We also need to replace the symlinks because netlify is not following them From eb6a7066dd1f6a0385efd6ef720b63848885297f Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Wed, 7 Jun 2023 17:14:11 +0900 Subject: [PATCH 112/205] Adding a _test for the Jordan axioms and fixing a docstring. --- src/sage/algebras/jordan_algebra.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/sage/algebras/jordan_algebra.py b/src/sage/algebras/jordan_algebra.py index d81293f1bad..81bdecbce3e 100644 --- a/src/sage/algebras/jordan_algebra.py +++ b/src/sage/algebras/jordan_algebra.py @@ -213,6 +213,29 @@ def __classcall_private__(self, arg0, arg1=None, names=None): return JordanAlgebraSymmetricBilinear(arg0, arg1, names=names) + def _test_jordan_relations(self, **options): + r""" + Test the Jordan algebra relations. + + The Jordan algebra relations are + + - `xy = yx`, and + - `(xy)(xx) = x(y(xx))` (the Jordan identity). + + EXAMPLES:: + + sage: O = OctonionAlgebra(GF(7), 1, 3, 4) + sage: J = JordanAlgebra(O) + sage: J._test_jordan_relations() + """ + tester = self._tester(**options) + S = tester.some_elements() + from sage.misc.misc import some_tuples + for x, y in some_tuples(S, 2, tester._max_runs): + tester.assertEqual(x * y, y * x) + tester.assertEqual((x * y) * (x * x), x * (y * (x * x))) + + class SpecialJordanAlgebra(JordanAlgebra): r""" A (special) Jordan algebra `A^+` from an associative algebra `A`. @@ -1068,7 +1091,7 @@ def bar(self): class ExceptionalJordanAlgebra(JordanAlgebra): r""" The exceptional `27` dimensional Jordan algebra as self-adjoint - `3 \times 3` over an octonion algebra. + `3 \times 3` matrix over an octonion algebra. Let `\mathbf{O}` be the :class:`OctonionAlgebra` over a commutative ring `R` of characteristic not equal to `2`. The *exceptional Jordan From f58dde78165bba0cfc584ec3c99a1f70957e8e74 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Wed, 7 Jun 2023 10:31:26 +0100 Subject: [PATCH 113/205] missing "`" added --- src/sage/coding/code_bounds.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/coding/code_bounds.py b/src/sage/coding/code_bounds.py index 706bcb2cb34..52e47b48c16 100644 --- a/src/sage/coding/code_bounds.py +++ b/src/sage/coding/code_bounds.py @@ -137,7 +137,7 @@ - ``elias_bound_asymp(delta,q)``, asymptotic analog of Elias bound. -- ``hamming_upper_bound(n,q,d)` +- ``hamming_upper_bound(n,q,d)`` - ``hamming_bound_asymp(delta,q)``, asymptotic analog of Hamming bound. From b13cbf4c381a983dd62f8595cc7e9ee7b3fbc5da Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 7 Jun 2023 07:55:30 -0700 Subject: [PATCH 114/205] .github/workflows/doc-build.yml: Reduce verbosity --- .github/workflows/doc-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index a94916f37d7..dde57a7057f 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -50,7 +50,7 @@ jobs: if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) # Keep track of changes to built HTML - (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && (echo ".buildinfo"; echo ".inv") > .gitignore; git add -A && git commit -m "old") + (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && (echo ".buildinfo"; echo ".inv") > .gitignore; git add -A && git commit --quiet -m "old") - name: Incremental build and docbuild id: incremental From 136337ceceac4c5b911aafecc284e354a9d8ca60 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 7 Jun 2023 07:55:46 -0700 Subject: [PATCH 115/205] .github/workflows/doc-build.yml: Remove redundant bootstrap --- .github/workflows/doc-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index dde57a7057f..dd1a0364fa5 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -67,7 +67,7 @@ jobs: if: always() && steps.worktree.outcome == 'success' && steps.incremental.outcome != 'success' run: | set -ex - ./bootstrap && make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage && ./config.status && make doc-html + make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage && ./config.status && make doc-html working-directory: ./worktree-image env: MAKE: make -j2 From 1d9027d563b0a68a1e04dea4ffca05e91ac02845 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 24 Apr 2023 22:36:52 -0700 Subject: [PATCH 116/205] sage.combinat.combinat_cython: Split out some modules --- src/sage/combinat/combinat_cython.pxd | 3 - src/sage/combinat/combinat_cython.pyx | 423 +----------------- .../posets/linear_extension_iterator.pyx | 287 ++++++++++++ src/sage/combinat/set_partition_iterator.pyx | 129 ++++++ 4 files changed, 423 insertions(+), 419 deletions(-) create mode 100644 src/sage/combinat/posets/linear_extension_iterator.pyx create mode 100644 src/sage/combinat/set_partition_iterator.pyx diff --git a/src/sage/combinat/combinat_cython.pxd b/src/sage/combinat/combinat_cython.pxd index c27be7b0bed..40cae00a781 100644 --- a/src/sage/combinat/combinat_cython.pxd +++ b/src/sage/combinat/combinat_cython.pxd @@ -2,7 +2,4 @@ from sage.libs.gmp.all cimport mpz_t cdef mpz_stirling_s2(mpz_t s, unsigned long n, unsigned long k) -cdef list from_word(list w, list base_set) - cdef list convert(Py_ssize_t* f, Py_ssize_t n) - diff --git a/src/sage/combinat/combinat_cython.pyx b/src/sage/combinat/combinat_cython.pyx index 1f8c56cc16d..1f0fb649ef0 100644 --- a/src/sage/combinat/combinat_cython.pyx +++ b/src/sage/combinat/combinat_cython.pyx @@ -16,12 +16,16 @@ AUTHORS: Lyndon words, and perfect matchings """ -cimport cython - from cysignals.memory cimport check_allocarray, sig_free from sage.libs.gmp.all cimport * from sage.rings.integer cimport Integer +from sage.misc.lazy_import import LazyImport + +set_partition_iterator = LazyImport('sage.combinat.set_partition_iterator', 'set_partition_iterator', deprecation=99999) +set_partition_iterator_blocks = LazyImport('sage.combinat.set_partition_iterator', 'set_partition_iterator_blocks', deprecation=99999) +linear_extension_iterator = LazyImport('sage.combinat.posets.linear_extension_iterator', 'linear_extension_iterator', deprecation=99999) + cdef void mpz_addmul_alt(mpz_t s, mpz_t t, mpz_t u, unsigned long parity): """ @@ -199,133 +203,6 @@ def lyndon_word_iterator(Py_ssize_t n, Py_ssize_t k): while a[i] == n - 1: i -= 1 -##################################################################### -## Set partition iterators - -@cython.wraparound(False) -@cython.boundscheck(False) -cdef list from_word(list w, list base_set): - cdef list sp = [] - cdef Py_ssize_t i - cdef Py_ssize_t b - for i in range(len(w)): - b = (w[i]) - x = base_set[i] - if len(sp) <= b: - sp.append([x]) - else: - sp[b].append(x) - return sp - -@cython.wraparound(False) -@cython.boundscheck(False) -def set_partition_iterator(base_set): - """ - A fast iterator for the set partitions of the base set, which - returns lists of lists instead of set partitions types. - - EXAMPLES:: - - sage: from sage.combinat.combinat_cython import set_partition_iterator - sage: list(set_partition_iterator([1,-1,x])) - [[[1, -1, x]], - [[1, -1], [x]], - [[1, x], [-1]], - [[1], [-1, x]], - [[1], [-1], [x]]] - """ - cdef list base = list(base_set) - - # Knuth, TAOCP 4A 7.2.1.5, Algorithm H - cdef Py_ssize_t N = len(base) - # H1: initialize - cdef list a = [0] * N - if N <= 1: - yield from_word(a, base) - return - - cdef list b = [1] * N - cdef Py_ssize_t j - cdef Py_ssize_t last = N - 1 - while True: - # H2: visit - yield from_word(a, base) - if a[last] == b[last]: - # H4: find j - j = N - 2 - while a[j] == b[j]: - j -= 1 - # H5: increase a_j - if j == 0: - break - a[j] += 1 - # H6: zero out a_{j+1},...,a_{n-1} - b[last] = b[j] + int(a[j] == b[j]) - j += 1 - while j < N - 1: - a[j] = 0 - b[j] = b[last] - j += 1 - a[last] = 0 - else: - # H3: increase a_{n-1} - a[last] += 1 - -@cython.wraparound(False) -@cython.boundscheck(False) -def _set_partition_block_gen(Py_ssize_t n, Py_ssize_t k, list a): - r""" - Recursively generate set partitions of ``n`` with fixed block - size ``k`` using Algorithm 4.23 from [Rus2003]_. - ``a`` is a list of size ``n``. - - EXAMPLES:: - - sage: from sage.combinat.combinat_cython import _set_partition_block_gen - sage: a = list(range(3)) - sage: for p in _set_partition_block_gen(3, 2, a): - ....: print(p) - [0, 1, 0] - [0, 1, 1] - [0, 0, 1] - """ - cdef Py_ssize_t i - if n == k: - yield a - return - - for i in range(k): - a[n-1] = i - for P in _set_partition_block_gen(n-1, k, a): - yield P - a[n-1] = n-1 - if k > 1: - a[n-1] = k-1 - for P in _set_partition_block_gen(n-1, k-1, a): - yield P - a[n-1] = n-1 - -@cython.wraparound(False) -@cython.boundscheck(False) -def set_partition_iterator_blocks(base_set, Py_ssize_t k): - """ - A fast iterator for the set partitions of the base set into the - specified number of blocks, which returns lists of lists - instead of set partitions types. - - EXAMPLES:: - - sage: from sage.combinat.combinat_cython import set_partition_iterator_blocks - sage: list(set_partition_iterator_blocks([1,-1,x], 2)) - [[[1, x], [-1]], [[1], [-1, x]], [[1, -1], [x]]] - """ - cdef list base = list(base_set) - cdef Py_ssize_t n = len(base) - cdef list a = list(range(n)) - # TODO: implement _set_partition_block_gen as an iterative algorithm - for P in _set_partition_block_gen(n, k, a): - yield from_word( P, base) - ## Perfect matchings iterator def perfect_matchings_iterator(Py_ssize_t n): @@ -410,292 +287,6 @@ cdef list convert(Py_ssize_t* f, Py_ssize_t n): ret.append((i, f[i])) return ret -##################################################################### -## Linear extension iterator - -from copy import copy -def _linear_extension_prepare(D): - r""" - The preprocessing routine in Figure 7 of "Generating Linear - Extensions Fast" by Preusse and Ruskey. - - INPUT: - - - ``D``, the Hasse diagram of a poset - - OUTPUT: - - - a triple ``(le, a, b)``, where ``le`` is the first linear - extension, and ``a`` and ``b`` are lists such that ``a[i]`` and - ``b[i]`` are minimal elements of ``D`` after removing ``a[:i]`` - and ``b[:i]``. - - TESTS:: - - sage: from sage.combinat.combinat_cython import _linear_extension_prepare - sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram - sage: _linear_extension_prepare(D) - ([0, 1, 2, 3, 4], [1, 3], [2, 4]) - - """ - dag_copy = copy(D) # this copy is destroyed during preparation - le = [] - a = [] - b = [] - - # the preprocessing routine found in Figure 7 of - # "Generating Linear Extensions Fast" by - # Pruesse and Ruskey - while dag_copy.num_verts() != 0: - # find all the minimal elements of dag_copy - minimal_elements = dag_copy.sources() - if not minimal_elements: - raise ValueError("the digraph must be acyclic to have linear extensions") - elif len(minimal_elements) == 1: - le.append(minimal_elements[0]) - dag_copy.delete_vertex(minimal_elements[0]) - else: - ap = minimal_elements[0] - bp = minimal_elements[1] - a.append(ap) - b.append(bp) - le.append(ap) - le.append(bp) - dag_copy.delete_vertex(ap) - dag_copy.delete_vertex(bp) - - return (le, a, b) - -@cython.wraparound(False) -@cython.boundscheck(False) -cdef void _linear_extension_switch(list _le, list _a, list _b, list _is_plus, Py_ssize_t i): - """ - This implements the ``Switch`` procedure described on page 7 - of "Generating Linear Extensions Fast" by Pruesse and Ruskey. - - If ``i == -1``, then the sign is changed. Otherwise, then - ``_a[i]`` and ``_b[i]`` are transposed. - - """ - cdef Py_ssize_t a_index, b_index - if i == -1: - _is_plus[0] = not _is_plus[0] - else: - a = _a[i] - b = _b[i] - a_index = _le.index(a) - b_index = _le.index(b) - _le[a_index] = b - _le[b_index] = a - _b[i] = a - _a[i] = b - -@cython.wraparound(False) -@cython.boundscheck(False) -cdef bint _linear_extension_right_a(_D, list _le, list _a, list _b, Py_ssize_t i): - """ - Return ``True`` if and only if ``_a[i]`` is incomparable with the - element to its right in ``_le`` and the element to the right is - not ``_b[i]``. - - This is the ``Right`` function described on page 8 of - "Generating Linear Extensions Fast" by Pruesse and Ruskey. - - :: - - sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram # not tested - sage: _linear_extension_right_a(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 0) # not tested - False - sage: _linear_extension_right_a(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 1) # not tested - False - - """ - cdef Py_ssize_t yindex - x = _a[i] - yindex = _le.index(x) + 1 - if yindex >= len(_le): - return False - y = _le[yindex] - return y != _b[i] and _D.are_incomparable(x, y) - -@cython.wraparound(False) -@cython.boundscheck(False) -cdef bint _linear_extension_right_b(_D, list _le, list _a, list _b, Py_ssize_t i): - """ - Return True if and only if ``_b[i]`` is incomparable with the - elements to its right in ``_le``. - - This is the ``Right`` function described on page 8 of - "Generating Linear Extensions Fast" by Pruesse and Ruskey. - - :: - - sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram # not tested - sage: _linear_extension_right_b(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 0) # not tested - False - sage: _linear_extension_right_b(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 1) # not tested - False - - """ - cdef Py_ssize_t yindex - x = _b[i] - yindex = _le.index(x) + 1 - if yindex >= len(_le): - return False - y = _le[yindex] - return _D.are_incomparable(x, y) - -@cython.wraparound(False) -@cython.boundscheck(False) -def _linear_extension_gen(_D, list _le, list _a, list _b, list _is_plus, Py_ssize_t i): - """ - This a Python version of the GenLE routine found in Figure 8 - of "Generating Linear Extensions Fast" by Pruesse and Ruskey. - - TESTS:: - - sage: from sage.combinat.combinat_cython import _linear_extension_prepare, _linear_extension_gen - sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram - sage: le, a, b = _linear_extension_prepare(D) - sage: [e for e in _linear_extension_gen(D, le, a, b, [True], len(a)-1)] - [[0, 2, 1, 3, 4]] - - """ - cdef int mra, mrb, mla - cdef Py_ssize_t index, index1 - cdef bint typical - if i == -1: - return - - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - mrb = 0 - typical = False - while _linear_extension_right_b(_D, _le, _a, _b, i): - mrb += 1 - # move_right - index = _le.index(_b[i]) - index1 = index + 1 - _le[index] = _le[index1] - _le[index1] = _b[i] - if _is_plus[0]: - yield _le[:] - - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - mra = 0 - while _linear_extension_right_a(_D, _le, _a, _b, i): - typical = True - mra += 1 - # move_right - index = _le.index(_a[i]) - index1 = index+1 - _le[index] = _le[index1] - _le[index1] = _a[i] - if _is_plus[0]: - yield _le[:] - - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - - if typical: - _linear_extension_switch(_le, _a, _b, _is_plus, i-1) - if _is_plus[0]: - yield _le[:] - - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - if mrb % 2 == 1: - mla = mra - 1 - else: - mla = mra + 1 - for _ in range(mla): - # move_left - index = _le.index(_a[i]) - index1 = index-1 - _le[index] = _le[index1] - _le[index1] = _a[i] - if _is_plus[0]: - yield _le[:] - - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - - if typical and (mrb % 2 == 1): - # move_left - index = _le.index(_a[i]) - index1 = index-1 - _le[index] = _le[index1] - _le[index1] = _a[i] - if _is_plus[0]: - yield _le[:] - else: - _linear_extension_switch(_le, _a, _b, _is_plus, i-1) - if _is_plus[0]: - yield _le[:] - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - for _ in range(mrb): - # move_left - index = _le.index(_b[i]) - index1 = index-1 - _le[index] = _le[index1] - _le[index1] = _b[i] - if _is_plus[0]: - yield _le[:] - - for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): - yield e - - -def linear_extension_iterator(D): - """ - Iterate over the linear extensions of the poset. - - The list ``_le`` keeps track of the current linear extensions. The - boolean variable ``is_plus`` keeps track of the "sign". - - INPUT: - - - ``D``, the Hasse diagram of a poset. - - .. WARNING:: - - It is assumed that ``D`` is not modified while the linear - extensions are generated. - - EXAMPLES:: - - sage: from sage.combinat.combinat_cython import linear_extension_iterator - sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram - sage: list(linear_extension_iterator(D)) - [[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: D = posets.BooleanLattice(3)._hasse_diagram - sage: len(list(linear_extension_iterator(D))) - 48 - - sage: D = posets.AntichainPoset(9)._hasse_diagram - sage: len(list(linear_extension_iterator(D))) == factorial(9) # long time - True - """ - _le, _a, _b = _linear_extension_prepare(D) - _max_pair = len(_a) - 1 - _is_plus = [True] # this is modified by _linear_extension_switch - - yield _le[:] - for e in _linear_extension_gen(D, _le, _a, _b, _is_plus, _max_pair): - yield e - _linear_extension_switch(_le, _a, _b, _is_plus, _max_pair) - if _is_plus[0]: - yield _le[:] - for e in _linear_extension_gen(D, _le, _a, _b, _is_plus, _max_pair): - yield e - ##################################################################### ## Set partition composition @@ -711,7 +302,7 @@ def set_partition_composition(tuple sp1, tuple sp2): sage: sp1 = ((1,-2),(2,-1)) sage: sp2 = ((1,-2),(2,-1)) sage: p, c = set_partition_composition(sp1, sp2) - sage: (SetPartition(p), c) == (SetPartition([[1,-1],[2,-2]]), 0) + sage: (SetPartition(p), c) == (SetPartition([[1,-1],[2,-2]]), 0) # optional - sage.combinat True """ cdef int num_loops = 0 # The number of loops removed diff --git a/src/sage/combinat/posets/linear_extension_iterator.pyx b/src/sage/combinat/posets/linear_extension_iterator.pyx new file mode 100644 index 00000000000..21437e91005 --- /dev/null +++ b/src/sage/combinat/posets/linear_extension_iterator.pyx @@ -0,0 +1,287 @@ +r""" +Fast linear extension iterator +""" +cimport cython + +from copy import copy +def _linear_extension_prepare(D): + r""" + The preprocessing routine in Figure 7 of "Generating Linear + Extensions Fast" by Preusse and Ruskey. + + INPUT: + + - ``D``, the Hasse diagram of a poset + + OUTPUT: + + - a triple ``(le, a, b)``, where ``le`` is the first linear + extension, and ``a`` and ``b`` are lists such that ``a[i]`` and + ``b[i]`` are minimal elements of ``D`` after removing ``a[:i]`` + and ``b[:i]``. + + TESTS:: + + sage: from sage.combinat.posets.linear_extension_iterator import _linear_extension_prepare + sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram + sage: _linear_extension_prepare(D) + ([0, 1, 2, 3, 4], [1, 3], [2, 4]) + + """ + dag_copy = copy(D) # this copy is destroyed during preparation + le = [] + a = [] + b = [] + + # the preprocessing routine found in Figure 7 of + # "Generating Linear Extensions Fast" by + # Pruesse and Ruskey + while dag_copy.num_verts() != 0: + # find all the minimal elements of dag_copy + minimal_elements = dag_copy.sources() + if not minimal_elements: + raise ValueError("the digraph must be acyclic to have linear extensions") + elif len(minimal_elements) == 1: + le.append(minimal_elements[0]) + dag_copy.delete_vertex(minimal_elements[0]) + else: + ap = minimal_elements[0] + bp = minimal_elements[1] + a.append(ap) + b.append(bp) + le.append(ap) + le.append(bp) + dag_copy.delete_vertex(ap) + dag_copy.delete_vertex(bp) + + return (le, a, b) + +@cython.wraparound(False) +@cython.boundscheck(False) +cdef void _linear_extension_switch(list _le, list _a, list _b, list _is_plus, Py_ssize_t i): + """ + This implements the ``Switch`` procedure described on page 7 + of "Generating Linear Extensions Fast" by Pruesse and Ruskey. + + If ``i == -1``, then the sign is changed. Otherwise, then + ``_a[i]`` and ``_b[i]`` are transposed. + + """ + cdef Py_ssize_t a_index, b_index + if i == -1: + _is_plus[0] = not _is_plus[0] + else: + a = _a[i] + b = _b[i] + a_index = _le.index(a) + b_index = _le.index(b) + _le[a_index] = b + _le[b_index] = a + _b[i] = a + _a[i] = b + +@cython.wraparound(False) +@cython.boundscheck(False) +cdef bint _linear_extension_right_a(_D, list _le, list _a, list _b, Py_ssize_t i): + """ + Return ``True`` if and only if ``_a[i]`` is incomparable with the + element to its right in ``_le`` and the element to the right is + not ``_b[i]``. + + This is the ``Right`` function described on page 8 of + "Generating Linear Extensions Fast" by Pruesse and Ruskey. + + :: + + sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram # not tested + sage: _linear_extension_right_a(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 0) # not tested + False + sage: _linear_extension_right_a(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 1) # not tested + False + + """ + cdef Py_ssize_t yindex + x = _a[i] + yindex = _le.index(x) + 1 + if yindex >= len(_le): + return False + y = _le[yindex] + return y != _b[i] and _D.are_incomparable(x, y) + +@cython.wraparound(False) +@cython.boundscheck(False) +cdef bint _linear_extension_right_b(_D, list _le, list _a, list _b, Py_ssize_t i): + """ + Return True if and only if ``_b[i]`` is incomparable with the + elements to its right in ``_le``. + + This is the ``Right`` function described on page 8 of + "Generating Linear Extensions Fast" by Pruesse and Ruskey. + + :: + + sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram # not tested + sage: _linear_extension_right_b(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 0) # not tested + False + sage: _linear_extension_right_b(D, [0, 1, 2, 4, 3], [1, 4], [2, 3], 1) # not tested + False + + """ + cdef Py_ssize_t yindex + x = _b[i] + yindex = _le.index(x) + 1 + if yindex >= len(_le): + return False + y = _le[yindex] + return _D.are_incomparable(x, y) + +@cython.wraparound(False) +@cython.boundscheck(False) +def _linear_extension_gen(_D, list _le, list _a, list _b, list _is_plus, Py_ssize_t i): + """ + This a Python version of the GenLE routine found in Figure 8 + of "Generating Linear Extensions Fast" by Pruesse and Ruskey. + + TESTS:: + + sage: from sage.combinat.posets.linear_extension_iterator import _linear_extension_prepare, _linear_extension_gen + sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram + sage: le, a, b = _linear_extension_prepare(D) + sage: [e for e in _linear_extension_gen(D, le, a, b, [True], len(a)-1)] + [[0, 2, 1, 3, 4]] + + """ + cdef int mra, mrb, mla + cdef Py_ssize_t index, index1 + cdef bint typical + if i == -1: + return + + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + mrb = 0 + typical = False + while _linear_extension_right_b(_D, _le, _a, _b, i): + mrb += 1 + # move_right + index = _le.index(_b[i]) + index1 = index + 1 + _le[index] = _le[index1] + _le[index1] = _b[i] + if _is_plus[0]: + yield _le[:] + + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + mra = 0 + while _linear_extension_right_a(_D, _le, _a, _b, i): + typical = True + mra += 1 + # move_right + index = _le.index(_a[i]) + index1 = index+1 + _le[index] = _le[index1] + _le[index1] = _a[i] + if _is_plus[0]: + yield _le[:] + + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + + if typical: + _linear_extension_switch(_le, _a, _b, _is_plus, i-1) + if _is_plus[0]: + yield _le[:] + + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + if mrb % 2 == 1: + mla = mra - 1 + else: + mla = mra + 1 + for _ in range(mla): + # move_left + index = _le.index(_a[i]) + index1 = index-1 + _le[index] = _le[index1] + _le[index1] = _a[i] + if _is_plus[0]: + yield _le[:] + + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + + if typical and (mrb % 2 == 1): + # move_left + index = _le.index(_a[i]) + index1 = index-1 + _le[index] = _le[index1] + _le[index1] = _a[i] + if _is_plus[0]: + yield _le[:] + else: + _linear_extension_switch(_le, _a, _b, _is_plus, i-1) + if _is_plus[0]: + yield _le[:] + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + for _ in range(mrb): + # move_left + index = _le.index(_b[i]) + index1 = index-1 + _le[index] = _le[index1] + _le[index1] = _b[i] + if _is_plus[0]: + yield _le[:] + + for e in _linear_extension_gen(_D, _le, _a, _b, _is_plus, i-1): + yield e + + +def linear_extension_iterator(D): + """ + Iterate over the linear extensions of the poset. + + The list ``_le`` keeps track of the current linear extensions. The + boolean variable ``is_plus`` keeps track of the "sign". + + INPUT: + + - ``D``, the Hasse diagram of a poset. + + .. WARNING:: + + It is assumed that ``D`` is not modified while the linear + extensions are generated. + + EXAMPLES:: + + sage: from sage.combinat.posets.linear_extension_iterator import linear_extension_iterator + sage: D = Poset({ 0:[1,2], 1:[3], 2:[3,4] })._hasse_diagram + sage: list(linear_extension_iterator(D)) + [[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: D = posets.BooleanLattice(3)._hasse_diagram + sage: len(list(linear_extension_iterator(D))) + 48 + + sage: D = posets.AntichainPoset(9)._hasse_diagram + sage: len(list(linear_extension_iterator(D))) == factorial(9) # long time + True + """ + _le, _a, _b = _linear_extension_prepare(D) + _max_pair = len(_a) - 1 + _is_plus = [True] # this is modified by _linear_extension_switch + + yield _le[:] + for e in _linear_extension_gen(D, _le, _a, _b, _is_plus, _max_pair): + yield e + _linear_extension_switch(_le, _a, _b, _is_plus, _max_pair) + if _is_plus[0]: + yield _le[:] + for e in _linear_extension_gen(D, _le, _a, _b, _is_plus, _max_pair): + yield e diff --git a/src/sage/combinat/set_partition_iterator.pyx b/src/sage/combinat/set_partition_iterator.pyx new file mode 100644 index 00000000000..9b83127d61a --- /dev/null +++ b/src/sage/combinat/set_partition_iterator.pyx @@ -0,0 +1,129 @@ +r""" +Fast set partition iterators +""" +cimport cython + + +@cython.wraparound(False) +@cython.boundscheck(False) +cdef list from_word(list w, list base_set): + cdef list sp = [] + cdef Py_ssize_t i + cdef Py_ssize_t b + for i in range(len(w)): + b = (w[i]) + x = base_set[i] + if len(sp) <= b: + sp.append([x]) + else: + sp[b].append(x) + return sp + +@cython.wraparound(False) +@cython.boundscheck(False) +def set_partition_iterator(base_set): + """ + A fast iterator for the set partitions of the base set, which + returns lists of lists instead of set partitions types. + + EXAMPLES:: + + sage: from sage.combinat.set_partition_iterator import set_partition_iterator + sage: list(set_partition_iterator([1,-1,x])) # optional - sage.symbolic + [[[1, -1, x]], + [[1, -1], [x]], + [[1, x], [-1]], + [[1], [-1, x]], + [[1], [-1], [x]]] + """ + cdef list base = list(base_set) + + # Knuth, TAOCP 4A 7.2.1.5, Algorithm H + cdef Py_ssize_t N = len(base) + # H1: initialize + cdef list a = [0] * N + if N <= 1: + yield from_word(a, base) + return + + cdef list b = [1] * N + cdef Py_ssize_t j + cdef Py_ssize_t last = N - 1 + while True: + # H2: visit + yield from_word(a, base) + if a[last] == b[last]: + # H4: find j + j = N - 2 + while a[j] == b[j]: + j -= 1 + # H5: increase a_j + if j == 0: + break + a[j] += 1 + # H6: zero out a_{j+1},...,a_{n-1} + b[last] = b[j] + int(a[j] == b[j]) + j += 1 + while j < N - 1: + a[j] = 0 + b[j] = b[last] + j += 1 + a[last] = 0 + else: + # H3: increase a_{n-1} + a[last] += 1 + +@cython.wraparound(False) +@cython.boundscheck(False) +def _set_partition_block_gen(Py_ssize_t n, Py_ssize_t k, list a): + r""" + Recursively generate set partitions of ``n`` with fixed block + size ``k`` using Algorithm 4.23 from [Rus2003]_. + ``a`` is a list of size ``n``. + + EXAMPLES:: + + sage: from sage.combinat.set_partition_iterator import _set_partition_block_gen + sage: a = list(range(3)) + sage: for p in _set_partition_block_gen(3, 2, a): + ....: print(p) + [0, 1, 0] + [0, 1, 1] + [0, 0, 1] + """ + cdef Py_ssize_t i + if n == k: + yield a + return + + for i in range(k): + a[n-1] = i + for P in _set_partition_block_gen(n-1, k, a): + yield P + a[n-1] = n-1 + if k > 1: + a[n-1] = k-1 + for P in _set_partition_block_gen(n-1, k-1, a): + yield P + a[n-1] = n-1 + +@cython.wraparound(False) +@cython.boundscheck(False) +def set_partition_iterator_blocks(base_set, Py_ssize_t k): + """ + A fast iterator for the set partitions of the base set into the + specified number of blocks, which returns lists of lists + instead of set partitions types. + + EXAMPLES:: + + sage: from sage.combinat.set_partition_iterator import set_partition_iterator_blocks + sage: list(set_partition_iterator_blocks([1,-1,x], 2)) # optional - sage.symbolic + [[[1, x], [-1]], [[1], [-1, x]], [[1, -1], [x]]] + """ + cdef list base = list(base_set) + cdef Py_ssize_t n = len(base) + cdef list a = list(range(n)) + # TODO: implement _set_partition_block_gen as an iterative algorithm + for P in _set_partition_block_gen(n, k, a): + yield from_word( P, base) From 2c6de282d3df5bda30d6756a1c36f582c2575151 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 24 Apr 2023 22:44:59 -0700 Subject: [PATCH 117/205] Update imports from sage.combinat.combinat_cython --- src/sage/combinat/diagram_algebras.py | 3 ++- src/sage/combinat/posets/hasse_diagram.py | 2 +- src/sage/combinat/posets/linear_extensions.py | 2 +- src/sage/combinat/set_partition.py | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index bd281fdbb77..8bef929e9c6 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -31,9 +31,10 @@ from sage.structure.unique_representation import UniqueRepresentation from sage.combinat.combinat import bell_number, catalan_number from sage.structure.global_options import GlobalOptions -from sage.combinat.combinat_cython import (set_partition_iterator, perfect_matchings_iterator, +from sage.combinat.combinat_cython import (perfect_matchings_iterator, set_partition_composition) from sage.combinat.set_partition import SetPartitions, AbstractSetPartition +from sage.combinat.set_partition_iterator import set_partition_iterator from sage.combinat.symmetric_group_algebra import SymmetricGroupAlgebra_n from sage.combinat.permutation import Permutations from sage.graphs.graph import Graph diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 7e1f1c6e4c6..e2c1fb46ff3 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -126,7 +126,7 @@ def linear_extensions(self): sage: list(H.linear_extensions()) [[0, 1, 2, 3], [0, 2, 1, 3]] """ - from sage.combinat.combinat_cython import linear_extension_iterator + from sage.combinat.posets.linear_extension_iterator import linear_extension_iterator return linear_extension_iterator(self) def greedy_linear_extensions_iterator(self): diff --git a/src/sage/combinat/posets/linear_extensions.py b/src/sage/combinat/posets/linear_extensions.py index e14be386228..84471d31e45 100644 --- a/src/sage/combinat/posets/linear_extensions.py +++ b/src/sage/combinat/posets/linear_extensions.py @@ -667,7 +667,7 @@ def __iter__(self): sage: list(L) [[1, 2, 3, 4], [2, 1, 3, 4], [2, 1, 4, 3], [1, 4, 2, 3], [1, 2, 4, 3]] """ - from sage.combinat.combinat_cython import linear_extension_iterator + from sage.combinat.posets.linear_extension_iterator import linear_extension_iterator vertex_to_element = self._poset._vertex_to_element for lin_ext in linear_extension_iterator(self._poset._hasse_diagram): yield self._element_constructor_([vertex_to_element(_) for _ in lin_ext]) diff --git a/src/sage/combinat/set_partition.py b/src/sage/combinat/set_partition.py index 6edf7d963da..f39895daa35 100644 --- a/src/sage/combinat/set_partition.py +++ b/src/sage/combinat/set_partition.py @@ -43,8 +43,8 @@ from sage.rings.infinity import infinity from sage.rings.integer import Integer from sage.combinat.combinatorial_map import combinatorial_map -from sage.combinat.combinat_cython import (set_partition_iterator, - set_partition_iterator_blocks) +from sage.combinat.set_partition_iterator import (set_partition_iterator, + set_partition_iterator_blocks) from sage.combinat.partition import Partition, Partitions from sage.combinat.combinat import bell_number, stirling_number2 as stirling2 from sage.combinat.permutation import Permutation From a5c8861da869250acfaf68e5727e73423d4c1c54 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 7 Jun 2023 09:57:15 -0700 Subject: [PATCH 118/205] Put in PR number for deprecations --- src/sage/combinat/combinat_cython.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/combinat_cython.pyx b/src/sage/combinat/combinat_cython.pyx index 1f0fb649ef0..be3236bcecc 100644 --- a/src/sage/combinat/combinat_cython.pyx +++ b/src/sage/combinat/combinat_cython.pyx @@ -22,9 +22,9 @@ from sage.libs.gmp.all cimport * from sage.rings.integer cimport Integer from sage.misc.lazy_import import LazyImport -set_partition_iterator = LazyImport('sage.combinat.set_partition_iterator', 'set_partition_iterator', deprecation=99999) -set_partition_iterator_blocks = LazyImport('sage.combinat.set_partition_iterator', 'set_partition_iterator_blocks', deprecation=99999) -linear_extension_iterator = LazyImport('sage.combinat.posets.linear_extension_iterator', 'linear_extension_iterator', deprecation=99999) +set_partition_iterator = LazyImport('sage.combinat.set_partition_iterator', 'set_partition_iterator', deprecation=35564) +set_partition_iterator_blocks = LazyImport('sage.combinat.set_partition_iterator', 'set_partition_iterator_blocks', deprecation=35564) +linear_extension_iterator = LazyImport('sage.combinat.posets.linear_extension_iterator', 'linear_extension_iterator', deprecation=35564) cdef void mpz_addmul_alt(mpz_t s, mpz_t t, mpz_t u, unsigned long parity): From 200c071d0785190312d6e6984008b56d6316aacd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 24 May 2023 21:27:39 -0700 Subject: [PATCH 119/205] sage.combinat.posets.hasse_cython_flint: Split from .hasse_cython --- src/sage/combinat/posets/hasse_cython.pyx | 142 +---------------- .../combinat/posets/hasse_cython_flint.pyx | 148 ++++++++++++++++++ src/sage/combinat/posets/hasse_diagram.py | 21 +-- 3 files changed, 163 insertions(+), 148 deletions(-) create mode 100644 src/sage/combinat/posets/hasse_cython_flint.pyx diff --git a/src/sage/combinat/posets/hasse_cython.pyx b/src/sage/combinat/posets/hasse_cython.pyx index 0e4d13ff033..0ed6145a533 100644 --- a/src/sage/combinat/posets/hasse_cython.pyx +++ b/src/sage/combinat/posets/hasse_cython.pyx @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Some fast computations for finite posets """ @@ -11,146 +10,13 @@ Some fast computations for finite posets # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** -from cysignals.signals cimport sig_check -from cysignals.memory cimport sig_malloc, sig_free - -from sage.libs.flint.fmpz cimport * -from sage.libs.flint.fmpz_mat cimport * - -from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense - -from sage.rings.integer_ring import ZZ -from sage.matrix.matrix_space import MatrixSpace from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets +from sage.misc.lazy_import import lazy_import from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest - -cpdef Matrix_integer_dense moebius_matrix_fast(list positions): - """ - Compute the Möbius matrix of a poset by a specific triangular inversion. - - INPUT: - - a list of sets of integers describing the poset, as given by the - lazy attribute ``_leq_storage`` of Hasse diagrams. - - OUTPUT: - - a dense matrix - - EXAMPLES:: - - sage: from sage.combinat.posets.hasse_cython import moebius_matrix_fast - sage: D = [{0,1},{1}] - sage: moebius_matrix_fast(D) - [ 1 -1] - [ 0 1] - sage: P = posets.TamariLattice(5) - sage: H = P._hasse_diagram - sage: D = H._leq_storage - sage: moebius_matrix_fast(D) - 42 x 42 dense matrix over Integer Ring (...) - """ - cdef Matrix_integer_dense A - cdef Py_ssize_t n = len(positions) - cdef Py_ssize_t i - cdef int j, k - A = Matrix_integer_dense.__new__(Matrix_integer_dense, - MatrixSpace(ZZ, n, n), None, None, None) - fmpz_mat_one(A._matrix) - cdef Py_ssize_t *pos_lens = sig_malloc(n*sizeof(Py_ssize_t)) - cdef int **pos_array = sig_malloc(n*sizeof(int*)) - cdef Py_ssize_t jind, kind - for i in range(n): - pos_lens[i] = len(positions[i]) - pos_array[i] = sig_malloc(pos_lens[i]*sizeof(int)) - for jind,j in enumerate(positions[i]): - pos_array[i][jind] = j - - for i in range(n - 1, -1, -1): - sig_check() - for jind in range(pos_lens[i]): - j = pos_array[i][jind] - if j != i: - for kind in range(pos_lens[j]): - k = pos_array[j][kind] - fmpz_sub(fmpz_mat_entry(A._matrix, i, k), - fmpz_mat_entry(A._matrix, i, k), - fmpz_mat_entry(A._matrix, j, k)) - for i in range(n): - sig_free(pos_array[i]) - sig_free(pos_array) - sig_free(pos_lens) - return A - - -cpdef Matrix_integer_dense coxeter_matrix_fast(list positions): - """ - Compute the Coxeter matrix of a poset by a specific algorithm. - - INPUT: - - a list of sets of integers describing the poset, as given by the - lazy attribute ``_leq_storage`` of Hasse diagrams. - - OUTPUT: - - a dense matrix - - EXAMPLES:: - - sage: from sage.combinat.posets.hasse_cython import coxeter_matrix_fast - sage: D = [{0,1},{1}] - sage: coxeter_matrix_fast(D) - [ 0 -1] - [ 1 -1] - sage: P = posets.TamariLattice(5) - sage: H = P._hasse_diagram - sage: D = H._leq_storage - sage: coxeter_matrix_fast(D) - 42 x 42 dense matrix over Integer Ring (...) - """ - cdef Matrix_integer_dense A - cdef Py_ssize_t n = len(positions) - cdef Py_ssize_t i - cdef int j, k - A = Matrix_integer_dense.__new__(Matrix_integer_dense, - MatrixSpace(ZZ, n, n), None, None, None) - fmpz_mat_one(A._matrix) - cdef Py_ssize_t *pos_lens = sig_malloc(n*sizeof(Py_ssize_t)) - cdef int **pos_array = sig_malloc(n*sizeof(int*)) - cdef Py_ssize_t jind, kind - for i in range(n): - pos_lens[i] = len(positions[i]) - pos_array[i] = sig_malloc(pos_lens[i]*sizeof(int)) - for jind,j in enumerate(positions[i]): - pos_array[i][jind] = j - - for i in range(n - 1, -1, -1): - sig_check() - for jind in range(pos_lens[i]): - j = pos_array[i][jind] - if j != i: - for kind in range(pos_lens[j]): - k = pos_array[j][kind] - fmpz_sub(fmpz_mat_entry(A._matrix, k, i), - fmpz_mat_entry(A._matrix, k, i), - fmpz_mat_entry(A._matrix, k, j)) - for i in range(n): - sig_check() - for jind in range(pos_lens[i]): - j = pos_array[i][jind] - if j != i: - for k in range(n): - fmpz_add(fmpz_mat_entry(A._matrix, i, k), - fmpz_mat_entry(A._matrix, i, k), - fmpz_mat_entry(A._matrix, j, k)) - for i in range(n): - sig_free(pos_array[i]) - sig_free(pos_array) - sig_free(pos_lens) - fmpz_mat_scalar_mul_si(A._matrix, A._matrix, -1) - return A +lazy_import('sage.combinat.posets.hasse_cython_flint', + ['coxeter_matrix_fast', 'moebius_matrix_fast'], + deprecation=35564) class IncreasingChains(RecursivelyEnumeratedSet_forest): diff --git a/src/sage/combinat/posets/hasse_cython_flint.pyx b/src/sage/combinat/posets/hasse_cython_flint.pyx new file mode 100644 index 00000000000..8f1c3d71bf6 --- /dev/null +++ b/src/sage/combinat/posets/hasse_cython_flint.pyx @@ -0,0 +1,148 @@ +r""" +Some fast computations for finite posets using FLINT matrices +""" +# **************************************************************************** +# Copyright (C) 2020 Frédéric Chapoton +# +# 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. +# https://www.gnu.org/licenses/ +# **************************************************************************** +from cysignals.signals cimport sig_check +from cysignals.memory cimport sig_malloc, sig_free + +from sage.libs.flint.fmpz cimport * +from sage.libs.flint.fmpz_mat cimport * +from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense +from sage.matrix.matrix_space import MatrixSpace +from sage.rings.integer_ring import ZZ + + +cpdef Matrix_integer_dense moebius_matrix_fast(list positions): + """ + Compute the Möbius matrix of a poset by a specific triangular inversion. + + INPUT: + + a list of sets of integers describing the poset, as given by the + lazy attribute ``_leq_storage`` of Hasse diagrams. + + OUTPUT: + + a dense matrix + + EXAMPLES:: + + sage: from sage.combinat.posets.hasse_cython import moebius_matrix_fast + sage: D = [{0,1},{1}] + sage: moebius_matrix_fast(D) + [ 1 -1] + [ 0 1] + sage: P = posets.TamariLattice(5) + sage: H = P._hasse_diagram + sage: D = H._leq_storage + sage: moebius_matrix_fast(D) + 42 x 42 dense matrix over Integer Ring (...) + """ + cdef Matrix_integer_dense A + cdef Py_ssize_t n = len(positions) + cdef Py_ssize_t i + cdef int j, k + A = Matrix_integer_dense.__new__(Matrix_integer_dense, + MatrixSpace(ZZ, n, n), None, None, None) + fmpz_mat_one(A._matrix) + cdef Py_ssize_t *pos_lens = sig_malloc(n*sizeof(Py_ssize_t)) + cdef int **pos_array = sig_malloc(n*sizeof(int*)) + cdef Py_ssize_t jind, kind + for i in range(n): + pos_lens[i] = len(positions[i]) + pos_array[i] = sig_malloc(pos_lens[i]*sizeof(int)) + for jind,j in enumerate(positions[i]): + pos_array[i][jind] = j + + for i in range(n - 1, -1, -1): + sig_check() + for jind in range(pos_lens[i]): + j = pos_array[i][jind] + if j != i: + for kind in range(pos_lens[j]): + k = pos_array[j][kind] + fmpz_sub(fmpz_mat_entry(A._matrix, i, k), + fmpz_mat_entry(A._matrix, i, k), + fmpz_mat_entry(A._matrix, j, k)) + for i in range(n): + sig_free(pos_array[i]) + sig_free(pos_array) + sig_free(pos_lens) + return A + + +cpdef Matrix_integer_dense coxeter_matrix_fast(list positions): + """ + Compute the Coxeter matrix of a poset by a specific algorithm. + + INPUT: + + a list of sets of integers describing the poset, as given by the + lazy attribute ``_leq_storage`` of Hasse diagrams. + + OUTPUT: + + a dense matrix + + EXAMPLES:: + + sage: from sage.combinat.posets.hasse_cython import coxeter_matrix_fast + sage: D = [{0,1},{1}] + sage: coxeter_matrix_fast(D) + [ 0 -1] + [ 1 -1] + sage: P = posets.TamariLattice(5) + sage: H = P._hasse_diagram + sage: D = H._leq_storage + sage: coxeter_matrix_fast(D) + 42 x 42 dense matrix over Integer Ring (...) + """ + cdef Matrix_integer_dense A + cdef Py_ssize_t n = len(positions) + cdef Py_ssize_t i + cdef int j, k + A = Matrix_integer_dense.__new__(Matrix_integer_dense, + MatrixSpace(ZZ, n, n), None, None, None) + fmpz_mat_one(A._matrix) + cdef Py_ssize_t *pos_lens = sig_malloc(n*sizeof(Py_ssize_t)) + cdef int **pos_array = sig_malloc(n*sizeof(int*)) + cdef Py_ssize_t jind, kind + for i in range(n): + pos_lens[i] = len(positions[i]) + pos_array[i] = sig_malloc(pos_lens[i]*sizeof(int)) + for jind,j in enumerate(positions[i]): + pos_array[i][jind] = j + + for i in range(n - 1, -1, -1): + sig_check() + for jind in range(pos_lens[i]): + j = pos_array[i][jind] + if j != i: + for kind in range(pos_lens[j]): + k = pos_array[j][kind] + fmpz_sub(fmpz_mat_entry(A._matrix, k, i), + fmpz_mat_entry(A._matrix, k, i), + fmpz_mat_entry(A._matrix, k, j)) + for i in range(n): + sig_check() + for jind in range(pos_lens[i]): + j = pos_array[i][jind] + if j != i: + for k in range(n): + fmpz_add(fmpz_mat_entry(A._matrix, i, k), + fmpz_mat_entry(A._matrix, i, k), + fmpz_mat_entry(A._matrix, j, k)) + for i in range(n): + sig_free(pos_array[i]) + sig_free(pos_array) + sig_free(pos_lens) + fmpz_mat_scalar_mul_si(A._matrix, A._matrix, -1) + return A diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index e2c1fb46ff3..30477e09c10 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- r""" Hasse diagrams of posets @@ -17,19 +16,21 @@ # **************************************************************************** from __future__ import annotations +from collections import deque + +from sage.arith.misc import binomial +from sage.combinat.posets.hasse_cython import IncreasingChains from sage.graphs.digraph import DiGraph -from sage.matrix.constructor import matrix -from sage.rings.integer_ring import ZZ -from sage.rings.finite_rings.finite_field_constructor import GF -from sage.misc.lazy_attribute import lazy_attribute from sage.misc.cachefunc import cached_method -from sage.arith.misc import binomial +from sage.misc.lazy_attribute import lazy_attribute +from sage.misc.lazy_import import lazy_import from sage.misc.rest_index_of_methods import gen_rest_table_index -from sage.combinat.posets.hasse_cython import (moebius_matrix_fast, - coxeter_matrix_fast, - IncreasingChains) +from sage.rings.integer_ring import ZZ -from collections import deque +lazy_import('sage.combinat.posets.hasse_cython_flint', + ['moebius_matrix_fast', 'coxeter_matrix_fast']) +lazy_import('sage.matrix.constructor', 'matrix') +lazy_import('sage.rings.finite_rings.finite_field_constructor', 'GF') class LatticeError(ValueError): From 2b11a99aed310a385dc0b5948fde170366aa68ff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 27 May 2023 16:20:01 -0700 Subject: [PATCH 120/205] src/sage/combinat/posets/hasse_cython*.pyx: Fix up imports --- src/sage/combinat/posets/hasse_cython.pyx | 9 +++++---- src/sage/combinat/posets/hasse_cython_flint.pyx | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/sage/combinat/posets/hasse_cython.pyx b/src/sage/combinat/posets/hasse_cython.pyx index 0ed6145a533..277e8a23cfd 100644 --- a/src/sage/combinat/posets/hasse_cython.pyx +++ b/src/sage/combinat/posets/hasse_cython.pyx @@ -11,12 +11,13 @@ Some fast computations for finite posets # https://www.gnu.org/licenses/ # **************************************************************************** from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets -from sage.misc.lazy_import import lazy_import +from sage.misc.lazy_import import LazyImport from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest -lazy_import('sage.combinat.posets.hasse_cython_flint', - ['coxeter_matrix_fast', 'moebius_matrix_fast'], - deprecation=35564) +coxeter_matrix_fast = LazyImport('sage.combinat.posets.hasse_cython_flint', 'coxeter_matrix_fast', + deprecation=35564) +moebius_matrix_fast = LazyImport('sage.combinat.posets.hasse_cython_flint', 'moebius_matrix_fast', + deprecation=35564) class IncreasingChains(RecursivelyEnumeratedSet_forest): diff --git a/src/sage/combinat/posets/hasse_cython_flint.pyx b/src/sage/combinat/posets/hasse_cython_flint.pyx index 8f1c3d71bf6..1d26c95c60e 100644 --- a/src/sage/combinat/posets/hasse_cython_flint.pyx +++ b/src/sage/combinat/posets/hasse_cython_flint.pyx @@ -35,7 +35,7 @@ cpdef Matrix_integer_dense moebius_matrix_fast(list positions): EXAMPLES:: - sage: from sage.combinat.posets.hasse_cython import moebius_matrix_fast + sage: from sage.combinat.posets.hasse_cython_flint import moebius_matrix_fast sage: D = [{0,1},{1}] sage: moebius_matrix_fast(D) [ 1 -1] @@ -94,7 +94,7 @@ cpdef Matrix_integer_dense coxeter_matrix_fast(list positions): EXAMPLES:: - sage: from sage.combinat.posets.hasse_cython import coxeter_matrix_fast + sage: from sage.combinat.posets.hasse_cython_flint import coxeter_matrix_fast sage: D = [{0,1},{1}] sage: coxeter_matrix_fast(D) [ 0 -1] From 52ed3be974d77ef278f98acfb04544ef83ddf4f6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 7 Jun 2023 10:20:16 -0700 Subject: [PATCH 121/205] Update PR numbers in deprecations --- src/sage/combinat/combinat_cython.pyx | 6 +++--- src/sage/combinat/posets/hasse_cython.pyx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/combinat/combinat_cython.pyx b/src/sage/combinat/combinat_cython.pyx index be3236bcecc..49dd5483402 100644 --- a/src/sage/combinat/combinat_cython.pyx +++ b/src/sage/combinat/combinat_cython.pyx @@ -22,9 +22,9 @@ from sage.libs.gmp.all cimport * from sage.rings.integer cimport Integer from sage.misc.lazy_import import LazyImport -set_partition_iterator = LazyImport('sage.combinat.set_partition_iterator', 'set_partition_iterator', deprecation=35564) -set_partition_iterator_blocks = LazyImport('sage.combinat.set_partition_iterator', 'set_partition_iterator_blocks', deprecation=35564) -linear_extension_iterator = LazyImport('sage.combinat.posets.linear_extension_iterator', 'linear_extension_iterator', deprecation=35564) +set_partition_iterator = LazyImport('sage.combinat.set_partition_iterator', 'set_partition_iterator', deprecation=35741) +set_partition_iterator_blocks = LazyImport('sage.combinat.set_partition_iterator', 'set_partition_iterator_blocks', deprecation=35741) +linear_extension_iterator = LazyImport('sage.combinat.posets.linear_extension_iterator', 'linear_extension_iterator', deprecation=35741) cdef void mpz_addmul_alt(mpz_t s, mpz_t t, mpz_t u, unsigned long parity): diff --git a/src/sage/combinat/posets/hasse_cython.pyx b/src/sage/combinat/posets/hasse_cython.pyx index 277e8a23cfd..17f6444aaa1 100644 --- a/src/sage/combinat/posets/hasse_cython.pyx +++ b/src/sage/combinat/posets/hasse_cython.pyx @@ -15,9 +15,9 @@ from sage.misc.lazy_import import LazyImport from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest coxeter_matrix_fast = LazyImport('sage.combinat.posets.hasse_cython_flint', 'coxeter_matrix_fast', - deprecation=35564) + deprecation=35741) moebius_matrix_fast = LazyImport('sage.combinat.posets.hasse_cython_flint', 'moebius_matrix_fast', - deprecation=35564) + deprecation=35741) class IncreasingChains(RecursivelyEnumeratedSet_forest): From 9e136c1193da1067e8c79a0d856329c47147782e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 24 Apr 2023 22:46:08 -0700 Subject: [PATCH 122/205] sage.combinat.{combinat,permutation,set_partition}: Make some imports lazy --- src/sage/combinat/combinat.py | 24 +++++++++++----------- src/sage/combinat/permutation.py | 33 +++++++++++++++--------------- src/sage/combinat/set_partition.py | 6 ++++-- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index 195ff344e50..7d446d41420 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -64,18 +64,12 @@ **Implemented in other modules (listed for completeness):** -The ``sage.arith.all`` module contains the following +The package :mod:`sage.arith` contains the following combinatorial functions: -- binomial the binomial coefficient (wrapped from PARI) +- :func:`binomial` the binomial coefficient (wrapped from PARI) -- factorial (wrapped from PARI) - -- partition (from the Python Cookbook) Generator of the list of - all the partitions of the integer `n`. - -- :func:`number_of_partitions` (wrapped from PARI) the - *number* of partitions: +- :func:`factorial` (wrapped from PARI) - :func:`falling_factorial` Definition: for integer `a \ge 0` we have `x(x-1) \cdots (x-a+1)`. In all @@ -87,7 +81,12 @@ other cases we use the GAMMA-function: `\frac {\Gamma(x+a)} {\Gamma(x)}`. -- gaussian_binomial the gaussian binomial +From other modules: + +- :func:`number_of_partitions` (wrapped from PARI) the + *number* of partitions: + +- :func:`sage.combinat.q_analogues.gaussian_binomial` the Gaussian binomial .. MATH:: @@ -174,8 +173,6 @@ from sage.rings.infinity import infinity from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.libs.pari.all import pari -from sage.misc.prandom import randint from sage.misc.misc_c import prod from sage.misc.cachefunc import cached_function from sage.structure.sage_object import SageObject @@ -187,7 +184,10 @@ from sage.misc.classcall_metaclass import ClasscallMetaclass from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass from sage.structure.element import Element + lazy_import('sage.interfaces.maxima_lib', 'maxima') +lazy_import('sage.libs.pari.all', 'pari') +lazy_import('sage.misc.prandom', 'randint') def bell_number(n, algorithm='flint', **options) -> Integer: diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index 9593055e9ed..4d7b3d09923 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -242,6 +242,7 @@ from __future__ import annotations from typing import Iterator import itertools +import operator from sage.arith.misc import factorial, multinomial from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets @@ -256,16 +257,10 @@ from sage.combinat.permutation_cython import (left_action_product, right_action_product, left_action_same_n, right_action_same_n, map_to_list, next_perm) -from sage.combinat.rsk import RSK, RSK_inverse from sage.combinat.tools import transitive_ideal -from sage.graphs.digraph import DiGraph -from sage.groups.perm_gps.permgroup_element import PermutationGroupElement -from sage.groups.perm_gps.permgroup_named import SymmetricGroup -from sage.libs.gap.libgap import libgap -from sage.matrix.matrix_space import MatrixSpace from sage.misc.cachefunc import cached_method from sage.misc.decorators import rename_keyword -from sage.misc.prandom import sample +from sage.misc.lazy_import import lazy_import from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing @@ -274,7 +269,18 @@ from sage.structure.parent import Parent from sage.structure.element import Element, get_coercion_model from sage.structure.unique_representation import UniqueRepresentation -import operator + +lazy_import('sage.combinat.rsk', ['RSK', 'RSK_inverse']) +lazy_import('sage.combinat.tableau', 'Tableau') +lazy_import('sage.combinat.words.finite_word', 'evaluation_dict') +lazy_import('sage.graphs.digraph', 'DiGraph') +lazy_import('sage.groups.cactus_group', 'CactusGroup') +lazy_import('sage.groups.perm_gps.permgroup_element', 'PermutationGroupElement') +lazy_import('sage.groups.perm_gps.permgroup_named', 'SymmetricGroup') +lazy_import('sage.libs.gap.libgap', 'libgap') +lazy_import('sage.matrix.matrix_space', 'MatrixSpace') +lazy_import('sage.misc.prandom', 'sample') + class Permutation(CombinatorialElement): r""" @@ -441,7 +447,6 @@ def __classcall_private__(cls, l, check=True): sage: P.parent() Standard permutations """ - import sage.combinat.tableau as tableau if isinstance(l, Permutation): return l elif isinstance(l, PermutationGroupElement): @@ -461,11 +466,11 @@ def __classcall_private__(cls, l, check=True): #if l is a pair of standard tableaux or a pair of lists elif isinstance(l, (tuple, list)) and len(l) == 2 and \ - all(isinstance(x, tableau.Tableau) for x in l): + all(isinstance(x, Tableau) for x in l): return RSK_inverse(*l, output='permutation') elif isinstance(l, (tuple, list)) and len(l) == 2 and \ all(isinstance(x, list) for x in l): - P,Q = [tableau.Tableau(_) for _ in l] + P,Q = [Tableau(_) for _ in l] return RSK_inverse(P, Q, 'permutation') # if it's a tuple or nonempty list of tuples, also assume cycle # notation @@ -870,7 +875,6 @@ def to_tableau_by_shape(self, shape): sage: Permutation([3,4,1,2,5]).to_tableau_by_shape([3,2]).reading_word_permutation() [3, 4, 1, 2, 5] """ - import sage.combinat.tableau as tableau if sum(shape) != len(self): raise ValueError("the size of the partition must be the size of self") @@ -879,7 +883,7 @@ def to_tableau_by_shape(self, shape): for i in reversed(shape): t = [w[:i]] + t w = w[i:] - return tableau.Tableau(t) + return Tableau(t) def to_cycles(self, singletons=True, use_min=True): """ @@ -6924,7 +6928,6 @@ def _coerce_map_from_(self, G): return self._from_permutation_group_element if isinstance(G, StandardPermutations_n) and G.n <= self.n: return True - from sage.groups.cactus_group import CactusGroup if isinstance(G, CactusGroup) and G.n() <= self.n: return self._from_cactus_group_element return super()._coerce_map_from_(G) @@ -8682,8 +8685,6 @@ def permutohedron_lequal(p1, p2, side="right"): ############ # Patterns # ############ -from sage.combinat.words.finite_word import evaluation_dict - def to_standard(p, key=None): r""" diff --git a/src/sage/combinat/set_partition.py b/src/sage/combinat/set_partition.py index 6edf7d963da..3c3acef4299 100644 --- a/src/sage/combinat/set_partition.py +++ b/src/sage/combinat/set_partition.py @@ -40,6 +40,7 @@ from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass +from sage.misc.lazy_import import lazy_import from sage.rings.infinity import infinity from sage.rings.integer import Integer from sage.combinat.combinatorial_map import combinatorial_map @@ -50,9 +51,10 @@ from sage.combinat.permutation import Permutation from sage.arith.misc import factorial from sage.misc.prandom import random, randint, sample -from sage.probability.probability_distribution import GeneralDiscreteDistribution from sage.sets.disjoint_set import DisjointSet -from sage.combinat.posets.hasse_diagram import HasseDiagram + +lazy_import('sage.combinat.posets.hasse_diagram', 'HasseDiagram') +lazy_import('sage.probability.probability_distribution', 'GeneralDiscreteDistribution') class AbstractSetPartition(ClonableArray, From d7ca2985727b25f8097c7c707a038acf0f643747 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 25 Apr 2023 23:30:27 -0700 Subject: [PATCH 123/205] sage.combinat.subset: Move subsets, powerset here from sage.misc.misc --- src/sage/combinat/subset.py | 63 +++++++++++++++++++++++++++++++++++ src/sage/misc/misc.py | 66 ++----------------------------------- 2 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/sage/combinat/subset.py b/src/sage/combinat/subset.py index c27b1eb04ed..962240160d6 100644 --- a/src/sage/combinat/subset.py +++ b/src/sage/combinat/subset.py @@ -1471,3 +1471,66 @@ def _element_constructor_(self, x): [(), (0,), (1,), (2,), (0, 1), (0, 2), (1, 2), (0, 1, 2)] """ return self.element_class(sorted(set(x))) + + +def powerset(X): + r""" + Iterator over the *list* of all subsets of the iterable ``X``, in no + particular order. Each list appears exactly once, up to order. + + INPUT: + + - ``X`` - an iterable + + OUTPUT: iterator of lists + + EXAMPLES:: + + sage: list(powerset([1,2,3])) + [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]] + sage: [z for z in powerset([0,[1,2]])] + [[], [0], [[1, 2]], [0, [1, 2]]] + + Iterating over the power set of an infinite set is also allowed:: + + sage: i = 0 + sage: L = [] + sage: for x in powerset(ZZ): + ....: if i > 10: + ....: break + ....: else: + ....: i += 1 + ....: L.append(x) + sage: print(" ".join(str(x) for x in L)) + [] [0] [1] [0, 1] [-1] [0, -1] [1, -1] [0, 1, -1] [2] [0, 2] [1, 2] + + You may also use subsets as an alias for powerset:: + + sage: subsets([1,2,3]) + + sage: list(subsets([1,2,3])) + [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]] + + The reason we return lists instead of sets is that the elements of + sets must be hashable and many structures on which one wants the + powerset consist of non-hashable objects. + + AUTHORS: + + - William Stein + + - Nils Bruin (2006-12-19): rewrite to work for not-necessarily + finite objects X. + """ + yield [] + pairs = [] + power2 = 1 + for x in X: + pairs.append((power2, x)) + next_power2 = power2 << 1 + for w in range(power2, next_power2): + yield [x for m, x in pairs if m & w] + power2 = next_power2 + + +subsets = powerset diff --git a/src/sage/misc/misc.py b/src/sage/misc/misc.py index f263f53bad3..dd4514a00e7 100644 --- a/src/sage/misc/misc.py +++ b/src/sage/misc/misc.py @@ -48,6 +48,9 @@ from sage.env import DOT_SAGE, HOSTNAME from sage.misc.lazy_import import lazy_import +lazy_import("sage.combinat.subset", ["powerset", "subsets"], + deprecation=99999) + lazy_import("sage.misc.call", ["AttrCallObject", "attrcall", "call_method"], deprecation=29869) @@ -1056,69 +1059,6 @@ def _some_tuples_sampling(elements, repeat, max_samples, n): yield tuple(elements[j] for j in Integer(a).digits(n, padto=repeat)) -def powerset(X): - r""" - Iterator over the *list* of all subsets of the iterable X, in no - particular order. Each list appears exactly once, up to order. - - INPUT: - - - ``X`` - an iterable - - OUTPUT: iterator of lists - - EXAMPLES:: - - sage: list(powerset([1,2,3])) - [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]] - sage: [z for z in powerset([0,[1,2]])] - [[], [0], [[1, 2]], [0, [1, 2]]] - - Iterating over the power set of an infinite set is also allowed:: - - sage: i = 0 - sage: L = [] - sage: for x in powerset(ZZ): - ....: if i > 10: - ....: break - ....: else: - ....: i += 1 - ....: L.append(x) - sage: print(" ".join(str(x) for x in L)) - [] [0] [1] [0, 1] [-1] [0, -1] [1, -1] [0, 1, -1] [2] [0, 2] [1, 2] - - You may also use subsets as an alias for powerset:: - - sage: subsets([1,2,3]) - - sage: list(subsets([1,2,3])) - [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]] - - The reason we return lists instead of sets is that the elements of - sets must be hashable and many structures on which one wants the - powerset consist of non-hashable objects. - - AUTHORS: - - - William Stein - - - Nils Bruin (2006-12-19): rewrite to work for not-necessarily - finite objects X. - """ - yield [] - pairs = [] - power2 = 1 - for x in X: - pairs.append((power2, x)) - next_power2 = power2 << 1 - for w in range(power2, next_power2): - yield [x for m, x in pairs if m & w] - power2 = next_power2 - - -subsets = powerset - - ################################################################# # Misc. ################################################################# From 84ec7c524ae78c3e594d88bee8c5726c1e942a63 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 25 Apr 2023 23:07:10 -0700 Subject: [PATCH 124/205] Update .all imports of subsets, powerset --- src/sage/combinat/all.py | 2 +- src/sage/misc/all.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/all.py b/src/sage/combinat/all.py index 2206ea2873a..8aef61122ee 100644 --- a/src/sage/combinat/all.py +++ b/src/sage/combinat/all.py @@ -218,7 +218,7 @@ lazy_import('sage.combinat.multiset_partition_into_sets_ordered', ['OrderedMultisetPartitionIntoSets', 'OrderedMultisetPartitionsIntoSets']) -from .subset import Subsets +from .subset import Subsets, subsets, powerset from .necklace import Necklaces lazy_import('sage.combinat.dyck_word', ('DyckWords', 'DyckWord')) lazy_import('sage.combinat.nu_dyck_word', ('NuDyckWords', 'NuDyckWord')) diff --git a/src/sage/misc/all.py b/src/sage/misc/all.py index 8fea19524eb..c72ea65e117 100644 --- a/src/sage/misc/all.py +++ b/src/sage/misc/all.py @@ -7,7 +7,7 @@ from .misc import (BackslashOperator, cputime, - union, uniq, powerset, subsets, + union, uniq, exists, forall, is_iterator, random_sublist, walltime, pad_zeros, From c9666c2f7bfc17344b4d4c5c09804488fc658d30 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 7 Jun 2023 12:22:37 -0700 Subject: [PATCH 125/205] Put in PR number for deprecations --- src/sage/misc/misc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/misc.py b/src/sage/misc/misc.py index dd4514a00e7..79497378a67 100644 --- a/src/sage/misc/misc.py +++ b/src/sage/misc/misc.py @@ -49,7 +49,7 @@ from sage.misc.lazy_import import lazy_import lazy_import("sage.combinat.subset", ["powerset", "subsets"], - deprecation=99999) + deprecation=35564) lazy_import("sage.misc.call", ["AttrCallObject", "attrcall", "call_method"], deprecation=29869) From 6b96af87e5de757fb5b699c8896f4041f481bde0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 26 Apr 2023 08:49:41 -0700 Subject: [PATCH 126/205] Update imports of subsets, powerset --- src/sage/algebras/quantum_clifford.py | 2 +- src/sage/arith/misc.py | 2 +- src/sage/combinat/blob_algebra.py | 2 +- src/sage/combinat/combinat.py | 2 +- src/sage/combinat/diagram.py | 2 +- src/sage/combinat/diagram_algebras.py | 2 +- src/sage/combinat/root_system/cartan_matrix.py | 2 +- src/sage/combinat/tableau.py | 2 +- src/sage/databases/jones.py | 2 +- src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx | 2 +- src/sage/game_theory/cooperative_game.py | 2 +- src/sage/game_theory/normal_form_game.py | 2 +- src/sage/geometry/polyhedral_complex.py | 2 +- src/sage/graphs/graph.py | 2 +- src/sage/rings/function_field/ideal.py | 2 +- src/sage/rings/polynomial/cyclotomic.pyx | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/sage/algebras/quantum_clifford.py b/src/sage/algebras/quantum_clifford.py index 1e57682f255..5079283e8ec 100644 --- a/src/sage/algebras/quantum_clifford.py +++ b/src/sage/algebras/quantum_clifford.py @@ -27,7 +27,7 @@ from sage.rings.fraction_field import FractionField from sage.sets.finite_enumerated_set import FiniteEnumeratedSet from itertools import product -from sage.misc.misc import powerset +from sage.combinat.subset import powerset class QuantumCliffordAlgebra(CombinatorialFreeModule): r""" diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index d3b5d164054..de6c74acb40 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -20,7 +20,7 @@ import math from collections.abc import Iterable -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.misc.misc_c import prod from sage.structure.element import parent diff --git a/src/sage/combinat/blob_algebra.py b/src/sage/combinat/blob_algebra.py index 95899fd66a6..657c70a5c0e 100644 --- a/src/sage/combinat/blob_algebra.py +++ b/src/sage/combinat/blob_algebra.py @@ -23,7 +23,7 @@ from sage.structure.richcmp import richcmp #from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass from sage.misc.cachefunc import cached_method -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.arith.misc import binomial from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.categories.algebras import Algebras diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index 7d446d41420..5d27891dee0 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -2892,7 +2892,7 @@ def unshuffle_iterator(a, one=1) -> Iterator: [(((), (3, 1)), 3/2), (((3,), (1,)), 3/2), (((1,), (3,)), -3/2), (((3, 1), ()), 3/2)] """ - from sage.misc.misc import powerset + from sage.combinat.subset import powerset n = len(a) for I in powerset(range(n)): sorted_I = tuple(sorted(I)) diff --git a/src/sage/combinat/diagram.py b/src/sage/combinat/diagram.py index dcde71bff63..ed32713b5c2 100644 --- a/src/sage/combinat/diagram.py +++ b/src/sage/combinat/diagram.py @@ -615,7 +615,7 @@ def __iter__(self): """ from sage.sets.non_negative_integers import NonNegativeIntegers from sage.categories.cartesian_product import cartesian_product - from sage.misc.misc import subsets + from sage.combinat.subset import subsets # the product of positive integers automatically implements an # an enumeration which allows us to get out of the first column N = NonNegativeIntegers() diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index bd281fdbb77..da6628ed840 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -231,7 +231,7 @@ def planar_partitions_rec(X): if len(X) > 1: yield ([X[0]], [X[1]]) return - from sage.misc.misc import powerset + from sage.combinat.subset import powerset from itertools import product for S in powerset(range(len(X)-1)): if not S: diff --git a/src/sage/combinat/root_system/cartan_matrix.py b/src/sage/combinat/root_system/cartan_matrix.py index 3a26227b4f1..77f175f0364 100644 --- a/src/sage/combinat/root_system/cartan_matrix.py +++ b/src/sage/combinat/root_system/cartan_matrix.py @@ -32,7 +32,7 @@ from sage.matrix.matrix_space import MatrixSpace from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass from sage.misc.classcall_metaclass import typecall -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.matrix.matrix_integer_sparse import Matrix_integer_sparse from sage.rings.integer_ring import ZZ from sage.combinat.root_system.cartan_type import CartanType, CartanType_abstract diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 4df26efd41d..c33a09fd483 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -100,7 +100,7 @@ from sage.combinat.posets.posets import Poset from sage.groups.perm_gps.permgroup import PermutationGroup from sage.misc.inherit_comparison import InheritComparisonClasscallMetaclass -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.misc.misc_c import prod from sage.misc.persist import register_unpickle_override from sage.rings.finite_rings.integer_mod_ring import IntegerModRing diff --git a/src/sage/databases/jones.py b/src/sage/databases/jones.py index 6f6318d0c2d..5afcaaa3f6b 100644 --- a/src/sage/databases/jones.py +++ b/src/sage/databases/jones.py @@ -71,7 +71,7 @@ from sage.rings.number_field.number_field import NumberField from sage.rings.rational_field import RationalField from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.env import SAGE_SHARE from sage.misc.persist import load, save diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx b/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx index dcb12407b7a..3d40d748a17 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx @@ -21,7 +21,7 @@ AUTHORS: from sage.arith.functions cimport LCM_list from sage.rings.finite_rings.finite_field_constructor import GF -from sage.misc.misc import subsets +from sage.combinat.subset import subsets cpdef _fast_possible_periods(self, return_points=False): diff --git a/src/sage/game_theory/cooperative_game.py b/src/sage/game_theory/cooperative_game.py index 0cb18189191..b95ba0f655a 100644 --- a/src/sage/game_theory/cooperative_game.py +++ b/src/sage/game_theory/cooperative_game.py @@ -21,7 +21,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** from itertools import permutations, combinations -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.rings.integer import Integer from sage.structure.sage_object import SageObject diff --git a/src/sage/game_theory/normal_form_game.py b/src/sage/game_theory/normal_form_game.py index 5068c8e10e3..cd6e371eeb2 100644 --- a/src/sage/game_theory/normal_form_game.py +++ b/src/sage/game_theory/normal_form_game.py @@ -635,7 +635,7 @@ from itertools import product from .parser import Parser from sage.misc.latex import latex -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.rings.rational_field import QQ from sage.structure.sage_object import SageObject from sage.matrix.constructor import matrix diff --git a/src/sage/geometry/polyhedral_complex.py b/src/sage/geometry/polyhedral_complex.py index 629a4f9ba2a..cff7b73c94e 100644 --- a/src/sage/geometry/polyhedral_complex.py +++ b/src/sage/geometry/polyhedral_complex.py @@ -117,7 +117,7 @@ from sage.rings.integer_ring import ZZ from sage.graphs.graph import Graph from sage.combinat.posets.posets import Poset -from sage.misc.misc import powerset +from sage.combinat.subset import powerset class PolyhedralComplex(GenericCellComplex): diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index b351b8501c0..8aa4efbce0f 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -3946,7 +3946,7 @@ def chromatic_symmetric_function(self, R=None): """ from sage.combinat.sf.sf import SymmetricFunctions from sage.combinat.partition import _Partitions - from sage.misc.misc import powerset + from sage.combinat.subset import powerset if R is None: R = ZZ p = SymmetricFunctions(R).p() diff --git a/src/sage/rings/function_field/ideal.py b/src/sage/rings/function_field/ideal.py index 8d203e9f019..25317e4d80c 100644 --- a/src/sage/rings/function_field/ideal.py +++ b/src/sage/rings/function_field/ideal.py @@ -93,7 +93,7 @@ # **************************************************************************** from sage.misc.latex import latex -from sage.misc.misc import powerset +from sage.combinat.subset import powerset from sage.structure.parent import Parent from sage.structure.element import Element from sage.structure.richcmp import richcmp diff --git a/src/sage/rings/polynomial/cyclotomic.pyx b/src/sage/rings/polynomial/cyclotomic.pyx index c4594dba8ad..ed0558413ea 100644 --- a/src/sage/rings/polynomial/cyclotomic.pyx +++ b/src/sage/rings/polynomial/cyclotomic.pyx @@ -35,7 +35,7 @@ from sage.structure.element cimport parent from sage.arith.misc import factor from sage.rings.integer_ring import ZZ from sage.misc.misc_c import prod -from sage.misc.misc import subsets +from sage.combinat.subset import subsets from sage.libs.pari.all import pari From f591ef9a90c02a6afac6c42927103317b8067753 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 26 Apr 2023 15:42:41 -0700 Subject: [PATCH 127/205] src/sage/arith/misc.py: Remove import cycle --- src/sage/arith/misc.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index de6c74acb40..c29005e03ba 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -20,7 +20,6 @@ import math from collections.abc import Iterable -from sage.combinat.subset import powerset from sage.misc.misc_c import prod from sage.structure.element import parent @@ -6042,6 +6041,8 @@ def squarefree_divisors(x): sage: list(squarefree_divisors(mpz(12))) [1, 2, 3, 6] """ + from sage.combinat.subset import powerset + for a in powerset(prime_divisors(x)): yield prod(a, ZZ.one()) From c94c34ed56a78f6dc3331324021da4c703f439a7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 2 May 2023 17:14:34 -0700 Subject: [PATCH 128/205] sage.misc.misc: Replace deprecated sorting 'uniq', move stable 'uniq' to sage.combinat.subset (with deprecation) --- src/sage/combinat/all.py | 2 +- src/sage/combinat/subset.py | 28 ++++++++++++++++++- src/sage/misc/all.py | 1 - src/sage/misc/misc.py | 49 +--------------------------------- src/sage/sets/condition_set.py | 4 +-- 5 files changed, 31 insertions(+), 53 deletions(-) diff --git a/src/sage/combinat/all.py b/src/sage/combinat/all.py index 8aef61122ee..0f43e6bbcfe 100644 --- a/src/sage/combinat/all.py +++ b/src/sage/combinat/all.py @@ -218,7 +218,7 @@ lazy_import('sage.combinat.multiset_partition_into_sets_ordered', ['OrderedMultisetPartitionIntoSets', 'OrderedMultisetPartitionsIntoSets']) -from .subset import Subsets, subsets, powerset +from .subset import Subsets, subsets, powerset, uniq from .necklace import Necklaces lazy_import('sage.combinat.dyck_word', ('DyckWords', 'DyckWord')) lazy_import('sage.combinat.nu_dyck_word', ('NuDyckWords', 'NuDyckWord')) diff --git a/src/sage/combinat/subset.py b/src/sage/combinat/subset.py index 962240160d6..a08a5474cae 100644 --- a/src/sage/combinat/subset.py +++ b/src/sage/combinat/subset.py @@ -39,7 +39,6 @@ from sage.sets.set import Set, Set_object_enumerated from sage.arith.misc import binomial -from sage.misc.misc import _stable_uniq as uniq from sage.rings.integer_ring import ZZ from sage.rings.integer import Integer from . import combination @@ -1534,3 +1533,30 @@ def powerset(X): subsets = powerset + + +def uniq(L): + """ + Iterate over the elements of ``L``, yielding every element at most + once: keep only the first occurrence of any item. + + The items must be hashable. + + INPUT: + + - ``L`` -- iterable + + EXAMPLES:: + + sage: L = [1, 1, 8, -5, 3, -5, 'a', 'x', 'a'] + sage: it = uniq(L); it + + sage: list(it) + [1, 8, -5, 3, 'a', 'x'] + """ + seen = set() + for x in L: + if x in seen: + continue + yield x + seen.add(x) diff --git a/src/sage/misc/all.py b/src/sage/misc/all.py index c72ea65e117..b58c90e5c22 100644 --- a/src/sage/misc/all.py +++ b/src/sage/misc/all.py @@ -7,7 +7,6 @@ from .misc import (BackslashOperator, cputime, - union, uniq, exists, forall, is_iterator, random_sublist, walltime, pad_zeros, diff --git a/src/sage/misc/misc.py b/src/sage/misc/misc.py index 79497378a67..ac285817431 100644 --- a/src/sage/misc/misc.py +++ b/src/sage/misc/misc.py @@ -48,7 +48,7 @@ from sage.env import DOT_SAGE, HOSTNAME from sage.misc.lazy_import import lazy_import -lazy_import("sage.combinat.subset", ["powerset", "subsets"], +lazy_import("sage.combinat.subset", ["powerset", "subsets", "uniq"], deprecation=35564) lazy_import("sage.misc.call", ["AttrCallObject", "attrcall", "call_method"], @@ -557,53 +557,6 @@ def union(x, y=None): return list(set(x).union(y)) -def uniq(x): - """ - Return the sublist of all elements in the list x that is sorted and - is such that the entries in the sublist are unique. - - EXAMPLES:: - - sage: uniq([1, 1, 8, -5, 3, -5, -13, 13, -13]) - doctest:...: DeprecationWarning: the output of uniq(X) being sorted is deprecated; use sorted(set(X)) instead if you want sorted output - See https://github.com/sagemath/sage/issues/27014 for details. - [-13, -5, 1, 3, 8, 13] - """ - # After deprecation period, rename _stable_uniq -> uniq - from sage.misc.superseded import deprecation - deprecation(27014, "the output of uniq(X) being sorted is deprecated; use sorted(set(X)) instead if you want sorted output") - return sorted(set(x)) - - -def _stable_uniq(L): - """ - Iterate over the elements of ``L``, yielding every element at most - once: keep only the first occurrence of any item. - - The items must be hashable. - - INPUT: - - - ``L`` -- iterable - - EXAMPLES:: - - sage: from sage.misc.misc import _stable_uniq - sage: L = [1, 1, 8, -5, 3, -5, 'a', 'x', 'a'] - sage: it = _stable_uniq(L) - sage: it - - sage: list(it) - [1, 8, -5, 3, 'a', 'x'] - """ - seen = set() - for x in L: - if x in seen: - continue - yield x - seen.add(x) - - def exactly_one_is_true(iterable): r""" Return whether exactly one element of ``iterable`` evaluates ``True``. diff --git a/src/sage/sets/condition_set.py b/src/sage/sets/condition_set.py index 34265775dd3..de33e6f655e 100644 --- a/src/sage/sets/condition_set.py +++ b/src/sage/sets/condition_set.py @@ -18,7 +18,7 @@ from sage.categories.sets_cat import Sets from sage.categories.enumerated_sets import EnumeratedSets from sage.misc.cachefunc import cached_method -from sage.misc.misc import _stable_uniq +from sage.combinat.subset import uniq from sage.structure.element import Expression from .set import Set, Set_base, Set_boolean_operators, Set_add_sub_operators @@ -173,7 +173,7 @@ def __classcall_private__(cls, universe, *predicates, vars=None, names=None, cat else: other_predicates.append(predicate) - predicates = list(_stable_uniq(callable_symbolic_predicates + other_predicates)) + predicates = list(uniq(callable_symbolic_predicates + other_predicates)) if not other_predicates and not callable_symbolic_predicates: if names is None and category is None: From f5e39adf6c534605513e9f44871393b13413f62e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 13 May 2023 18:04:10 -0700 Subject: [PATCH 129/205] src/sage/combinat/root_system/coxeter_type.py: Replace lazy import by method-local import --- src/sage/combinat/root_system/coxeter_type.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/root_system/coxeter_type.py b/src/sage/combinat/root_system/coxeter_type.py index 39fa6ca0d01..bb0f32a7f02 100644 --- a/src/sage/combinat/root_system/coxeter_type.py +++ b/src/sage/combinat/root_system/coxeter_type.py @@ -24,7 +24,6 @@ import sage.rings.abc from sage.matrix.args import SparseEntry from sage.matrix.constructor import Matrix -from sage.symbolic.ring import SR from sage.structure.unique_representation import UniqueRepresentation from sage.structure.sage_object import SageObject @@ -401,6 +400,7 @@ def val(x): else: from sage.functions.trig import cos from sage.symbolic.constants import pi + from sage.symbolic.ring import SR def val(x): if x > -1: From 6a2b1b29ec86efec4432f9789f8736e44b3c8741 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 7 Jun 2023 12:26:27 -0700 Subject: [PATCH 130/205] sage.combinat: Modularization fixes --- src/sage/categories/coxeter_groups.py | 5 +++- src/sage/categories/finite_coxeter_groups.py | 15 ++++++----- src/sage/categories/loop_crystals.py | 4 +-- .../combinat/designs/difference_family.py | 10 +++---- src/sage/combinat/root_system/coxeter_type.py | 22 +++++++--------- src/sage/rings/abc.pyx | 26 +++++++++++++++++++ 6 files changed, 55 insertions(+), 27 deletions(-) diff --git a/src/sage/categories/coxeter_groups.py b/src/sage/categories/coxeter_groups.py index 95c31d20695..4cb0b21d7a1 100644 --- a/src/sage/categories/coxeter_groups.py +++ b/src/sage/categories/coxeter_groups.py @@ -1327,7 +1327,10 @@ def _test_coxeter_relations(self, **options): one = self.one() for si in s: tester.assertEqual(si**2, one) - cox_mat = self.coxeter_matrix() + try: + cox_mat = self.coxeter_matrix() + except ImportError: + return I = cox_mat.index_set() for ii, i in enumerate(I): for j in I[ii + 1:]: diff --git a/src/sage/categories/finite_coxeter_groups.py b/src/sage/categories/finite_coxeter_groups.py index 0ec68ca2b99..12239cc7ec2 100644 --- a/src/sage/categories/finite_coxeter_groups.py +++ b/src/sage/categories/finite_coxeter_groups.py @@ -10,6 +10,8 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** +import sage.rings.abc + from sage.misc.cachefunc import cached_method, cached_in_parent_method from sage.misc.lazy_attribute import lazy_attribute from sage.categories.category_with_axiom import CategoryWithAxiom @@ -746,13 +748,14 @@ def permutahedron(self, point=None, base_ring=None): from sage.rings.integer_ring import ZZ point = [ZZ.one()] * n v = sum(point[i-1] * weights[i] for i in weights.keys()) - from sage.geometry.polyhedron.constructor import Polyhedron - from sage.rings.qqbar import AA, QQbar - from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField vertices = [v*w for w in self] - if base_ring is None and v.base_ring() in [UniversalCyclotomicField(), QQbar]: - vertices = [v.change_ring(AA) for v in vertices] - base_ring = AA + if base_ring is None: + if isinstance(v.base_ring(), [sage.rings.abc.UniversalCyclotomicField, + sage.rings.abc.AlgebraicField_common]): + from sage.rings.qqbar import AA + vertices = [v.change_ring(AA) for v in vertices] + base_ring = AA + from sage.geometry.polyhedron.constructor import Polyhedron return Polyhedron(vertices=vertices, base_ring=base_ring) class ElementMethods: diff --git a/src/sage/categories/loop_crystals.py b/src/sage/categories/loop_crystals.py index b7dbd37a3c6..2d5f1ca1914 100644 --- a/src/sage/categories/loop_crystals.py +++ b/src/sage/categories/loop_crystals.py @@ -968,7 +968,7 @@ def energy_function(self, algorithm=None): ....: for b in hw) True """ - from sage.functions.other import ceil + from sage.arith.misc import integer_ceil as ceil C = self.parent().crystals[0] ell = ceil(C.s()/C.cartan_type().c()[C.r()]) @@ -1101,7 +1101,7 @@ def e_string_to_ground_state(self): ....: for elt in hw) True """ - from sage.functions.other import ceil + from sage.arith.misc import integer_ceil as ceil ell = max(ceil(K.s()/K.cartan_type().c()[K.r()]) for K in self.parent().crystals) diff --git a/src/sage/combinat/designs/difference_family.py b/src/sage/combinat/designs/difference_family.py index 52a95805ea5..fb510a83b0e 100644 --- a/src/sage/combinat/designs/difference_family.py +++ b/src/sage/combinat/designs/difference_family.py @@ -1530,7 +1530,6 @@ def relative_difference_set_from_homomorphism(q, N, d, check=True, return_group= return G2, second_diff_set return second_diff_set - def is_relative_difference_set(R, G, H, params, verbose=False): r""" Check if ``R`` is a difference set of ``G`` relative to ``H``, with the given parameters. @@ -2040,9 +2039,6 @@ def skew_supplementary_difference_set_over_polynomial_ring(n, existence=False, c ... NotImplementedError: skew SDS of order 7 not yet implemented """ - from sage.symbolic.ring import SymbolicRing - from sage.rings.finite_rings.integer_mod_ring import Zmod - data = { 81: (3, lambda x: x**4 - x**3 - 1, 16, 5, [1, 2, 4, 6, 8, 10, 12, 14], [1, 2, 3, 4, 10, 11, 13], @@ -2060,9 +2056,11 @@ def skew_supplementary_difference_set_over_polynomial_ring(n, existence=False, c mod, poly, exp, order, ind1, ind2, ind3, ind4 = data[n] + from sage.rings.finite_rings.integer_mod_ring import Zmod + Z3 = Zmod(mod) - R = SymbolicRing() - x = R.var('x') + R = ZZ['x'] + x = R.gen() F = Z3.extension(poly(x)) H = [F.gen() ** (exp * i) for i in range(order)] diff --git a/src/sage/combinat/root_system/coxeter_type.py b/src/sage/combinat/root_system/coxeter_type.py index bb0f32a7f02..c2bf3bc0fce 100644 --- a/src/sage/combinat/root_system/coxeter_type.py +++ b/src/sage/combinat/root_system/coxeter_type.py @@ -17,16 +17,19 @@ # https://www.gnu.org/licenses/ # **************************************************************************** +import sage.rings.abc + +from sage.combinat.root_system.cartan_type import CartanType from sage.misc.abstract_method import abstract_method from sage.misc.cachefunc import cached_method from sage.misc.classcall_metaclass import ClasscallMetaclass -from sage.combinat.root_system.cartan_type import CartanType -import sage.rings.abc from sage.matrix.args import SparseEntry from sage.matrix.constructor import Matrix from sage.structure.unique_representation import UniqueRepresentation from sage.structure.sage_object import SageObject +lazy_import('sage.rings.universal_cyclotomic_field', 'UniversalCyclotomicField') + class CoxeterType(SageObject, metaclass=ClasscallMetaclass): """ @@ -371,19 +374,12 @@ def bilinear_form(self, R=None): n = self.rank() mat = self.coxeter_matrix()._matrix - from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField - UCF = UniversalCyclotomicField() - if R is None: - R = UCF - # if UCF.has_coerce_map_from(base_ring): - # R = UCF - # else: - # R = base_ring + R = UniversalCyclotomicField() # Compute the matrix with entries `- \cos( \pi / m_{ij} )`. - E = UCF.gen - if R is UCF: + if isinstance(R, sage.rings.abc.UniversalCyclotomicField): + E = R.gen def val(x): if x > -1: @@ -391,6 +387,8 @@ def val(x): else: return R(x) elif isinstance(R, sage.rings.abc.NumberField_quadratic): + from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField + E = UniversalCyclotomicField().gen def val(x): if x > -1: diff --git a/src/sage/rings/abc.pyx b/src/sage/rings/abc.pyx index 2aa3421721d..d967cfbb95c 100644 --- a/src/sage/rings/abc.pyx +++ b/src/sage/rings/abc.pyx @@ -56,6 +56,32 @@ class NumberField_cyclotomic(Field): pass +class UniversalCyclotomicField(Field): + r""" + Abstract base class for :class:`~sage.rings.universal_cyclotomic_field.UniversalCyclotomicField`. + + This class is defined for the purpose of :func:`isinstance` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: import sage.rings.abc + sage: K = UniversalCyclotomicField() # optional - sage.rings.number_field + sage: isinstance(K, sage.rings.abc.UniversalCyclotomicField) # optional - sage.rings.number_field + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.UniversalCyclotomicField.__subclasses__() # optional - sage.rings.number_field + [] + + sage: len(sage.rings.abc.NumberField_cyclotomic.__subclasses__()) <= 1 + True + """ + + pass + + class AlgebraicField_common(Field): r""" Abstract base class for :class:`~sage.rings.qqbar.AlgebraicField_common`. From f756d118305b2170fe8e2bda628f26f1c929a990 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 17 May 2023 17:11:54 -0700 Subject: [PATCH 131/205] src/sage/combinat/root_system/coxeter_type.py: Fix import --- src/sage/categories/finite_coxeter_groups.py | 4 ++-- src/sage/combinat/root_system/coxeter_type.py | 2 +- src/sage/rings/universal_cyclotomic_field.py | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/sage/categories/finite_coxeter_groups.py b/src/sage/categories/finite_coxeter_groups.py index 12239cc7ec2..a03a7ca5495 100644 --- a/src/sage/categories/finite_coxeter_groups.py +++ b/src/sage/categories/finite_coxeter_groups.py @@ -750,8 +750,8 @@ def permutahedron(self, point=None, base_ring=None): v = sum(point[i-1] * weights[i] for i in weights.keys()) vertices = [v*w for w in self] if base_ring is None: - if isinstance(v.base_ring(), [sage.rings.abc.UniversalCyclotomicField, - sage.rings.abc.AlgebraicField_common]): + if isinstance(v.base_ring(), (sage.rings.abc.UniversalCyclotomicField, + sage.rings.abc.AlgebraicField_common)): from sage.rings.qqbar import AA vertices = [v.change_ring(AA) for v in vertices] base_ring = AA diff --git a/src/sage/combinat/root_system/coxeter_type.py b/src/sage/combinat/root_system/coxeter_type.py index c2bf3bc0fce..cad3482bb17 100644 --- a/src/sage/combinat/root_system/coxeter_type.py +++ b/src/sage/combinat/root_system/coxeter_type.py @@ -25,6 +25,7 @@ from sage.misc.classcall_metaclass import ClasscallMetaclass from sage.matrix.args import SparseEntry from sage.matrix.constructor import Matrix +from sage.misc.lazy_import import lazy_import from sage.structure.unique_representation import UniqueRepresentation from sage.structure.sage_object import SageObject @@ -387,7 +388,6 @@ def val(x): else: return R(x) elif isinstance(R, sage.rings.abc.NumberField_quadratic): - from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField E = UniversalCyclotomicField().gen def val(x): diff --git a/src/sage/rings/universal_cyclotomic_field.py b/src/sage/rings/universal_cyclotomic_field.py index 2c6097e74e8..173224323ce 100644 --- a/src/sage/rings/universal_cyclotomic_field.py +++ b/src/sage/rings/universal_cyclotomic_field.py @@ -163,6 +163,8 @@ - Sebastian Oehms (2019): add :meth:`_factor_univariate_polynomial` (see :trac:`28631`) """ +import sage.rings.abc + from sage.misc.cachefunc import cached_method from sage.structure.richcmp import rich_to_bool @@ -1281,7 +1283,7 @@ def minpoly(self, var='x'): return QQ[var](QQ['x_1'](str(gap_p))) -class UniversalCyclotomicField(UniqueRepresentation, Field): +class UniversalCyclotomicField(UniqueRepresentation, sage.rings.abc.UniversalCyclotomicField): r""" The universal cyclotomic field. From f5dae8ffcfbe37dd631f7b3905106407407f1d8e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 27 May 2023 20:13:55 -0700 Subject: [PATCH 132/205] src/sage/combinat/designs/incidence_structures.py: Modularization fixes for imports --- src/sage/combinat/designs/incidence_structures.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/designs/incidence_structures.py b/src/sage/combinat/designs/incidence_structures.py index 1aa6c34d733..fbb003122ab 100644 --- a/src/sage/combinat/designs/incidence_structures.py +++ b/src/sage/combinat/designs/incidence_structures.py @@ -39,10 +39,13 @@ # https://www.gnu.org/licenses/ # # ************************************************************************** from __future__ import annotations -from sage.rings.integer import Integer + from sage.misc.latex import latex +from sage.misc.lazy_import import lazy_import +from sage.rings.integer import Integer from sage.sets.set import Set -from sage.libs.gap.libgap import libgap + +lazy_import('sage.libs.gap.libgap', 'libgap') class IncidenceStructure(): @@ -173,7 +176,6 @@ def __init__(self, points=None, blocks=None, incidence_matrix=None, sage: IncidenceStructure([]) Incidence structure with 0 points and 0 blocks """ - from sage.matrix.constructor import matrix from sage.structure.element import Matrix # Reformatting input @@ -189,6 +191,7 @@ def __init__(self, points=None, blocks=None, incidence_matrix=None, assert incidence_matrix is None, "'incidence_matrix' cannot be defined when 'points' is defined" if incidence_matrix: + from sage.matrix.constructor import matrix M = matrix(incidence_matrix) v = M.nrows() self._points = list(range(v)) From 0d1bc449dceb65690814ead1d1f3a39e5dc0e4dd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 27 May 2023 20:17:26 -0700 Subject: [PATCH 133/205] src/sage/combinat/interval_posets.py: Don't fail if DyckWords cannot be imported --- src/sage/combinat/interval_posets.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/interval_posets.py b/src/sage/combinat/interval_posets.py index a2d4f6e607c..70b165befee 100644 --- a/src/sage/combinat/interval_posets.py +++ b/src/sage/combinat/interval_posets.py @@ -3042,7 +3042,13 @@ def final_forest(element) -> TIP: """ if isinstance(element, TamariIntervalPoset): return element.final_forest() - if element in DyckWords(): + + try: + DW = DyckWords() + except ImportError: + DW = () + + if element in DW: binary_tree = element.to_binary_tree_tamari() elif element in BinaryTrees() or element in LabelledBinaryTrees(): binary_tree = element @@ -3149,7 +3155,13 @@ def initial_forest(element) -> TIP: """ if isinstance(element, TamariIntervalPoset): return element.initial_forest() - if element in DyckWords(): + + try: + DW = DyckWords() + except ImportError: + DW = () + + if element in DW: binary_tree = element.to_binary_tree_tamari() elif element in BinaryTrees() or element in LabelledBinaryTrees(): binary_tree = element From fa0c443f5ded81bd87963e4a388904ebe61d6704 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 29 May 2023 12:45:11 -0700 Subject: [PATCH 134/205] sage.combinat: Modularization fixes for imports --- src/sage/combinat/designs/bibd.py | 10 ++++++---- src/sage/combinat/integer_vector_weighted.py | 4 +++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/sage/combinat/designs/bibd.py b/src/sage/combinat/designs/bibd.py index 2265e113040..071c1db387e 100644 --- a/src/sage/combinat/designs/bibd.py +++ b/src/sage/combinat/designs/bibd.py @@ -50,12 +50,16 @@ --------- """ +from sage.arith.misc import binomial, is_prime_power, is_square from sage.categories.sets_cat import EmptySetError +from sage.misc.lazy_import import lazy_import from sage.misc.unknown import Unknown + from .design_catalog import transversal_design # type:ignore -from sage.arith.misc import binomial, is_prime_power -from .group_divisible_designs import GroupDivisibleDesign from .designs_pyx import is_pairwise_balanced_design +from .group_divisible_designs import GroupDivisibleDesign + +lazy_import('sage.schemes.plane_conics.constructor', 'Conic') def biplane(n, existence=False): @@ -413,8 +417,6 @@ def BruckRyserChowla_check(v, k, lambd): True """ - from sage.arith.misc import is_square - from sage.schemes.plane_conics.constructor import Conic from sage.rings.rational_field import QQ # design is not symmetric diff --git a/src/sage/combinat/integer_vector_weighted.py b/src/sage/combinat/integer_vector_weighted.py index 1b110c34140..071c814f3bb 100644 --- a/src/sage/combinat/integer_vector_weighted.py +++ b/src/sage/combinat/integer_vector_weighted.py @@ -20,13 +20,15 @@ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets from sage.categories.sets_with_grading import SetsWithGrading +from sage.misc.lazy_import import lazy_import from sage.sets.disjoint_union_enumerated_sets import DisjointUnionEnumeratedSets from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.combinat.integer_vector import IntegerVector -from sage.combinat.words.word import Word from sage.combinat.permutation import Permutation +lazy_import('sage.combinat.words.word', 'Word') + class WeightedIntegerVectors(Parent, UniqueRepresentation): r""" From c0c213c4f283c57ea0e62a70767a70e3d16f0e0e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 7 Jun 2023 14:04:23 -0700 Subject: [PATCH 135/205] src/doc/en/reference/combinat/module_list.rst: Add set_partition_iterator --- src/doc/en/reference/combinat/module_list.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/src/doc/en/reference/combinat/module_list.rst b/src/doc/en/reference/combinat/module_list.rst index b469a7e30f4..a4f05a0fdc7 100644 --- a/src/doc/en/reference/combinat/module_list.rst +++ b/src/doc/en/reference/combinat/module_list.rst @@ -291,6 +291,7 @@ Comprehensive Module List sage/combinat/rsk sage/combinat/schubert_polynomial sage/combinat/set_partition + sage/combinat/set_partition_iterator sage/combinat/set_partition_ordered sage/combinat/sf/all sage/combinat/sf/character From d961aec28421bac544d0760404735baecf0df206 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 7 Jun 2023 17:55:09 -0700 Subject: [PATCH 136/205] sage.coding: More fixes to imports, # optional --- src/sage/coding/linear_code.py | 6 +++--- src/sage/coding/source_coding/huffman.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index 754b97c25dc..ae80ec10894 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -1,4 +1,4 @@ -# sage.doctest: sage.modules sage.rings.finite_rings +# sage.doctest: optional - sage.modules sage.rings.finite_rings r""" Generic structures for linear codes over the Hamming metric @@ -217,7 +217,6 @@ class should inherit from this class. Also ``AbstractLinearCode`` should never from sage.combinat.subset import Subsets from sage.cpython.string import bytes_to_str from sage.features.gap import GapPackage -from sage.interfaces.gap import gap from sage.matrix.matrix_space import MatrixSpace from sage.misc.cachefunc import cached_method from sage.misc.functional import is_even @@ -234,6 +233,7 @@ class should inherit from this class. Also ``AbstractLinearCode`` should never lazy_import('sage.groups.perm_gps.permgroup_named', 'SymmetricGroup') lazy_import('sage.groups.perm_gps.permgroup', 'PermutationGroup') +lazy_import('sage.interfaces.gap', 'gap') # ***************************************************************************** @@ -466,7 +466,7 @@ def automorphism_group_gens(self, equivalence="semilinear"): depends on which packages are loaded, so we must re-seed GAP to ensure a consistent result for this example:: - sage: libgap.set_seed(0) + sage: libgap.set_seed(0) # optional - sage.libs.gap 0 sage: C = codes.HammingCode(GF(4, 'z'), 3) sage: C.automorphism_group_gens() diff --git a/src/sage/coding/source_coding/huffman.py b/src/sage/coding/source_coding/huffman.py index 1bdf176509e..eb138738f2f 100644 --- a/src/sage/coding/source_coding/huffman.py +++ b/src/sage/coding/source_coding/huffman.py @@ -544,7 +544,7 @@ def _generate_edges(self, tree, parent="", bit=""): sage: from sage.coding.source_coding.huffman import Huffman sage: H = Huffman("Sage") sage: T = H.tree() # optional - sage.graphs - sage: T.edges(sort=True, labels=None) # indirect doctest + sage: T.edges(sort=True, labels=None) # indirect doctest # optional - sage.graphs [('0', 'S: 00'), ('0', 'a: 01'), ('1', 'e: 10'), ('1', 'g: 11'), ('root', '0'), ('root', '1')] """ if parent == "": From 8199be3f525a104aa5884040c214c94602f33c42 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 7 Jun 2023 17:58:38 -0700 Subject: [PATCH 137/205] sage.structure: More # optional - sage.modular sage.schemes --- src/sage/structure/coerce.pyx | 8 +++---- src/sage/structure/coerce_actions.pyx | 34 +++++++++++++++------------ src/sage/structure/factorization.py | 11 ++++----- src/sage/structure/parent.pyx | 24 +++++++++++-------- 4 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/sage/structure/coerce.pyx b/src/sage/structure/coerce.pyx index c916f877fe2..b3081701b44 100644 --- a/src/sage/structure/coerce.pyx +++ b/src/sage/structure/coerce.pyx @@ -35,9 +35,9 @@ On failure, a TypeError is always raised. Some arithmetic operations (such as multiplication) can indicate an action rather than arithmetic in a common parent. For example:: - sage: E = EllipticCurve('37a') - sage: P = E(0,0) - sage: 5*P + sage: E = EllipticCurve('37a') # optional - sage.schemes + sage: P = E(0,0) # optional - sage.schemes + sage: 5*P # optional - sage.schemes (1/4 : -5/8 : 1) where there is action of `\ZZ` on the points of `E` given by the additive @@ -439,7 +439,7 @@ cpdef bint is_numpy_type(t): False sage: is_numpy_type(Integer) False - sage: is_numpy_type(Sudoku) + sage: is_numpy_type(Sudoku) # optional - sage.combinat False sage: is_numpy_type(None) False diff --git a/src/sage/structure/coerce_actions.pyx b/src/sage/structure/coerce_actions.pyx index 3096282f068..146c41379b7 100644 --- a/src/sage/structure/coerce_actions.pyx +++ b/src/sage/structure/coerce_actions.pyx @@ -55,9 +55,11 @@ cdef class GenericAction(Action): for otherwise they could be garbage collected, giving rise to random errors (see :trac:`18157`). :: - sage: M = MatrixSpace(ZZ,2) - sage: sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) - Left action by Full MatrixSpace of 2 by 2 dense matrices over Integer Ring on Set P^1(QQ) of all cusps + sage: M = MatrixSpace(ZZ, 2) # optional - sage.modules + sage: sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) # optional - sage.modular sage.modules + Left action + by Full MatrixSpace of 2 by 2 dense matrices over Integer Ring + on Set P^1(QQ) of all cusps sage: Z6 = Zmod(6) sage: sage.structure.coerce_actions.GenericAction(QQ, Z6, True) @@ -92,9 +94,9 @@ cdef class GenericAction(Action): errors (see :trac:`18157`). :: - sage: M = MatrixSpace(ZZ,2) - sage: A = sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) - sage: A.codomain() + sage: M = MatrixSpace(ZZ, 2) # optional - sage.modules + sage: A = sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) # optional - sage.modular sage.modules + sage: A.codomain() # optional - sage.modular sage.modules Set P^1(QQ) of all cusps sage: S3 = SymmetricGroup(3) # optional - sage.groups @@ -140,14 +142,14 @@ cdef class ActedUponAction(GenericAction): """ TESTS:: - sage: M = MatrixSpace(ZZ,2) - sage: A = sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) - sage: A.act(matrix(ZZ, 2, [1,0,2,-1]), Cusp(1,2)) + sage: M = MatrixSpace(ZZ, 2) # optional - sage.modules + sage: A = sage.structure.coerce_actions.ActedUponAction(M, Cusps, True) # optional - sage.modular sage.modules + sage: A.act(matrix(ZZ, 2, [1,0,2,-1]), Cusp(1,2)) # optional - sage.modular sage.modules Infinity - sage: A(matrix(ZZ, 2, [1,0,2,-1]), Cusp(1,2)) + sage: A(matrix(ZZ, 2, [1,0,2,-1]), Cusp(1,2)) # optional - sage.modular sage.modules Infinity - sage: type(A) + sage: type(A) # optional - sage.modular sage.modules <... 'sage.structure.coerce_actions.ActedUponAction'> """ return (x)._acted_upon_(g, not self._is_left) @@ -170,10 +172,12 @@ def detect_element_action(Parent X, Y, bint X_on_left, X_el=None, Y_el=None): sage: detect_element_action(ZZx, ZZ, False) Left scalar multiplication by Integer Ring on Univariate Polynomial Ring in x over Integer Ring sage: detect_element_action(ZZx, QQ, True) - Right scalar multiplication by Rational Field on Univariate Polynomial Ring in x over Integer Ring - sage: detect_element_action(Cusps, M, False) - Left action by Full MatrixSpace of 2 by 2 dense matrices over Integer Ring on Set P^1(QQ) of all cusps - sage: detect_element_action(Cusps, M, True), + Right scalar multiplication by Rational Field + on Univariate Polynomial Ring in x over Integer Ring + sage: detect_element_action(Cusps, M, False) # optional - sage.modular sage.modules + Left action by Full MatrixSpace of 2 by 2 dense matrices over Integer Ring + on Set P^1(QQ) of all cusps + sage: detect_element_action(Cusps, M, True), # optional - sage.modular sage.modules (None,) sage: detect_element_action(ZZ, QQ, True), (None,) diff --git a/src/sage/structure/factorization.py b/src/sage/structure/factorization.py index 0d4a704783c..a547bee0820 100644 --- a/src/sage/structure/factorization.py +++ b/src/sage/structure/factorization.py @@ -121,15 +121,14 @@ Factorizations can involve fairly abstract mathematical objects:: - sage: F = ModularSymbols(11,4).factorization() - sage: F + sage: F = ModularSymbols(11,4).factorization(); F # optional - sage.modular (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) * (Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 6 for Gamma_0(11) of weight 4 with sign 0 over Rational Field) - sage: type(F) + sage: type(F) # optional - sage.modular @@ -528,8 +527,8 @@ def universe(self): sage: (F*F^-1).universe() # optional - sage.combinat sage.modules Free Algebra on 3 generators (x, y, z) over Rational Field - sage: F = ModularSymbols(11,4).factorization() - sage: F.universe() + sage: F = ModularSymbols(11,4).factorization() # optional - sage.modular + sage: F.universe() # optional - sage.modular """ try: return self.__universe @@ -772,7 +771,7 @@ def _cr(self): Next we factor a modular symbols space:: - sage: F = ModularSymbols(11).factor(); F + sage: F = ModularSymbols(11).factor(); F # optional - sage.modular (Modular Symbols subspace of dimension 1 of ...) * (Modular Symbols subspace of dimension 1 of ...) * (Modular Symbols subspace of dimension 1 of ...) diff --git a/src/sage/structure/parent.pyx b/src/sage/structure/parent.pyx index dccccf1bbc8..d7bf7971731 100644 --- a/src/sage/structure/parent.pyx +++ b/src/sage/structure/parent.pyx @@ -2570,17 +2570,17 @@ cdef class Parent(sage.structure.category_object.CategoryObject): """ TESTS:: - sage: E = EllipticCurve([1,0]) - sage: coercion_model.get_action(E, ZZ, operator.mul) + sage: E = EllipticCurve([1,0]) # optional - sage.schemes + sage: coercion_model.get_action(E, ZZ, operator.mul) # optional - sage.schemes Right Integer Multiplication by Integer Ring on Elliptic Curve defined by y^2 = x^3 + x over Rational Field - sage: coercion_model.get_action(ZZ, E, operator.mul) + sage: coercion_model.get_action(ZZ, E, operator.mul) # optional - sage.schemes Left Integer Multiplication by Integer Ring on Elliptic Curve defined by y^2 = x^3 + x over Rational Field - sage: coercion_model.get_action(E, int, operator.mul) + sage: coercion_model.get_action(E, int, operator.mul) # optional - sage.schemes Right Integer Multiplication by Set of Python objects of class 'int' on Elliptic Curve defined by y^2 = x^3 + x over Rational Field - sage: coercion_model.get_action(int, E, operator.mul) + sage: coercion_model.get_action(int, E, operator.mul) # optional - sage.schemes Left Integer Multiplication by Set of Python objects of class 'int' on Elliptic Curve defined by y^2 = x^3 + x over Rational Field @@ -2603,7 +2603,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): :: - sage: print(coercion_model.get_action(E, ZZ, operator.pow)) + sage: print(coercion_model.get_action(E, ZZ, operator.pow)) # optional - sage.schemes None """ # G acts on S, G -> G', R -> S => G' acts on R (?) @@ -2829,8 +2829,10 @@ cdef class Parent(sage.structure.category_object.CategoryObject): False sage: [R._is_numerical() for R in [QQ['x'], QQ[['x']]]] [False, False] - sage: [R._is_numerical() for R in [RIF, RBF, CIF, CBF]] - [False, False, False, False] + sage: [R._is_numerical() for R in [RBF, CBF]] # optional - sage.libs.flint + [False, False] + sage: [R._is_numerical() for R in [RIF, CIF]] + [False, False] """ try: from sage.rings.complex_mpfr import ComplexField @@ -2863,8 +2865,10 @@ cdef class Parent(sage.structure.category_object.CategoryObject): False sage: [R._is_real_numerical() for R in [QQ['x'], QQ[['x']]]] [False, False] - sage: [R._is_real_numerical() for R in [RIF, RBF, CIF, CBF]] - [False, False, False, False] + sage: [R._is_real_numerical() for R in [RBF, CBF]] # optional - sage.libs.flint + [False, False] + sage: [R._is_real_numerical() for R in [RIF, CIF]] # optional - sage.libs.flint + [False, False] """ try: from sage.rings.real_mpfr import RealField, mpfr_prec_min From 62439b39d591c620055423c476af43b44efa3797 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 7 Jun 2023 18:04:50 -0700 Subject: [PATCH 138/205] src/sage/matroids/constructor.py: Fix # optional --- src/sage/matroids/constructor.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/matroids/constructor.py b/src/sage/matroids/constructor.py index 11221faf9a1..12ca5ec2873 100644 --- a/src/sage/matroids/constructor.py +++ b/src/sage/matroids/constructor.py @@ -615,10 +615,9 @@ def Matroid(groundset=None, data=None, **kwds): The ``regular`` option:: - sage: M = Matroid(reduced_matrix=[[1, 1, 0], + sage: M = Matroid(reduced_matrix=[[1, 1, 0], # optional - sage.graphs ....: [1, 0, 1], - ....: [0, 1, 1]], regular=True) - sage: M + ....: [0, 1, 1]], regular=True); M Regular matroid of rank 3 on 6 elements with 16 bases sage: M.is_isomorphic(matroids.CompleteGraphic(4)) From 4772d0530151d0056878aa63d59c1923a2af40d8 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Thu, 8 Jun 2023 14:11:10 +0900 Subject: [PATCH 139/205] Making the linter happy. --- src/sage/algebras/jordan_algebra.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/algebras/jordan_algebra.py b/src/sage/algebras/jordan_algebra.py index 81bdecbce3e..81c40105f8a 100644 --- a/src/sage/algebras/jordan_algebra.py +++ b/src/sage/algebras/jordan_algebra.py @@ -212,7 +212,6 @@ def __classcall_private__(self, arg0, arg1=None, names=None): arg1.set_immutable() return JordanAlgebraSymmetricBilinear(arg0, arg1, names=names) - def _test_jordan_relations(self, **options): r""" Test the Jordan algebra relations. From fe07439f5fb7fe417bcee0b89830a665e138ffe5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 8 Jun 2023 09:34:22 -0700 Subject: [PATCH 140/205] sage.combinat: Add '# cython: binding=True' to the split cython modules --- src/sage/combinat/combinat_cython.pyx | 1 + src/sage/combinat/posets/hasse_cython.pyx | 1 + src/sage/combinat/posets/hasse_cython_flint.pyx | 1 + src/sage/combinat/posets/linear_extension_iterator.pyx | 1 + src/sage/combinat/set_partition_iterator.pyx | 1 + 5 files changed, 5 insertions(+) diff --git a/src/sage/combinat/combinat_cython.pyx b/src/sage/combinat/combinat_cython.pyx index 49dd5483402..c0905491ac2 100644 --- a/src/sage/combinat/combinat_cython.pyx +++ b/src/sage/combinat/combinat_cython.pyx @@ -1,3 +1,4 @@ +# cython: binding=True """ Fast computation of combinatorial functions (Cython + mpz) diff --git a/src/sage/combinat/posets/hasse_cython.pyx b/src/sage/combinat/posets/hasse_cython.pyx index 17f6444aaa1..8f7a869fc17 100644 --- a/src/sage/combinat/posets/hasse_cython.pyx +++ b/src/sage/combinat/posets/hasse_cython.pyx @@ -1,3 +1,4 @@ +# cython: binding=True r""" Some fast computations for finite posets """ diff --git a/src/sage/combinat/posets/hasse_cython_flint.pyx b/src/sage/combinat/posets/hasse_cython_flint.pyx index 1d26c95c60e..0b33eed0b3f 100644 --- a/src/sage/combinat/posets/hasse_cython_flint.pyx +++ b/src/sage/combinat/posets/hasse_cython_flint.pyx @@ -1,3 +1,4 @@ +# cython: binding=True r""" Some fast computations for finite posets using FLINT matrices """ diff --git a/src/sage/combinat/posets/linear_extension_iterator.pyx b/src/sage/combinat/posets/linear_extension_iterator.pyx index 21437e91005..5eb101b32e2 100644 --- a/src/sage/combinat/posets/linear_extension_iterator.pyx +++ b/src/sage/combinat/posets/linear_extension_iterator.pyx @@ -1,3 +1,4 @@ +# cython: binding=True r""" Fast linear extension iterator """ diff --git a/src/sage/combinat/set_partition_iterator.pyx b/src/sage/combinat/set_partition_iterator.pyx index 9b83127d61a..fff6a71fefe 100644 --- a/src/sage/combinat/set_partition_iterator.pyx +++ b/src/sage/combinat/set_partition_iterator.pyx @@ -1,3 +1,4 @@ +# cython: binding=True r""" Fast set partition iterators """ From 0f14234fa3318889ef441dc996d2160f4dcf658a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 5 Jun 2023 13:45:43 -0700 Subject: [PATCH 141/205] src/doc/bootstrap: In reference manual show modularized sagelib packages separately --- build/bin/sage-spkg-info | 2 +- src/doc/bootstrap | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/build/bin/sage-spkg-info b/build/bin/sage-spkg-info index 4e53139fa7e..d02b3ac347f 100755 --- a/build/bin/sage-spkg-info +++ b/build/bin/sage-spkg-info @@ -9,7 +9,7 @@ PKG_SCRIPTS="$SAGE_ROOT/build/pkgs/$PKG_BASE" for ext in rst txt; do SPKG_FILE="$PKG_SCRIPTS/SPKG.$ext" if [ -f "$SPKG_FILE" ]; then - cat "$SPKG_FILE" + sed "1,3s/^ *Sage: Open Source Mathematics Software:/$PKG_BASE:/" "$SPKG_FILE" break fi done diff --git a/src/doc/bootstrap b/src/doc/bootstrap index 6dd50fd5cec..f049f62599d 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -100,7 +100,16 @@ Sage depends. It installs them automatically if it does not find equivalent system packages. EOF -for PKG_BASE in $(sage-package list --has-file SPKG.rst :standard: | sort); do +for PKG_BASE in $(sage-package list --has-file SPKG.rst :standard: | grep -v '^sagemath_' | sort); do + echo "* :ref:\`spkg_$PKG_BASE\`" +done >> "$OUTPUT_INDEX" +cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" < "$OUTPUT_DIR"/$PKG_BASE.rst echo >> "$OUTPUT_INDEX" " $PKG_BASE" done +cat >> "$OUTPUT_INDEX" < Date: Fri, 9 Jun 2023 13:32:06 -0700 Subject: [PATCH 142/205] src/doc/en/reference: Move 'Features' from misc to spkg --- src/doc/bootstrap | 38 +++++++++++++++++++++++++++++ src/doc/en/reference/misc/index.rst | 38 ----------------------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/doc/bootstrap b/src/doc/bootstrap index f049f62599d..215ac1c51ed 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -147,6 +147,44 @@ All External Packages index_alph + +Runtime-Detectable Features and Conditional Doctests +---------------------------------------------------- + +.. toctree:: + :maxdepth: 1 + + sage/features + sage/features/sagemath + sage/features/pkg_systems + sage/features/bliss + sage/features/csdp + sage/features/databases + sage/features/dvipng + sage/features/ffmpeg + sage/features/four_ti_2 + sage/features/gap + sage/features/graph_generators + sage/features/graphviz + sage/features/imagemagick + sage/features/interfaces + sage/features/internet + sage/features/kenzo + sage/features/latex + sage/features/latte + sage/features/lrs + sage/features/mcqd + sage/features/meataxe + sage/features/mip_backends + sage/features/normaliz + sage/features/pandoc + sage/features/pdf2svg + sage/features/polymake + sage/features/rubiks + sage/features/tdlib + sage/features/join_feature + sage/features/all + EOF OUTPUT_INDEX="$OUTPUT_DIR"/index_alph.rst diff --git a/src/doc/en/reference/misc/index.rst b/src/doc/en/reference/misc/index.rst index 8a26fcb9a00..e9b082794b9 100644 --- a/src/doc/en/reference/misc/index.rst +++ b/src/doc/en/reference/misc/index.rst @@ -141,44 +141,6 @@ Fast Expression Evaluation .. sage/ext/interpreters/wrapper_rdf .. sage/ext/interpreters/wrapper_rr -Features -~~~~~~~~ - -.. toctree:: - :maxdepth: 1 - - sage/features - sage/features/join_feature - sage/features/all - sage/features/sagemath - sage/features/pkg_systems - sage/features/bliss - sage/features/csdp - sage/features/databases - sage/features/dvipng - sage/features/ffmpeg - sage/features/four_ti_2 - sage/features/gap - sage/features/graph_generators - sage/features/graphviz - sage/features/imagemagick - sage/features/interfaces - sage/features/internet - sage/features/kenzo - sage/features/latex - sage/features/latte - sage/features/lrs - sage/features/mcqd - sage/features/meataxe - sage/features/mip_backends - sage/features/normaliz - sage/features/pandoc - sage/features/pdf2svg - sage/features/polymake - sage/features/rubiks - sage/features/tdlib - - Code Evaluation --------------- From 7630b03a38497dd6b711acb046e1b3d33f885455 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 9 Jun 2023 16:28:50 -0700 Subject: [PATCH 143/205] Fix markup --- src/doc/bootstrap | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doc/bootstrap b/src/doc/bootstrap index 215ac1c51ed..3161b78de17 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -194,11 +194,11 @@ Details of external packages Packages are in alphabetical order. +.. default-role:: code + .. toctree:: :maxdepth: 1 -.. default-role:: code - EOF for PKG_BASE in $(sage-package list --has-file SPKG.rst | sort); do PKG_SCRIPTS=build/pkgs/$PKG_BASE @@ -210,6 +210,7 @@ for PKG_BASE in $(sage-package list --has-file SPKG.rst | sort); do echo >> "$OUTPUT_INDEX" " $PKG_BASE" done cat >> "$OUTPUT_INDEX" < Date: Fri, 9 Jun 2023 19:52:49 -0700 Subject: [PATCH 144/205] sage.features: Add links to spkgs --- src/doc/bootstrap | 22 +++++++++---------- src/sage/features/bliss.py | 2 +- src/sage/features/cddlib.py | 2 +- src/sage/features/csdp.py | 2 +- src/sage/features/databases.py | 31 +++++++++++++++++---------- src/sage/features/dvipng.py | 2 +- src/sage/features/ffmpeg.py | 2 +- src/sage/features/four_ti_2.py | 4 ++-- src/sage/features/gap.py | 4 ++-- src/sage/features/gfan.py | 2 +- src/sage/features/graph_generators.py | 8 +++---- src/sage/features/graphviz.py | 16 +++++++------- src/sage/features/igraph.py | 2 +- src/sage/features/imagemagick.py | 9 ++++---- src/sage/features/interfaces.py | 2 +- src/sage/features/kenzo.py | 2 +- src/sage/features/latte.py | 7 +++--- src/sage/features/lrs.py | 2 +- src/sage/features/mcqd.py | 3 ++- src/sage/features/meataxe.py | 3 ++- src/sage/features/msolve.py | 10 ++++----- src/sage/features/nauty.py | 4 ++-- src/sage/features/normaliz.py | 2 +- src/sage/features/palp.py | 6 +++--- src/sage/features/pandoc.py | 2 +- src/sage/features/pdf2svg.py | 2 +- src/sage/features/phitigra.py | 4 ++-- src/sage/features/pkg_systems.py | 2 +- src/sage/features/polymake.py | 6 +++--- src/sage/features/rubiks.py | 18 ++++++++-------- src/sage/features/singular.py | 4 ++-- src/sage/features/sphinx.py | 4 ++-- src/sage/features/tdlib.py | 2 +- 33 files changed, 102 insertions(+), 91 deletions(-) diff --git a/src/doc/bootstrap b/src/doc/bootstrap index 3161b78de17..11bbc5510a5 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -89,8 +89,8 @@ fi OUTPUT_INDEX="$OUTPUT_DIR"/index.rst cat > "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" <` is present and functional. EXAMPLES:: diff --git a/src/sage/features/cddlib.py b/src/sage/features/cddlib.py index 5badbd251c0..b37f0304948 100644 --- a/src/sage/features/cddlib.py +++ b/src/sage/features/cddlib.py @@ -17,7 +17,7 @@ class CddExecutable(Executable): r""" A :class:`~sage.features.Feature` describing the presence of an executable - which comes as a part of ``cddlib``. + which comes as a part of :ref:`cddlib `. EXAMPLES:: diff --git a/src/sage/features/csdp.py b/src/sage/features/csdp.py index 9c04779558c..b1e253b237c 100644 --- a/src/sage/features/csdp.py +++ b/src/sage/features/csdp.py @@ -25,7 +25,7 @@ class CSDP(Executable): r""" A :class:`~sage.features.Feature` which checks for the ``theta`` binary - of CSDP. + of :ref:`CSDP `. EXAMPLES:: diff --git a/src/sage/features/databases.py b/src/sage/features/databases.py index 7fa05ca099a..37ee2852113 100644 --- a/src/sage/features/databases.py +++ b/src/sage/features/databases.py @@ -26,8 +26,8 @@ class DatabaseConwayPolynomials(StaticFile): r""" - A :class:`~sage.features.Feature` which describes the presence of Frank Luebeck's - database of Conway polynomials. + A :class:`~sage.features.Feature` which describes the presence of :ref:`Frank Luebeck's + database of Conway polynomials `. EXAMPLES:: @@ -60,8 +60,9 @@ def __init__(self): class DatabaseCremona(StaticFile): r""" - A :class:`~sage.features.Feature` which describes the presence of John Cremona's - database of elliptic curves. + A :class:`~sage.features.Feature` which describes the presence of :ref:`John Cremona's + database of elliptic curves ` + (or its :ref:`small version `. INPUT: @@ -94,7 +95,8 @@ def __init__(self, name="cremona", spkg="database_cremona_ellcurve"): class DatabaseJones(StaticFile): r""" - A :class:`~sage.features.Feature` which describes the presence of John Jones's tables of number fields. + A :class:`~sage.features.Feature` which describes the presence of + :ref:`John Jones's tables of number fields `. EXAMPLES:: @@ -118,12 +120,13 @@ def __init__(self): class DatabaseKnotInfo(PythonModule): r""" - A :class:`~sage.features.Feature` which describes the presence of the databases at the + A :class:`~sage.features.Feature` which describes the presence of the + :ref:`package providing the KnotInfo and LinkInfo databases `. + + The homes of these databases are the web-pages `KnotInfo `__ and `LinkInfo `__. - - EXAMPLES:: sage: from sage.features.databases import DatabaseKnotInfo @@ -140,9 +143,13 @@ def __init__(self): """ PythonModule.__init__(self, 'database_knotinfo', spkg='database_knotinfo') + class DatabaseCubicHecke(PythonModule): r""" - A :class:`~sage.features.Feature` which describes the presence of the databases at the + A :class:`~sage.features.Feature` which describes the presence of the + :ref:`Cubic Hecke algebra database package `. + + The home of this database is the web-page `Cubic Hecke algebra on 4 strands `__ of Ivan Marin. @@ -162,10 +169,12 @@ def __init__(self): """ PythonModule.__init__(self, 'database_cubic_hecke', spkg='database_cubic_hecke') + class DatabaseReflexivePolytopes(StaticFile): r""" - A :class:`~sage.features.Feature` which describes the presence of the PALP database - of reflexive lattice polytopes. + A :class:`~sage.features.Feature` which describes the presence of the + :ref:`PALP databases of reflexive three-dimensional ` + and :ref:`four-dimensional lattice polytopes `. EXAMPLES:: diff --git a/src/sage/features/dvipng.py b/src/sage/features/dvipng.py index 281084a6e72..270c1b8ede9 100644 --- a/src/sage/features/dvipng.py +++ b/src/sage/features/dvipng.py @@ -15,7 +15,7 @@ class dvipng(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``dvipng`` + A :class:`~sage.features.Feature` describing the presence of :ref:`dvipng `. EXAMPLES:: diff --git a/src/sage/features/ffmpeg.py b/src/sage/features/ffmpeg.py index 681af26494c..36a23594162 100644 --- a/src/sage/features/ffmpeg.py +++ b/src/sage/features/ffmpeg.py @@ -15,7 +15,7 @@ class FFmpeg(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``ffmpeg`` + A :class:`~sage.features.Feature` describing the presence of :ref:`ffmpeg `. EXAMPLES:: diff --git a/src/sage/features/four_ti_2.py b/src/sage/features/four_ti_2.py index e898f601599..2af1c1e25d2 100644 --- a/src/sage/features/four_ti_2.py +++ b/src/sage/features/four_ti_2.py @@ -8,7 +8,7 @@ class FourTi2Executable(Executable): r""" - A :class:`~sage.features.Feature` for the 4ti2 executables. + A :class:`~sage.features.Feature` for the :ref:`4ti2 ` executables. """ def __init__(self, name): r""" @@ -27,7 +27,7 @@ def __init__(self, name): class FourTi2(JoinFeature): r""" - A :class:`~sage.features.Feature` describing the presence of the ``4ti2`` executables. + A :class:`~sage.features.Feature` describing the presence of all :ref:`4ti2 ` executables. EXAMPLES:: diff --git a/src/sage/features/gap.py b/src/sage/features/gap.py index 67c905a35c3..dad0e975804 100644 --- a/src/sage/features/gap.py +++ b/src/sage/features/gap.py @@ -1,5 +1,5 @@ r""" -Features for testing the presence of GAP packages +Features for testing the presence of the SageMath interfaces to ``gap`` and of GAP packages """ # ***************************************************************************** # Copyright (C) 2016 Julian Rüth @@ -62,7 +62,7 @@ def _is_present(self): class sage__libs__gap(JoinFeature): r""" A :class:`sage.features.Feature` describing the presence of :mod:`sage.libs.gap` - (the library interface to GAP) and :mod:`sage.interfaces.gap` (the pexpect + (the library interface to :ref:`GAP `) and :mod:`sage.interfaces.gap` (the pexpect interface to GAP). By design, we do not distinguish between these two, in order to facilitate the conversion of code from the pexpect interface to the library interface. diff --git a/src/sage/features/gfan.py b/src/sage/features/gfan.py index d9a74db9e1b..040ea64ec5d 100644 --- a/src/sage/features/gfan.py +++ b/src/sage/features/gfan.py @@ -16,7 +16,7 @@ class GfanExecutable(Executable): r""" - A :class:`~sage.features.Feature` for the gfan executables. + A :class:`~sage.features.Feature` for the :ref:`gfan ` executables. """ def __init__(self, cmd=None): r""" diff --git a/src/sage/features/graph_generators.py b/src/sage/features/graph_generators.py index 3d484c59f6b..47c4557241c 100644 --- a/src/sage/features/graph_generators.py +++ b/src/sage/features/graph_generators.py @@ -1,5 +1,5 @@ r""" -Features for testing the presence of various graph generator programs +Features for testing the presence of graph generator programs ``benzene``, ``buckygen``, ``plantri`` """ # ***************************************************************************** @@ -23,7 +23,7 @@ class Plantri(Executable): r""" - A :class:`~sage.features.Feature` which checks for the ``plantri`` binary. + A :class:`~sage.features.Feature` which checks for the :ref:`plantri ` binary. EXAMPLES:: @@ -70,7 +70,7 @@ def is_functional(self): class Buckygen(Executable): r""" - A :class:`~sage.features.Feature` which checks for the ``buckygen`` binary. + A :class:`~sage.features.Feature` which checks for the :ref:`buckygen ` binary. EXAMPLES:: @@ -117,7 +117,7 @@ def is_functional(self): class Benzene(Executable): r""" - A :class:`~sage.features.Feature` which checks for the ``benzene`` + A :class:`~sage.features.Feature` which checks for the :ref:`benzene ` binary. EXAMPLES:: diff --git a/src/sage/features/graphviz.py b/src/sage/features/graphviz.py index 2105eda9d8c..abf9b7615fa 100644 --- a/src/sage/features/graphviz.py +++ b/src/sage/features/graphviz.py @@ -19,9 +19,9 @@ class dot(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``dot`` + A :class:`~sage.features.Feature` describing the presence of ``dot``. - EXAMPLES:: + TESTS:: sage: from sage.features.graphviz import dot sage: dot().is_present() # optional - graphviz @@ -42,9 +42,9 @@ def __init__(self): class neato(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``neato`` + A :class:`~sage.features.Feature` describing the presence of ``neato``. - EXAMPLES:: + TESTS: sage: from sage.features.graphviz import neato sage: neato().is_present() # optional - graphviz @@ -65,9 +65,9 @@ def __init__(self): class twopi(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``twopi`` + A :class:`~sage.features.Feature` describing the presence of ``twopi``. - EXAMPLES:: + TESTS:: sage: from sage.features.graphviz import twopi sage: twopi().is_present() # optional - graphviz @@ -89,8 +89,8 @@ def __init__(self): class Graphviz(JoinFeature): r""" A :class:`~sage.features.Feature` describing the presence of - the ``dot``, ``neato``, and ``twopi`` executables from the - ``graphviz`` package. + the :class:`dot`, :class:`neato`, and :class:`twopi` executables from the + :ref:`graphviz ` package. EXAMPLES:: diff --git a/src/sage/features/igraph.py b/src/sage/features/igraph.py index 6bb83294a95..bcf81f9cec7 100644 --- a/src/sage/features/igraph.py +++ b/src/sage/features/igraph.py @@ -19,7 +19,7 @@ class python_igraph(JoinFeature): r""" A :class:`sage.features.Feature` describing the presence of the - Python package ``igraph``. + Python package :ref:`igraph `. EXAMPLES:: diff --git a/src/sage/features/imagemagick.py b/src/sage/features/imagemagick.py index b7aa3aeb9a2..499d29d6f52 100644 --- a/src/sage/features/imagemagick.py +++ b/src/sage/features/imagemagick.py @@ -1,7 +1,7 @@ r""" Feature for testing the presence of ``imagemagick`` -Currently we only check for the presence of ``convert``. When needed other +Currently we only check for the presence of ``convert``. When needed, other commands like ``magick``, ``magick-script``, ``convert``, ``mogrify``, ``identify``, ``composite``, ``montage``, ``compare``, etc. could be also checked in this module. @@ -22,7 +22,7 @@ class Convert(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``convert`` + A :class:`~sage.features.Feature` describing the presence of ``convert``. EXAMPLES:: @@ -103,12 +103,13 @@ def is_functional(self): # The command seems functional return FeatureTestResult(self, True) + class ImageMagick(JoinFeature): r""" A :class:`~sage.features.Feature` describing the presence of - ``ImageMagick`` + :ref:`ImageMagick _` - Currently, only the availability of ``convert`` is checked. + Currently, only the availability of the :class:`convert` program is checked. EXAMPLES:: diff --git a/src/sage/features/interfaces.py b/src/sage/features/interfaces.py index e31e7b72d61..ddfc3b9b7ee 100644 --- a/src/sage/features/interfaces.py +++ b/src/sage/features/interfaces.py @@ -1,5 +1,5 @@ r""" -Features for testing whether interpreter interfaces are functional +Features for testing whether interpreter interfaces to ``magma``, ``maple``, ``mathematica`` etc. are functional """ # **************************************************************************** diff --git a/src/sage/features/kenzo.py b/src/sage/features/kenzo.py index 655602427b8..b9ccd8537fe 100644 --- a/src/sage/features/kenzo.py +++ b/src/sage/features/kenzo.py @@ -19,7 +19,7 @@ class Kenzo(Feature): r""" - A :class:`~sage.features.Feature` describing the presence of ``Kenzo``. + A :class:`~sage.features.Feature` describing the presence of :class:`Kenzo `. EXAMPLES:: diff --git a/src/sage/features/latte.py b/src/sage/features/latte.py index e88752bd561..9c043d8d016 100644 --- a/src/sage/features/latte.py +++ b/src/sage/features/latte.py @@ -24,7 +24,7 @@ class Latte_count(Executable): r""" - Feature for the executable ``count`` from the LattE suite. + Feature for the executable ``count`` from :ref:`LattE integrale `. """ def __init__(self): r""" @@ -41,7 +41,7 @@ def __init__(self): class Latte_integrate(Executable): r""" - Feature for the executable ``integrate`` from the LattE suite. + Feature for the executable ``integrate`` from :ref:`LattE integrale `. """ def __init__(self): r""" @@ -58,8 +58,7 @@ def __init__(self): class Latte(JoinFeature): r""" - A :class:`~sage.features.Feature` describing the presence of the ``LattE`` - binaries which comes as a part of ``latte_int``. + A :class:`~sage.features.Feature` describing the presence of excecutables from :ref:`LattE integrale `. EXAMPLES:: diff --git a/src/sage/features/lrs.py b/src/sage/features/lrs.py index 501d1d371e7..6eb0a11b642 100644 --- a/src/sage/features/lrs.py +++ b/src/sage/features/lrs.py @@ -140,7 +140,7 @@ def is_functional(self): class Lrslib(JoinFeature): r""" A :class:`~sage.features.Feature` describing the presence of the executables - which comes as a part of ``lrslib``. + :class:`lrs ` and :class:`lrsnash ` provided by the :ref:`lrslib ` package. EXAMPLES:: diff --git a/src/sage/features/mcqd.py b/src/sage/features/mcqd.py index faf7ace441d..036e8fc727b 100644 --- a/src/sage/features/mcqd.py +++ b/src/sage/features/mcqd.py @@ -17,7 +17,8 @@ class Mcqd(JoinFeature): r""" - A :class:`~sage.features.Feature` describing the presence of :mod:`~sage.graphs.mcqd` + A :class:`~sage.features.Feature` describing the presence of the :mod:`~sage.graphs.mcqd` module, + which is the SageMath interface to the :ref:`mcqd ` library EXAMPLES:: diff --git a/src/sage/features/meataxe.py b/src/sage/features/meataxe.py index 78de1bdfe03..cc2a69cfeff 100644 --- a/src/sage/features/meataxe.py +++ b/src/sage/features/meataxe.py @@ -19,7 +19,8 @@ class Meataxe(JoinFeature): r""" - A :class:`~sage.features.Feature` describing the presence of ``meataxe``. + A :class:`~sage.features.Feature` describing the presence of the Sage modules + that depend on the :ref:`meataxe ` library. EXAMPLES:: diff --git a/src/sage/features/msolve.py b/src/sage/features/msolve.py index 557632ff500..31cc42e6176 100644 --- a/src/sage/features/msolve.py +++ b/src/sage/features/msolve.py @@ -24,12 +24,12 @@ class msolve(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of msolve + A :class:`~sage.features.Feature` describing the presence of :ref:`msolve `. EXAMPLES:: sage: from sage.features.msolve import msolve - sage: msolve().is_present() # optional - msolve + sage: msolve().is_present() # optional - msolve FeatureTestResult('msolve', True) """ def __init__(self): @@ -45,12 +45,12 @@ def __init__(self): def is_functional(self): r""" - Test if our installation of msolve is working + Test if our installation of msolve is working. - EXAMPLES:: + TESTS:: sage: from sage.features.msolve import msolve - sage: msolve().is_functional() # optional - msolve + sage: msolve().is_functional() # optional - msolve FeatureTestResult('msolve', True) """ msolve_out = subprocess.run(["msolve", "-h"], capture_output=True) diff --git a/src/sage/features/nauty.py b/src/sage/features/nauty.py index f3df59f4a9c..f57b5de2363 100644 --- a/src/sage/features/nauty.py +++ b/src/sage/features/nauty.py @@ -19,7 +19,7 @@ class NautyExecutable(Executable): r""" - A :class:`~sage.features.Feature` which checks for nauty executables. + A :class:`~sage.features.Feature` which checks for executables from the :ref:`nauty ` package. EXAMPLES:: @@ -43,7 +43,7 @@ def __init__(self, name): class Nauty(JoinFeature): r""" A :class:`~sage.features.Feature` describing the presence of the executables - which comes as a part of ``nauty``. + which comes as a part of :ref:`nauty `. EXAMPLES:: diff --git a/src/sage/features/normaliz.py b/src/sage/features/normaliz.py index acf8c9242c1..80b3891daf3 100644 --- a/src/sage/features/normaliz.py +++ b/src/sage/features/normaliz.py @@ -18,7 +18,7 @@ class PyNormaliz(JoinFeature): r""" A :class:`~sage.features.Feature` describing the presence of the - Python package ``PyNormaliz``. + Python package :ref:`PyNormaliz `. EXAMPLES:: diff --git a/src/sage/features/palp.py b/src/sage/features/palp.py index e9936f705ce..35758a0ecc7 100644 --- a/src/sage/features/palp.py +++ b/src/sage/features/palp.py @@ -17,11 +17,11 @@ class PalpExecutable(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of a PALP executable. + A :class:`~sage.features.Feature` describing the presence of a :ref:`PALP ` executable. INPUT: - - ``palpprog`` -- string, one of "poly", "class", "nef", "cws". + - ``palpprog`` -- string, one of ``"poly"``, ``"class"``, ``"nef"``, ``"cws"``. - ``suff`` -- string or ``None``. """ @@ -44,7 +44,7 @@ def __init__(self, palpprog, suff=None): class Palp(JoinFeature): r""" - A :class:`~sage.features.Feature` describing the presence of ``PALP``. + A :class:`~sage.features.Feature` describing the presence of :ref:`PALP `. """ def __init__(self): r""" diff --git a/src/sage/features/pandoc.py b/src/sage/features/pandoc.py index a00a2b6f8e4..00ee6055024 100644 --- a/src/sage/features/pandoc.py +++ b/src/sage/features/pandoc.py @@ -18,7 +18,7 @@ class Pandoc(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``pandoc`` + A :class:`~sage.features.Feature` describing the presence of :ref:`pandoc `. EXAMPLES:: diff --git a/src/sage/features/pdf2svg.py b/src/sage/features/pdf2svg.py index 2b60574fe85..98578ecb6a1 100644 --- a/src/sage/features/pdf2svg.py +++ b/src/sage/features/pdf2svg.py @@ -15,7 +15,7 @@ class pdf2svg(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``pdf2svg`` + A :class:`~sage.features.Feature` describing the presence of :ref:`pdf2svg `. EXAMPLES:: diff --git a/src/sage/features/phitigra.py b/src/sage/features/phitigra.py index 60ef8f46dde..6c1896bd8df 100644 --- a/src/sage/features/phitigra.py +++ b/src/sage/features/phitigra.py @@ -1,5 +1,5 @@ r""" -Check for phitigra +Check for ``phitigra`` """ # ***************************************************************************** @@ -16,7 +16,7 @@ class Phitigra(PythonModule): r""" - A :class:`sage.features.Feature` describing the presence of phitigra. + A :class:`sage.features.Feature` describing the presence of :ref:`phitigra `. Phitigra is provided by an optional package in the Sage distribution. diff --git a/src/sage/features/pkg_systems.py b/src/sage/features/pkg_systems.py index 334f8378050..8485fab0c7d 100644 --- a/src/sage/features/pkg_systems.py +++ b/src/sage/features/pkg_systems.py @@ -1,5 +1,5 @@ r""" -Features for testing the presence of package systems +Features for testing the presence of package systems ``sage_spkg``, ``conda``, ``pip``, ``debian``, ``fedora`` etc. """ # ***************************************************************************** diff --git a/src/sage/features/polymake.py b/src/sage/features/polymake.py index 6168c6c9978..d2b433b1c7f 100644 --- a/src/sage/features/polymake.py +++ b/src/sage/features/polymake.py @@ -1,5 +1,5 @@ r""" -Feature for testing the presence of the Python interface to polymake +Feature for testing the presence of ``jupymake``, the Python interface to polymake """ # ***************************************************************************** @@ -17,8 +17,8 @@ class JuPyMake(JoinFeature): r""" - A :class:`~sage.features.Feature` describing the presence of the :mod:`JuPyMake` - module, a Python interface to the polymake library. + A :class:`~sage.features.Feature` describing the presence of the :ref:`JuPyMake ` + module, a Python interface to the :ref:`polymake ` library. EXAMPLES:: diff --git a/src/sage/features/rubiks.py b/src/sage/features/rubiks.py index b9bd2f126f7..07250532cb6 100644 --- a/src/sage/features/rubiks.py +++ b/src/sage/features/rubiks.py @@ -20,7 +20,7 @@ class cu2(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``cu2`` + A :class:`~sage.features.Feature` describing the presence of ``cu2``. EXAMPLES:: @@ -42,7 +42,7 @@ def __init__(self): class size222(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``size222`` + A :class:`~sage.features.Feature` describing the presence of ``size222``. EXAMPLES:: @@ -64,7 +64,7 @@ def __init__(self): class optimal(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``optimal`` + A :class:`~sage.features.Feature` describing the presence of ``optimal``. EXAMPLES:: @@ -86,7 +86,7 @@ def __init__(self): class mcube(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``mcube`` + A :class:`~sage.features.Feature` describing the presence of ``mcube``. EXAMPLES:: @@ -108,7 +108,7 @@ def __init__(self): class dikcube(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``dikcube`` + A :class:`~sage.features.Feature` describing the presence of ``dikcube``. EXAMPLES:: @@ -130,7 +130,7 @@ def __init__(self): class cubex(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of ``cubex`` + A :class:`~sage.features.Feature` describing the presence of ``cubex``. EXAMPLES:: @@ -152,9 +152,9 @@ def __init__(self): class Rubiks(JoinFeature): r""" - A :class:`~sage.features.Feature` describing the presence of - ``cu2``, ``cubex``, ``dikcube``, ``mcube``, ``optimal``, and - ``size222``. + A :class:`~sage.features.Feature` describing the presence of the + :class:`cu2`, :class:`cubex`, :class:`dikcube`, :class:`mcube`, :class:`optimal`, and + :class:`size222` programs from the :ref:`rubiks ` package. EXAMPLES:: diff --git a/src/sage/features/singular.py b/src/sage/features/singular.py index c3bd3b6be03..5c83ff8a099 100644 --- a/src/sage/features/singular.py +++ b/src/sage/features/singular.py @@ -1,5 +1,5 @@ r""" -Features for testing the presence of Singular +Features for testing the presence of ``singular`` and the SageMath interfaces to it """ # ***************************************************************************** @@ -18,7 +18,7 @@ class Singular(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of the Singular executable. + A :class:`~sage.features.Feature` describing the presence of the :ref:`singular ` executable. EXAMPLES:: diff --git a/src/sage/features/sphinx.py b/src/sage/features/sphinx.py index 44283765fd1..c83370cf28a 100644 --- a/src/sage/features/sphinx.py +++ b/src/sage/features/sphinx.py @@ -1,5 +1,5 @@ r""" -Check for Sphinx +Features for testing the presence of ``sphinx`` """ # ***************************************************************************** @@ -16,7 +16,7 @@ class Sphinx(PythonModule): r""" - A :class:`sage.features.Feature` describing the presence of Sphinx. + A :class:`sage.features.Feature` describing the presence of :ref:`Sphinx `. Sphinx is provided by a standard package in the Sage distribution, but it can be disabled by ``configure --disable-doc``. diff --git a/src/sage/features/tdlib.py b/src/sage/features/tdlib.py index afde40f7de7..128c056a49c 100644 --- a/src/sage/features/tdlib.py +++ b/src/sage/features/tdlib.py @@ -18,7 +18,7 @@ class Tdlib(JoinFeature): r""" - A :class:`~sage.features.Feature` describing the presence of the ``tdlib``. + A :class:`~sage.features.Feature` describing the presence of the SageMath interface to the :ref:`tdlib ` library. """ def __init__(self): r""" From f50376209c5ef888f2721aa1a7e1db65a519649a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 9 Jun 2023 21:42:38 -0700 Subject: [PATCH 145/205] Fix markup --- src/sage/features/csdp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/features/csdp.py b/src/sage/features/csdp.py index b1e253b237c..e8aa55e50ea 100644 --- a/src/sage/features/csdp.py +++ b/src/sage/features/csdp.py @@ -25,7 +25,7 @@ class CSDP(Executable): r""" A :class:`~sage.features.Feature` which checks for the ``theta`` binary - of :ref:`CSDP `. + of :ref:`CSDP `. EXAMPLES:: From a1a211fdb3a93095bfdbed5b8088bbf1aacb2af0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 9 Jun 2023 23:28:43 -0700 Subject: [PATCH 146/205] Fix up ref --- src/sage/features/databases.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/features/databases.py b/src/sage/features/databases.py index 37ee2852113..1447c5beb14 100644 --- a/src/sage/features/databases.py +++ b/src/sage/features/databases.py @@ -62,7 +62,7 @@ class DatabaseCremona(StaticFile): r""" A :class:`~sage.features.Feature` which describes the presence of :ref:`John Cremona's database of elliptic curves ` - (or its :ref:`small version `. + (or its :ref:`small version `. INPUT: From a67136a66743166903bfab61620ef09ce7fd3655 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 08:40:52 -0700 Subject: [PATCH 147/205] sage.coding: Wrap some long lines --- src/sage/coding/abstract_code.py | 6 +-- src/sage/coding/binary_code.pyx | 52 ++++++++++--------- src/sage/coding/channel.py | 22 ++++---- src/sage/coding/code_bounds.py | 11 ++-- src/sage/coding/code_constructions.py | 4 +- src/sage/coding/guruswami_sudan/gs_decoder.py | 12 +++-- .../coding/guruswami_sudan/interpolation.py | 9 ++-- src/sage/coding/linear_code_no_metric.py | 6 +-- src/sage/coding/punctured_code.py | 37 +++++++------ src/sage/coding/reed_muller_code.py | 44 +++++++++------- src/sage/coding/self_dual_codes.py | 20 +++---- 11 files changed, 123 insertions(+), 100 deletions(-) diff --git a/src/sage/coding/abstract_code.py b/src/sage/coding/abstract_code.py index 0eb3c061190..85cdce652b9 100644 --- a/src/sage/coding/abstract_code.py +++ b/src/sage/coding/abstract_code.py @@ -197,9 +197,9 @@ class AbstractCode(Parent): ``MyDecoderClass``. - As the class :class:`AbstractCode` is not designed to be instantiated, it does not have any - representation methods. You should implement ``_repr_`` and ``_latex_`` - methods in the subclass. + As the class :class:`AbstractCode` is not designed to be instantiated, it + does not have any representation methods. You should implement ``_repr_`` + and ``_latex_`` methods in the subclass. """ def __init__(self, length, default_encoder_name=None, diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index d1f3553bae0..ebd262d3ffa 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -162,29 +162,31 @@ def test_word_perms(t_limit=5.0): These are structures written in pure C for speed, and are tested from this function, which performs the following tests: - 1. Tests :func:`create_word_perm`, which creates a :class:`WordPermutation` from a Python - list `L` representing a permutation `i \mapsto L[i]`. Takes a random word and - permutes it by a random list permutation, and tests that the result - agrees with doing it the slow way. - - 1b. Tests :func:`create_array_word_perm`, which creates a :class:`WordPermutation` from a - C array. Does the same as above. - - 2. Tests :func:`create_comp_word_perm`, which creates a :class:`WordPermutation` as a - composition of two :class:`WordPermutation` objects. Takes a random word and - two random permutations, and tests that the result of permuting by the - composition is correct. - - 3. Tests :func:`create_inv_word_perm` and :func:`create_id_word_perm`, which create a - :class:`WordPermutation` as the inverse and identity permutations, resp. - Takes a random word and a random permutation, and tests that the result - permuting by the permutation and its inverse in either order, and - permuting by the identity both return the original word. + 1. Tests :func:`create_word_perm`, which creates a :class:`WordPermutation` + from a Python list `L` representing a permutation `i \mapsto + L[i]`. Takes a random word and permutes it by a random list permutation, + and tests that the result agrees with doing it the slow way. + + 1b. Tests :func:`create_array_word_perm`, which creates a + :class:`WordPermutation` from a C array. Does the same as above. + + 2. Tests :func:`create_comp_word_perm`, which creates a + :class:`WordPermutation` as a composition of two + :class:`WordPermutation` objects. Takes a random word and two random + permutations, and tests that the result of permuting by the composition + is correct. + + 3. Tests :func:`create_inv_word_perm` and :func:`create_id_word_perm`, + which create a :class:`WordPermutation` as the inverse and identity + permutations, resp. Takes a random word and a random permutation, and + tests that the result permuting by the permutation and its inverse in + either order, and permuting by the identity both return the original + word. .. NOTE:: - The functions :func:`permute_word_by_wp` and :func:`dealloc_word_perm` are implicitly - involved in each of the above tests. + The functions :func:`permute_word_by_wp` and :func:`dealloc_word_perm` + are implicitly involved in each of the above tests. TESTS:: @@ -866,8 +868,8 @@ cdef class BinaryCode: def matrix(self): """ - Returns the generator matrix of the :class:`BinaryCode`, i.e. the code is the - rowspace of ``B.matrix()``. + Return the generator matrix of the :class:`BinaryCode`, i.e. the code is + the rowspace of ``B.matrix()``. EXAMPLES:: @@ -3910,9 +3912,9 @@ cdef class BinaryCodeClassifier: - ``n`` -- limit on the degree of the code - - ``d`` -- test whether new vector has weight divisible by `d`. If `d=4`, this - ensures that all doubly-even canonically augmented children are - generated. + - ``d`` -- test whether new vector has weight divisible by `d`. If + `d=4`, this ensures that all doubly-even canonically augmented + children are generated. EXAMPLES:: diff --git a/src/sage/coding/channel.py b/src/sage/coding/channel.py index f467521fe95..50ea5f5cb1f 100644 --- a/src/sage/coding/channel.py +++ b/src/sage/coding/channel.py @@ -446,8 +446,8 @@ class ErrorErasureChannel(Channel): r""" Channel which adds errors and erases several positions in any message it transmits. - The output space of this channel is a Cartesian product - between its input space and a VectorSpace of the same dimension over `\GF{2}`. + The output space of this channel is a Cartesian product between its input + space and a VectorSpace of the same dimension over `\GF{2}`. INPUT: @@ -561,8 +561,8 @@ def _latex_(self): def transmit_unsafe(self, message): r""" - Return ``message`` with as many errors as ``self._number_errors`` in it, and as many erasures - as ``self._number_erasures`` in it. + Return ``message`` with as many errors as ``self._number_errors`` in it, + and as many erasures as ``self._number_erasures`` in it. If ``self._number_errors`` was passed as an tuple for the number of errors, it will pick a random integer between the bounds of the tuple and use it as the number of errors. @@ -583,9 +583,10 @@ def transmit_unsafe(self, message): - a couple of vectors, namely: - - the transmitted message, which is ``message`` with erroneous and erased positions - - the erasure vector, which contains ``1`` at the erased positions of the transmitted message - and ``0`` elsewhere. + - the transmitted message, which is ``message`` with erroneous and + erased positions + - the erasure vector, which contains ``1`` at the erased positions of + the transmitted message and ``0`` elsewhere. EXAMPLES:: @@ -672,14 +673,15 @@ class QarySymmetricChannel(Channel): EXAMPLES: - We construct a :class:`QarySymmetricChannel` which corrupts 30% of all transmitted - symbols:: + We construct a :class:`QarySymmetricChannel` which corrupts 30% of all + transmitted symbols:: sage: epsilon = 0.3 sage: Chan = channels.QarySymmetricChannel(GF(59)^50, epsilon) sage: Chan q-ary symmetric channel with error probability 0.300000000000000, - of input and output space Vector space of dimension 50 over Finite Field of size 59 + of input and output space + Vector space of dimension 50 over Finite Field of size 59 """ def __init__(self, space, epsilon): diff --git a/src/sage/coding/code_bounds.py b/src/sage/coding/code_bounds.py index 52e47b48c16..9b82bb74b50 100644 --- a/src/sage/coding/code_bounds.py +++ b/src/sage/coding/code_bounds.py @@ -152,8 +152,8 @@ - Delsarte (a.k.a. Linear Programming (LP)) upper bounds. -PROBLEM: In this module we shall typically either (a) seek bounds -on `k`, given `n`, `d`, `q`, (b) seek bounds on `R`, `\delta`, `q` (assuming `n` is +PROBLEM: In this module we shall typically either (a) seek bounds on `k`, given +`n`, `d`, `q`, (b) seek bounds on `R`, `\delta`, `q` (assuming `n` is "infinity"). .. TODO:: @@ -300,10 +300,11 @@ def dimension_upper_bound(n, d, q, algorithm=None): Return an upper bound for the dimension of a linear code. Return an upper bound `B(n,d) = B_q(n,d)` for the - dimension of a linear code of length n, minimum distance d over a - field of size q. + dimension of a linear code of length `n`, minimum distance `d` over a + field of size `q`. - Parameter ``algorithm`` has the same meaning as in :func:`codesize_upper_bound` + Parameter ``algorithm`` has the same meaning as in + :func:`codesize_upper_bound` EXAMPLES:: diff --git a/src/sage/coding/code_constructions.py b/src/sage/coding/code_constructions.py index 946bb0112a0..f22ec507161 100644 --- a/src/sage/coding/code_constructions.py +++ b/src/sage/coding/code_constructions.py @@ -502,8 +502,8 @@ def QuadraticResidueCode(n,F): `n`'th root of unity; `i` ranges over the set of quadratic residues modulo `n`). - See :class:`QuadraticResidueCodeEvenPair` and :class:`QuadraticResidueCodeOddPair` - for a more general construction. + See :class:`QuadraticResidueCodeEvenPair` and + :class:`QuadraticResidueCodeOddPair` for a more general construction. INPUT: diff --git a/src/sage/coding/guruswami_sudan/gs_decoder.py b/src/sage/coding/guruswami_sudan/gs_decoder.py index 0b415489454..2497629e0f4 100644 --- a/src/sage/coding/guruswami_sudan/gs_decoder.py +++ b/src/sage/coding/guruswami_sudan/gs_decoder.py @@ -37,9 +37,9 @@ def n_k_params(C, n_k): r""" - Internal helper function for the :class:`GRSGuruswamiSudanDecoder` class for allowing to - specify either a GRS code `C` or the length and dimensions `n, k` directly, - in all the static functions. + Internal helper function for the :class:`GRSGuruswamiSudanDecoder` class for + allowing to specify either a GRS code `C` or the length and dimensions `n, + k` directly, in all the static functions. If neither `C` or `n,k` were specified to those functions, an appropriate error should be raised. Otherwise, `n, k` of the code or the supplied tuple @@ -49,7 +49,8 @@ def n_k_params(C, n_k): - ``C`` -- A GRS code or ``None`` - - ``n_k`` -- A tuple `(n,k)` being length and dimension of a GRS code, or ``None``. + - ``n_k`` -- A tuple `(n,k)` being length and dimension of a GRS code, or + ``None``. OUTPUT: @@ -164,7 +165,8 @@ class GRSGuruswamiSudanDecoder(Decoder): that will be used. The following possibilities are currently available: * ``"LinearAlgebra"`` -- uses a linear system solver. - * ``"LeeOSullivan"`` -- uses Lee O'Sullivan method based on row reduction of a matrix + * ``"LeeOSullivan"`` -- uses Lee O'Sullivan method based on row reduction + of a matrix * ``None`` -- one of the above will be chosen based on the size of the code and the parameters. diff --git a/src/sage/coding/guruswami_sudan/interpolation.py b/src/sage/coding/guruswami_sudan/interpolation.py index 56441f92f28..0e2e931b3d0 100644 --- a/src/sage/coding/guruswami_sudan/interpolation.py +++ b/src/sage/coding/guruswami_sudan/interpolation.py @@ -242,7 +242,8 @@ def gs_interpolation_linalg(points, tau, parameters, wy): - ``parameters`` -- (default: ``None``) a pair of integers, where: - - the first integer is the multiplicity parameter of Guruswami-Sudan algorithm and + - the first integer is the multiplicity parameter of Guruswami-Sudan + algorithm and - the second integer is the list size parameter. - ``wy`` -- an integer, the `y`-weight, where we seek `Q` of low @@ -314,7 +315,8 @@ def lee_osullivan_module(points, parameters, wy): - ``parameters`` -- (default: ``None``) a pair of integers, where: - - the first integer is the multiplicity parameter `s` of Guruswami-Sudan algorithm and + - the first integer is the multiplicity parameter `s` of Guruswami-Sudan + algorithm and - the second integer is the list size parameter. - ``wy`` -- an integer, the `y`-weight, where we seek `Q` of low @@ -368,7 +370,8 @@ def gs_interpolation_lee_osullivan(points, tau, parameters, wy): - ``tau`` -- an integer, the number of errors one wants to decode. - ``parameters`` -- (default: ``None``) a pair of integers, where: - - the first integer is the multiplicity parameter of Guruswami-Sudan algorithm and + - the first integer is the multiplicity parameter of Guruswami-Sudan + algorithm and - the second integer is the list size parameter. - ``wy`` -- an integer, the `y`-weight, where we seek ``Q`` of low diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index 97db593fb4b..0cb08292699 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -77,9 +77,9 @@ class AbstractLinearCodeNoMetric(AbstractCode, Module): :class:`sage.coding.linear_code.LinearCode`. - As the class :class:`AbstractLinearCodeNoMetric` is not designed to be instantiated, it does not - have any representation methods. You should implement ``_repr_`` and ``_latex_`` - methods in the subclass. + As the class :class:`AbstractLinearCodeNoMetric` is not designed to be + instantiated, it does not have any representation methods. You should + implement ``_repr_`` and ``_latex_`` methods in the subclass. .. WARNING:: diff --git a/src/sage/coding/punctured_code.py b/src/sage/coding/punctured_code.py index 9372bca4af9..dbb1de87cca 100644 --- a/src/sage/coding/punctured_code.py +++ b/src/sage/coding/punctured_code.py @@ -69,8 +69,9 @@ def _insert_punctured_positions(l, punctured_points, value = None): - ``punctured_points`` -- a set of integers - - ``value`` -- (default: ``None``) an element to insert in every position given in``punctured_points``. - If it is let to ``None``, a random value will be chosen for each insertion. + - ``value`` -- (default: ``None``) an element to insert in every position + given in``punctured_points``. If it is let to ``None``, a random value + will be chosen for each insertion. EXAMPLES:: @@ -121,13 +122,15 @@ def __init__(self, C, positions): r""" TESTS: - If one of the positions to puncture is bigger than the length of ``C``, an exception will be raised:: + If one of the positions to puncture is bigger than the length of ``C``, + an exception will be raised:: sage: C = codes.random_linear_code(GF(7), 11, 5) sage: Cp = codes.PuncturedCode(C, {4,8,15}) Traceback (most recent call last): ... - ValueError: Positions to puncture must be positive integers smaller than the length of the provided code + ValueError: Positions to puncture must be positive integers smaller + than the length of the provided code """ if not isinstance(positions, (Integer, int, set, list)): raise TypeError("positions must be either a Sage Integer, a Python int, a set or a list") @@ -439,18 +442,19 @@ class PuncturedCodeOriginalCodeDecoder(Decoder): - ``strategy`` -- (default: ``None``) the strategy used to decode. The available strategies are: - * ``'error-erasure'`` -- uses an error-erasure decoder over the original code if available, - fails otherwise. + * ``'error-erasure'`` -- uses an error-erasure decoder over the original + code if available, fails otherwise. * ``'random-values'`` -- fills the punctured positions with random elements in ``code``'s base field and tries to decode using the default decoder of the original code - * ``'try-all'`` -- fills the punctured positions with every possible combination of - symbols until decoding succeeds, or until every combination have been tried + * ``'try-all'`` -- fills the punctured positions with every possible + combination of symbols until decoding succeeds, or until every + combination have been tried - * ``None`` -- uses ``error-erasure`` if an error-erasure decoder is available, - switch to ``random-values`` behaviour otherwise + * ``None`` -- uses ``error-erasure`` if an error-erasure decoder is + available, switch to ``random-values`` behaviour otherwise - ``original_decoder`` -- (default: ``None``) the decoder that will be used over the original code. It has to be a decoder object over the original code. @@ -468,10 +472,11 @@ class PuncturedCodeOriginalCodeDecoder(Decoder): Decoder of Puncturing of [15, 7, 9] Reed-Solomon Code over GF(16) on position(s) [3] through Error-Erasure decoder for [15, 7, 9] Reed-Solomon Code over GF(16) - As seen above, if all optional are left blank, and if an error-erasure decoder is - available, it will be chosen as the original decoder. - Now, if one forces ``strategy`` to ``'try-all'`` or ``'random-values'``, the - default decoder of the original code will be chosen, even if an error-erasure is available:: + As seen above, if all optional are left blank, and if an error-erasure + decoder is available, it will be chosen as the original decoder. Now, if + one forces ``strategy`` to ``'try-all'`` or ``'random-values'``, the default + decoder of the original code will be chosen, even if an error-erasure is + available:: sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) sage: Cp = codes.PuncturedCode(C, 3) @@ -479,8 +484,8 @@ class PuncturedCodeOriginalCodeDecoder(Decoder): sage: "error-erasure" in D.decoder_type() False - And if one fills ``original_decoder`` and ``strategy`` fields with contradictory - elements, the ``original_decoder`` takes precedence:: + And if one fills ``original_decoder`` and ``strategy`` fields with + contradictory elements, the ``original_decoder`` takes precedence:: sage: C = codes.GeneralizedReedSolomonCode(GF(16, 'a').list()[:15], 7) sage: Cp = codes.PuncturedCode(C, 3) diff --git a/src/sage/coding/reed_muller_code.py b/src/sage/coding/reed_muller_code.py index 9546fbf99ef..6885532757b 100644 --- a/src/sage/coding/reed_muller_code.py +++ b/src/sage/coding/reed_muller_code.py @@ -199,21 +199,23 @@ class QAryReedMullerCode(AbstractLinearCode): .. NOTE:: - It is better to use the aforementioned method rather than calling - this class directly, as :meth:`ReedMullerCode` creates either - a binary or a `q`-ary Reed-Muller code according to the arguments it receives. + It is better to use the aforementioned method rather than calling this + class directly, as :meth:`ReedMullerCode` creates either a binary or a + `q`-ary Reed-Muller code according to the arguments it receives. INPUT: - ``base_field`` -- A finite field, which is the base field of the code. - - ``order`` -- The order of the Reed-Muller Code, i.e., the maximum degree of the polynomial to be used in the code. + - ``order`` -- The order of the Reed-Muller Code, i.e., the maximum degree + of the polynomial to be used in the code. - ``num_of_var`` -- The number of variables used in polynomial. .. WARNING:: - For now, this implementation only supports Reed-Muller codes whose order is less than q. + For now, this implementation only supports Reed-Muller codes whose order + is less than q. EXAMPLES:: @@ -304,7 +306,8 @@ def minimum_distance(self): r""" Return the minimum distance between two words in ``self``. - The minimum distance of a `q`-ary Reed-Muller code with order `d` and number of variables `m` is `(q-d)q^{m-1}` + The minimum distance of a `q`-ary Reed-Muller code with order `d` and + number of variables `m` is `(q-d)q^{m-1}` EXAMPLES:: @@ -379,14 +382,15 @@ class BinaryReedMullerCode(AbstractLinearCode): .. NOTE:: - It is better to use the aforementioned method rather than calling - this class directly, as :meth:`ReedMullerCode` creates either - a binary or a `q`-ary Reed-Muller code according to the arguments it receives. + It is better to use the aforementioned method rather than calling this + class directly, as :meth:`ReedMullerCode` creates either a binary or a + `q`-ary Reed-Muller code according to the arguments it receives. INPUT: - - ``order`` -- The order of the Reed-Muller Code, i.e., the maximum degree of the polynomial to be used in the code. + - ``order`` -- The order of the Reed-Muller Code, i.e., the maximum degree + of the polynomial to be used in the code. - ``num_of_var`` -- The number of variables used in the polynomial. @@ -437,7 +441,9 @@ def __init__(self, order, num_of_var): def order(self): r""" - Return the order of ``self``. Order is the maximum degree of the polynomial used in the Reed-Muller code. + Return the order of ``self``. + + Order is the maximum degree of the polynomial used in the Reed-Muller code. EXAMPLES:: @@ -463,7 +469,8 @@ def minimum_distance(self): r""" Return the minimum distance of ``self``. - The minimum distance of a binary Reed-Muller code of order `d` and number of variables `m` is `q^{m-d}` + The minimum distance of a binary Reed-Muller code of order `d` and + number of variables `m` is `q^{m-d}` EXAMPLES:: @@ -522,8 +529,8 @@ class ReedMullerVectorEncoder(Encoder): Consider a Reed-Muller code of order `r`, number of variables `m`, length `n`, dimension `k` over some finite field `F`. Let those variables be `(x_1, x_2, \dots, x_m)`. - We order the monomials by lowest power on lowest index variables. If we have three monomials - `x_1 x_2`, `x_1 x_2^2` and `x_1^2 x_2`, the ordering is: + We order the monomials by lowest power on lowest index variables. If we have + three monomials `x_1 x_2`, `x_1 x_2^2` and `x_1^2 x_2`, the ordering is: `x_1 x_2 < x_1 x_2^2 < x_1^2 x_2` Let now `(v_1,v_2,\ldots,v_k)` be a vector of `F`, which corresponds to the polynomial @@ -669,7 +676,8 @@ def generator_matrix(self): def points(self): r""" - Return the points of `F^m`, where `F` is base field and `m` is the number of variables, in order of which polynomials are evaluated on. + Return the points of `F^m`, where `F` is the base field and `m` is the + number of variables, in order of which polynomials are evaluated on. EXAMPLES:: @@ -711,9 +719,9 @@ class ReedMullerPolynomialEncoder(Encoder): - ``code`` -- The associated code of this encoder. - - ``polynomial_ring`` -- (default:``None``) The polynomial ring from which the message is chosen. - If this is set to ``None``, a polynomial ring in `x` will be built - from the code parameters. + - ``polynomial_ring`` -- (default:``None``) The polynomial ring from which + the message is chosen. If this is set to ``None``, a polynomial ring in + `x` will be built from the code parameters. EXAMPLES:: diff --git a/src/sage/coding/self_dual_codes.py b/src/sage/coding/self_dual_codes.py index c0f8be086d6..67f90226ccb 100644 --- a/src/sage/coding/self_dual_codes.py +++ b/src/sage/coding/self_dual_codes.py @@ -6,18 +6,18 @@ The main function is ``self_dual_binary_codes``, which is a case-by-case list of entries, each represented by a Python dictionary. -Format of each entry: a Python dictionary with keys "order autgp", "spectrum", -"code", "Comment", "Type", where +Format of each entry: a Python dictionary with keys ``"order autgp"``, ``"spectrum"``, +``"code"``, ``"Comment"``, ``"Type"``, where -- "code" -- a sd code C of length n, dim n/2, over GF(2) +- ``"code"`` -- a sd code `C` of length `n`, dim `n/2`, over `\GF{2}` -- "order autgp" -- order of the permutation automorphism group of C +- ``"order autgp"`` -- order of the permutation automorphism group of `C` -- "Type" -- the type of C (which can be "I" or "II", in the binary case) +- ``"Type"`` -- the type of `C` (which can be ``"I"`` or ``"II"``, in the binary case) -- "spectrum" -- the spectrum [A0,A1,...,An] +- ``"spectrum"`` -- the spectrum `[A_0,A_1,...,A_n]` -- "Comment" -- possibly an empty string. +- ``"Comment"`` -- possibly an empty string. Python dictionaries were used since they seemed to be both human-readable and allow others to update the database easiest. @@ -53,8 +53,8 @@ Here's a rather naive construction of self-dual codes in the binary case: -For even `m`, let `A_m` denote the `m\times m` matrix over `\GF{2}` given by adding -the all 1's matrix to the identity matrix (in +For even `m`, let `A_m` denote the `m\times m` matrix over `\GF{2}` +given by adding the all 1's matrix to the identity matrix (in ``MatrixSpace(GF(2),m,m)`` of course). If `M_1, ..., M_r` are square matrices, let `diag(M_1,M_2,...,M_r)` denote the "block diagonal" matrix with the matrices `M_i` on the diagonal and 0's elsewhere. Let @@ -66,7 +66,7 @@ `C(m_1,...,m_r,s)` are SD. SD codes not of this form will be called (for the purpose of -documenting the code below) "exceptional". Except when n is +documenting the code below) "exceptional". Except when `n` is "small", most sd codes are exceptional (based on a counting argument and table 9.1 in the Huffman+Pless [HP2003]_, page 347). From 97d240e6c367febf38664c1a53496d5f7dcbf46b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 10:56:28 -0700 Subject: [PATCH 148/205] src/sage/arith/misc.py: Re-align # optional --- src/sage/arith/misc.py | 1003 ++++++++++++++++++++-------------------- 1 file changed, 504 insertions(+), 499 deletions(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index e5cb916200a..db23ac32ae9 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -82,26 +82,26 @@ def algdep(z, degree, known_bits=None, use_bits=None, known_digits=None, EXAMPLES:: - sage: algdep(1.888888888888888, 1) # optional - sage.libs.pari + sage: algdep(1.888888888888888, 1) # optional - sage.libs.pari 9*x - 17 - sage: algdep(0.12121212121212, 1) # optional - sage.libs.pari + sage: algdep(0.12121212121212, 1) # optional - sage.libs.pari 33*x - 4 - sage: algdep(sqrt(2), 2) # optional - sage.libs.pari sage.symbolic + sage: algdep(sqrt(2), 2) # optional - sage.libs.pari sage.symbolic x^2 - 2 This example involves a complex number:: - sage: z = (1/2) * (1 + RDF(sqrt(3)) * CC.0); z # optional - sage.symbolic + sage: z = (1/2) * (1 + RDF(sqrt(3)) * CC.0); z # optional - sage.symbolic 0.500000000000000 + 0.866025403784439*I - sage: algdep(z, 6) # optional - sage.symbolic + sage: algdep(z, 6) # optional - sage.symbolic x^2 - x + 1 This example involves a `p`-adic number:: - sage: K = Qp(3, print_mode='series') # optional - sage.rings.padics - sage: a = K(7/19); a # optional - sage.rings.padics + sage: K = Qp(3, print_mode='series') # optional - sage.rings.padics + sage: a = K(7/19); a # optional - sage.rings.padics 1 + 2*3 + 3^2 + 3^3 + 2*3^4 + 2*3^5 + 3^8 + 2*3^9 + 3^11 + 3^12 + 2*3^15 + 2*3^16 + 3^17 + 2*3^19 + O(3^20) - sage: algdep(a, 1) # optional - sage.rings.padics + sage: algdep(a, 1) # optional - sage.rings.padics 19*x - 7 These examples show the importance of proper precision control. We @@ -109,82 +109,82 @@ def algdep(z, degree, known_bits=None, use_bits=None, known_digits=None, 33'rd bit:: sage: z = sqrt(RealField(200)(2)) + (1/2)^33 - sage: p = algdep(z, 4); p # optional - sage.libs.pari + sage: p = algdep(z, 4); p # optional - sage.libs.pari 227004321085*x^4 - 216947902586*x^3 - 99411220986*x^2 + 82234881648*x - 211871195088 - sage: factor(p) # optional - sage.libs.pari + sage: factor(p) # optional - sage.libs.pari 227004321085*x^4 - 216947902586*x^3 - 99411220986*x^2 + 82234881648*x - 211871195088 - sage: algdep(z, 4, known_bits=32) # optional - sage.libs.pari + sage: algdep(z, 4, known_bits=32) # optional - sage.libs.pari x^2 - 2 - sage: algdep(z, 4, known_digits=10) # optional - sage.libs.pari + sage: algdep(z, 4, known_digits=10) # optional - sage.libs.pari x^2 - 2 - sage: algdep(z, 4, use_bits=25) # optional - sage.libs.pari + sage: algdep(z, 4, use_bits=25) # optional - sage.libs.pari x^2 - 2 - sage: algdep(z, 4, use_digits=8) # optional - sage.libs.pari + sage: algdep(z, 4, use_digits=8) # optional - sage.libs.pari x^2 - 2 Using the ``height_bound`` and ``proof`` parameters, we can see that `pi` is not the root of an integer polynomial of degree at most 5 and coefficients bounded above by 10:: - sage: algdep(pi.n(), 5, height_bound=10, proof=True) is None # optional - sage.libs.pari sage.symbolic + sage: algdep(pi.n(), 5, height_bound=10, proof=True) is None # optional - sage.libs.pari sage.symbolic True For stronger results, we need more precision:: - sage: algdep(pi.n(), 5, height_bound=100, proof=True) is None # optional - sage.libs.pari sage.symbolic + sage: algdep(pi.n(), 5, height_bound=100, proof=True) is None # optional - sage.libs.pari sage.symbolic Traceback (most recent call last): ... ValueError: insufficient precision for non-existence proof - sage: algdep(pi.n(200), 5, height_bound=100, proof=True) is None # optional - sage.libs.pari sage.symbolic + sage: algdep(pi.n(200), 5, height_bound=100, proof=True) is None # optional - sage.libs.pari sage.symbolic True - sage: algdep(pi.n(), 10, height_bound=10, proof=True) is None # optional - sage.libs.pari sage.symbolic + sage: algdep(pi.n(), 10, height_bound=10, proof=True) is None # optional - sage.libs.pari sage.symbolic Traceback (most recent call last): ... ValueError: insufficient precision for non-existence proof - sage: algdep(pi.n(200), 10, height_bound=10, proof=True) is None # optional - sage.libs.pari sage.symbolic + sage: algdep(pi.n(200), 10, height_bound=10, proof=True) is None # optional - sage.libs.pari sage.symbolic True We can also use ``proof=True`` to get positive results:: - sage: a = sqrt(2) + sqrt(3) + sqrt(5) # optional - sage.libs.pari sage.symbolic - sage: algdep(a.n(), 8, height_bound=1000, proof=True) # optional - sage.libs.pari sage.symbolic + sage: a = sqrt(2) + sqrt(3) + sqrt(5) # optional - sage.libs.pari sage.symbolic + sage: algdep(a.n(), 8, height_bound=1000, proof=True) # optional - sage.libs.pari sage.symbolic Traceback (most recent call last): ... ValueError: insufficient precision for uniqueness proof - sage: f = algdep(a.n(1000), 8, height_bound=1000, proof=True); f # optional - sage.libs.pari sage.symbolic + sage: f = algdep(a.n(1000), 8, height_bound=1000, proof=True); f # optional - sage.libs.pari sage.symbolic x^8 - 40*x^6 + 352*x^4 - 960*x^2 + 576 - sage: f(a).expand() # optional - sage.libs.pari sage.symbolic + sage: f(a).expand() # optional - sage.libs.pari sage.symbolic 0 TESTS:: - sage: algdep(complex("1+2j"), 4) # optional - sage.libs.pari + sage: algdep(complex("1+2j"), 4) # optional - sage.libs.pari x^2 - 2*x + 5 We get an irreducible polynomial even if PARI returns a reducible one:: sage: z = CDF(1, RR(3).sqrt())/2 - sage: pari(z).algdep(5) # optional - sage.libs.pari + sage: pari(z).algdep(5) # optional - sage.libs.pari x^5 + x^2 - sage: algdep(z, 5) # optional - sage.libs.pari + sage: algdep(z, 5) # optional - sage.libs.pari x^2 - x + 1 Check that cases where a constant polynomial might look better get handled correctly:: sage: z = CC(-1)**(1/3) - sage: algdep(z, 1) # optional - sage.libs.pari + sage: algdep(z, 1) # optional - sage.libs.pari x Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8, float64 # optional - numpy - sage: algdep(float64(1.888888888888888), int8(1)) # optional - numpy sage.libs.pari + sage: from numpy import int8, float64 # optional - numpy + sage: algdep(float64(1.888888888888888), int8(1)) # optional - numpy sage.libs.pari 9*x - 17 sage: from gmpy2 import mpz, mpfr - sage: algdep(mpfr(1.888888888888888), mpz(1)) # optional - sage.libs.pari + sage: algdep(mpfr(1.888888888888888), mpz(1)) # optional - sage.libs.pari 9*x - 17 """ if proof and not height_bound: @@ -322,9 +322,9 @@ def bernoulli(n, algorithm='default', num_threads=1): -691/2730 sage: bernoulli(12, algorithm='pari') # optional - sage.libs.pari -691/2730 - sage: bernoulli(12, algorithm='bernmm') + sage: bernoulli(12, algorithm='bernmm') # optional - sage.libs.ntl -691/2730 - sage: bernoulli(12, algorithm='bernmm', num_threads=4) + sage: bernoulli(12, algorithm='bernmm', num_threads=4) # optional - sage.libs.ntl -691/2730 TESTS:: @@ -333,7 +333,7 @@ def bernoulli(n, algorithm='default', num_threads=1): sage: algs += ['arb'] # optional - sage.libs.flint sage: algs += ['gap'] # optional - sage.libs.gap sage: algs += ['gp', 'pari'] # optional - sage.libs.pari - sage: algs += ['bernmm'] + sage: algs += ['bernmm'] # optional - sage.libs.ntl sage: algs += ['flint'] # optional - sage.libs.flint sage: test_list = [ZZ.random_element(2, 2255) for _ in range(500)] sage: vals = [[bernoulli(i, algorithm=j) for j in algs] for i in test_list] # long time (up to 21s on sage.math, 2011) @@ -341,7 +341,7 @@ def bernoulli(n, algorithm='default', num_threads=1): True sage: algs = [] sage: algs += ['gp', 'pari'] # optional - sage.libs.pari - sage: algs += ['bernmm'] + sage: algs += ['bernmm'] # optional - sage.libs.ntl sage: test_list = [ZZ.random_element(2256, 5000) for _ in range(500)] sage: vals = [[bernoulli(i, algorithm=j) for j in algs] for i in test_list] # long time (up to 30s on sage.math, 2011) sage: all(len(set(x))==1 for x in vals) # long time (depends on previous line) @@ -526,7 +526,7 @@ def is_prime(n): sage: a = 2**2048 + 981 sage: is_prime(a) # not tested - takes ~ 1min sage: proof.arithmetic(False) - sage: is_prime(a) # instantaneous! # optional - sage.libs.pari + sage: is_prime(a) # instantaneous! # optional - sage.libs.pari True sage: proof.arithmetic(True) @@ -551,8 +551,8 @@ def is_prime(n): (cf. :trac:`32340`) and we should not warn:: sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field - sage: is_prime(1 + i) # optional - sage.rings.number_field + sage: K. = NumberField(x^2 + 1) # optional - sage.rings.number_field + sage: is_prime(1 + i) # optional - sage.rings.number_field True """ try: @@ -593,19 +593,19 @@ def is_pseudoprime(n): EXAMPLES:: - sage: is_pseudoprime(389) # optional - sage.libs.pari + sage: is_pseudoprime(389) # optional - sage.libs.pari True - sage: is_pseudoprime(2000) # optional - sage.libs.pari + sage: is_pseudoprime(2000) # optional - sage.libs.pari False - sage: is_pseudoprime(2) # optional - sage.libs.pari + sage: is_pseudoprime(2) # optional - sage.libs.pari True - sage: is_pseudoprime(-1) # optional - sage.libs.pari + sage: is_pseudoprime(-1) # optional - sage.libs.pari False sage: factor(-6) -1 * 2 * 3 - sage: is_pseudoprime(1) # optional - sage.libs.pari + sage: is_pseudoprime(1) # optional - sage.libs.pari False - sage: is_pseudoprime(-2) # optional - sage.libs.pari + sage: is_pseudoprime(-2) # optional - sage.libs.pari False """ return ZZ(n).is_pseudoprime() @@ -628,51 +628,51 @@ def is_prime_power(n, get_data=False): EXAMPLES:: - sage: is_prime_power(389) # optional - sage.libs.pari + sage: is_prime_power(389) # optional - sage.libs.pari True - sage: is_prime_power(2000) # optional - sage.libs.pari + sage: is_prime_power(2000) # optional - sage.libs.pari False - sage: is_prime_power(2) # optional - sage.libs.pari + sage: is_prime_power(2) # optional - sage.libs.pari True - sage: is_prime_power(1024) # optional - sage.libs.pari + sage: is_prime_power(1024) # optional - sage.libs.pari True - sage: is_prime_power(1024, get_data=True) # optional - sage.libs.pari + sage: is_prime_power(1024, get_data=True) # optional - sage.libs.pari (2, 10) The same results can be obtained with:: - sage: 389.is_prime_power() # optional - sage.libs.pari + sage: 389.is_prime_power() # optional - sage.libs.pari True - sage: 2000.is_prime_power() # optional - sage.libs.pari + sage: 2000.is_prime_power() # optional - sage.libs.pari False - sage: 2.is_prime_power() # optional - sage.libs.pari + sage: 2.is_prime_power() # optional - sage.libs.pari True - sage: 1024.is_prime_power() # optional - sage.libs.pari + sage: 1024.is_prime_power() # optional - sage.libs.pari True - sage: 1024.is_prime_power(get_data=True) # optional - sage.libs.pari + sage: 1024.is_prime_power(get_data=True) # optional - sage.libs.pari (2, 10) TESTS:: - sage: is_prime_power(-1) # optional - sage.libs.pari + sage: is_prime_power(-1) # optional - sage.libs.pari False - sage: is_prime_power(1) # optional - sage.libs.pari + sage: is_prime_power(1) # optional - sage.libs.pari False - sage: is_prime_power(QQ(997^100)) # optional - sage.libs.pari + sage: is_prime_power(QQ(997^100)) # optional - sage.libs.pari True - sage: is_prime_power(1/2197) # optional - sage.libs.pari + sage: is_prime_power(1/2197) # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: no conversion of this rational to integer - sage: is_prime_power("foo") # optional - sage.libs.pari + sage: is_prime_power("foo") # optional - sage.libs.pari Traceback (most recent call last): ... TypeError: unable to convert 'foo' to an integer sage: from gmpy2 import mpz - sage: is_prime_power(mpz(389)) # optional - sage.libs.pari + sage: is_prime_power(mpz(389)) # optional - sage.libs.pari True - sage: from numpy import int16 # optional - numpy - sage: is_prime_power(int16(389)) # optional - numpy sage.libs.pari + sage: from numpy import int16 # optional - numpy + sage: is_prime_power(int16(389)) # optional - numpy sage.libs.pari True """ return ZZ(n).is_prime_power(get_data=get_data) @@ -695,39 +695,39 @@ def is_pseudoprime_power(n, get_data=False): EXAMPLES:: - sage: is_pseudoprime_power(389) # optional - sage.libs.pari + sage: is_pseudoprime_power(389) # optional - sage.libs.pari True - sage: is_pseudoprime_power(2000) # optional - sage.libs.pari + sage: is_pseudoprime_power(2000) # optional - sage.libs.pari False - sage: is_pseudoprime_power(2) # optional - sage.libs.pari + sage: is_pseudoprime_power(2) # optional - sage.libs.pari True - sage: is_pseudoprime_power(1024) # optional - sage.libs.pari + sage: is_pseudoprime_power(1024) # optional - sage.libs.pari True - sage: is_pseudoprime_power(-1) # optional - sage.libs.pari + sage: is_pseudoprime_power(-1) # optional - sage.libs.pari False - sage: is_pseudoprime_power(1) # optional - sage.libs.pari + sage: is_pseudoprime_power(1) # optional - sage.libs.pari False - sage: is_pseudoprime_power(997^100) # optional - sage.libs.pari + sage: is_pseudoprime_power(997^100) # optional - sage.libs.pari True Use of the get_data keyword:: - sage: is_pseudoprime_power(3^1024, get_data=True) # optional - sage.libs.pari + sage: is_pseudoprime_power(3^1024, get_data=True) # optional - sage.libs.pari (3, 1024) - sage: is_pseudoprime_power(2^256, get_data=True) # optional - sage.libs.pari + sage: is_pseudoprime_power(2^256, get_data=True) # optional - sage.libs.pari (2, 256) - sage: is_pseudoprime_power(31, get_data=True) # optional - sage.libs.pari + sage: is_pseudoprime_power(31, get_data=True) # optional - sage.libs.pari (31, 1) - sage: is_pseudoprime_power(15, get_data=True) # optional - sage.libs.pari + sage: is_pseudoprime_power(15, get_data=True) # optional - sage.libs.pari (15, 0) Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 # optional - numpy - sage: is_pseudoprime_power(int16(1024)) # optional - numpy sage.libs.pari + sage: from numpy import int16 # optional - numpy + sage: is_pseudoprime_power(int16(1024)) # optional - numpy sage.libs.pari True sage: from gmpy2 import mpz - sage: is_pseudoprime_power(mpz(1024)) # optional - sage.libs.pari + sage: is_pseudoprime_power(mpz(1024)) # optional - sage.libs.pari True """ return ZZ(n).is_prime_power(proof=False, get_data=get_data) @@ -791,8 +791,8 @@ def valuation(m, *args, **kwds): Traceback (most recent call last): ... ValueError: You can only compute the valuation with respect to a integer larger than 1. - sage: from numpy import int16 # optional - numpy - sage: valuation(int16(512), int16(2)) # optional - numpy + sage: from numpy import int16 # optional - numpy + sage: valuation(int16(512), int16(2)) # optional - numpy 9 sage: from gmpy2 import mpz sage: valuation(mpz(512), mpz(2)) @@ -829,49 +829,49 @@ def prime_powers(start, stop=None): EXAMPLES:: - sage: prime_powers(20) # optional - sage.libs.pari + sage: prime_powers(20) # optional - sage.libs.pari [2, 3, 4, 5, 7, 8, 9, 11, 13, 16, 17, 19] - sage: len(prime_powers(1000)) # optional - sage.libs.pari + sage: len(prime_powers(1000)) # optional - sage.libs.pari 193 - sage: len(prime_range(1000)) # optional - sage.libs.pari + sage: len(prime_range(1000)) # optional - sage.libs.pari 168 - sage: a = [z for z in range(95, 1234) if is_prime_power(z)] # optional - sage.libs.pari - sage: b = prime_powers(95, 1234) # optional - sage.libs.pari - sage: len(b) # optional - sage.libs.pari + sage: a = [z for z in range(95, 1234) if is_prime_power(z)] # optional - sage.libs.pari + sage: b = prime_powers(95, 1234) # optional - sage.libs.pari + sage: len(b) # optional - sage.libs.pari 194 - sage: len(a) # optional - sage.libs.pari + sage: len(a) # optional - sage.libs.pari 194 - sage: a[:10] # optional - sage.libs.pari + sage: a[:10] # optional - sage.libs.pari [97, 101, 103, 107, 109, 113, 121, 125, 127, 128] - sage: b[:10] # optional - sage.libs.pari + sage: b[:10] # optional - sage.libs.pari [97, 101, 103, 107, 109, 113, 121, 125, 127, 128] - sage: a == b # optional - sage.libs.pari + sage: a == b # optional - sage.libs.pari True - sage: prime_powers(100) == [i for i in range(100) if is_prime_power(i)] # optional - sage.libs.pari + sage: prime_powers(100) == [i for i in range(100) if is_prime_power(i)] # optional - sage.libs.pari True - sage: prime_powers(10, 7) # optional - sage.libs.pari + sage: prime_powers(10, 7) # optional - sage.libs.pari [] - sage: prime_powers(-5) # optional - sage.libs.pari + sage: prime_powers(-5) # optional - sage.libs.pari [] - sage: prime_powers(-1, 3) # optional - sage.libs.pari + sage: prime_powers(-1, 3) # optional - sage.libs.pari [2] TESTS: Check that output are always Sage integers (:trac:`922`):: - sage: v = prime_powers(10) # optional - sage.libs.pari - sage: type(v[0]) # optional - sage.libs.pari + sage: v = prime_powers(10) # optional - sage.libs.pari + sage: type(v[0]) # optional - sage.libs.pari - sage: prime_powers(0, 1) # optional - sage.libs.pari + sage: prime_powers(0, 1) # optional - sage.libs.pari [] - sage: prime_powers(2) # optional - sage.libs.pari + sage: prime_powers(2) # optional - sage.libs.pari [] - sage: prime_powers(3) # optional - sage.libs.pari + sage: prime_powers(3) # optional - sage.libs.pari [2] sage: prime_powers("foo") @@ -886,18 +886,18 @@ def prime_powers(start, stop=None): Check that long input are accepted (:trac:`17852`):: - sage: prime_powers(6l) # optional - sage.libs.pari + sage: prime_powers(6l) # optional - sage.libs.pari [2, 3, 4, 5] - sage: prime_powers(6l, 10l) # optional - sage.libs.pari + sage: prime_powers(6l, 10l) # optional - sage.libs.pari [7, 8, 9] Check numpy and gmpy2 support:: - sage: from numpy import int8 # optional - numpy - sage: prime_powers(int8(20)) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: prime_powers(int8(20)) # optional - numpy sage.libs.pari [2, 3, 4, 5, 7, 8, 9, 11, 13, 16, 17, 19] sage: from gmpy2 import mpz - sage: prime_powers(mpz(20)) # optional - sage.libs.pari + sage: prime_powers(mpz(20)) # optional - sage.libs.pari [2, 3, 4, 5, 7, 8, 9, 11, 13, 16, 17, 19] """ start = ZZ(start) @@ -939,11 +939,11 @@ def primes_first_n(n, leave_pari=False): EXAMPLES:: - sage: primes_first_n(10) # optional - sage.libs.pari + sage: primes_first_n(10) # optional - sage.libs.pari [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] - sage: len(primes_first_n(1000)) # optional - sage.libs.pari + sage: len(primes_first_n(1000)) # optional - sage.libs.pari 1000 - sage: primes_first_n(0) # optional - sage.libs.pari + sage: primes_first_n(0) # optional - sage.libs.pari [] """ if n < 0: @@ -981,13 +981,13 @@ def eratosthenes(n): [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47] sage: len(eratosthenes(100)) 25 - sage: eratosthenes(213) == prime_range(213) # optional - sage.libs.pari + sage: eratosthenes(213) == prime_range(213) # optional - sage.libs.pari True TESTS:: - sage: from numpy import int8 # optional - numpy - sage: eratosthenes(int8(3)) # optional - numpy + sage: from numpy import int8 # optional - numpy + sage: eratosthenes(int8(3)) # optional - numpy [2, 3] sage: from gmpy2 import mpz sage: eratosthenes(mpz(3)) @@ -1053,17 +1053,17 @@ def primes(start, stop=None, proof=None): EXAMPLES:: - sage: for p in primes(5, 10): # optional - sage.libs.pari + sage: for p in primes(5, 10): # optional - sage.libs.pari ....: print(p) 5 7 - sage: list(primes(13)) # optional - sage.libs.pari + sage: list(primes(13)) # optional - sage.libs.pari [2, 3, 5, 7, 11] - sage: list(primes(10000000000, 10000000100)) # optional - sage.libs.pari + sage: list(primes(10000000000, 10000000100)) # optional - sage.libs.pari [10000000019, 10000000033, 10000000061, 10000000069, 10000000097] - sage: max(primes(10^100, 10^100+10^4, proof=False)) # optional - sage.libs.pari + sage: max(primes(10^100, 10^100+10^4, proof=False)) # optional - sage.libs.pari 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009631 - sage: next(p for p in primes(10^20, infinity) if is_prime(2*p+1)) # optional - sage.libs.pari + sage: next(p for p in primes(10^20, infinity) if is_prime(2*p+1)) # optional - sage.libs.pari 100000000000000001243 @@ -1081,13 +1081,13 @@ def primes(start, stop=None, proof=None): 13 17 19 - sage: next(p for p in primes(10,oo)) # checks alternate infinity notation # optional - sage.libs.pari + sage: next(p for p in primes(10,oo)) # checks alternate infinity notation # optional - sage.libs.pari 11 - sage: from numpy import int8 # optional - numpy - sage: list(primes(int8(13))) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: list(primes(int8(13))) # optional - numpy sage.libs.pari [2, 3, 5, 7, 11] sage: from gmpy2 import mpz - sage: list(primes(mpz(13))) # optional - sage.libs.pari + sage: list(primes(mpz(13))) # optional - sage.libs.pari [2, 3, 5, 7, 11] """ from sage.rings.infinity import infinity @@ -1127,40 +1127,40 @@ def next_prime_power(n): EXAMPLES:: - sage: next_prime_power(1) # optional - sage.libs.pari + sage: next_prime_power(1) # optional - sage.libs.pari 2 - sage: next_prime_power(2) # optional - sage.libs.pari + sage: next_prime_power(2) # optional - sage.libs.pari 3 - sage: next_prime_power(10) # optional - sage.libs.pari + sage: next_prime_power(10) # optional - sage.libs.pari 11 - sage: next_prime_power(7) # optional - sage.libs.pari + sage: next_prime_power(7) # optional - sage.libs.pari 8 - sage: next_prime_power(99) # optional - sage.libs.pari + sage: next_prime_power(99) # optional - sage.libs.pari 101 The same results can be obtained with:: - sage: 1.next_prime_power() # optional - sage.libs.pari + sage: 1.next_prime_power() # optional - sage.libs.pari 2 - sage: 2.next_prime_power() # optional - sage.libs.pari + sage: 2.next_prime_power() # optional - sage.libs.pari 3 - sage: 10.next_prime_power() # optional - sage.libs.pari + sage: 10.next_prime_power() # optional - sage.libs.pari 11 Note that `2` is the smallest prime power:: - sage: next_prime_power(-10) # optional - sage.libs.pari + sage: next_prime_power(-10) # optional - sage.libs.pari 2 - sage: next_prime_power(0) # optional - sage.libs.pari + sage: next_prime_power(0) # optional - sage.libs.pari 2 TESTS:: - sage: from numpy import int8 # optional - numpy - sage: next_prime_power(int8(10)) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: next_prime_power(int8(10)) # optional - numpy sage.libs.pari 11 sage: from gmpy2 import mpz - sage: next_prime_power(mpz(10)) # optional - sage.libs.pari + sage: next_prime_power(mpz(10)) # optional - sage.libs.pari 11 """ return ZZ(n).next_prime_power() @@ -1178,22 +1178,22 @@ def next_probable_prime(n): EXAMPLES:: - sage: next_probable_prime(-100) # optional - sage.libs.pari + sage: next_probable_prime(-100) # optional - sage.libs.pari 2 - sage: next_probable_prime(19) # optional - sage.libs.pari + sage: next_probable_prime(19) # optional - sage.libs.pari 23 - sage: next_probable_prime(int(999999999)) # optional - sage.libs.pari + sage: next_probable_prime(int(999999999)) # optional - sage.libs.pari 1000000007 - sage: next_probable_prime(2^768) # optional - sage.libs.pari + sage: next_probable_prime(2^768) # optional - sage.libs.pari 1552518092300708935148979488462502555256886017116696611139052038026050952686376886330878408828646477950487730697131073206171580044114814391444287275041181139204454976020849905550265285631598444825262999193716468750892846853816058039 TESTS:: - sage: from numpy import int8 # optional - numpy - sage: next_probable_prime(int8(19)) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: next_probable_prime(int8(19)) # optional - numpy sage.libs.pari 23 sage: from gmpy2 import mpz - sage: next_probable_prime(mpz(19)) # optional - sage.libs.pari + sage: next_probable_prime(mpz(19)) # optional - sage.libs.pari 23 """ return ZZ(n).next_probable_prime() @@ -1217,33 +1217,33 @@ def next_prime(n, proof=None): EXAMPLES:: - sage: next_prime(-100) # optional - sage.libs.pari + sage: next_prime(-100) # optional - sage.libs.pari 2 - sage: next_prime(1) # optional - sage.libs.pari + sage: next_prime(1) # optional - sage.libs.pari 2 - sage: next_prime(2) # optional - sage.libs.pari + sage: next_prime(2) # optional - sage.libs.pari 3 - sage: next_prime(3) # optional - sage.libs.pari + sage: next_prime(3) # optional - sage.libs.pari 5 - sage: next_prime(4) # optional - sage.libs.pari + sage: next_prime(4) # optional - sage.libs.pari 5 Notice that the next_prime(5) is not 5 but 7. :: - sage: next_prime(5) # optional - sage.libs.pari + sage: next_prime(5) # optional - sage.libs.pari 7 - sage: next_prime(2004) # optional - sage.libs.pari + sage: next_prime(2004) # optional - sage.libs.pari 2011 TESTS:: - sage: from numpy import int8 # optional - numpy - sage: next_prime(int8(3)) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: next_prime(int8(3)) # optional - numpy sage.libs.pari 5 sage: from gmpy2 import mpz - sage: next_probable_prime(mpz(3)) # optional - sage.libs.pari + sage: next_probable_prime(mpz(3)) # optional - sage.libs.pari 5 """ return ZZ(n).next_prime(proof) @@ -1256,38 +1256,38 @@ def previous_prime(n): EXAMPLES:: - sage: previous_prime(10) # optional - sage.libs.pari + sage: previous_prime(10) # optional - sage.libs.pari 7 - sage: previous_prime(7) # optional - sage.libs.pari + sage: previous_prime(7) # optional - sage.libs.pari 5 - sage: previous_prime(8) # optional - sage.libs.pari + sage: previous_prime(8) # optional - sage.libs.pari 7 - sage: previous_prime(7) # optional - sage.libs.pari + sage: previous_prime(7) # optional - sage.libs.pari 5 - sage: previous_prime(5) # optional - sage.libs.pari + sage: previous_prime(5) # optional - sage.libs.pari 3 - sage: previous_prime(3) # optional - sage.libs.pari + sage: previous_prime(3) # optional - sage.libs.pari 2 - sage: previous_prime(2) # optional - sage.libs.pari + sage: previous_prime(2) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no previous prime - sage: previous_prime(1) # optional - sage.libs.pari + sage: previous_prime(1) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no previous prime - sage: previous_prime(-20) # optional - sage.libs.pari + sage: previous_prime(-20) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no previous prime TESTS:: - sage: from numpy import int8 # optional - numpy - sage: previous_prime(int8(7)) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: previous_prime(int8(7)) # optional - numpy sage.libs.pari 5 sage: from gmpy2 import mpz - sage: previous_prime(mpz(7)) # optional - sage.libs.pari + sage: previous_prime(mpz(7)) # optional - sage.libs.pari 5 """ n = ZZ(n) - 1 @@ -1322,52 +1322,52 @@ def previous_prime_power(n): EXAMPLES:: - sage: previous_prime_power(3) # optional - sage.libs.pari + sage: previous_prime_power(3) # optional - sage.libs.pari 2 - sage: previous_prime_power(10) # optional - sage.libs.pari + sage: previous_prime_power(10) # optional - sage.libs.pari 9 - sage: previous_prime_power(7) # optional - sage.libs.pari + sage: previous_prime_power(7) # optional - sage.libs.pari 5 - sage: previous_prime_power(127) # optional - sage.libs.pari + sage: previous_prime_power(127) # optional - sage.libs.pari 125 The same results can be obtained with:: - sage: 3.previous_prime_power() # optional - sage.libs.pari + sage: 3.previous_prime_power() # optional - sage.libs.pari 2 - sage: 10.previous_prime_power() # optional - sage.libs.pari + sage: 10.previous_prime_power() # optional - sage.libs.pari 9 - sage: 7.previous_prime_power() # optional - sage.libs.pari + sage: 7.previous_prime_power() # optional - sage.libs.pari 5 - sage: 127.previous_prime_power() # optional - sage.libs.pari + sage: 127.previous_prime_power() # optional - sage.libs.pari 125 Input less than or equal to `2` raises errors:: - sage: previous_prime_power(2) # optional - sage.libs.pari + sage: previous_prime_power(2) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no prime power less than 2 - sage: previous_prime_power(-10) # optional - sage.libs.pari + sage: previous_prime_power(-10) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no prime power less than 2 :: - sage: n = previous_prime_power(2^16 - 1) # optional - sage.libs.pari - sage: while is_prime(n): # optional - sage.libs.pari + sage: n = previous_prime_power(2^16 - 1) # optional - sage.libs.pari + sage: while is_prime(n): # optional - sage.libs.pari ....: n = previous_prime_power(n) - sage: factor(n) # optional - sage.libs.pari + sage: factor(n) # optional - sage.libs.pari 251^2 TESTS:: - sage: from numpy import int8 # optional - numpy - sage: previous_prime_power(int8(10)) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: previous_prime_power(int8(10)) # optional - numpy sage.libs.pari 9 sage: from gmpy2 import mpz - sage: previous_prime_power(mpz(10)) # optional - sage.libs.pari + sage: previous_prime_power(mpz(10)) # optional - sage.libs.pari 9 """ return ZZ(n).previous_prime_power() @@ -1522,22 +1522,22 @@ def divisors(n): This function works whenever one has unique factorization:: - sage: K. = QuadraticField(7) # optional - sage.rings.number_field - sage: divisors(K.ideal(7)) # optional - sage.rings.number_field + sage: K. = QuadraticField(7) # optional - sage.rings.number_field + sage: divisors(K.ideal(7)) # optional - sage.rings.number_field [Fractional ideal (1), Fractional ideal (a), Fractional ideal (7)] - sage: divisors(K.ideal(3)) # optional - sage.rings.number_field + sage: divisors(K.ideal(3)) # optional - sage.rings.number_field [Fractional ideal (1), Fractional ideal (3), - Fractional ideal (a - 2), Fractional ideal (a + 2)] - sage: divisors(K.ideal(35)) # optional - sage.rings.number_field + Fractional ideal (a - 2), Fractional ideal (a + 2)] + sage: divisors(K.ideal(35)) # optional - sage.rings.number_field [Fractional ideal (1), Fractional ideal (5), Fractional ideal (a), - Fractional ideal (7), Fractional ideal (5*a), Fractional ideal (35)] + Fractional ideal (7), Fractional ideal (5*a), Fractional ideal (35)] TESTS:: sage: divisors(int(300)) [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 25, 30, 50, 60, 75, 100, 150, 300] - sage: import numpy # optional - numpy - sage: divisors(numpy.int8(100)) # optional - numpy + sage: import numpy # optional - numpy + sage: divisors(numpy.int8(100)) # optional - numpy [1, 2, 4, 5, 10, 20, 25, 50, 100] sage: import gmpy2 sage: divisors(gmpy2.mpz(100)) @@ -1599,13 +1599,13 @@ class Sigma: :: - sage: P = plot(sigma, 1, 100) # optional - sage.plot + sage: P = plot(sigma, 1, 100) # optional - sage.plot This method also works with k-th powers. :: - sage: P = plot(sigma, 1, 100, k=2) # optional - sage.plot + sage: P = plot(sigma, 1, 100, k=2) # optional - sage.plot AUTHORS: @@ -1617,21 +1617,21 @@ class Sigma: sage: sigma(100,4) 106811523 - sage: sigma(factorial(100),3).mod(144169) # optional - sage.libs.pari + sage: sigma(factorial(100), 3).mod(144169) # optional - sage.libs.pari 3672 - sage: sigma(factorial(150),12).mod(691) # optional - sage.libs.pari + sage: sigma(factorial(150), 12).mod(691) # optional - sage.libs.pari 176 - sage: RR(sigma(factorial(133),20)) # optional - sage.libs.pari + sage: RR(sigma(factorial(133),20)) # optional - sage.libs.pari 2.80414775675747e4523 - sage: sigma(factorial(100),0) # optional - sage.libs.pari + sage: sigma(factorial(100),0) # optional - sage.libs.pari 39001250856960000 - sage: sigma(factorial(41),1) # optional - sage.libs.pari + sage: sigma(factorial(41),1) # optional - sage.libs.pari 229199532273029988767733858700732906511758707916800 - sage: from numpy import int8 # optional - numpy - sage: sigma(int8(100), int8(4)) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: sigma(int8(100), int8(4)) # optional - numpy sage.libs.pari 106811523 sage: from gmpy2 import mpz - sage: sigma(mpz(100), mpz(4)) # optional - sage.libs.pari + sage: sigma(mpz(100), mpz(4)) # optional - sage.libs.pari 106811523 """ def __repr__(self): @@ -1655,9 +1655,9 @@ def __call__(self, n, k=1): sage: from sage.arith.misc import Sigma sage: q = Sigma() - sage: q(10) # optional - sage.libs.pari + sage: q(10) # optional - sage.libs.pari 18 - sage: q(10,2) # optional - sage.libs.pari + sage: q(10,2) # optional - sage.libs.pari 130 """ n = ZZ(n) @@ -1699,8 +1699,8 @@ def plot(self, xmin=1, xmax=50, k=1, pointsize=30, rgbcolor=(0,0,1), join=True, EXAMPLES:: sage: from sage.arith.misc import Sigma - sage: p = Sigma().plot() # optional - sage.plot # optional - sage.libs.pari - sage: p.ymax() # optional - sage.plot # optional - sage.libs.pari + sage: p = Sigma().plot() # optional - sage.libs.pari sage.plot + sage: p.ymax() # optional - sage.libs.pari sage.plot 124.0 """ v = [(n, sigma(n, k)) for n in range(xmin, xmax + 1)] @@ -1790,33 +1790,33 @@ def gcd(a, b=None, **kwargs): Make sure we try QQ and not merely ZZ (:trac:`13014`):: - sage: bool(gcd(2/5, 3/7) == gcd(SR(2/5), SR(3/7))) # optional - sage.symbolic + sage: bool(gcd(2/5, 3/7) == gcd(SR(2/5), SR(3/7))) # optional - sage.symbolic True Make sure that the gcd of Expressions stays symbolic:: sage: parent(gcd(2, 4)) Integer Ring - sage: parent(gcd(SR(2), 4)) # optional - sage.symbolic + sage: parent(gcd(SR(2), 4)) # optional - sage.symbolic Symbolic Ring - sage: parent(gcd(2, SR(4))) # optional - sage.symbolic + sage: parent(gcd(2, SR(4))) # optional - sage.symbolic Symbolic Ring - sage: parent(gcd(SR(2), SR(4))) # optional - sage.symbolic + sage: parent(gcd(SR(2), SR(4))) # optional - sage.symbolic Symbolic Ring Verify that objects without gcd methods but which cannot be coerced to ZZ or QQ raise an error:: - sage: F. = FreeMonoid(2) # optional - sage.groups - sage: gcd(a, b) # optional - sage.groups + sage: F. = FreeMonoid(2) # optional - sage.groups + sage: gcd(a, b) # optional - sage.groups Traceback (most recent call last): ... TypeError: unable to call gcd with a Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: GCD(int8(97), int8(100)) # optional - numpy + sage: from numpy import int8 # optional - numpy + sage: GCD(int8(97), int8(100)) # optional - numpy 1 sage: from gmpy2 import mpq, mpz sage: GCD(mpq(2/3), mpq(4/5)) @@ -1915,8 +1915,8 @@ def xlcm(m, n): TESTS:: - sage: from numpy import int16 # optional - numpy - sage: xlcm(int16(120), int16(36)) # optional - numpy + sage: from numpy import int16 # optional - numpy + sage: xlcm(int16(120), int16(36)) # optional - numpy (360, 40, 9) sage: from gmpy2 import mpz sage: xlcm(mpz(120), mpz(36)) @@ -1981,15 +1981,15 @@ def xgcd(a, b): sage: xgcd(x^3 - 1, x^2 - 1) (x - 1, 1, -x) - sage: K. = NumberField(x^2 - 3) # optional - sage.rings.number_field - sage: g.xgcd(g + 2) # optional - sage.rings.number_field + sage: K. = NumberField(x^2 - 3) # optional - sage.rings.number_field + sage: g.xgcd(g + 2) # optional - sage.rings.number_field (1, 1/3*g, 0) - sage: R. = K[] # optional - sage.rings.number_field - sage: S. = R.fraction_field()[] # optional - sage.rings.number_field - sage: xgcd(y^2, a*y + b) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: S. = R.fraction_field()[] # optional - sage.rings.number_field + sage: xgcd(y^2, a*y + b) # optional - sage.rings.number_field (1, a^2/b^2, ((-a)/b^2)*y + 1/b) - sage: xgcd((b+g)*y^2, (a+g)*y + b) # optional - sage.rings.number_field + sage: xgcd((b+g)*y^2, (a+g)*y + b) # optional - sage.rings.number_field (1, (a^2 + (2*g)*a + 3)/(b^3 + g*b^2), ((-a + (-g))/b^2)*y + 1/b) Here is an example of a xgcd for two polynomials over the integers, where the linear @@ -2005,10 +2005,10 @@ def xgcd(a, b): Tests with numpy and gmpy2 types:: - sage: from numpy import int8 # optional - numpy - sage: xgcd(4,int8(8)) # optional - numpy + sage: from numpy import int8 # optional - numpy + sage: xgcd(4, int8(8)) # optional - numpy (4, 1, 0) - sage: xgcd(int8(4),int8(8)) # optional - numpy + sage: xgcd(int8(4), int8(8)) # optional - numpy (4, 1, 0) sage: from gmpy2 import mpz sage: xgcd(mpz(4), mpz(8)) @@ -2020,10 +2020,10 @@ def xgcd(a, b): We check that :trac:`3330` has been fixed:: - sage: R. = NumberField(x^2 - 3, 'g').extension(x^2 - 7, 'h')[] # optional - sage.rings.number_field - sage: h = R.base_ring().gen() # optional - sage.rings.number_field - sage: S. = R.fraction_field()[] # optional - sage.rings.number_field - sage: xgcd(y^2, a*h*y + b) # optional - sage.rings.number_field + sage: R. = NumberField(x^2 - 3, 'g').extension(x^2 - 7, 'h')[] # optional - sage.rings.number_field + sage: h = R.base_ring().gen() # optional - sage.rings.number_field + sage: S. = R.fraction_field()[] # optional - sage.rings.number_field + sage: xgcd(y^2, a*h*y + b) # optional - sage.rings.number_field (1, 7*a^2/b^2, (((-h)*a)/b^2)*y + 1/b) """ try: @@ -2138,20 +2138,20 @@ def inverse_mod(a, m): :: - sage: inverse_mod(7,1) + sage: inverse_mod(7, 1) 0 - sage: inverse_mod(5,14) + sage: inverse_mod(5, 14) 3 - sage: inverse_mod(3,-5) + sage: inverse_mod(3, -5) 2 Tests with numpy and mpz numbers:: sage: from numpy import int8 # optional - numpy - sage: inverse_mod(int8(5),int8(14)) # optional - numpy + sage: inverse_mod(int8(5), int8(14)) # optional - numpy 3 sage: from gmpy2 import mpz - sage: inverse_mod(mpz(5),mpz(14)) + sage: inverse_mod(mpz(5), mpz(14)) 3 """ try: @@ -2228,13 +2228,13 @@ def power_mod(a, n, m): EXAMPLES:: - sage: power_mod(2,388,389) + sage: power_mod(2, 388, 389) 1 - sage: power_mod(2,390,391) + sage: power_mod(2, 390, 391) 285 - sage: power_mod(2,-1,7) + sage: power_mod(2, -1, 7) 4 - sage: power_mod(11,1,7) + sage: power_mod(11, 1, 7) 4 This function works for fairly general rings:: @@ -2242,7 +2242,7 @@ def power_mod(a, n, m): sage: R. = ZZ[] sage: power_mod(3*x, 10, 7) 4*x^10 - sage: power_mod(-3*x^2+4, 7, 2*x^3-5) + sage: power_mod(-3*x^2 + 4, 7, 2*x^3 - 5) x^14 + x^8 + x^6 + x^3 + 962509*x^2 - 791910*x - 698281 TESTS:: @@ -2260,7 +2260,7 @@ def power_mod(a, n, m): sage: power_mod(int32(2), int32(390), int32(391)) # optional - numpy 285 sage: from gmpy2 import mpz - sage: power_mod(mpz(2),mpz(390),mpz(391)) + sage: power_mod(mpz(2), mpz(390), mpz(391)) mpz(285) """ if not m: @@ -2414,7 +2414,7 @@ def mqrr_rational_reconstruction(u, m, T): EXAMPLES:: - sage: mqrr_rational_reconstruction(21,3100,13) + sage: mqrr_rational_reconstruction(21, 3100, 13) (21, 1) Tests with numpy and gmpy2 numbers:: @@ -2423,7 +2423,7 @@ def mqrr_rational_reconstruction(u, m, T): sage: mqrr_rational_reconstruction(int16(21), int16(3100), int16(13)) # optional - numpy (21, 1) sage: from gmpy2 import mpz - sage: mqrr_rational_reconstruction(mpz(21),mpz(3100),mpz(13)) + sage: mqrr_rational_reconstruction(mpz(21), mpz(3100), mpz(13)) (21, 1) """ u = py_scalar_to_element(u) @@ -2519,10 +2519,10 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): EXAMPLES:: - sage: f(n) = n^2 # optional - sage.symbolic - sage: is_prime(f(3)) # optional - sage.symbolic + sage: f(n) = n^2 # optional - sage.symbolic + sage: is_prime(f(3)) # optional - sage.symbolic False - sage: factor(f(3)) # optional - sage.symbolic + sage: factor(f(3)) # optional - sage.symbolic 9 INPUT: @@ -2583,7 +2583,7 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): -1 sage: f.value() -20 - sage: factor(-next_prime(10^2) * next_prime(10^7)) # optional - sage.libs.pari + sage: factor(-next_prime(10^2) * next_prime(10^7)) # optional - sage.libs.pari -1 * 101 * 10000019 :: @@ -2606,7 +2606,7 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): 1 sage: factor(-1) -1 - sage: factor(2^(2^7)+1) # optional - sage.libs.pari + sage: factor(2^(2^7) + 1) # optional - sage.libs.pari 59649589127497217 * 5704689200685129054721 Sage calls PARI's factor, which has proof False by default. @@ -2616,42 +2616,42 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): :: - sage: factor(3^89-1, proof=False) # optional - sage.libs.pari + sage: factor(3^89 - 1, proof=False) # optional - sage.libs.pari 2 * 179 * 1611479891519807 * 5042939439565996049162197 :: - sage: factor(2^197 + 1) # long time (2s) # optional - sage.libs.pari + sage: factor(2^197 + 1) # long time (2s) # optional - sage.libs.pari 3 * 197002597249 * 1348959352853811313 * 251951573867253012259144010843 Any object which has a factor method can be factored like this:: - sage: K. = QuadraticField(-1) # optional - sage.rings.number_field - sage: factor(122 - 454*i) # optional - sage.rings.number_field + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: factor(122 - 454*i) # optional - sage.rings.number_field (-i) * (-i - 2)^3 * (i + 1)^3 * (-2*i + 3) * (i + 4) To access the data in a factorization:: - sage: f = factor(420); f # optional - sage.libs.pari + sage: f = factor(420); f # optional - sage.libs.pari 2^2 * 3 * 5 * 7 - sage: [x for x in f] # optional - sage.libs.pari + sage: [x for x in f] # optional - sage.libs.pari [(2, 2), (3, 1), (5, 1), (7, 1)] - sage: [p for p,e in f] # optional - sage.libs.pari + sage: [p for p,e in f] # optional - sage.libs.pari [2, 3, 5, 7] - sage: [e for p,e in f] # optional - sage.libs.pari + sage: [e for p,e in f] # optional - sage.libs.pari [2, 1, 1, 1] - sage: [p^e for p,e in f] # optional - sage.libs.pari + sage: [p^e for p,e in f] # optional - sage.libs.pari [4, 3, 5, 7] We can factor Python, numpy and gmpy2 numbers:: sage: factor(math.pi) 3.141592653589793 - sage: import numpy # optional - numpy - sage: factor(numpy.int8(30)) # optional - numpy sage.libs.pari + sage: import numpy # optional - numpy + sage: factor(numpy.int8(30)) # optional - numpy sage.libs.pari 2 * 3 * 5 sage: import gmpy2 - sage: factor(gmpy2.mpz(30)) # optional - sage.libs.pari + sage: factor(gmpy2.mpz(30)) # optional - sage.libs.pari 2 * 3 * 5 TESTS:: @@ -2703,14 +2703,14 @@ def radical(n, *args, **kwds): Traceback (most recent call last): ... ArithmeticError: radical of 0 is not defined - sage: K. = QuadraticField(-1) # optional - sage.rings.number_field - sage: radical(K(2)) # optional - sage.rings.number_field + sage: K. = QuadraticField(-1) # optional - sage.rings.number_field + sage: radical(K(2)) # optional - sage.rings.number_field i + 1 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: radical(int8(50)) # optional - numpy + sage: from numpy import int8 # optional - numpy + sage: radical(int8(50)) # optional - numpy 10 sage: from gmpy2 import mpz sage: radical(mpz(50)) @@ -2763,7 +2763,7 @@ def prime_divisors(n): For polynomials we get all irreducible factors:: sage: R. = PolynomialRing(QQ) - sage: prime_divisors(x^12 - 1) # optional - sage.libs.pari + sage: prime_divisors(x^12 - 1) # optional - sage.libs.pari [x - 1, x + 1, x^2 - x + 1, x^2 + 1, x^2 + x + 1, x^4 - x^2 + 1] Tests with numpy and gmpy2 numbers:: @@ -2888,7 +2888,7 @@ def is_square(n, root=False): False sage: is_square(CDF(-2.2)) True - sage: is_square((x-1)^2) + sage: is_square((x-1)^2) # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError: is_square() not implemented for @@ -2911,7 +2911,7 @@ def is_square(n, root=False): Tests with Polynomial:: sage: R. = LaurentPolynomialRing(QQ, 'v') - sage: H = IwahoriHeckeAlgebra('A3', v**2) + sage: H = IwahoriHeckeAlgebra('A3', v**2) # optional - sage.combinat sage.modules sage: R. = QQ[] sage: p = a*b + c*d*a*d*a + 5 sage: is_square(p**2) @@ -2940,32 +2940,32 @@ def is_squarefree(n): EXAMPLES:: - sage: is_squarefree(100) # optional - sage.libs.pari + sage: is_squarefree(100) # optional - sage.libs.pari False - sage: is_squarefree(101) # optional - sage.libs.pari + sage: is_squarefree(101) # optional - sage.libs.pari True sage: R = ZZ['x'] sage: x = R.gen() - sage: is_squarefree((x^2+x+1) * (x-2)) # optional - sage.libs.pari + sage: is_squarefree((x^2+x+1) * (x-2)) # optional - sage.libs.pari True - sage: is_squarefree((x-1)**2 * (x-3)) # optional - sage.libs.pari + sage: is_squarefree((x-1)**2 * (x-3)) # optional - sage.libs.pari False - sage: O = ZZ[sqrt(-1)] # optional - sage.rings.number_field sage.symbolic - sage: I = O.gen(1) # optional - sage.rings.number_field sage.symbolic - sage: is_squarefree(I + 1) # optional - sage.rings.number_field sage.symbolic + sage: O = ZZ[sqrt(-1)] # optional - sage.rings.number_field sage.symbolic + sage: I = O.gen(1) # optional - sage.rings.number_field sage.symbolic + sage: is_squarefree(I + 1) # optional - sage.rings.number_field sage.symbolic True - sage: is_squarefree(O(2)) # optional - sage.rings.number_field sage.symbolic + sage: is_squarefree(O(2)) # optional - sage.rings.number_field sage.symbolic False - sage: O(2).factor() # optional - sage.rings.number_field sage.symbolic + sage: O(2).factor() # optional - sage.rings.number_field sage.symbolic (-I) * (I + 1)^2 This method fails on domains which are not Unique Factorization Domains:: - sage: O = ZZ[sqrt(-5)] # optional - sage.rings.number_field sage.symbolic - sage: a = O.gen(1) # optional - sage.rings.number_field sage.symbolic - sage: is_squarefree(a - 3) # optional - sage.rings.number_field sage.symbolic + sage: O = ZZ[sqrt(-5)] # optional - sage.rings.number_field sage.symbolic + sage: a = O.gen(1) # optional - sage.rings.number_field sage.symbolic + sage: is_squarefree(a - 3) # optional - sage.rings.number_field sage.symbolic Traceback (most recent call last): ... ArithmeticError: non-principal ideal in factorization @@ -2973,14 +2973,14 @@ def is_squarefree(n): Tests with numpy and gmpy2 numbers:: sage: from numpy import int8 # optional - numpy - sage: is_squarefree(int8(100)) # optional - numpy # optional - sage.libs.pari + sage: is_squarefree(int8(100)) # optional - numpy sage.libs.pari False - sage: is_squarefree(int8(101)) # optional - numpy # optional - sage.libs.pari + sage: is_squarefree(int8(101)) # optional - numpy sage.libs.pari True sage: from gmpy2 import mpz - sage: is_squarefree(mpz(100)) # optional - sage.libs.pari + sage: is_squarefree(mpz(100)) # optional - sage.libs.pari False - sage: is_squarefree(mpz(101)) # optional - sage.libs.pari + sage: is_squarefree(mpz(101)) # optional - sage.libs.pari True """ e = py_scalar_to_element(n) @@ -3017,11 +3017,11 @@ class Euler_Phi: 1 sage: euler_phi(2) 1 - sage: euler_phi(3) # optional - sage.libs.pari + sage: euler_phi(3) # optional - sage.libs.pari 2 - sage: euler_phi(12) # optional - sage.libs.pari + sage: euler_phi(12) # optional - sage.libs.pari 4 - sage: euler_phi(37) # optional - sage.libs.pari + sage: euler_phi(37) # optional - sage.libs.pari 36 Notice that euler_phi is defined to be 0 on negative numbers and @@ -3040,7 +3040,7 @@ class Euler_Phi: :: - sage: euler_phi(21) # optional - sage.libs.pari + sage: euler_phi(21) # optional - sage.libs.pari 12 sage: [i for i in range(21) if gcd(21,i) == 1] [1, 2, 4, 5, 8, 10, 11, 13, 16, 17, 19, 20] @@ -3050,22 +3050,22 @@ class Euler_Phi: :: - sage: len([i for i in range(21) if gcd(21,i) == 1]) == euler_phi(21) # optional - sage.libs.pari + sage: len([i for i in range(21) if gcd(21,i) == 1]) == euler_phi(21) # optional - sage.libs.pari True The phi function also has a special plotting method. :: - sage: P = plot(euler_phi, -3, 71) # optional - sage.libs.pari sage.plot + sage: P = plot(euler_phi, -3, 71) # optional - sage.libs.pari sage.plot Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: euler_phi(int8(37)) # optional - numpy sage.libs.pari sage.plot + sage: from numpy import int8 # optional - numpy + sage: euler_phi(int8(37)) # optional - numpy sage.libs.pari sage.plot 36 sage: from gmpy2 import mpz - sage: euler_phi(mpz(37)) # optional - sage.libs.pari sage.plot + sage: euler_phi(mpz(37)) # optional - sage.libs.pari sage.plot 36 AUTHORS: @@ -3093,9 +3093,9 @@ def __call__(self, n): EXAMPLES:: sage: from sage.arith.misc import Euler_Phi - sage: Euler_Phi()(10) # optional - sage.libs.pari + sage: Euler_Phi()(10) # optional - sage.libs.pari 4 - sage: Euler_Phi()(720) # optional - sage.libs.pari + sage: Euler_Phi()(720) # optional - sage.libs.pari 192 """ if n <= 0: @@ -3129,8 +3129,8 @@ def plot(self, xmin=1, xmax=50, pointsize=30, rgbcolor=(0, 0, 1), EXAMPLES:: sage: from sage.arith.misc import Euler_Phi - sage: p = Euler_Phi().plot() # optional - sage.plot - sage: p.ymax() # optional - sage.plot + sage: p = Euler_Phi().plot() # optional - sage.plot + sage: p.ymax() # optional - sage.plot 46.0 """ v = [(n, euler_phi(n)) for n in range(xmin, xmax + 1)] @@ -3196,7 +3196,7 @@ def carmichael_lambda(n): True sage: carmichael_lambda(4) == euler_phi(4) # optional - sage.libs.pari True - sage: p = random_prime(1000, lbound=3, proof=True) + sage: p = random_prime(1000, lbound=3, proof=True) # optional - sage.libs.pari sage: k = randint(1, 1000) sage: carmichael_lambda(p^k) == euler_phi(p^k) # optional - sage.libs.pari True @@ -3347,50 +3347,54 @@ def crt(a, b, m=None, n=None): Note that this also works for polynomial rings:: sage: x = polygen(ZZ, 'x') - sage: K. = NumberField(x^3 - 7) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: f = y^2 + 3 # optional - sage.rings.number_field - sage: g = y^3 - 5 # optional - sage.rings.number_field - sage: CRT(1, 3, f, g) # optional - sage.rings.number_field + sage: K. = NumberField(x^3 - 7) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: f = y^2 + 3 # optional - sage.rings.number_field + sage: g = y^3 - 5 # optional - sage.rings.number_field + sage: CRT(1, 3, f, g) # optional - sage.rings.number_field -3/26*y^4 + 5/26*y^3 + 15/26*y + 53/26 - sage: CRT(1, a, f, g) # optional - sage.rings.number_field + sage: CRT(1, a, f, g) # optional - sage.rings.number_field (-3/52*a + 3/52)*y^4 + (5/52*a - 5/52)*y^3 + (15/52*a - 15/52)*y + 27/52*a + 25/52 You can also do this for any number of moduli:: - sage: K. = NumberField(x^3 - 7) # optional - sage.rings.number_field - sage: R. = K[] # optional - sage.rings.number_field - sage: CRT([], []) # optional - sage.rings.number_field + sage: K. = NumberField(x^3 - 7) # optional - sage.rings.number_field + sage: R. = K[] # optional - sage.rings.number_field + sage: CRT([], []) # optional - sage.rings.number_field 0 - sage: CRT([a], [x]) # optional - sage.rings.number_field + sage: CRT([a], [x]) # optional - sage.rings.number_field a - sage: f = x^2 + 3 # optional - sage.rings.number_field - sage: g = x^3 - 5 # optional - sage.rings.number_field - sage: h = x^5 + x^2 - 9 # optional - sage.rings.number_field - sage: k = CRT([1, a, 3], [f, g, h]); k # optional - sage.rings.number_field - (127/26988*a - 5807/386828)*x^9 + (45/8996*a - 33677/1160484)*x^8 + (2/173*a - 6/173)*x^7 + (133/6747*a - 5373/96707)*x^6 + (-6/2249*a + 18584/290121)*x^5 + (-277/8996*a + 38847/386828)*x^4 + (-135/4498*a + 42673/193414)*x^3 + (-1005/8996*a + 470245/1160484)*x^2 + (-1215/8996*a + 141165/386828)*x + 621/8996*a + 836445/386828 - sage: k.mod(f) # optional - sage.rings.number_field + sage: f = x^2 + 3 # optional - sage.rings.number_field + sage: g = x^3 - 5 # optional - sage.rings.number_field + sage: h = x^5 + x^2 - 9 # optional - sage.rings.number_field + sage: k = CRT([1, a, 3], [f, g, h]); k # optional - sage.rings.number_field + (127/26988*a - 5807/386828)*x^9 + (45/8996*a - 33677/1160484)*x^8 + + (2/173*a - 6/173)*x^7 + (133/6747*a - 5373/96707)*x^6 + + (-6/2249*a + 18584/290121)*x^5 + (-277/8996*a + 38847/386828)*x^4 + + (-135/4498*a + 42673/193414)*x^3 + (-1005/8996*a + 470245/1160484)*x^2 + + (-1215/8996*a + 141165/386828)*x + 621/8996*a + 836445/386828 + sage: k.mod(f) # optional - sage.rings.number_field 1 - sage: k.mod(g) # optional - sage.rings.number_field + sage: k.mod(g) # optional - sage.rings.number_field a - sage: k.mod(h) # optional - sage.rings.number_field + sage: k.mod(h) # optional - sage.rings.number_field 3 If the moduli are not coprime, a solution may not exist:: - sage: crt(4,8,8,12) + sage: crt(4, 8, 8, 12) 20 - sage: crt(4,6,8,12) + sage: crt(4, 6, 8, 12) Traceback (most recent call last): ... ValueError: no solution to crt problem since gcd(8,12) does not divide 4-6 sage: x = polygen(QQ) - sage: crt(2,3,x-1,x+1) + sage: crt(2, 3, x - 1, x + 1) -1/2*x + 5/2 - sage: crt(2,x,x^2-1,x^2+1) + sage: crt(2, x, x^2 - 1, x^2 + 1) -1/2*x^3 + x^2 + 1/2*x + 1 - sage: crt(2,x,x^2-1,x^3-1) + sage: crt(2, x, x^2 - 1, x^3 - 1) Traceback (most recent call last): ... ValueError: no solution to crt problem since gcd(x^2 - 1,x^3 - 1) does not divide 2-x @@ -3400,13 +3404,13 @@ def crt(a, b, m=None, n=None): crt also work with numpy and gmpy2 numbers:: - sage: import numpy # optional - numpy - sage: crt(numpy.int8(2), numpy.int8(3), numpy.int8(7), numpy.int8(11)) # optional - numpy + sage: import numpy # optional - numpy + sage: crt(numpy.int8(2), numpy.int8(3), numpy.int8(7), numpy.int8(11)) # optional - numpy 58 sage: from gmpy2 import mpz sage: crt(mpz(2), mpz(3), mpz(7), mpz(11)) 58 - sage: crt(mpz(2), 3, mpz(7), numpy.int8(11)) # optional - numpy + sage: crt(mpz(2), 3, mpz(7), numpy.int8(11)) # optional - numpy 58 """ if isinstance(a, list): @@ -3493,8 +3497,8 @@ def CRT_list(values, moduli): sage: CRT([32r,2r,2r],[60r,90r,150r]) 452 - sage: from numpy import int8 # optional - numpy - sage: CRT_list([int8(2), int8(3), int8(2)], [int8(3), int8(5), int8(7)]) # optional - numpy + sage: from numpy import int8 # optional - numpy + sage: CRT_list([int8(2), int8(3), int8(2)], [int8(3), int8(5), int8(7)]) # optional - numpy 23 sage: from gmpy2 import mpz sage: CRT_list([mpz(2),mpz(3),mpz(2)], [mpz(3),mpz(5),mpz(7)]) @@ -3598,7 +3602,7 @@ def CRT_vectors(X, moduli): sage: CRT_vectors([[3,5,7],[3,5,11]], [2,3]) [3, 5, 5] - sage: CRT_vectors([vector(ZZ, [2,3,1]), Sequence([1,7,8], ZZ)], [8,9]) # optional - sage.modules + sage: CRT_vectors([vector(ZZ, [2,3,1]), Sequence([1,7,8], ZZ)], [8,9]) # optional - sage.modules [10, 43, 17] """ # First find the CRT basis: @@ -3640,15 +3644,15 @@ def binomial(x, m, **kwds): EXAMPLES:: sage: from sage.arith.misc import binomial - sage: binomial(5,2) + sage: binomial(5, 2) 10 - sage: binomial(2,0) + sage: binomial(2, 0) 1 - sage: binomial(1/2, 0) # optional - sage.libs.pari + sage: binomial(1/2, 0) # optional - sage.libs.pari 1 - sage: binomial(3,-1) + sage: binomial(3, -1) 0 - sage: binomial(20,10) + sage: binomial(20, 10) 184756 sage: binomial(-2, 5) -6 @@ -3656,11 +3660,11 @@ def binomial(x, m, **kwds): 0 sage: binomial(RealField()('2.5'), 2) 1.87500000000000 - sage: n = var('n'); binomial(n, 2) # optional - sage.symbolic + sage: n = var('n'); binomial(n, 2) # optional - sage.symbolic 1/2*(n - 1)*n - sage: n = var('n'); binomial(n, n) # optional - sage.symbolic + sage: n = var('n'); binomial(n, n) # optional - sage.symbolic 1 - sage: n = var('n'); binomial(n, n-1) # optional - sage.symbolic + sage: n = var('n'); binomial(n, n - 1) # optional - sage.symbolic n sage: binomial(2^100, 2^100) 1 @@ -3668,7 +3672,7 @@ def binomial(x, m, **kwds): sage: x = polygen(ZZ) sage: binomial(x, 3) 1/6*x^3 - 1/2*x^2 + 1/3*x - sage: binomial(x, x-3) + sage: binomial(x, x - 3) 1/6*x^3 - 1/2*x^2 + 1/3*x If `x \in \ZZ`, there is an optional 'algorithm' parameter, which @@ -3693,17 +3697,17 @@ def binomial(x, m, **kwds): 1/2 sage: binomial(10^20 + 1/1, 10^20) 100000000000000000001 - sage: binomial(SR(10**7), 10**7) # optional - sage.symbolic + sage: binomial(SR(10**7), 10**7) # optional - sage.symbolic 1 - sage: binomial(3/2, SR(1/1)) # optional - sage.symbolic + sage: binomial(3/2, SR(1/1)) # optional - sage.symbolic 3/2 Some floating point cases -- see :trac:`7562`, :trac:`9633`, and :trac:`12448`:: - sage: binomial(1.,3) + sage: binomial(1., 3) 0.000000000000000 - sage: binomial(-2.,3) + sage: binomial(-2., 3) -4.00000000000000 sage: binomial(0.5r, 5) 0.02734375 @@ -3748,8 +3752,8 @@ def binomial(x, m, **kwds): sage: binomial(y,3).parent() Multivariate Polynomial Ring in x, y over Ring of integers modulo 7 - sage: n = var('n') - sage: binomial(n,2) + sage: n = var('n') # optional - sage.symbolic + sage: binomial(n,2) # optional - sage.symbolic 1/2*(n - 1)*n Invalid inputs:: @@ -3760,8 +3764,8 @@ def binomial(x, m, **kwds): ... TypeError: either m or x-m must be an integer - sage: k, i = var('k,i') # optional - sage.symbolic - sage: binomial(k,i) # optional - sage.symbolic + sage: k, i = var('k,i') # optional - sage.symbolic + sage: binomial(k,i) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: either m or x-m must be an integer @@ -3798,15 +3802,15 @@ def binomial(x, m, **kwds): :func:`~sage.functions.other.binomial` from the module :mod:`sage.functions.other`:: - sage: from sage.functions.other import binomial # optional - sage.symbolic - sage: binomial(k, i) # optional - sage.symbolic + sage: from sage.functions.other import binomial # optional - sage.symbolic + sage: binomial(k, i) # optional - sage.symbolic binomial(k, i) binomial support numpy and gmpy2 parameters:: sage: from sage.arith.misc import binomial - sage: import numpy # optional - numpy - sage: binomial(numpy.int32(20), numpy.int32(10)) # optional - numpy + sage: import numpy # optional - numpy + sage: binomial(numpy.int32(20), numpy.int32(10)) # optional - numpy 184756 sage: import gmpy2 sage: binomial(gmpy2.mpz(20), gmpy2.mpz(10)) @@ -3887,9 +3891,9 @@ def multinomial(*ks): 618970023101454657175683075 sage: multinomial([2^30, 2, 1]) 618970023101454657175683075 - sage: multinomial(Composition([1, 3])) # optional - sage.combinat + sage: multinomial(Composition([1, 3])) # optional - sage.combinat 4 - sage: multinomial(Partition([4, 2])) # optional - sage.combinat + sage: multinomial(Partition([4, 2])) # optional - sage.combinat 15 TESTS: @@ -4263,15 +4267,15 @@ def primitive_root(n, check=True): EXAMPLES:: - sage: primitive_root(23) # optional - sage.libs.pari + sage: primitive_root(23) # optional - sage.libs.pari 5 - sage: primitive_root(-46) # optional - sage.libs.pari + sage: primitive_root(-46) # optional - sage.libs.pari 5 - sage: primitive_root(25) # optional - sage.libs.pari + sage: primitive_root(25) # optional - sage.libs.pari 2 - sage: print([primitive_root(p) for p in primes(100)]) # optional - sage.libs.pari + sage: print([primitive_root(p) for p in primes(100)]) # optional - sage.libs.pari [1, 2, 2, 3, 2, 2, 3, 2, 5, 2, 3, 2, 6, 3, 5, 2, 2, 2, 2, 7, 5, 3, 2, 3, 5] - sage: primitive_root(8) # optional - sage.libs.pari + sage: primitive_root(8) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root @@ -4287,57 +4291,57 @@ def primitive_root(n, check=True): :: sage: n = 10^50 + 151 # a prime - sage: primitive_root(n) # optional - sage.libs.pari + sage: primitive_root(n) # optional - sage.libs.pari 11 - sage: primitive_root(n, check=False) # optional - sage.libs.pari + sage: primitive_root(n, check=False) # optional - sage.libs.pari 11 TESTS: Various special cases:: - sage: primitive_root(-1) # optional - sage.libs.pari + sage: primitive_root(-1) # optional - sage.libs.pari 0 - sage: primitive_root(0) # optional - sage.libs.pari + sage: primitive_root(0) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root - sage: primitive_root(1) # optional - sage.libs.pari + sage: primitive_root(1) # optional - sage.libs.pari 0 - sage: primitive_root(2) # optional - sage.libs.pari + sage: primitive_root(2) # optional - sage.libs.pari 1 - sage: primitive_root(3) # optional - sage.libs.pari + sage: primitive_root(3) # optional - sage.libs.pari 2 - sage: primitive_root(4) # optional - sage.libs.pari + sage: primitive_root(4) # optional - sage.libs.pari 3 We test that various numbers without primitive roots give an error - see :trac:`10836`:: - sage: primitive_root(15) # optional - sage.libs.pari + sage: primitive_root(15) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root - sage: primitive_root(16) # optional - sage.libs.pari + sage: primitive_root(16) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root - sage: primitive_root(1729) # optional - sage.libs.pari + sage: primitive_root(1729) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root - sage: primitive_root(4*7^8) # optional - sage.libs.pari + sage: primitive_root(4*7^8) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: no primitive root Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: primitive_root(int8(-46)) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: primitive_root(int8(-46)) # optional - numpy sage.libs.pari 5 sage: from gmpy2 import mpz - sage: primitive_root(mpz(-46)) # optional - sage.libs.pari + sage: primitive_root(mpz(-46)) # optional - sage.libs.pari 5 """ from sage.libs.pari.all import pari @@ -4373,29 +4377,29 @@ def nth_prime(n): EXAMPLES:: - sage: nth_prime(3) # optional - sage.libs.pari + sage: nth_prime(3) # optional - sage.libs.pari 5 - sage: nth_prime(10) # optional - sage.libs.pari + sage: nth_prime(10) # optional - sage.libs.pari 29 - sage: nth_prime(10^7) # optional - sage.libs.pari + sage: nth_prime(10^7) # optional - sage.libs.pari 179424673 :: - sage: nth_prime(0) # optional - sage.libs.pari + sage: nth_prime(0) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: nth prime meaningless for non-positive n (=0) TESTS:: - sage: all(prime_pi(nth_prime(j)) == j for j in range(1, 1000, 10)) # optional - sage.libs.pari + sage: all(prime_pi(nth_prime(j)) == j for j in range(1, 1000, 10)) # optional - sage.libs.pari True - sage: from numpy import int8 # optional - numpy - sage: nth_prime(int8(10)) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: nth_prime(int8(10)) # optional - numpy sage.libs.pari 29 sage: from gmpy2 import mpz - sage: nth_prime(mpz(10)) # optional - sage.libs.pari + sage: nth_prime(mpz(10)) # optional - sage.libs.pari 29 """ if n <= 0: @@ -4461,39 +4465,39 @@ class Moebius: EXAMPLES:: - sage: moebius(-5) # optional - sage.libs.pari + sage: moebius(-5) # optional - sage.libs.pari -1 - sage: moebius(9) # optional - sage.libs.pari + sage: moebius(9) # optional - sage.libs.pari 0 - sage: moebius(12) # optional - sage.libs.pari + sage: moebius(12) # optional - sage.libs.pari 0 - sage: moebius(-35) # optional - sage.libs.pari + sage: moebius(-35) # optional - sage.libs.pari 1 - sage: moebius(-1) # optional - sage.libs.pari + sage: moebius(-1) # optional - sage.libs.pari 1 - sage: moebius(7) # optional - sage.libs.pari + sage: moebius(7) # optional - sage.libs.pari -1 :: - sage: moebius(0) # potentially nonstandard! # optional - sage.libs.pari + sage: moebius(0) # potentially nonstandard! # optional - sage.libs.pari 0 The moebius function even makes sense for non-integer inputs. :: - sage: x = GF(7)['x'].0 # optional - sage.libs.pari - sage: moebius(x + 2) # optional - sage.libs.pari + sage: x = GF(7)['x'].0 # optional - sage.libs.pari + sage: moebius(x + 2) # optional - sage.libs.pari -1 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: moebius(int8(-5)) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: moebius(int8(-5)) # optional - numpy sage.libs.pari -1 sage: from gmpy2 import mpz - sage: moebius(mpz(-5)) # optional - sage.libs.pari + sage: moebius(mpz(-5)) # optional - sage.libs.pari -1 """ def __call__(self, n): @@ -4501,7 +4505,7 @@ def __call__(self, n): EXAMPLES:: sage: from sage.arith.misc import Moebius - sage: Moebius().__call__(7) # optional - sage.libs.pari + sage: Moebius().__call__(7) # optional - sage.libs.pari -1 """ n = py_scalar_to_element(n) @@ -4559,8 +4563,8 @@ def plot(self, xmin=0, xmax=50, pointsize=30, rgbcolor=(0,0,1), join=True, EXAMPLES:: sage: from sage.arith.misc import Moebius - sage: p = Moebius().plot() # optional - sage.plot - sage: p.ymax() # optional - sage.plot + sage: p = Moebius().plot() # optional - sage.plot + sage: p.ymax() # optional - sage.plot 1.0 """ values = self.range(xmin, xmax + 1) @@ -4582,12 +4586,12 @@ def range(self, start, stop=None, step=None): EXAMPLES:: - sage: v = moebius.range(-10, 10); v # optional - sage.libs.pari + sage: v = moebius.range(-10, 10); v # optional - sage.libs.pari [1, 0, 0, -1, 1, -1, 0, -1, -1, 1, 0, 1, -1, -1, 0, -1, 1, -1, 0, 0] - sage: v == [moebius(n) for n in range(-10, 10)] # optional - sage.libs.pari + sage: v == [moebius(n) for n in range(-10, 10)] # optional - sage.libs.pari True - sage: v = moebius.range(-1000, 2000, 4) # optional - sage.libs.pari - sage: v == [moebius(n) for n in range(-1000, 2000, 4)] # optional - sage.libs.pari + sage: v = moebius.range(-1000, 2000, 4) # optional - sage.libs.pari + sage: v == [moebius(n) for n in range(-1000, 2000, 4)] # optional - sage.libs.pari True """ if stop is None: @@ -4651,14 +4655,15 @@ def continuant(v, n=None): sage: q = continuant([1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10]) sage: p/q 517656/190435 - sage: continued_fraction([2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10]).convergent(14) # optional - sage.libs.pari + sage: F = continued_fraction([2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10]) + sage: F.convergent(14) # optional - sage.libs.pari 517656/190435 - sage: x = PolynomialRing(RationalField(),'x',5).gens() + sage: x = PolynomialRing(RationalField(), 'x', 5).gens() sage: continuant(x) x0*x1*x2*x3*x4 + x0*x1*x2 + x0*x1*x4 + x0*x3*x4 + x2*x3*x4 + x0 + x2 + x4 sage: continuant(x, 3) x0*x1*x2 + x0 + x2 - sage: continuant(x,2) + sage: continuant(x, 2) x0*x1 + 1 We verify the identity @@ -4670,7 +4675,7 @@ def continuant(v, n=None): for `n = 6` using polynomial arithmetic:: sage: z = QQ['z'].0 - sage: continuant((z,z,z,z,z,z,z,z,z,z,z,z,z,z,z),6) + sage: continuant((z,z,z,z,z,z,z,z,z,z,z,z,z,z,z), 6) z^6 + 5*z^4 + 6*z^2 + 1 sage: continuant(9) @@ -4684,7 +4689,7 @@ def continuant(v, n=None): sage: continuant([int8(1), int8(2), int8(3)]) # optional - numpy 10 sage: from gmpy2 import mpz - sage: continuant([mpz(1),mpz(2),mpz(3)]) + sage: continuant([mpz(1), mpz(2), mpz(3)]) mpz(10) AUTHORS: @@ -4718,18 +4723,18 @@ def number_of_divisors(n): EXAMPLES:: - sage: number_of_divisors(100) # optional - sage.libs.pari + sage: number_of_divisors(100) # optional - sage.libs.pari 9 - sage: number_of_divisors(-720) # optional - sage.libs.pari + sage: number_of_divisors(-720) # optional - sage.libs.pari 30 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: number_of_divisors(int8(100)) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: number_of_divisors(int8(100)) # optional - numpy sage.libs.pari 9 sage: from gmpy2 import mpz - sage: number_of_divisors(mpz(100)) # optional - sage.libs.pari + sage: number_of_divisors(mpz(100)) # optional - sage.libs.pari 9 """ m = ZZ(n) @@ -4767,33 +4772,33 @@ def hilbert_symbol(a, b, p, algorithm="pari"): EXAMPLES:: - sage: hilbert_symbol(-1, -1, -1, algorithm='all') # optional - sage.libs.pari + sage: hilbert_symbol(-1, -1, -1, algorithm='all') # optional - sage.libs.pari -1 - sage: hilbert_symbol(2, 3, 5, algorithm='all') # optional - sage.libs.pari + sage: hilbert_symbol(2, 3, 5, algorithm='all') # optional - sage.libs.pari 1 - sage: hilbert_symbol(4, 3, 5, algorithm='all') # optional - sage.libs.pari + sage: hilbert_symbol(4, 3, 5, algorithm='all') # optional - sage.libs.pari 1 - sage: hilbert_symbol(0, 3, 5, algorithm='all') # optional - sage.libs.pari + sage: hilbert_symbol(0, 3, 5, algorithm='all') # optional - sage.libs.pari 0 - sage: hilbert_symbol(-1, -1, 2, algorithm='all') # optional - sage.libs.pari + sage: hilbert_symbol(-1, -1, 2, algorithm='all') # optional - sage.libs.pari -1 - sage: hilbert_symbol(1, -1, 2, algorithm='all') # optional - sage.libs.pari + sage: hilbert_symbol(1, -1, 2, algorithm='all') # optional - sage.libs.pari 1 - sage: hilbert_symbol(3, -1, 2, algorithm='all') # optional - sage.libs.pari + sage: hilbert_symbol(3, -1, 2, algorithm='all') # optional - sage.libs.pari -1 - sage: hilbert_symbol(QQ(-1)/QQ(4), -1, 2) == -1 # optional - sage.libs.pari + sage: hilbert_symbol(QQ(-1)/QQ(4), -1, 2) == -1 # optional - sage.libs.pari True - sage: hilbert_symbol(QQ(-1)/QQ(4), -1, 3) == 1 # optional - sage.libs.pari + sage: hilbert_symbol(QQ(-1)/QQ(4), -1, 3) == 1 # optional - sage.libs.pari True Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: hilbert_symbol(int8(2), int8(3), int8(5), algorithm='all') # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: hilbert_symbol(int8(2), int8(3), int8(5), algorithm='all') # optional - numpy sage.libs.pari 1 sage: from gmpy2 import mpz - sage: hilbert_symbol(mpz(2), mpz(3), mpz(5), algorithm='all') # optional - sage.libs.pari + sage: hilbert_symbol(mpz(2), mpz(3), mpz(5), algorithm='all') # optional - sage.libs.pari 1 AUTHORS: @@ -4872,22 +4877,22 @@ def hilbert_conductor(a, b): EXAMPLES:: - sage: hilbert_conductor(-1, -1) # optional - sage.libs.pari + sage: hilbert_conductor(-1, -1) # optional - sage.libs.pari 2 - sage: hilbert_conductor(-1, -11) # optional - sage.libs.pari + sage: hilbert_conductor(-1, -11) # optional - sage.libs.pari 11 - sage: hilbert_conductor(-2, -5) # optional - sage.libs.pari + sage: hilbert_conductor(-2, -5) # optional - sage.libs.pari 5 - sage: hilbert_conductor(-3, -17) # optional - sage.libs.pari + sage: hilbert_conductor(-3, -17) # optional - sage.libs.pari 17 Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: hilbert_conductor(int8(-3), int8(-17)) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: hilbert_conductor(int8(-3), int8(-17)) # optional - numpy sage.libs.pari 17 sage: from gmpy2 import mpz - sage: hilbert_conductor(mpz(-3), mpz(-17)) # optional - sage.libs.pari + sage: hilbert_conductor(mpz(-3), mpz(-17)) # optional - sage.libs.pari 17 AUTHOR: @@ -4915,19 +4920,19 @@ def hilbert_conductor_inverse(d): EXAMPLES:: - sage: hilbert_conductor_inverse(2) # optional - sage.libs.pari + sage: hilbert_conductor_inverse(2) # optional - sage.libs.pari (-1, -1) - sage: hilbert_conductor_inverse(3) # optional - sage.libs.pari + sage: hilbert_conductor_inverse(3) # optional - sage.libs.pari (-1, -3) - sage: hilbert_conductor_inverse(6) # optional - sage.libs.pari + sage: hilbert_conductor_inverse(6) # optional - sage.libs.pari (-1, 3) - sage: hilbert_conductor_inverse(30) # optional - sage.libs.pari + sage: hilbert_conductor_inverse(30) # optional - sage.libs.pari (-3, -10) - sage: hilbert_conductor_inverse(4) # optional - sage.libs.pari + sage: hilbert_conductor_inverse(4) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: d needs to be squarefree - sage: hilbert_conductor_inverse(-1) # optional - sage.libs.pari + sage: hilbert_conductor_inverse(-1) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: d needs to be positive @@ -4938,18 +4943,18 @@ def hilbert_conductor_inverse(d): TESTS:: - sage: for i in range(100): # optional - sage.libs.pari + sage: for i in range(100): # optional - sage.libs.pari ....: d = ZZ.random_element(2**32).squarefree_part() ....: if hilbert_conductor(*hilbert_conductor_inverse(d)) != d: ....: print("hilbert_conductor_inverse failed for d = {}".format(d)) Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: hilbert_conductor_inverse(int8(30)) # optional - numpy sage.libs.pari + sage: from numpy import int8 # optional - numpy + sage: hilbert_conductor_inverse(int8(30)) # optional - numpy sage.libs.pari (-3, -10) sage: from gmpy2 import mpz - sage: hilbert_conductor_inverse(mpz(30)) # optional - sage.libs.pari + sage: hilbert_conductor_inverse(mpz(30)) # optional - sage.libs.pari (-3, -10) """ Z = ZZ @@ -5025,25 +5030,25 @@ def falling_factorial(x, a): sage: falling_factorial(10, 3) 720 - sage: falling_factorial(10, RR('3.0')) # optional - sage.symbolic + sage: falling_factorial(10, RR('3.0')) # optional - sage.symbolic 720.000000000000 - sage: falling_factorial(10, RR('3.3')) # optional - sage.symbolic + sage: falling_factorial(10, RR('3.3')) # optional - sage.symbolic 1310.11633396601 sage: falling_factorial(10, 10) 3628800 sage: factorial(10) 3628800 - sage: a = falling_factorial(1+I, I); a # optional - sage.symbolic + sage: a = falling_factorial(1 + I, I); a # optional - sage.symbolic gamma(I + 2) - sage: CC(a) # optional - sage.symbolic + sage: CC(a) # optional - sage.symbolic 0.652965496420167 + 0.343065839816545*I - sage: falling_factorial(1+I, 4) + sage: falling_factorial(1 + I, 4) 4*I + 2 sage: falling_factorial(I, 4) -10 sage: M = MatrixSpace(ZZ, 4, 4) - sage: A = M([1,0,1,0,1,0,1,0,1,0,10,10,1,0,1,1]) + sage: A = M([1,0,1,0, 1,0,1,0, 1,0,10,10, 1,0,1,1]) sage: falling_factorial(A, 2) # A(A - I) [ 1 0 10 10] [ 1 0 10 10] @@ -5058,13 +5063,13 @@ def falling_factorial(x, a): Check that :trac:`14858` is fixed:: - sage: falling_factorial(-4, SR(2)) # optional - sage.symbolic + sage: falling_factorial(-4, SR(2)) # optional - sage.symbolic 20 Check that :trac:`16770` is fixed:: - sage: d = var('d') # optional - sage.symbolic - sage: parent(falling_factorial(d, 0)) # optional - sage.symbolic + sage: d = var('d') # optional - sage.symbolic + sage: parent(falling_factorial(d, 0)) # optional - sage.symbolic Symbolic Ring Check that :trac:`20075` is fixed:: @@ -5074,8 +5079,8 @@ def falling_factorial(x, a): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: falling_factorial(int8(10), int8(3)) # optional - numpy + sage: from numpy import int8 # optional - numpy + sage: falling_factorial(int8(10), int8(3)) # optional - numpy 720 sage: from gmpy2 import mpz sage: falling_factorial(mpz(10), mpz(3)) @@ -5150,15 +5155,15 @@ def rising_factorial(x, a): Check that :trac:`14858` is fixed:: - sage: bool(rising_factorial(-4, 2) == # optional - sage.symbolic + sage: bool(rising_factorial(-4, 2) == # optional - sage.symbolic ....: rising_factorial(-4, SR(2)) == ....: rising_factorial(SR(-4), SR(2))) True Check that :trac:`16770` is fixed:: - sage: d = var('d') - sage: parent(rising_factorial(d, 0)) + sage: d = var('d') # optional - sage.symbolic + sage: parent(rising_factorial(d, 0)) # optional - sage.symbolic Symbolic Ring Check that :trac:`20075` is fixed:: @@ -5168,8 +5173,8 @@ def rising_factorial(x, a): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: rising_factorial(int8(10), int8(3)) # optional - numpy + sage: from numpy import int8 # optional - numpy + sage: rising_factorial(int8(10), int8(3)) # optional - numpy 1320 sage: from gmpy2 import mpz sage: rising_factorial(mpz(10), mpz(3)) @@ -5198,15 +5203,15 @@ def integer_ceil(x): sage: integer_ceil(5.4) 6 - sage: integer_ceil(x) # optional - sage.symbolic + sage: integer_ceil(x) # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError: computation of ceil of x not implemented Tests with numpy and gmpy2 numbers:: - sage: from numpy import float32 # optional - numpy - sage: integer_ceil(float32(5.4)) # optional - numpy + sage: from numpy import float32 # optional - numpy + sage: integer_ceil(float32(5.4)) # optional - numpy 6 sage: from gmpy2 import mpfr sage: integer_ceil(mpfr(5.4)) @@ -5244,15 +5249,15 @@ def integer_floor(x): sage: integer_floor(RDF(-5/2)) -3 - sage: integer_floor(x) # optional - sage.symbolic + sage: integer_floor(x) # optional - sage.symbolic Traceback (most recent call last): ... NotImplementedError: computation of floor of x not implemented Tests with numpy and gmpy2 numbers:: - sage: from numpy import float32 # optional - numpy - sage: integer_floor(float32(5.4)) # optional - numpy + sage: from numpy import float32 # optional - numpy + sage: integer_floor(float32(5.4)) # optional - numpy 5 sage: from gmpy2 import mpfr sage: integer_floor(mpfr(5.4)) @@ -5308,11 +5313,11 @@ def two_squares(n): ValueError: 21 is not a sum of 2 squares sage: two_squares(21^2) (0, 21) - sage: a,b = two_squares(100000000000000000129); a,b + sage: a, b = two_squares(100000000000000000129); a, b # optional - sage.libs.pari (4418521500, 8970878873) - sage: a^2 + b^2 + sage: a^2 + b^2 # optional - sage.libs.pari 100000000000000000129 - sage: two_squares(2^222+1) + sage: two_squares(2^222 + 1) # optional - sage.libs.pari (253801659504708621991421712450521, 2583712713213354898490304645018692) sage: two_squares(0) (0, 0) @@ -5323,17 +5328,17 @@ def two_squares(n): TESTS:: - sage: for _ in range(100): + sage: for _ in range(100): # optional - sage.libs.pari ....: a = ZZ.random_element(2**16, 2**20) ....: b = ZZ.random_element(2**16, 2**20) ....: n = a**2 + b**2 - ....: aa,bb = two_squares(n) + ....: aa, bb = two_squares(n) ....: assert aa**2 + bb**2 == n Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 # optional - numpy - sage: two_squares(int16(389)) # optional - numpy + sage: from numpy import int16 # optional - numpy + sage: two_squares(int16(389)) # optional - numpy (10, 17) sage: from gmpy2 import mpz sage: two_squares(mpz(389)) @@ -5430,11 +5435,11 @@ def three_squares(n): (3, 24, 49) sage: three_squares(7^100) (0, 0, 1798465042647412146620280340569649349251249) - sage: three_squares(11^111-1) + sage: three_squares(11^111 - 1) # optional - sage.libs.pari (616274160655975340150706442680, 901582938385735143295060746161, 6270382387635744140394001363065311967964099981788593947233) - sage: three_squares(7 * 2^41) + sage: three_squares(7 * 2^41) # optional - sage.libs.pari (1048576, 2097152, 3145728) - sage: three_squares(7 * 2^42) + sage: three_squares(7 * 2^42) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: 30786325577728 is not a sum of 3 squares @@ -5447,18 +5452,18 @@ def three_squares(n): TESTS:: - sage: for _ in range(100): + sage: for _ in range(100): # optional - sage.libs.pari ....: a = ZZ.random_element(2**16, 2**20) ....: b = ZZ.random_element(2**16, 2**20) ....: c = ZZ.random_element(2**16, 2**20) ....: n = a**2 + b**2 + c**2 - ....: aa,bb,cc = three_squares(n) + ....: aa, bb, cc = three_squares(n) ....: assert aa**2 + bb**2 + cc**2 == n Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 # optional - numpy - sage: three_squares(int16(389)) # optional - numpy + sage: from numpy import int16 # optional - numpy + sage: three_squares(int16(389)) # optional - numpy (1, 8, 18) sage: from gmpy2 import mpz sage: three_squares(mpz(389)) @@ -5574,23 +5579,23 @@ def four_squares(n): (0, 0, 3, 11) sage: four_squares(1101011011004) (90, 102, 1220, 1049290) - sage: four_squares(10^100-1) + sage: four_squares(10^100 - 1) # optional - sage.libs.pari (155024616290, 2612183768627, 14142135623730950488016887, 99999999999999999999999999999999999999999999999999) - sage: for i in range(2^129, 2^129+10000): # long time + sage: for i in range(2^129, 2^129+10000): # long time # optional - sage.libs.pari ....: S = four_squares(i) ....: assert sum(x^2 for x in S) == i TESTS:: - sage: for _ in range(100): - ....: n = ZZ.random_element(2**32,2**34) - ....: aa,bb,cc,dd = four_squares(n) + sage: for _ in range(100): # optional - sage.libs.pari + ....: n = ZZ.random_element(2**32, 2**34) + ....: aa, bb, cc, dd = four_squares(n) ....: assert aa**2 + bb**2 + cc**2 + dd**2 == n Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 # optional - numpy - sage: four_squares(int16(389)) # optional - numpy + sage: from numpy import int16 # optional - numpy + sage: four_squares(int16(389)) # optional - numpy (0, 1, 8, 18) sage: from gmpy2 import mpz sage: four_squares(mpz(389)) @@ -5651,7 +5656,7 @@ def sum_of_k_squares(k, n): (1, 2, 5, 98) sage: sum_of_k_squares(5, 9634) (0, 1, 2, 5, 98) - sage: sum_of_k_squares(6, 11^1111-1) + sage: sum_of_k_squares(6, 11^1111 - 1) # optional - sage.libs.pari (19215400822645944253860920437586326284, 37204645194585992174252915693267578306, 3473654819477394665857484221256136567800161086815834297092488779216863122, 5860191799617673633547572610351797996721850737768032876360978911074629287841061578270832330322236796556721252602860754789786937515870682024273948, 20457423294558182494001919812379023992538802203730791019728543439765347851316366537094696896669915675685581905102118246887673397020172285247862426612188418787649371716686651256443143210952163970564228423098202682066311189439731080552623884051737264415984619097656479060977602722566383385989, 311628095411678159849237738619458396497534696043580912225334269371611836910345930320700816649653412141574887113710604828156159177769285115652741014638785285820578943010943846225597311231847997461959204894255074229895666356909071243390280307709880906261008237873840245959883405303580405277298513108957483306488193844321589356441983980532251051786704380984788999660195252373574924026139168936921591652831237741973242604363696352878914129671292072201700073286987126265965322808664802662993006926302359371379531571194266134916767573373504566621665949840469229781956838744551367172353) sage: sum_of_k_squares(7, 0) (0, 0, 0, 0, 0, 0, 0) @@ -5684,8 +5689,8 @@ def sum_of_k_squares(k, n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int16 # optional - numpy - sage: sum_of_k_squares(int16(2), int16(9634)) # optional - numpy + sage: from numpy import int16 # optional - numpy + sage: sum_of_k_squares(int16(2), int16(9634)) # optional - numpy (15, 97) sage: from gmpy2 import mpz sage: sum_of_k_squares(mpz(2), mpz(9634)) @@ -5756,8 +5761,8 @@ def subfactorial(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: subfactorial(int8(8)) # optional - numpy + sage: from numpy import int8 # optional - numpy + sage: subfactorial(int8(8)) # optional - numpy 14833 sage: from gmpy2 import mpz sage: subfactorial(mpz(8)) @@ -5797,10 +5802,10 @@ def is_power_of_two(n): Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: is_power_of_two(int8(16)) # optional - numpy + sage: from numpy import int8 # optional - numpy + sage: is_power_of_two(int8(16)) # optional - numpy True - sage: is_power_of_two(int8(24)) # optional - numpy + sage: is_power_of_two(int8(24)) # optional - numpy False sage: from gmpy2 import mpz sage: is_power_of_two(mpz(16)) @@ -5817,7 +5822,7 @@ def differences(lis, n=1): EXAMPLES:: - sage: differences(prime_range(50)) # optional - sage.libs.pari + sage: differences(prime_range(50)) # optional - sage.libs.pari [1, 2, 2, 4, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4] sage: differences([i^2 for i in range(1,11)]) [3, 5, 7, 9, 11, 13, 15, 17, 19] @@ -5825,16 +5830,16 @@ def differences(lis, n=1): [10, 22, 40, 64, 94, 130, 172, 220, 274, 334, 400, 472, 550, 634, 724, 820, 922, 1030, 1144] sage: differences([i^3 - i^2 for i in range(1,21)], 2) [10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70, 76, 82, 88, 94, 100, 106, 112] - sage: differences([p - i^2 for i, p in enumerate(prime_range(50))], 3) # optional - sage.libs.pari + sage: differences([p - i^2 for i, p in enumerate(prime_range(50))], 3) # optional - sage.libs.pari [-1, 2, -4, 4, -4, 4, 0, -6, 8, -6, 0, 4] Tests with numpy and gmpy2 numbers:: - sage: from numpy import int8 # optional - numpy - sage: differences([int8(1), int8(4), int8(6), int8(19)]) # optional - numpy + sage: from numpy import int8 # optional - numpy + sage: differences([int8(1), int8(4), int8(6), int8(19)]) # optional - numpy [3, 2, 13] sage: from gmpy2 import mpz - sage: differences([mpz(1),mpz(4),mpz(6),mpz(19)]) + sage: differences([mpz(1), mpz(4), mpz(6), mpz(19)]) [mpz(3), mpz(2), mpz(13)] AUTHORS: @@ -6195,42 +6200,42 @@ def gauss_sum(char_value, finite_field): EXAMPLES:: sage: from sage.arith.misc import gauss_sum - sage: F = GF(5); q = 5 # optional - sage.libs.pari - sage: zq = UniversalCyclotomicField().zeta(q-1) # optional - sage.libs.pari - sage: L = [gauss_sum(zq**i, F) for i in range(5)]; L # optional - sage.libs.pari + sage: F = GF(5); q = 5 # optional - sage.libs.pari + sage: zq = UniversalCyclotomicField().zeta(q - 1) # optional - sage.libs.pari + sage: L = [gauss_sum(zq**i, F) for i in range(5)]; L # optional - sage.libs.pari [-1, E(20)^4 + E(20)^13 - E(20)^16 - E(20)^17, E(5) - E(5)^2 - E(5)^3 + E(5)^4, E(20)^4 - E(20)^13 - E(20)^16 + E(20)^17, -1] - sage: [g*g.conjugate() for g in L] # optional - sage.libs.pari + sage: [g*g.conjugate() for g in L] # optional - sage.libs.pari [1, 5, 5, 5, 1] - sage: F = GF(11**2); q = 11**2 # optional - sage.libs.pari - sage: zq = UniversalCyclotomicField().zeta(q - 1) # optional - sage.libs.pari - sage: g = gauss_sum(zq**4, F) # optional - sage.libs.pari - sage: g*g.conjugate() # optional - sage.libs.pari + sage: F = GF(11**2); q = 11**2 # optional - sage.libs.pari + sage: zq = UniversalCyclotomicField().zeta(q - 1) # optional - sage.libs.pari + sage: g = gauss_sum(zq**4, F) # optional - sage.libs.pari + sage: g*g.conjugate() # optional - sage.libs.pari 121 TESTS:: - sage: F = GF(11); q = 11 # optional - sage.libs.pari sage.rings.number_field - sage: zq = UniversalCyclotomicField().zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field - sage: gauss_sum(zq**2, F).n(60) # optional - sage.libs.pari sage.rings.number_field + sage: F = GF(11); q = 11 # optional - sage.libs.pari sage.rings.number_field + sage: zq = UniversalCyclotomicField().zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field + sage: gauss_sum(zq**2, F).n(60) # optional - sage.libs.pari sage.rings.number_field 2.6361055643248352 + 2.0126965627574471*I - sage: zq = QQbar.zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field - sage: gauss_sum(zq**2, F) # optional - sage.libs.pari sage.rings.number_field + sage: zq = QQbar.zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field + sage: gauss_sum(zq**2, F) # optional - sage.libs.pari sage.rings.number_field 2.636105564324836? + 2.012696562757447?*I - sage: zq = ComplexField(60).zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field - sage: gauss_sum(zq**2, F) # optional - sage.libs.pari sage.rings.number_field + sage: zq = ComplexField(60).zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field + sage: gauss_sum(zq**2, F) # optional - sage.libs.pari sage.rings.number_field 2.6361055643248352 + 2.0126965627574471*I - sage: F = GF(7); q = 7 # optional - sage.libs.pari sage.rings.number_field - sage: zq = QQbar.zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field - sage: D = DirichletGroup(7, QQbar) # optional - sage.libs.pari sage.rings.number_field - sage: all(D[i].gauss_sum() == gauss_sum(zq**i, F) for i in range(6)) # optional - sage.libs.pari sage.rings.number_field + sage: F = GF(7); q = 7 # optional - sage.libs.pari sage.rings.number_field + sage: zq = QQbar.zeta(q - 1) # optional - sage.libs.pari sage.rings.number_field + sage: D = DirichletGroup(7, QQbar) # optional - sage.libs.pari sage.rings.number_field + sage: all(D[i].gauss_sum() == gauss_sum(zq**i, F) for i in range(6)) # optional - sage.libs.pari sage.rings.number_field True sage: gauss_sum(1, QQ) From 3c002acf7b62e27cf91bb74361ffa48ec41f2f81 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 11:10:44 -0700 Subject: [PATCH 149/205] src/sage/features/sagemath.py: Fix alignment of # optional in features added here --- src/sage/features/sagemath.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index 8ea01d3ab90..969747b34e8 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -123,7 +123,7 @@ class sage__modular(JoinFeature): EXAMPLES:: sage: from sage.features.sagemath import sage__modular - sage: sage__modular().is_present() # optional - sage.modular + sage: sage__modular().is_present() # optional - sage.modular FeatureTestResult('sage.modular', True) """ def __init__(self): @@ -169,7 +169,7 @@ class sage__libs__flint(JoinFeature): EXAMPLES:: sage: from sage.features.sagemath import sage__libs__flint - sage: sage__libs__flint().is_present() # optional - sage.libs.flint + sage: sage__libs__flint().is_present() # optional - sage.libs.flint FeatureTestResult('sage.libs.flint', True) """ def __init__(self): @@ -194,7 +194,7 @@ class sage__libs__ntl(JoinFeature): EXAMPLES:: sage: from sage.features.sagemath import sage__libs__ntl - sage: sage__libs__ntl().is_present() # optional - sage.libs.ntl + sage: sage__libs__ntl().is_present() # optional - sage.libs.ntl FeatureTestResult('sage.libs.ntl', True) """ def __init__(self): @@ -376,7 +376,7 @@ class sage__rings__polynomial__pbori(JoinFeature): EXAMPLES:: sage: from sage.features.sagemath import sage__rings__polynomial__pbori - sage: sage__rings__polynomial__pbori().is_present() # optional - sage.rings.polynomial.pbori + sage: sage__rings__polynomial__pbori().is_present() # optional - sage.rings.polynomial.pbori FeatureTestResult('sage.rings.polynomial.pbori', True) """ def __init__(self): @@ -442,7 +442,7 @@ class sage__schemes(JoinFeature): EXAMPLES:: sage: from sage.features.sagemath import sage__schemes - sage: sage__schemes().is_present() # optional - sage.schemes + sage: sage__schemes().is_present() # optional - sage.schemes FeatureTestResult('sage.schemes', True) """ def __init__(self): From ce9a1ad2e17718ab392a3c873c73afcd5925e17c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 11:19:31 -0700 Subject: [PATCH 150/205] src/sage/arith/misc.py (primes): Fix bad merge; docstring cosmetics --- src/sage/arith/misc.py | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index db23ac32ae9..df32d004bcc 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -1018,37 +1018,37 @@ def eratosthenes(n): return [ZZ(2)] + [ZZ(x) for x in s if x and x <= n] -def primes(start, stop=None, proof=None): +def primes(start=2, stop=None, proof=None): r""" - Return an iterator over all primes between start and stop-1, - inclusive. This is much slower than ``prime_range``, but + Return an iterator over all primes between ``start`` and ``stop-1``, + inclusive. This is much slower than :func:`prime_range`, but potentially uses less memory. As with :func:`next_prime`, the optional - argument proof controls whether the numbers returned are + argument ``proof`` controls whether the numbers returned are guaranteed to be prime or not. - This command is like the Python 3 ``range`` command, except it only iterates - over primes. In some cases it is better to use primes than - ``prime_range``, because primes does not build a list of all primes in - the range in memory all at once. However, it is potentially much - slower since it simply calls the :func:`next_prime` function - repeatedly, and :func:`next_prime` is slow. + This command is like the Python 3 :func:`range` command, except it only + iterates over primes. In some cases it is better to use :func:`primes` than + :func:`prime_range`, because :func:`primes` does not build a list of all + primes in the range in memory all at once. However, it is potentially much + slower since it simply calls the :func:`next_prime` function repeatedly, and + :func:`next_prime` is slow. INPUT: - - ``start`` - an integer - lower bound for the primes + - ``start`` -- an integer (optional, default: 2) lower bound for the primes - - ``stop`` - an integer (or infinity) optional argument - - giving upper (open) bound for the primes + - ``stop`` -- an integer (or infinity) upper (open) bound for the + primes - - ``proof`` - bool or None (default: None) If True, the function - yields only proven primes. If False, the function uses a - pseudo-primality test, which is much faster for really big - numbers but does not provide a proof of primality. If None, - uses the global default (see :mod:`sage.structure.proof.proof`) + - ``proof`` -- bool or ``None`` (default: ``None``) If ``True``, the + function yields only proven primes. If ``False``, the function uses a + pseudo-primality test, which is much faster for really big numbers but + does not provide a proof of primality. If ``None``, uses the global + default (see :mod:`sage.structure.proof.proof`) OUTPUT: - - an iterator over primes from start to stop-1, inclusive + - an iterator over primes from ``start`` to ``stop-1``, inclusive EXAMPLES:: From ae63b5204ee3c6504bcc4f93b9baf6ea45c6f4eb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 11:31:07 -0700 Subject: [PATCH 151/205] src/sage/arith/misc.py (factor): Fix bad merge; docstring cosmetics --- src/sage/arith/misc.py | 83 ++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index df32d004bcc..7cdd54cb54c 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -1384,53 +1384,53 @@ def random_prime(n, proof=None, lbound=2): INPUT: - - ``n`` - an integer >= 2. + - ``n`` - an integer `\geq 2`. - - ``proof`` - bool or None (default: None) If False, the function uses a + - ``proof`` - bool or ``None`` (default: ``None``) If ``False``, the function uses a pseudo-primality test, which is much faster for really big numbers but - does not provide a proof of primality. If None, uses the global default + does not provide a proof of primality. If ``None``, uses the global default (see :mod:`sage.structure.proof.proof`) - - ``lbound`` - an integer >= 2, lower bound for the chosen primes + - ``lbound`` - an integer `\geq 2`, lower bound for the chosen primes EXAMPLES:: - sage: p = random_prime(100000) # optional - sage.libs.pari - sage: p.is_prime() # optional - sage.libs.pari + sage: p = random_prime(100000) # optional - sage.libs.pari + sage: p.is_prime() # optional - sage.libs.pari True - sage: p <= 100000 # optional - sage.libs.pari + sage: p <= 100000 # optional - sage.libs.pari True - sage: random_prime(2) # optional - sage.libs.pari + sage: random_prime(2) # optional - sage.libs.pari 2 Here we generate a random prime between 100 and 200:: - sage: p = random_prime(200, lbound=100) # optional - sage.libs.pari - sage: p.is_prime() # optional - sage.libs.pari + sage: p = random_prime(200, lbound=100) # optional - sage.libs.pari + sage: p.is_prime() # optional - sage.libs.pari True - sage: 100 <= p <= 200 # optional - sage.libs.pari + sage: 100 <= p <= 200 # optional - sage.libs.pari True If all we care about is finding a pseudo prime, then we can pass in ``proof=False`` :: - sage: p = random_prime(200, proof=False, lbound=100) # optional - sage.libs.pari - sage: p.is_pseudoprime() # optional - sage.libs.pari + sage: p = random_prime(200, proof=False, lbound=100) # optional - sage.libs.pari + sage: p.is_pseudoprime() # optional - sage.libs.pari True - sage: 100 <= p <= 200 # optional - sage.libs.pari + sage: 100 <= p <= 200 # optional - sage.libs.pari True TESTS:: - sage: type(random_prime(2)) # optional - sage.libs.pari + sage: type(random_prime(2)) # optional - sage.libs.pari - sage: type(random_prime(100)) # optional - sage.libs.pari + sage: type(random_prime(100)) # optional - sage.libs.pari - sage: random_prime(1, lbound=-2) #caused Sage hang #10112 # optional - sage.libs.pari + sage: random_prime(1, lbound=-2) #caused Sage hang #10112 # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: n must be greater than or equal to 2 - sage: random_prime(126, lbound=114) # optional - sage.libs.pari + sage: random_prime(126, lbound=114) # optional - sage.libs.pari Traceback (most recent call last): ... ValueError: there are no primes between 114 and 126 (inclusive) @@ -2506,14 +2506,14 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): type of ``n``. If ``n`` is an integer, returns the factorization as an object - of type ``Factorization``. + of type :class:`Factorization`. - If n is not an integer, ``n.factor(proof=proof, **kwds)`` gets called. + If ``n`` is not an integer, ``n.factor(proof=proof, **kwds)`` gets called. See ``n.factor??`` for more documentation in this case. .. warning:: - This means that applying ``factor`` to an integer result of + This means that applying :func:`factor` to an integer result of a symbolic computation will not factor the integer, because it is considered as an element of a larger symbolic ring. @@ -2527,46 +2527,46 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): INPUT: - - ``n`` - an nonzero integer + - ``n`` -- a nonzero integer - - ``proof`` - bool or None (default: None) + - ``proof`` -- bool or ``None`` (default: ``None``) - - ``int_`` - bool (default: False) whether to return + - ``int_`` -- bool (default: ``False``) whether to return answers as Python ints - - ``algorithm`` - string + - ``algorithm`` -- string - - ``'pari'`` - (default) use the PARI c library + - ``'pari'`` -- (default) use the PARI c library - - ``'kash'`` - use KASH computer algebra system (requires that + - ``'kash'`` -- use KASH computer algebra system (requires that kash be installed) - - ``'magma'`` - use Magma (requires magma be installed) + - ``'magma'`` -- use Magma (requires magma be installed) - - ``verbose`` - integer (default: 0); PARI's debug + - ``verbose`` -- integer (default: 0); PARI's debug variable is set to this; e.g., set to 4 or 8 to see lots of output during factorization. OUTPUT: - - factorization of n + - factorization of `n` The qsieve and ecm commands give access to highly optimized implementations of algorithms for doing certain integer factorization problems. These implementations are not used by the - generic factor command, which currently just calls PARI (note that + generic :func:`factor` command, which currently just calls PARI (note that PARI also implements sieve and ecm algorithms, but they are not as optimized). Thus you might consider using them instead for certain numbers. The factorization returned is an element of the class - :class:`~sage.structure.factorization.Factorization`; see Factorization?? - for more details, and examples below for usage. A Factorization contains - both the unit factor (+1 or -1) and a sorted list of (prime, exponent) + :class:`~sage.structure.factorization.Factorization`; use ``Factorization??`` + to see more details, and examples below for usage. A :class:`~sage.structure.factorization.Factorization` contains + both the unit factor (`+1` or `-1`) and a sorted list of ``(prime, exponent)`` pairs. The factorization displays in pretty-print format but it is easy to - obtain access to the (prime,exponent) pairs and the unit, to + obtain access to the ``(prime, exponent)`` pairs and the unit, to recover the number from its factorization, and even to multiply two factorizations. See examples below. @@ -2586,6 +2586,11 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): sage: factor(-next_prime(10^2) * next_prime(10^7)) # optional - sage.libs.pari -1 * 101 * 10000019 + :: + + sage: factor(293292629867846432923017396246429, algorithm='flint') # optional - sage.libs.flint + 3 * 4852301647696687 * 20148007492971089 + :: sage: factor(-500, algorithm='kash') # optional - kash @@ -2609,10 +2614,10 @@ def factor(n, proof=None, int_=False, algorithm='pari', verbose=0, **kwds): sage: factor(2^(2^7) + 1) # optional - sage.libs.pari 59649589127497217 * 5704689200685129054721 - Sage calls PARI's factor, which has proof False by default. - Sage has a global proof flag, set to True by default (see - :mod:`sage.structure.proof.proof`, or proof.[tab]). To override - the default, call this function with proof=False. + Sage calls PARI's :pari:`factor`, which has ``proof=False`` by default. + Sage has a global proof flag, set to ``True`` by default (see + :mod:`sage.structure.proof.proof`, or use ``proof.[tab]``). To override + the default, call this function with ``proof=False``. :: From 6aaf4b9912dc7252c054bc66db4972c056772d13 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 11:35:59 -0700 Subject: [PATCH 152/205] src/sage/misc/functional.py (sqrt): Re-align # optional --- src/sage/misc/functional.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py index 58c4254c278..12817b97fb2 100644 --- a/src/sage/misc/functional.py +++ b/src/sage/misc/functional.py @@ -1915,25 +1915,25 @@ def sqrt(x, *args, **kwds): EXAMPLES:: - sage: sqrt(-1) + sage: sqrt(-1) # optional - sage.symbolic I - sage: sqrt(2) + sage: sqrt(2) # optional - sage.symbolic sqrt(2) - sage: sqrt(2)^2 + sage: sqrt(2)^2 # optional - sage.symbolic 2 sage: sqrt(4) 2 - sage: sqrt(4,all=True) + sage: sqrt(4, all=True) [2, -2] - sage: sqrt(x^2) + sage: sqrt(x^2) # optional - sage.symbolic sqrt(x^2) For a non-symbolic square root, there are a few options. The best is to numerically approximate afterward:: - sage: sqrt(2).n() # optional - sage.symbolic + sage: sqrt(2).n() # optional - sage.symbolic 1.41421356237310 - sage: sqrt(2).n(prec=100) # optional - sage.symbolic + sage: sqrt(2).n(prec=100) # optional - sage.symbolic 1.4142135623730950488016887242 Or one can input a numerical type:: @@ -1948,9 +1948,9 @@ def sqrt(x, *args, **kwds): To prevent automatic evaluation, one can use the ``hold`` parameter after coercing to the symbolic ring:: - sage: sqrt(SR(4),hold=True) + sage: sqrt(SR(4), hold=True) # optional - sage.symbolic sqrt(4) - sage: sqrt(4,hold=True) + sage: sqrt(4, hold=True) Traceback (most recent call last): ... TypeError: ..._do_sqrt() got an unexpected keyword argument 'hold' From facd551508f3e07dccb39575f64405f265a660a3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 11:45:19 -0700 Subject: [PATCH 153/205] src/sage/structure/formal_sum.py: Re-align # optional --- src/sage/structure/formal_sum.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/sage/structure/formal_sum.py b/src/sage/structure/formal_sum.py index deccad76ed2..835d8c040d9 100644 --- a/src/sage/structure/formal_sum.py +++ b/src/sage/structure/formal_sum.py @@ -104,24 +104,25 @@ def __init__(self, x, parent=None, check=True, reduce=True): sage: a.reduce() sage: a 4*2/3 - 5*7 - sage: FormalSum([(1, 2/3), (3, 2/3), (-5, 7)], parent=FormalSums(GF(5))) # optional - sage.rings.finite_rings + sage: FormalSum([(1, 2/3), (3, 2/3), (-5, 7)], parent=FormalSums(GF(5))) # optional - sage.rings.finite_rings 4*2/3 Notice below that the coefficient 5 doesn't get reduced modulo 5:: - sage: FormalSum([(1,2/3), (3,2/3), (-5, 7)], parent=FormalSums(GF(5)), check=False) # optional - sage.rings.finite_rings + sage: FormalSum([(1, 2/3), (3, 2/3), (-5, 7)], parent=FormalSums(GF(5)), # optional - sage.rings.finite_rings + ....: check=False) 4*2/3 - 5*7 Make sure we first reduce before checking coefficient types:: - sage: x,y = var('x, y') # optional - sage.symbolic - sage: FormalSum([(1/2,x), (2,y)], FormalSums(QQ)) # optional - sage.symbolic + sage: x,y = var('x, y') # optional - sage.symbolic + sage: FormalSum([(1/2,x), (2,y)], FormalSums(QQ)) # optional - sage.symbolic 1/2*x + 2*y - sage: FormalSum([(1/2,x), (2,y)], FormalSums(ZZ)) # optional - sage.symbolic + sage: FormalSum([(1/2,x), (2,y)], FormalSums(ZZ)) # optional - sage.symbolic Traceback (most recent call last): ... TypeError: no conversion of this rational to integer - sage: FormalSum([(1/2,x), (1/2,x), (2,y)], FormalSums(ZZ)) # optional - sage.symbolic + sage: FormalSum([(1/2,x), (1/2,x), (2,y)], FormalSums(ZZ)) # optional - sage.symbolic x + 2*y """ if x == 0: From cd5f1b4d873899267f634986ff43ef5c6958f1cb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 11:49:32 -0700 Subject: [PATCH 154/205] src/sage/structure/parent.pyx: Doctest cosmetics, add # optional --- src/sage/structure/parent.pyx | 85 ++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/src/sage/structure/parent.pyx b/src/sage/structure/parent.pyx index d7bf7971731..f8b4dc2c9c7 100644 --- a/src/sage/structure/parent.pyx +++ b/src/sage/structure/parent.pyx @@ -361,16 +361,22 @@ cdef class Parent(sage.structure.category_object.CategoryObject): EXAMPLES:: sage: P. = QQ[] - sage: Q = P.quotient(x^2+2) + sage: Q = P.quotient(x^2 + 2) sage: Q.category() - Join of Category of commutative rings and Category of subquotients of monoids and Category of quotients of semigroups + Join of + Category of commutative rings and + Category of subquotients of monoids and + Category of quotients of semigroups sage: first_class = Q.__class__ sage: Q._refine_category_(Fields()) sage: Q.category() - Join of Category of fields and Category of subquotients of monoids and Category of quotients of semigroups + Join of + Category of fields and + Category of subquotients of monoids and + Category of quotients of semigroups sage: first_class == Q.__class__ False - sage: TestSuite(Q).run() + sage: TestSuite(Q).run() # optional - sage.libs.singular TESTS: @@ -1077,21 +1083,21 @@ cdef class Parent(sage.structure.category_object.CategoryObject): True sage: I in RR False - sage: SR(2) in ZZ + sage: SR(2) in ZZ # optional - sage.symbolic True sage: RIF(1, 2) in RIF True - sage: pi in RIF # there is no element of RIF equal to pi + sage: pi in RIF # there is no element of RIF equal to pi # optional - sage.symbolic False - sage: sqrt(2) in CC + sage: sqrt(2) in CC # optional - sage.symbolic True - sage: pi in RR + sage: pi in RR # optional - sage.symbolic True - sage: pi in CC + sage: pi in CC # optional - sage.symbolic True - sage: pi in RDF + sage: pi in RDF # optional - sage.symbolic True - sage: pi in CDF + sage: pi in CDF # optional - sage.symbolic True Note that we have @@ -1148,9 +1154,9 @@ cdef class Parent(sage.structure.category_object.CategoryObject): Check that :trac:`24209` is fixed:: - sage: I in QQbar + sage: I in QQbar # optional - sage.rings.number_field True - sage: sqrt(-1) in QQbar + sage: sqrt(-1) in QQbar # optional - sage.rings.number_field sage.symbolic True """ P = parent(x) @@ -2049,8 +2055,8 @@ cdef class Parent(sage.structure.category_object.CategoryObject): cpdef bint has_coerce_map_from(self, S) except -2: """ - Return True if there is a natural map from S to self. - Otherwise, return False. + Return ``True`` if there is a natural map from ``S`` to ``self``. + Otherwise, return ``False``. EXAMPLES:: @@ -2103,12 +2109,12 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: import gc sage: _ = gc.collect() sage: K = GF(1<<55,'t') # optional - sage.rings.finite_rings - sage: for i in range(50): # optional - sage.rings.finite_rings + sage: for i in range(50): # optional - sage.rings.finite_rings sage.schemes ....: a = K.random_element() ....: E = EllipticCurve(j=a) ....: b = K.has_coerce_map_from(E) - sage: _ = gc.collect() # optional - sage.rings.finite_rings - sage: len([x for x in gc.get_objects() if isinstance(x, type(E))]) # optional - sage.rings.finite_rings + sage: _ = gc.collect() + sage: len([x for x in gc.get_objects() if isinstance(x, type(E))]) # optional - sage.rings.finite_rings sage.schemes 1 TESTS: @@ -2116,12 +2122,12 @@ cdef class Parent(sage.structure.category_object.CategoryObject): The following was fixed in :trac:`12969`:: sage: R = QQ['q,t'].fraction_field() - sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) # optional - sage.combinat - sage: H = Sym.macdonald().H() # optional - sage.combinat - sage: P = Sym.macdonald().P() # optional - sage.combinat - sage: m = Sym.monomial() # optional - sage.combinat - sage: Ht = Sym.macdonald().Ht() # optional - sage.combinat - sage: phi = m.coerce_map_from(P) # optional - sage.combinat + sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R) # optional - sage.combinat sage.modules + sage: H = Sym.macdonald().H() # optional - sage.combinat sage.modules + sage: P = Sym.macdonald().P() # optional - sage.combinat sage.modules + sage: m = Sym.monomial() # optional - sage.combinat sage.modules + sage: Ht = Sym.macdonald().Ht() # optional - sage.combinat sage.modules + sage: phi = m.coerce_map_from(P) # optional - sage.combinat sage.modules """ return copy(self._internal_coerce_map_from(S)) @@ -2299,9 +2305,9 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: p = QQ.random_element() # optional - sage.rings.number_field sage: c = phi(p) - p; c # optional - sage.rings.number_field 0 - sage: c.parent() is M + sage: c.parent() is M # optional - sage.rings.number_field True - sage: K.coerce_map_from(QQ) + sage: K.coerce_map_from(QQ) # optional - sage.rings.number_field Coercion map: From: Rational Field To: Number Field in a with defining polynomial x^2 - 2 over its base field @@ -2323,16 +2329,18 @@ cdef class Parent(sage.structure.category_object.CategoryObject): Check that :trac:`14982` is fixed, and more generally that we discover sensible coercion paths in the presence of embeddings:: - sage: K. = NumberField(x^2+1/2, embedding=CC(0,1)) - sage: L = NumberField(x^2+2, 'b', embedding=1/a) - sage: PolynomialRing(L, 'x').coerce_map_from(L) + sage: K. = NumberField(x^2 + 1/2, embedding=CC(0, 1)) # optional - sage.rings.number_field + sage: L = NumberField(x^2 + 2, 'b', embedding=1/a) # optional - sage.rings.number_field + sage: PolynomialRing(L, 'x').coerce_map_from(L) # optional - sage.rings.number_field Polynomial base injection morphism: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a - To: Univariate Polynomial Ring in x over Number Field in b with defining polynomial x^2 + 2 with b = -2*a - sage: PolynomialRing(K, 'x').coerce_map_from(L) + To: Univariate Polynomial Ring in x over Number Field in b + with defining polynomial x^2 + 2 with b = -2*a + sage: PolynomialRing(K, 'x').coerce_map_from(L) # optional - sage.rings.number_field Composite map: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a - To: Univariate Polynomial Ring in x over Number Field in a with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I + To: Univariate Polynomial Ring in x over Number Field in a + with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I Defn: Generic morphism: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a To: Number Field in a with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I @@ -2340,15 +2348,18 @@ cdef class Parent(sage.structure.category_object.CategoryObject): then Polynomial base injection morphism: From: Number Field in a with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I - To: Univariate Polynomial Ring in x over Number Field in a with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I - sage: MatrixSpace(L, 2, 2).coerce_map_from(L) + To: Univariate Polynomial Ring in x over Number Field in a + with defining polynomial x^2 + 1/2 with a = 0.7071067811865475?*I + sage: MatrixSpace(L, 2, 2).coerce_map_from(L) # optional - sage.rings.number_field Coercion map: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a - To: Full MatrixSpace of 2 by 2 dense matrices over Number Field in b with defining polynomial x^2 + 2 with b = -2*a - sage: PowerSeriesRing(L, 'x').coerce_map_from(L) + To: Full MatrixSpace of 2 by 2 dense matrices over Number Field in b + with defining polynomial x^2 + 2 with b = -2*a + sage: PowerSeriesRing(L, 'x').coerce_map_from(L) # optional - sage.rings.number_field Coercion map: From: Number Field in b with defining polynomial x^2 + 2 with b = -2*a - To: Power Series Ring in x over Number Field in b with defining polynomial x^2 + 2 with b = -2*a + To: Power Series Ring in x over Number Field in b + with defining polynomial x^2 + 2 with b = -2*a """ if isinstance(S, Parent) and (S)._embedding is not None: if (S)._embedding.codomain() is self: From c5ae906ecc50773e1aeee0c6a158b21fa86fc9a2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 11:51:58 -0700 Subject: [PATCH 155/205] src/sage/structure/parent_old.pyx: Add # optional --- src/sage/structure/parent_old.pyx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/structure/parent_old.pyx b/src/sage/structure/parent_old.pyx index db7f7bce274..adb70af2b98 100644 --- a/src/sage/structure/parent_old.pyx +++ b/src/sage/structure/parent_old.pyx @@ -13,7 +13,7 @@ TESTS: This came up in some subtle bug once:: - sage: gp(2) + gap(3) # optional - sage.libs.pari + sage: gp(2) + gap(3) # optional - sage.libs.gap sage.libs.pari 5 """ @@ -46,14 +46,14 @@ cdef class Parent(parent.Parent): TESTS:: - sage: V = VectorSpace(GF(2,'a'), 2) # optional - sage.rings.finite_rings - sage: V.list() # optional - sage.rings.finite_rings + sage: V = VectorSpace(GF(2,'a'), 2) # optional - sage.modules sage.rings.finite_rings + sage: V.list() # optional - sage.modules sage.rings.finite_rings [(0, 0), (1, 0), (0, 1), (1, 1)] - sage: MatrixSpace(GF(3), 1, 1).list() # optional - sage.rings.finite_rings + sage: MatrixSpace(GF(3), 1, 1).list() # optional - sage.modules sage.rings.finite_rings [[0], [1], [2]] sage: DirichletGroup(3).list() # optional - sage.groups [Dirichlet character modulo 3 of conductor 1 mapping 2 |--> 1, - Dirichlet character modulo 3 of conductor 3 mapping 2 |--> -1] + Dirichlet character modulo 3 of conductor 3 mapping 2 |--> -1] sage: K = GF(7^6,'a') # optional - sage.rings.finite_rings sage: K.list()[:10] # long time # optional - sage.rings.finite_rings [0, 1, 2, 3, 4, 5, 6, a, a + 1, a + 2] From 4f968a8c1ab9cf5491e18d951598e6e18112ff97 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 11:54:01 -0700 Subject: [PATCH 156/205] src/sage/structure/unique_representation.py: Add # optional --- src/sage/structure/unique_representation.py | 28 ++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/sage/structure/unique_representation.py b/src/sage/structure/unique_representation.py index a0174109283..c6ffa9cb739 100644 --- a/src/sage/structure/unique_representation.py +++ b/src/sage/structure/unique_representation.py @@ -424,10 +424,10 @@ class is directly created, then the cache is not used:: Using :class:`CachedRepresentation` has the advantage that one has a class and creates cached instances of this class by the usual Python syntax:: - sage: G = SymmetricGroup(6) - sage: issubclass(SymmetricGroup, sage.structure.unique_representation.CachedRepresentation) + sage: G = SymmetricGroup(6) # optional - sage.groups + sage: issubclass(SymmetricGroup, sage.structure.unique_representation.CachedRepresentation) # optional - sage.groups True - sage: isinstance(G, SymmetricGroup) + sage: isinstance(G, SymmetricGroup) # optional - sage.groups True In contrast, a factory is just a callable object that returns something that @@ -502,9 +502,9 @@ class :class:`~sage.misc.fast_methods.WithEqualityById`, which provides sage: G3 = G.subgroup([G((1,2,3,4,5,6)), G((1,2))]) # optional - sage.groups sage: G is G3 # optional - sage.groups False - sage: type(G) == type(G3) + sage: type(G) == type(G3) # optional - sage.groups False - sage: G == G3 + sage: G == G3 # optional - sage.groups True The unique representation behaviour can conveniently be implemented with a @@ -517,9 +517,9 @@ class that inherits from :class:`UniqueRepresentation`: By adding ring. Thus, it is reasonable to use :class:`UniqueRepresentation` in this case:: - sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) + sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) # optional - sage.combinat True - sage: issubclass(SymmetricFunctions, UniqueRepresentation) + sage: issubclass(SymmetricFunctions, UniqueRepresentation) # optional - sage.combinat True :class:`UniqueRepresentation` differs from :class:`CachedRepresentation` only @@ -1188,15 +1188,15 @@ class UniqueRepresentation(CachedRepresentation, WithEqualityById): the same memory representation), if and only if they were created using equal arguments. For example, calling twice:: - sage: f = SymmetricFunctions(QQ) # optional - sage.combinat - sage: g = SymmetricFunctions(QQ) # optional - sage.combinat + sage: f = SymmetricFunctions(QQ) # optional - sage.combinat sage.modules + sage: g = SymmetricFunctions(QQ) # optional - sage.combinat sage.modules to create the symmetric function algebra over `\QQ` actually gives back the same object:: - sage: f == g # optional - sage.combinat + sage: f == g # optional - sage.combinat sage.modules True - sage: f is g # optional - sage.combinat + sage: f is g # optional - sage.combinat sage.modules True This is a standard design pattern. It allows for sharing cached data (say @@ -1211,9 +1211,9 @@ class UniqueRepresentation(CachedRepresentation, WithEqualityById): derive from it, or make sure some of its super classes does. Also, it groups together the class and the factory in a single gadget:: - sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) # optional - sage.combinat + sage: isinstance(SymmetricFunctions(CC), SymmetricFunctions) # optional - sage.combinat sage.modules True - sage: issubclass(SymmetricFunctions, UniqueRepresentation) # optional - sage.combinat + sage: issubclass(SymmetricFunctions, UniqueRepresentation) # optional - sage.combinat sage.modules True This nice behaviour is not available when one just uses a factory:: @@ -1223,7 +1223,7 @@ class UniqueRepresentation(CachedRepresentation, WithEqualityById): ... TypeError: isinstance() arg 2 must be a type... - sage: isinstance(GF, sage.structure.factory.UniqueFactory) + sage: isinstance(GF, sage.structure.factory.UniqueFactory) # optional - sage.rings.finite_rings True In addition, :class:`~sage.structure.factory.UniqueFactory` only provides From 5aac3bfb3c1c0d1ebc473acdf6e338cf31ca7bca Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 12:10:54 -0700 Subject: [PATCH 157/205] Fix markup --- src/sage/coding/guruswami_sudan/interpolation.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/coding/guruswami_sudan/interpolation.py b/src/sage/coding/guruswami_sudan/interpolation.py index 0e2e931b3d0..8625bae5b49 100644 --- a/src/sage/coding/guruswami_sudan/interpolation.py +++ b/src/sage/coding/guruswami_sudan/interpolation.py @@ -175,6 +175,7 @@ def _interpolation_matrix_problem(points, tau, parameters, wy): - ``tau`` -- an integer, the number of errors one wants to decode. - ``parameters`` -- (default: ``None``) a pair of integers, where: + - the first integer is the multiplicity parameter of Guruswami-Sudan algorithm and - the second integer is the list size parameter. @@ -370,6 +371,7 @@ def gs_interpolation_lee_osullivan(points, tau, parameters, wy): - ``tau`` -- an integer, the number of errors one wants to decode. - ``parameters`` -- (default: ``None``) a pair of integers, where: + - the first integer is the multiplicity parameter of Guruswami-Sudan algorithm and - the second integer is the list size parameter. From c4a1e418a281d163eef2d9c7e2794f49fdc096d8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 10 Jun 2023 12:17:45 -0700 Subject: [PATCH 158/205] sage.features: Fix some spkg references --- src/sage/features/databases.py | 5 ++--- src/sage/features/dvipng.py | 2 +- src/sage/features/imagemagick.py | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/sage/features/databases.py b/src/sage/features/databases.py index 1447c5beb14..216dbb04af3 100644 --- a/src/sage/features/databases.py +++ b/src/sage/features/databases.py @@ -61,8 +61,7 @@ def __init__(self): class DatabaseCremona(StaticFile): r""" A :class:`~sage.features.Feature` which describes the presence of :ref:`John Cremona's - database of elliptic curves ` - (or its :ref:`small version `. + database of elliptic curves `. INPUT: @@ -74,7 +73,7 @@ class DatabaseCremona(StaticFile): sage: from sage.features.databases import DatabaseCremona sage: DatabaseCremona('cremona_mini').is_present() FeatureTestResult('database_cremona_mini_ellcurve', True) - sage: DatabaseCremona().is_present() # optional - database_cremona_ellcurve + sage: DatabaseCremona().is_present() # optional - database_cremona_ellcurve FeatureTestResult('database_cremona_ellcurve', True) """ def __init__(self, name="cremona", spkg="database_cremona_ellcurve"): diff --git a/src/sage/features/dvipng.py b/src/sage/features/dvipng.py index 270c1b8ede9..281084a6e72 100644 --- a/src/sage/features/dvipng.py +++ b/src/sage/features/dvipng.py @@ -15,7 +15,7 @@ class dvipng(Executable): r""" - A :class:`~sage.features.Feature` describing the presence of :ref:`dvipng `. + A :class:`~sage.features.Feature` describing the presence of ``dvipng`` EXAMPLES:: diff --git a/src/sage/features/imagemagick.py b/src/sage/features/imagemagick.py index 499d29d6f52..fceeed8b727 100644 --- a/src/sage/features/imagemagick.py +++ b/src/sage/features/imagemagick.py @@ -107,7 +107,7 @@ def is_functional(self): class ImageMagick(JoinFeature): r""" A :class:`~sage.features.Feature` describing the presence of - :ref:`ImageMagick _` + :ref:`ImageMagick ` Currently, only the availability of the :class:`convert` program is checked. From 443b7549ad36821e6e54829c8146cdae598ebd57 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sun, 11 Jun 2023 12:24:14 +0200 Subject: [PATCH 159/205] 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' From a29d22e9c9ef69296facbb3503eb1ba34985cdce Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Mon, 12 Jun 2023 13:11:35 +0900 Subject: [PATCH 160/205] Add note on a doctest that randomly behaves --- src/sage/doctest/test.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/sage/doctest/test.py b/src/sage/doctest/test.py index a36b3caf64f..60075a53578 100644 --- a/src/sage/doctest/test.py +++ b/src/sage/doctest/test.py @@ -251,17 +251,24 @@ Even though the doctester master process has exited, the child process is still alive, but it should be killed automatically -after the `die_timeout` given above (10 seconds):: +after the ``die_timeout`` given above (10 seconds):: sage: pid = int(open(F).read()) # long time sage: time.sleep(2) # long time sage: os.kill(pid, signal.SIGQUIT) # long time; 2 seconds passed => still alive sage: time.sleep(8) # long time - sage: os.kill(pid, signal.SIGQUIT) # long time; 10 seconds passed => dead + sage: os.kill(pid, signal.SIGQUIT) # long time; 10 seconds passed => dead # random Traceback (most recent call last): ... ProcessLookupError: ... +If the child process is dead and removed, the last output should be as above. +However, the child process interrupted its parent process (see +``"interrupt_diehard.rst"``), and became an orphan process. Depending on the +system, an orphan process may eventually become a zombie process instead of +being removed, and then the last output would just be a blank. Hence the ``# +random`` tag. + Test a doctest failing with ``abort()``:: sage: subprocess.call(["sage", "-t", "--warn-long", "0", # long time From a6d92ef44c81e87f6cc652e840892a87e4ee8f1b Mon Sep 17 00:00:00 2001 From: marizee Date: Mon, 12 Jun 2023 10:38:56 +0200 Subject: [PATCH 161/205] clarification on the MAX_MODULUS of float matrices --- src/sage/matrix/matrix_modn_dense_double.pyx | 5 +++-- src/sage/matrix/matrix_modn_dense_float.pyx | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sage/matrix/matrix_modn_dense_double.pyx b/src/sage/matrix/matrix_modn_dense_double.pyx index 08fb1c4e989..0c6ca7fee25 100644 --- a/src/sage/matrix/matrix_modn_dense_double.pyx +++ b/src/sage/matrix/matrix_modn_dense_double.pyx @@ -51,8 +51,9 @@ cdef class Matrix_modn_dense_double(Matrix_modn_dense_template): These are matrices with integer entries mod ``n`` represented as floating-point numbers in a 64-bit word for use with LinBox routines. - This allows for ``n`` up to `2^{23}`. The analogous - ``Matrix_modn_dense_float`` class is used for smaller moduli. + This allows for ``n`` up to `2^{23}`. By default, the analogous + ``Matrix_modn_dense_float`` class is used for smaller moduli, specifically + for ``n`` up to `2^{8}`. Routines here are for the most basic access, see the ``matrix_modn_dense_template.pxi`` file for higher-level routines. diff --git a/src/sage/matrix/matrix_modn_dense_float.pyx b/src/sage/matrix/matrix_modn_dense_float.pyx index 90e2409e222..8744cf494e3 100644 --- a/src/sage/matrix/matrix_modn_dense_float.pyx +++ b/src/sage/matrix/matrix_modn_dense_float.pyx @@ -3,7 +3,7 @@ # distutils: library_dirs = CBLAS_LIBDIR # distutils: include_dirs = CBLAS_INCDIR r""" -Dense matrices over `\ZZ/n\ZZ` for `n < 2^{11}` using LinBox's ``Modular`` +Dense matrices over `\ZZ/n\ZZ` for `n < 2^{8}` using LinBox's ``Modular`` AUTHORS: - Burcin Erocal @@ -44,12 +44,13 @@ include "matrix_modn_dense_template.pxi" cdef class Matrix_modn_dense_float(Matrix_modn_dense_template): r""" - Dense matrices over `\ZZ/n\ZZ` for `n < 2^{11}` using LinBox's ``Modular`` + Dense matrices over `\ZZ/n\ZZ` for `n < 2^{8}` using LinBox's ``Modular`` These are matrices with integer entries mod ``n`` represented as floating-point numbers in a 32-bit word for use with LinBox routines. - This allows for ``n`` up to `2^{11}`. The - ``Matrix_modn_dense_double`` class is used for larger moduli. + This could allow for ``n`` up to `2^{11}`, but for performance reasons + this is limited to ``n`` up to `2^{8}`, and for larger moduli the + ``Matrix_modn_dense_double`` class is used. Routines here are for the most basic access, see the ``matrix_modn_dense_template.pxi`` file for higher-level routines. From 0f2967e86bf05694dfd8f4cd8088bd396c9dc665 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Mon, 12 Jun 2023 12:46:37 +0100 Subject: [PATCH 162/205] remove deprecated in #32894 python module interfaces/primecount --- src/sage/interfaces/primecount.py | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 src/sage/interfaces/primecount.py diff --git a/src/sage/interfaces/primecount.py b/src/sage/interfaces/primecount.py deleted file mode 100644 index 518378e1fe2..00000000000 --- a/src/sage/interfaces/primecount.py +++ /dev/null @@ -1,5 +0,0 @@ -from sage.misc.superseded import deprecation -deprecation(32894, "the module sage.interfaces.primecount is deprecated - use primecountpy.primecount instead") -from sage.misc.lazy_import import lazy_import -lazy_import("primecountpy.primecount", ['phi', 'nth_prime', 'prime_pi', 'prime_pi_128'], - deprecation=(32894, "the module sage.interfaces.primecount is deprecated - use primecountpy.primecount instead")) From 2e5d4ce0588dbbfce90de7c1427ed7a2752a448b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 12 Jun 2023 08:40:31 -0700 Subject: [PATCH 163/205] .github/workflows/doc-build.yml: Build docs non-incrementally --- .github/workflows/doc-build.yml | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index dd1a0364fa5..01748c3c823 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -52,19 +52,32 @@ jobs: # Keep track of changes to built HTML (cd /sage/local/share/doc/sage/html/en && find . -name "*.html" | xargs sed -i '/class="sidebar-brand-text"/s/Sage [0-9a-z.]* /Sage dev /'; git init && (echo ".buildinfo"; echo ".inv") > .gitignore; git add -A && git commit --quiet -m "old") - - name: Incremental build and docbuild + - name: Incremental build id: incremental run: | # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. - ./bootstrap && make doc-html + ./bootstrap && make build working-directory: ./worktree-image env: MAKE: make -j2 SAGE_NUM_THREADS: 2 - - name: Build and docbuild (fallback to non-incremental) + - name: Build (fallback to non-incremental) id: build if: always() && steps.worktree.outcome == 'success' && steps.incremental.outcome != 'success' + run: | + set -ex + make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage && ./config.status && make build + working-directory: ./worktree-image + env: + MAKE: make -j2 + SAGE_NUM_THREADS: 2 + + - name: Build docs + id: docbuild + if: always() && (steps.incremental.outcome == 'success' || steps.build.outcome == 'success') + # Always non-incremental because of the concern that + # incremental docbuild may introduce broken links (inter-file references) though build succeeds run: | set -ex make doc-clean doc-uninstall sagelib-clean && git clean -fx src/sage && ./config.status && make doc-html @@ -75,7 +88,7 @@ jobs: - name: Copy docs id: copy - if: always() && (steps.incremental.outcome == 'success' || steps.build.outcome == 'success') + if: always() && steps.docbuild.outcome == 'success' run: | set -ex mkdir -p ./docs From ac1f1fe49b9c104718becfd1f5145b8a4f2534de Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 12 Jun 2023 15:13:39 -0700 Subject: [PATCH 164/205] src/sage/rings/big_oh.py: Fix # optional annotations here - this is doctested in src/sage/doctest/forker.py --- src/sage/rings/big_oh.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/big_oh.py b/src/sage/rings/big_oh.py index 386474cf653..ad43b8fbc84 100644 --- a/src/sage/rings/big_oh.py +++ b/src/sage/rings/big_oh.py @@ -94,7 +94,7 @@ def O(*x, **kwds): sage: A. = AsymptoticRing(growth_group='QQ^n * n^QQ * log(n)^QQ', # optional - sage.symbolic ....: coefficient_ring=QQ); A Asymptotic Ring over Rational Field - sage: O(n) + sage: O(n) # optional - sage.symbolic O(n) Application with Puiseux series:: @@ -108,17 +108,17 @@ def O(*x, **kwds): TESTS:: - sage: var('x, y') + sage: var('x, y') # optional - sage.symbolic (x, y) - sage: O(x) + sage: O(x) # optional - sage.symbolic Traceback (most recent call last): ... ArithmeticError: O(x) not defined - sage: O(y) + sage: O(y) # optional - sage.symbolic Traceback (most recent call last): ... ArithmeticError: O(y) not defined - sage: O(x, y) + sage: O(x, y) # optional - sage.symbolic Traceback (most recent call last): ... ArithmeticError: O(x, y) not defined From 908ad71a143b6c5ac3bc336bb5470f990791923c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 12 Jun 2023 16:44:48 -0700 Subject: [PATCH 165/205] .github/workflows/build.yml: Reword test steps --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2116ef2d515..ea2cb1aa79d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -66,7 +66,7 @@ jobs: if [ ! -f worktree-image/.gitignore ]; then cp .gitignore worktree-image/; fi (cd worktree-image && git add -A && git commit --allow-empty -m "old" -a && git tag -f old && git reset --hard new && git reset old) - - name: Incremental build and test --new + - name: Incremental build, test changed files (sage -t --new) id: incremental run: | # Now re-bootstrap and build. The build is incremental because we were careful with the timestamps. @@ -122,7 +122,7 @@ jobs: # Increase the length of the lines in the "short summary" COLUMNS: 120 - - name: Test --all --long + - name: Test all files (sage -t --all --long) if: always() && (steps.incremental.outcome == 'success' || steps.build.outcome == 'success') run: | ../sage -python -m pip install coverage From d70eb504f47a30422bb3d9cf760f532625ffc2b4 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 13 Jun 2023 11:34:49 +0900 Subject: [PATCH 166/205] Implementing the type B Ish arrangement. --- src/doc/en/reference/references/index.rst | 4 + .../hyperplane_arrangement/library.py | 80 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 52f520395d6..00a20947a30 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -6113,6 +6113,10 @@ REFERENCES: .. [TOPCOM] \J. Rambau, TOPCOM . +.. [TT2023] Tan Nhat Tran and Shuhei Tsujie. + *A type B analog of Ish arrangement*. + Preprint, :arxiv:`2304.12022`. (2023) + .. [TTWL2009] Trebst, Troyer, Wang and Ludwig, A short introduction to Fibonacci anyon models, :arxiv:`0902.3275`. diff --git a/src/sage/geometry/hyperplane_arrangement/library.py b/src/sage/geometry/hyperplane_arrangement/library.py index 4dc33701b56..c037764cc27 100644 --- a/src/sage/geometry/hyperplane_arrangement/library.py +++ b/src/sage/geometry/hyperplane_arrangement/library.py @@ -420,6 +420,86 @@ def Ish(self, n, K=QQ, names=None): A.characteristic_polynomial.set_cache(charpoly) return A + def IshB(self, n, K=QQ, names=None): + r""" + Return the type B Ish arrangement. + + INPUT: + + - ``n`` -- integer + - ``K`` -- field (default:``QQ``) + - ``names`` -- tuple of strings or ``None`` (default); the + variable names for the ambient space + + OUTPUT: + + The type `B` Ish arrangement, which is the set of `2n^2` hyperplanes + + .. MATH:: + + \{ x_i \pm x_j = 0 : 1 \leq i < j \leq n \} + \cup + \{ x_i = a : 1 \leq i\leq n, \quad i - n \leq a \leq n - i + 1 \}. + + + EXAMPLES:: + + sage: a = hyperplane_arrangements.IshB(2) + sage: a + Arrangement of 8 hyperplanes of dimension 2 and rank 2 + sage: a.hyperplanes() + (Hyperplane 0*t0 + t1 - 1, + Hyperplane 0*t0 + t1 + 0, + Hyperplane t0 - t1 + 0, + Hyperplane t0 + 0*t1 - 2, + Hyperplane t0 + 0*t1 - 1, + Hyperplane t0 + 0*t1 + 0, + Hyperplane t0 + 0*t1 + 1, + Hyperplane t0 + t1 + 0) + sage: a.cone().is_free() + True + + .. PLOT:: + :width: 300 px + + a = hyperplane_arrangements.IshB(2) + sphinx_plot(a.plot()) + + :: + + sage: a = hyperplane_arrangements.IshB(3); a + Arrangement of 18 hyperplanes of dimension 3 and rank 3 + sage: a.characteristic_polynomial() + x^3 - 18*x^2 + 108*x - 216 + sage: b = hyperplane_arrangements.Shi(['B', 3]) + sage: b.characteristic_polynomial() + x^3 - 18*x^2 + 108*x - 216 + + TESTS:: + + sage: a.characteristic_polynomial.clear_cache() + sage: a.characteristic_polynomial() + x^3 - 18*x^2 + 108*x - 216 + + REFERENCES: + + - [TT2023]_ + """ + H = make_parent(K, n, names) + x = H.gens() + hyperplanes = [] + for i in range(n): + for j in range(i+1, n): + hyperplanes.append(x[i] - x[j]) + hyperplanes.append(x[i] + x[j]) + for a in range(i+1-n, n-i+1): + hyperplanes.append(x[i] - a) + A = H(*hyperplanes) + x = polygen(QQ, 'x') + charpoly = (x - 2*n) ** n + A.characteristic_polynomial.set_cache(charpoly) + return A + def linial(self, n, K=QQ, names=None): r""" Return the linial hyperplane arrangement. From 6a1d149bb17b7dfc8ec1be58627dc7b54cc977dd Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 13 Jun 2023 13:22:59 +0900 Subject: [PATCH 167/205] Minor tweaks. --- src/sage/geometry/hyperplane_arrangement/library.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/geometry/hyperplane_arrangement/library.py b/src/sage/geometry/hyperplane_arrangement/library.py index c037764cc27..5d0b4aae4d7 100644 --- a/src/sage/geometry/hyperplane_arrangement/library.py +++ b/src/sage/geometry/hyperplane_arrangement/library.py @@ -441,7 +441,6 @@ def IshB(self, n, K=QQ, names=None): \cup \{ x_i = a : 1 \leq i\leq n, \quad i - n \leq a \leq n - i + 1 \}. - EXAMPLES:: sage: a = hyperplane_arrangements.IshB(2) @@ -460,7 +459,7 @@ def IshB(self, n, K=QQ, names=None): True .. PLOT:: - :width: 300 px + :width: 500 px a = hyperplane_arrangements.IshB(2) sphinx_plot(a.plot()) From 79e70569ee8780bc94d32dc59a11b70abd5285be Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 12 Jun 2023 22:33:27 -0700 Subject: [PATCH 168/205] sage.matrix.misc: Split by library dependency --- src/sage/matrix/matrix2.pyx | 8 +- src/sage/matrix/matrix_cyclo_dense.pyx | 2 +- src/sage/matrix/matrix_integer_dense.pyx | 2 +- src/sage/matrix/matrix_integer_sparse.pyx | 12 +- src/sage/matrix/misc.pyx | 179 +--------------------- src/sage/matrix/misc_flint.pyx | 106 +++++++++++++ src/sage/matrix/misc_mpfr.pyx | 79 ++++++++++ 7 files changed, 205 insertions(+), 183 deletions(-) create mode 100644 src/sage/matrix/misc_flint.pyx create mode 100644 src/sage/matrix/misc_mpfr.pyx diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index aa865ee08c3..d5402d5c3b0 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -14883,7 +14883,6 @@ cdef class Matrix(Matrix1): 12215 """ from sage.rings.real_double import RDF - from sage.rings.real_mpfr import RealField try: A = self.change_ring(RDF) m1 = A._hadamard_row_bound() @@ -14891,13 +14890,14 @@ cdef class Matrix(Matrix1): m2 = A._hadamard_row_bound() return min(m1, m2) except (OverflowError, TypeError): + from sage.rings.real_mpfr import RealField # Try using MPFR, which handles large numbers much better, but is slower. - from . import misc + from .misc_mpfr import hadamard_row_bound_mpfr R = RealField(53, rnd='RNDU') A = self.change_ring(R) - m1 = misc.hadamard_row_bound_mpfr(A) + m1 = hadamard_row_bound_mpfr(A) A = A.transpose() - m2 = misc.hadamard_row_bound_mpfr(A) + m2 = hadamard_row_bound_mpfr(A) return min(m1, m2) def find(self,f, indices=False): diff --git a/src/sage/matrix/matrix_cyclo_dense.pyx b/src/sage/matrix/matrix_cyclo_dense.pyx index 363fe637e93..0b78bb7fd78 100644 --- a/src/sage/matrix/matrix_cyclo_dense.pyx +++ b/src/sage/matrix/matrix_cyclo_dense.pyx @@ -63,7 +63,7 @@ from .matrix cimport Matrix from . import matrix_dense from .matrix_integer_dense cimport _lift_crt from sage.structure.element cimport Matrix as baseMatrix -from .misc import matrix_integer_dense_rational_reconstruction +from .misc_flint import matrix_integer_dense_rational_reconstruction from sage.arith.misc import binomial, previous_prime from sage.rings.rational_field import QQ diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index a2c8f46247f..89bd3075db8 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -3410,7 +3410,7 @@ cdef class Matrix_integer_dense(Matrix_dense): ... ZeroDivisionError: The modulus cannot be zero """ - from .misc import matrix_integer_dense_rational_reconstruction + from .misc_flint import matrix_integer_dense_rational_reconstruction return matrix_integer_dense_rational_reconstruction(self, N) def randomize(self, density=1, x=None, y=None, distribution=None, diff --git a/src/sage/matrix/matrix_integer_sparse.pyx b/src/sage/matrix/matrix_integer_sparse.pyx index e8f374d0e71..49ed3403fca 100644 --- a/src/sage/matrix/matrix_integer_sparse.pyx +++ b/src/sage/matrix/matrix_integer_sparse.pyx @@ -399,13 +399,15 @@ cdef class Matrix_integer_sparse(Matrix_sparse): def rational_reconstruction(self, N): """ - Use rational reconstruction to lift self to a matrix over the - rational numbers (if possible), where we view self as a matrix - modulo N. + Use rational reconstruction to lift ``self`` to a matrix over the + rational numbers (if possible), where we view ``self`` as a matrix + modulo `N`. EXAMPLES:: - sage: A = matrix(ZZ, 3, 4, [(1/3)%500, 2, 3, (-4)%500, 7, 2, 2, 3, 4, 3, 4, (5/7)%500], sparse=True) + sage: A = matrix(ZZ, 3, 4, [(1/3)%500, 2, 3, (-4)%500, + ....: 7, 2, 2, 3, + ....: 4, 3, 4, (5/7)%500], sparse=True) sage: A.rational_reconstruction(500) [1/3 2 3 -4] [ 7 2 2 3] @@ -415,7 +417,7 @@ cdef class Matrix_integer_sparse(Matrix_sparse): Check that :trac:`9345` is fixed:: - sage: A = random_matrix(ZZ, 3, 3, sparse = True) + sage: A = random_matrix(ZZ, 3, 3, sparse=True) sage: A.rational_reconstruction(0) Traceback (most recent call last): ... diff --git a/src/sage/matrix/misc.pyx b/src/sage/matrix/misc.pyx index 8d5bd2c9b4c..0512ed193b3 100644 --- a/src/sage/matrix/misc.pyx +++ b/src/sage/matrix/misc.pyx @@ -1,131 +1,33 @@ """ Misc matrix algorithms - -Code goes here mainly when it needs access to the internal structure -of several classes, and we want to avoid circular cimports. - -NOTE: The whole problem of avoiding circular imports -- the reason for -existence of this file -- is now a non-issue, since some bugs in -Cython were fixed. Probably all this code should be moved into the -relevant classes and this file deleted. """ from cysignals.signals cimport sig_check -cimport sage.rings.abc - from sage.arith.misc import CRT_basis, previous_prime from sage.arith.rational_reconstruction cimport mpq_rational_reconstruction from sage.data_structures.binary_search cimport * from sage.ext.mod_int cimport * -from sage.libs.flint.fmpq cimport fmpq_set_mpq, fmpq_canonicalise -from sage.libs.flint.fmpq_mat cimport fmpq_mat_entry_num, fmpq_mat_entry_den, fmpq_mat_entry -from sage.libs.flint.fmpz cimport fmpz_set_mpz, fmpz_one from sage.libs.gmp.mpq cimport * from sage.libs.gmp.mpz cimport * -from sage.libs.mpfr cimport * +from sage.misc.lazy_import import LazyImport from sage.misc.verbose import verbose from sage.modules.vector_integer_sparse cimport * from sage.modules.vector_modn_sparse cimport * from sage.modules.vector_rational_sparse cimport * from sage.rings.integer cimport Integer from sage.rings.rational_field import QQ -from sage.rings.real_mpfr cimport RealNumber from .matrix0 cimport Matrix -from .matrix_integer_dense cimport Matrix_integer_dense from .matrix_integer_sparse cimport Matrix_integer_sparse -from .matrix_rational_dense cimport Matrix_rational_dense from .matrix_rational_sparse cimport Matrix_rational_sparse - -def matrix_integer_dense_rational_reconstruction(Matrix_integer_dense A, Integer N): - """ - Given a matrix over the integers and an integer modulus, do - rational reconstruction on all entries of the matrix, viewed as - numbers mod N. This is done efficiently by assuming there is a - large common factor dividing the denominators. - - INPUT: - - A -- matrix - N -- an integer - - EXAMPLES:: - - sage: B = ((matrix(ZZ, 3,4, [1,2,3,-4,7,2,18,3,4,3,4,5])/3)%500).change_ring(ZZ) - sage: sage.matrix.misc.matrix_integer_dense_rational_reconstruction(B, 500) - [ 1/3 2/3 1 -4/3] - [ 7/3 2/3 6 1] - [ 4/3 1 4/3 5/3] - - TESTS: - - Check that :trac:`9345` is fixed:: - - sage: A = random_matrix(ZZ, 3) - sage: sage.matrix.misc.matrix_integer_dense_rational_reconstruction(A, 0) - Traceback (most recent call last): - ... - ZeroDivisionError: The modulus cannot be zero - """ - if not N: - raise ZeroDivisionError("The modulus cannot be zero") - cdef Matrix_rational_dense R - R = Matrix_rational_dense.__new__(Matrix_rational_dense, - A.parent().change_ring(QQ), 0,0,0) - - cdef mpz_t a, bnd, other_bnd, denom, tmp - cdef mpq_t qtmp - cdef Integer _bnd - cdef Py_ssize_t i, j - cdef int do_it - - mpz_init_set_si(denom, 1) - mpz_init(a) - mpz_init(tmp) - mpz_init(other_bnd) - mpq_init(qtmp) - - _bnd = (N//2).isqrt() - mpz_init_set(bnd, _bnd.value) - mpz_sub(other_bnd, N.value, bnd) - - for i in range(A._nrows): - for j in range(A._ncols): - sig_check() - A.get_unsafe_mpz(i, j, a) - if mpz_cmp_ui(denom, 1) != 0: - mpz_mul(a, a, denom) - mpz_fdiv_r(a, a, N.value) - do_it = 0 - if mpz_cmp(a, bnd) <= 0: - do_it = 1 - elif mpz_cmp(a, other_bnd) >= 0: - mpz_sub(a, a, N.value) - do_it = 1 - if do_it: - fmpz_set_mpz(fmpq_mat_entry_num(R._matrix, i, j), a) - if mpz_cmp_ui(denom, 1) != 0: - fmpz_set_mpz(fmpq_mat_entry_den(R._matrix, i, j), denom) - fmpq_canonicalise(fmpq_mat_entry(R._matrix, i, j)) - else: - fmpz_one(fmpq_mat_entry_den(R._matrix, i, j)) - else: - # Otherwise have to do it the hard way - A.get_unsafe_mpz(i, j, tmp) - mpq_rational_reconstruction(qtmp, tmp, N.value) - mpz_lcm(denom, denom, mpq_denref(qtmp)) - fmpq_set_mpq(fmpq_mat_entry(R._matrix, i, j), qtmp) - - mpz_clear(denom) - mpz_clear(a) - mpz_clear(tmp) - mpz_clear(other_bnd) - mpz_clear(bnd) - mpq_clear(qtmp) - - return R +matrix_integer_dense_rational_reconstruction = \ + LazyImport('sage.matrix.misc_flint', 'matrix_integer_dense_rational_reconstruction', + deprecation=99999) +hadamard_row_bound_mpfr = \ + LazyImport('sage.matrix.misc_mpfr', 'hadamard_row_bound_mpfr', + deprecation=99999) def matrix_integer_sparse_rational_reconstruction(Matrix_integer_sparse A, Integer N): @@ -464,70 +366,3 @@ def cmp_pivots(x, y): return 0 else: return -1 - - -def hadamard_row_bound_mpfr(Matrix A): - """ - Given a matrix A with entries that coerce to RR, compute the row - Hadamard bound on the determinant. - - INPUT: - - A -- a matrix over RR - - OUTPUT: - - integer -- an integer n such that the absolute value of the - determinant of this matrix is at most $10^n$. - - EXAMPLES: - - We create a very large matrix, compute the row Hadamard bound, - and also compute the row Hadamard bound of the transpose, which - happens to be sharp. :: - - sage: a = matrix(ZZ, 2, [2^10000,3^10000,2^50,3^19292]) - sage: import sage.matrix.misc - sage: sage.matrix.misc.hadamard_row_bound_mpfr(a.change_ring(RR)) - 13976 - sage: len(str(a.det())) - 12215 - sage: sage.matrix.misc.hadamard_row_bound_mpfr(a.transpose().change_ring(RR)) - 12215 - - Note that in the above example using RDF would overflow:: - - sage: b = a.change_ring(RDF) - sage: b._hadamard_row_bound() - Traceback (most recent call last): - ... - OverflowError: cannot convert float infinity to integer - """ - if not isinstance(A.base_ring(), sage.rings.abc.RealField): - raise TypeError("A must have base field an mpfr real field.") - - cdef RealNumber a, b - cdef mpfr_t s, d, pr - cdef Py_ssize_t i, j - - mpfr_init(s) - mpfr_init(d) - mpfr_init(pr) - mpfr_set_si(d, 0, MPFR_RNDU) - - for i in range(A._nrows): - mpfr_set_si(s, 0, MPFR_RNDU) - for j in range(A._ncols): - sig_check() - a = A.get_unsafe(i, j) - mpfr_mul(pr, a.value, a.value, MPFR_RNDU) - mpfr_add(s, s, pr, MPFR_RNDU) - mpfr_log10(s, s, MPFR_RNDU) - mpfr_add(d, d, s, MPFR_RNDU) - b = a._new() - mpfr_set(b.value, d, MPFR_RNDU) - b /= 2 - mpfr_clear(s) - mpfr_clear(d) - mpfr_clear(pr) - return b.ceil() diff --git a/src/sage/matrix/misc_flint.pyx b/src/sage/matrix/misc_flint.pyx new file mode 100644 index 00000000000..bcdace773c2 --- /dev/null +++ b/src/sage/matrix/misc_flint.pyx @@ -0,0 +1,106 @@ +r""" +Misc matrix algorithms using FLINT +""" + +from cysignals.signals cimport sig_check + +from sage.arith.rational_reconstruction cimport mpq_rational_reconstruction +from sage.libs.gmp.mpq cimport * +from sage.libs.gmp.mpz cimport * +from sage.libs.flint.fmpq cimport fmpq_set_mpq, fmpq_canonicalise +from sage.libs.flint.fmpq_mat cimport fmpq_mat_entry_num, fmpq_mat_entry_den, fmpq_mat_entry +from sage.libs.flint.fmpz cimport fmpz_set_mpz, fmpz_one +from sage.rings.integer cimport Integer +from sage.rings.rational_field import QQ + +from .matrix_integer_dense cimport Matrix_integer_dense +from .matrix_rational_dense cimport Matrix_rational_dense + + +def matrix_integer_dense_rational_reconstruction(Matrix_integer_dense A, Integer N): + """ + Given a matrix over the integers and an integer modulus, do + rational reconstruction on all entries of the matrix, viewed as + numbers mod N. This is done efficiently by assuming there is a + large common factor dividing the denominators. + + INPUT: + + A -- matrix + N -- an integer + + EXAMPLES:: + + sage: B = ((matrix(ZZ, 3,4, [1,2,3,-4,7,2,18,3,4,3,4,5])/3)%500).change_ring(ZZ) + sage: sage.matrix.misc.matrix_integer_dense_rational_reconstruction(B, 500) + [ 1/3 2/3 1 -4/3] + [ 7/3 2/3 6 1] + [ 4/3 1 4/3 5/3] + + TESTS: + + Check that :trac:`9345` is fixed:: + + sage: A = random_matrix(ZZ, 3) + sage: sage.matrix.misc.matrix_integer_dense_rational_reconstruction(A, 0) + Traceback (most recent call last): + ... + ZeroDivisionError: The modulus cannot be zero + """ + if not N: + raise ZeroDivisionError("The modulus cannot be zero") + cdef Matrix_rational_dense R + R = Matrix_rational_dense.__new__(Matrix_rational_dense, + A.parent().change_ring(QQ), 0,0,0) + + cdef mpz_t a, bnd, other_bnd, denom, tmp + cdef mpq_t qtmp + cdef Integer _bnd + cdef Py_ssize_t i, j + cdef int do_it + + mpz_init_set_si(denom, 1) + mpz_init(a) + mpz_init(tmp) + mpz_init(other_bnd) + mpq_init(qtmp) + + _bnd = (N//2).isqrt() + mpz_init_set(bnd, _bnd.value) + mpz_sub(other_bnd, N.value, bnd) + + for i in range(A._nrows): + for j in range(A._ncols): + sig_check() + A.get_unsafe_mpz(i, j, a) + if mpz_cmp_ui(denom, 1) != 0: + mpz_mul(a, a, denom) + mpz_fdiv_r(a, a, N.value) + do_it = 0 + if mpz_cmp(a, bnd) <= 0: + do_it = 1 + elif mpz_cmp(a, other_bnd) >= 0: + mpz_sub(a, a, N.value) + do_it = 1 + if do_it: + fmpz_set_mpz(fmpq_mat_entry_num(R._matrix, i, j), a) + if mpz_cmp_ui(denom, 1) != 0: + fmpz_set_mpz(fmpq_mat_entry_den(R._matrix, i, j), denom) + fmpq_canonicalise(fmpq_mat_entry(R._matrix, i, j)) + else: + fmpz_one(fmpq_mat_entry_den(R._matrix, i, j)) + else: + # Otherwise have to do it the hard way + A.get_unsafe_mpz(i, j, tmp) + mpq_rational_reconstruction(qtmp, tmp, N.value) + mpz_lcm(denom, denom, mpq_denref(qtmp)) + fmpq_set_mpq(fmpq_mat_entry(R._matrix, i, j), qtmp) + + mpz_clear(denom) + mpz_clear(a) + mpz_clear(tmp) + mpz_clear(other_bnd) + mpz_clear(bnd) + mpq_clear(qtmp) + + return R diff --git a/src/sage/matrix/misc_mpfr.pyx b/src/sage/matrix/misc_mpfr.pyx new file mode 100644 index 00000000000..bcb98868259 --- /dev/null +++ b/src/sage/matrix/misc_mpfr.pyx @@ -0,0 +1,79 @@ +r""" +Misc matrix algorithms using MPFR +""" + +from cysignals.signals cimport sig_check + +cimport sage.rings.abc + +from sage.libs.mpfr cimport * +from sage.rings.real_mpfr cimport RealNumber + +from .matrix0 cimport Matrix + + +def hadamard_row_bound_mpfr(Matrix A): + """ + Given a matrix A with entries that coerce to RR, compute the row + Hadamard bound on the determinant. + + INPUT: + + A -- a matrix over RR + + OUTPUT: + + integer -- an integer n such that the absolute value of the + determinant of this matrix is at most $10^n$. + + EXAMPLES: + + We create a very large matrix, compute the row Hadamard bound, + and also compute the row Hadamard bound of the transpose, which + happens to be sharp. :: + + sage: a = matrix(ZZ, 2, [2^10000,3^10000,2^50,3^19292]) + sage: import sage.matrix.misc + sage: sage.matrix.misc.hadamard_row_bound_mpfr(a.change_ring(RR)) + 13976 + sage: len(str(a.det())) + 12215 + sage: sage.matrix.misc.hadamard_row_bound_mpfr(a.transpose().change_ring(RR)) + 12215 + + Note that in the above example using RDF would overflow:: + + sage: b = a.change_ring(RDF) + sage: b._hadamard_row_bound() + Traceback (most recent call last): + ... + OverflowError: cannot convert float infinity to integer + """ + if not isinstance(A.base_ring(), sage.rings.abc.RealField): + raise TypeError("A must have base field an mpfr real field.") + + cdef RealNumber a, b + cdef mpfr_t s, d, pr + cdef Py_ssize_t i, j + + mpfr_init(s) + mpfr_init(d) + mpfr_init(pr) + mpfr_set_si(d, 0, MPFR_RNDU) + + for i in range(A._nrows): + mpfr_set_si(s, 0, MPFR_RNDU) + for j in range(A._ncols): + sig_check() + a = A.get_unsafe(i, j) + mpfr_mul(pr, a.value, a.value, MPFR_RNDU) + mpfr_add(s, s, pr, MPFR_RNDU) + mpfr_log10(s, s, MPFR_RNDU) + mpfr_add(d, d, s, MPFR_RNDU) + b = a._new() + mpfr_set(b.value, d, MPFR_RNDU) + b /= 2 + mpfr_clear(s) + mpfr_clear(d) + mpfr_clear(pr) + return b.ceil() From a0cf4d77ecf553281654e200bab48de4bca05df9 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 5 Jun 2023 22:31:32 +0200 Subject: [PATCH 169/205] gap: fix a comment --- src/sage/libs/gap/element.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index c5b793424c0..9475f078869 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -169,7 +169,7 @@ cdef char *gap_element_str(Obj obj): cdef Obj make_gap_record(sage_dict) except NULL: """ - Convert Sage lists into Gap lists + Convert Sage dictionary into Gap record INPUT: From c673173a68c9ffa8fb1e0ebe173334f88e772ee4 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 5 Jun 2023 22:32:14 +0200 Subject: [PATCH 170/205] gap: adapt get_global to use official libgap API --- src/sage/libs/gap/libgap.pyx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/libs/gap/libgap.pyx b/src/sage/libs/gap/libgap.pyx index 4157fcb1873..1ac75385071 100644 --- a/src/sage/libs/gap/libgap.pyx +++ b/src/sage/libs/gap/libgap.pyx @@ -539,8 +539,7 @@ class Gap(Parent): ... GAPError: Error, VAL_GVAR: No value bound to FooBar """ - value_global = self.function_factory('ValueGlobal') - return value_global(variable) + return GAP_ValueGlobalVariable(variable) def global_context(self, variable, value): """ From 8bcf6e3c97be53ce3470d11679e6fa9d1a6e659d Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 13 Jun 2023 12:30:32 +0200 Subject: [PATCH 171/205] gap: use CALL_WITH_STREAM to redirect output to string This avoids use of deeply internal GAP APIs which may change at any time. In particular `TypOutputFile` is likely to change again and again. In contrast, `CALL_WITH_STREAM` is on a much higher level (and even reachable from the GAP language itself). We have no plans to change it. --- src/sage/libs/gap/element.pyx | 12 +++++------- src/sage/libs/gap/gap_includes.pxd | 10 +++------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index c5b793424c0..97088603a8a 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -104,8 +104,7 @@ cdef char *capture_stdout(Obj func, Obj obj): print objects such as ``Print()`` and ``ViewObj()``. """ cdef Obj s, stream, output_text_string - cdef UInt res - cdef TypOutputFile output + cdef Obj l # The only way to get a string representation of an object that is truly # consistent with how it would be represented at the GAP REPL is to call # ViewObj on it. Unfortunately, ViewObj *prints* to the output stream, @@ -121,12 +120,11 @@ cdef char *capture_stdout(Obj func, Obj obj): output_text_string = GAP_ValueGlobalVariable("OutputTextString") stream = CALL_2ARGS(output_text_string, s, GAP_True) - if not OpenOutputStream(&output, stream): - raise GAPError("failed to open output capture stream for " - "representing GAP object") + l = GAP_NewPlist(1) + GAP_AssList(l, 1, obj) - CALL_1ARGS(func, obj) - CloseOutput(&output) + CALL_WITH_STREAM = GAP_ValueGlobalVariable("CALL_WITH_STREAM") + CALL_3ARGS(CALL_WITH_STREAM, stream, func, l) return CSTR_STRING(s) finally: GAP_Leave() diff --git a/src/sage/libs/gap/gap_includes.pxd b/src/sage/libs/gap/gap_includes.pxd index 24cd3df21ed..cc0a47dafd2 100644 --- a/src/sage/libs/gap/gap_includes.pxd +++ b/src/sage/libs/gap/gap_includes.pxd @@ -50,13 +50,6 @@ cdef extern from "gap/intobj.h" nogil: Int INT_INTOBJ(Obj) -cdef extern from "gap/io.h" nogil: - ctypedef struct TypOutputFile: - pass - UInt OpenOutputStream(TypOutputFile* output, Obj stream) - UInt CloseOutput(TypOutputFile* output) - - cdef extern from "gap/libgap-api.h" nogil: """ #define sig_GAP_Enter() {int t = GAP_Enter(); if (!t) sig_error();} @@ -89,6 +82,9 @@ cdef extern from "gap/libgap-api.h" nogil: bint GAP_IsList(Obj lst) UInt GAP_LenList(Obj lst) + void GAP_AssList(Obj lst, UInt pos, Obj val) + Obj GAP_ElmList(Obj lst, UInt pos) + Obj GAP_NewPlist(Int capacity) bint GAP_IsRecord(Obj obj) Obj GAP_NewPrecord(Int capacity) From 04bbe60e28b6e52d4fa914806d8624101356a0be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 13 Jun 2023 18:42:31 +0200 Subject: [PATCH 172/205] fix all remaining E251 warnings --- .../endPN_automorphism_group.py | 4 +-- .../arithmetic_dynamics/projective_ds.py | 8 ++--- .../dynamics/arithmetic_dynamics/wehlerK3.py | 22 ++++++------ .../dynamics/complex_dynamics/mandel_julia.py | 36 +++++++++---------- src/sage/modules/free_module.py | 10 +++--- src/sage/modules/submodule.py | 2 +- src/sage/modules/with_basis/morphism.py | 4 +-- 7 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py index 3688fb66623..e8e5ddba1c4 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py @@ -126,7 +126,7 @@ def automorphism_group_QQ_fixedpoints(rational_function, return_functions=False, else: elements = [matrix(F, 2, [1,0,0,1])] - rational_roots = h.roots(multiplicities = False) + rational_roots = h.roots(multiplicities=False) min_poly = 1 @@ -743,7 +743,7 @@ def automorphism_group_QQ_CRT(rational_function, prime_lower_bound=4, return_fun # compute automorphisms mod p phi_p = f.change_ring(GF(p))/g.change_ring(GF(p)) sorted_automorphisms = automorphism_group_FF(phi_p) - sorted_automorphisms.sort(key = PGL_order) + sorted_automorphisms.sort(key=PGL_order) orders = [PGL_order(A) for A in sorted_automorphisms] automorphisms.append(sorted_automorphisms) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index a6220f27801..2f0b963a6dd 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -4519,7 +4519,7 @@ def preperiodic_points(self, m, n, **kwds): # we now deform by a parameter t T = R['t'] t = T.gens()[0] - Pt = ProjectiveSpace(N-1, R=T, names = [str(i) for i in CR.gens()]) + Pt = ProjectiveSpace(N-1, R=T, names=[str(i) for i in CR.gens()]) deformed_polys = [poly + t*Pt.gens()[-1]**d for poly in new_f.defining_polynomials()[:-1]] deformed_polys += [new_f.defining_polynomials()[-1]] f_deformed = DynamicalSystem(deformed_polys) @@ -4869,7 +4869,7 @@ def periodic_points(self, n, minimal=True, formal=False, R=None, algorithm='vari # we now deform by a parameter t T = R['t'] t = T.gens()[0] - Pt = ProjectiveSpace(N-1, R=T, names = [str(i) for i in CR.gens()]) + Pt = ProjectiveSpace(N-1, R=T, names=[str(i) for i in CR.gens()]) deformed_polys = [poly + t*Pt.gens()[-1]**d for poly in new_f.defining_polynomials()[:-1]] deformed_polys += [new_f.defining_polynomials()[-1]] f_deformed = DynamicalSystem(deformed_polys) @@ -5694,7 +5694,7 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', # we now deform by a parameter t T = base_ring['k'] k = T.gens()[0] - Pt = ProjectiveSpace(N, R=T, names = [str(i) for i in CR.gens()]) + Pt = ProjectiveSpace(N, R=T, names=[str(i) for i in CR.gens()]) deformed_polys = [poly + k*Pt.gens()[-1]**d for poly in new_f.defining_polynomials()[:-1]] deformed_polys += [new_f.defining_polynomials()[-1]] f_deformed = DynamicalSystem(deformed_polys) @@ -6331,7 +6331,7 @@ def _is_preperiodic(self, P, err=0.1, return_period=False): # we calculate the canonical height without considering # if the domain is a subscheme - h = f.canonical_height(P, error_bound = err) + h = f.canonical_height(P, error_bound=err) # we know canonical height 0 if and only if preperiodic # however precision issues can occur so we can only tell *not* preperiodic # if the value is larger than the error diff --git a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py index 442bb514561..dde3194df5d 100644 --- a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py +++ b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py @@ -815,7 +815,7 @@ def degenerate_fibers(self): for n in range(3): affvars = list(R0.gens()) del affvars[n] - R1 = PolynomialRing(K, 2, affvars, order = 'lex') + R1 = PolynomialRing(K, 2, affvars, order='lex') mapvars = list(R1.gens()) mapvars.insert(n,1) phi1 = R0.hom(mapvars, R1) @@ -846,7 +846,7 @@ def degenerate_fibers(self): for n in range(3): affvars = list(R0.gens()) del affvars[n] - R1 = PolynomialRing(K, 2, affvars, order = 'lex') + R1 = PolynomialRing(K, 2, affvars, order='lex') mapvars = list(R1.gens()) mapvars.insert(n, 1) phi1 = R0.hom(mapvars,R1) @@ -867,7 +867,7 @@ def degenerate_fibers(self): return [xFibers,yFibers] @cached_method - def degenerate_primes(self,check = True): + def degenerate_primes(self,check=True): r""" Determine which primes `p` self has degenerate fibers over `GF(p)`. @@ -1179,7 +1179,7 @@ def sigmaX(self, P, **kwds): #Defines the ideal whose solution gives `(s0, s1)` and the two points #on the fiber - RR = PolynomialRing(BR, 5,'s0, s1, z0, z1, z2',order = 'lex') + RR = PolynomialRing(BR, 5,'s0, s1, z0, z1, z2',order='lex') s0, s1, z0, z1, z2 = RR.gens() I = RR.ideal([RR(T[0]), RR(T[1]), @@ -1189,7 +1189,7 @@ def sigmaX(self, P, **kwds): RR(T[7]) - (P[1][1]*z2 + P[1][2]*z1)]) #Find the points - SS = PolynomialRing(BR, 4,'s, z0, z1, z2', order = 'lex') + SS = PolynomialRing(BR, 4,'s, z0, z1, z2', order='lex') s, z0, z1, z2 = SS.gens() phi = RR.hom([s, 1, z0, z1, z2], SS) J = phi(I) @@ -1234,7 +1234,7 @@ def sigmaX(self, P, **kwds): SS(newT[7]) - (P[1][1]*z2 + P[1][2]*z1)]) #Find the points - SSS = PolynomialRing(BR, 3, 'z0, z1, z2', order = 'lex') + SSS = PolynomialRing(BR, 3, 'z0, z1, z2', order='lex') z0,z1,z2 = SSS.gens() phi = SS.hom([0, z0, z1, z2], SSS) J2 = phi(II) @@ -1248,7 +1248,7 @@ def sigmaX(self, P, **kwds): [a, b, c] = [V[0][z0], V[0][z1], V[0][z2]] if len(V) == 0 or [a,b,c] == [0, 0, 0]: - SS = PolynomialRing(BR, 3, 'z0, z1, z2', order = 'lex') + SS = PolynomialRing(BR, 3, 'z0, z1, z2', order='lex') z0,z1,z2 = SS.gens() phi = RR.hom([1, 0, z0, z1, z2], SS) J = phi(I) @@ -1430,7 +1430,7 @@ def sigmaY(self,P, **kwds): RR(T[6]) - (P[0][0]*z2 + P[0][2]*z0), RR(T[7]) - (P[0][1]*z2 + P[0][2]*z1)]) #Find the points - SS = PolynomialRing(BR, 4, 's, z0, z1, z2', order = 'lex') + SS = PolynomialRing(BR, 4, 's, z0, z1, z2', order='lex') s, z0, z1, z2 = SS.gens() phi = RR.hom([s, 1, z0, z1, z2], SS) J = phi(I) @@ -1486,7 +1486,7 @@ def sigmaY(self,P, **kwds): if len(V) == 1: [a, b, c] = [V[0][z0], V[0][z1], V[0][z2]] if len(V) == 0 or [a,b,c] == [0, 0, 0]: - SS = PolynomialRing(BR, 3, 'z0, z1, z2', order = 'lex') + SS = PolynomialRing(BR, 3, 'z0, z1, z2', order='lex') z0,z1,z2 = SS.gens() phi = RR.hom([1, 0, z0, z1, z2], SS) J = phi(I) @@ -1584,7 +1584,7 @@ def psi(self,a, **kwds): kwds.update({"check":False}) return self.sigmaX(A, **kwds) - def lambda_plus(self, P, v, N, m, n, prec = 100): + def lambda_plus(self, P, v, N, m, n, prec=100): r""" Evaluates the local canonical height plus function of Call-Silverman at the place ``v`` for ``P`` with ``N`` terms of the series. @@ -1744,7 +1744,7 @@ def lambda_minus(self, P, v, N, m, n, prec=100): local_height = beta*R((PK[1][i]/PK[1][n]).abs()).log() - R((PK[0][j]/PK[0][m]).abs()).log() for e in range(N): #Take the next iterate - Q = W.psi(PK, check = False) + Q = W.psi(PK, check=False) L = [x.abs() for x in list(Q[0])] l = L.index(max(L)) L = [y.abs() for y in list(Q[1])] diff --git a/src/sage/dynamics/complex_dynamics/mandel_julia.py b/src/sage/dynamics/complex_dynamics/mandel_julia.py index d78b29d56fa..7e41c0fca68 100644 --- a/src/sage/dynamics/complex_dynamics/mandel_julia.py +++ b/src/sage/dynamics/complex_dynamics/mandel_julia.py @@ -206,21 +206,21 @@ def mandelbrot_plot(f=None, **kwds): from ipywidgets.widgets import FloatSlider, IntSlider, ColorPicker, interact widgets = dict( - x_center = FloatSlider(min=-1.0, max=1.0, step=EPS, + x_center=FloatSlider(min=-1.0, max=1.0, step=EPS, value=x_center, description="Real center"), - y_center = FloatSlider(min=-1.0, max=1.0, step=EPS, + y_center=FloatSlider(min=-1.0, max=1.0, step=EPS, value=y_center, description="Imag center"), - image_width = FloatSlider(min=EPS, max=4.0, step=EPS, + image_width=FloatSlider(min=EPS, max=4.0, step=EPS, value=image_width, description="Width"), - max_iteration = IntSlider(min=0, max=1000, + max_iteration=IntSlider(min=0, max=1000, value=max_iteration, description="Iterations"), - pixel_count = IntSlider(min=10, max=1000, + pixel_count=IntSlider(min=10, max=1000, value=pixel_count, description="Pixels"), - level_sep = IntSlider(min=1, max=20, + level_sep=IntSlider(min=1, max=20, value=level_sep, description="Color sep"), - color_num = IntSlider(min=1, max=100, + color_num=IntSlider(min=1, max=100, value=number_of_colors, description="# Colors"), - base_color = ColorPicker(value=Color(base_color).html_color(), + base_color=ColorPicker(value=Color(base_color).html_color(), description="Base color"), ) @@ -729,25 +729,25 @@ def julia_plot(f=None, **kwds): from ipywidgets.widgets import FloatSlider, IntSlider, \ ColorPicker, interact widgets = dict( - c_real = FloatSlider(min=-2.0, max=2.0, step=EPS, + c_real=FloatSlider(min=-2.0, max=2.0, step=EPS, value=c_real, description="Real c"), - c_imag = FloatSlider(min=-2.0, max=2.0, step=EPS, + c_imag=FloatSlider(min=-2.0, max=2.0, step=EPS, value=c_imag, description="Imag c"), - x_center = FloatSlider(min=-1.0, max=1.0, step=EPS, + x_center=FloatSlider(min=-1.0, max=1.0, step=EPS, value=x_center, description="Real center"), - y_center = FloatSlider(min=-1.0, max=1.0, step=EPS, + y_center=FloatSlider(min=-1.0, max=1.0, step=EPS, value=y_center, description="Imag center"), - image_width = FloatSlider(min=EPS, max=4.0, step=EPS, + image_width=FloatSlider(min=EPS, max=4.0, step=EPS, value=image_width, description="Width"), - max_iteration = IntSlider(min=0, max=1000, + max_iteration=IntSlider(min=0, max=1000, value=max_iteration, description="Iterations"), - pixel_count = IntSlider(min=10, max=1000, + pixel_count=IntSlider(min=10, max=1000, value=pixel_count, description="Pixels"), - level_sep = IntSlider(min=1, max=20, + level_sep=IntSlider(min=1, max=20, value=level_sep, description="Color sep"), - color_num = IntSlider(min=1, max=100, + color_num=IntSlider(min=1, max=100, value=number_of_colors, description="# Colors"), - base_color = ColorPicker(value=base_color.html_color(), + base_color=ColorPicker(value=base_color.html_color(), description="Base color"), ) if mandelbrot: diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 8b1cc879d27..946c354e764 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -2592,7 +2592,7 @@ def basis_matrix(self, ring=None): except AttributeError: MAT = sage.matrix.matrix_space.MatrixSpace(self.coordinate_ring(), len(self.basis()), self.degree(), - sparse = self.is_sparse()) + sparse=self.is_sparse()) if self.is_ambient(): A = MAT.identity_matrix() else: @@ -5378,7 +5378,7 @@ def _dense_module(self): sage: M is S._dense_module() True """ - return FreeModule(base_ring=self.base_ring(), rank = self.rank(), sparse=False) + return FreeModule(base_ring=self.base_ring(), rank=self.rank(), sparse=False) def _sparse_module(self): """ @@ -5394,7 +5394,7 @@ def _sparse_module(self): sage: M._sparse_module() is S True """ - return FreeModule(base_ring=self.base_ring(), rank = self.rank(), sparse=True) + return FreeModule(base_ring=self.base_ring(), rank=self.rank(), sparse=True) def echelonized_basis_matrix(self): """ @@ -6683,7 +6683,7 @@ def _echelonized_basis(self, ambient, basis): # Return the first rank rows (i.e., the nonzero rows). d = self._denominator(basis) MAT = sage.matrix.matrix_space.MatrixSpace( - ambient.base_ring(), len(basis), ambient.degree(), sparse = ambient.is_sparse()) + ambient.base_ring(), len(basis), ambient.degree(), sparse=ambient.is_sparse()) if d != 1: basis = [x*d for x in basis] A = MAT(basis) @@ -7051,7 +7051,7 @@ def user_to_echelon_matrix(self): rows = sum([self.echelon_coordinates(b,check=False) for b in self.basis()], []) M = sage.matrix.matrix_space.MatrixSpace(self.base_ring().fraction_field(), self.dimension(), - sparse = self.is_sparse()) + sparse=self.is_sparse()) self.__user_to_echelon_matrix = M(rows) return self.__user_to_echelon_matrix diff --git a/src/sage/modules/submodule.py b/src/sage/modules/submodule.py index 4e0d6994f02..3ab5a195f49 100644 --- a/src/sage/modules/submodule.py +++ b/src/sage/modules/submodule.py @@ -165,7 +165,7 @@ def matrix(self): """ from sage.matrix.matrix_space import MatrixSpace MAT = MatrixSpace(self.base_ring(), len(self.gens()), self.degree(), - sparse = self.is_sparse()) + sparse=self.is_sparse()) A = MAT(self.gens()) A.set_immutable() return A diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index 9f51c7f2e7b..d6b4586ce83 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -1127,7 +1127,7 @@ def cokernel_basis_indices(self): raise NotImplementedError("cokernel_basis_indices implemented only for morphisms with a finite dimensional codomain") return [i for i in self.codomain().basis().keys() if self._inverse_on_support(i) is None] - def cokernel_projection(self, category = None): + def cokernel_projection(self, category=None): """ Return a projection on the co-kernel of ``self``. @@ -1517,7 +1517,7 @@ def __invert__(self): """ return self.codomain().module_morphism( diagonal=pointwise_inverse_function(self._diagonal), - codomain=self.domain(), category = self.category_for()) + codomain=self.domain(), category=self.category_for()) def pointwise_inverse_function(f): From 0d78193e041882a1220cfeab8372dec58c59506e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 13 Jun 2023 19:47:02 +0200 Subject: [PATCH 173/205] minor details as suggested --- src/sage/combinat/root_system/weyl_group.py | 4 ++-- src/sage/groups/group.pyx | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/sage/combinat/root_system/weyl_group.py b/src/sage/combinat/root_system/weyl_group.py index 0a4be1eb38f..8495143d726 100644 --- a/src/sage/combinat/root_system/weyl_group.py +++ b/src/sage/combinat/root_system/weyl_group.py @@ -544,7 +544,7 @@ def long_element_hardcoded(self): [twothirds, twothirds, -third]] m = matrix(QQ, 3, l) else: - m = diagonal_matrix([-1 for _ in range(self.n)]) + m = diagonal_matrix([-1] * self.n) return self(m) def classical(self): @@ -554,7 +554,7 @@ def classical(self): Caveat: we assume that 0 is a special node of the Dynkin diagram - TODO: extract parabolic subgroup method + .. TODO:: extract parabolic subgroup method EXAMPLES:: diff --git a/src/sage/groups/group.pyx b/src/sage/groups/group.pyx index 3635c0a1481..872d5c509d7 100644 --- a/src/sage/groups/group.pyx +++ b/src/sage/groups/group.pyx @@ -215,13 +215,11 @@ cdef class Group(Parent): sage: G.an_element() # optional - sage.groups f0*f1*f2*f3 """ - from sage.misc.misc_c import prod return self.prod(self.gens()) def quotient(self, H, **kwds): """ - Return the quotient of this group by the normal subgroup - `H`. + Return the quotient of this group by the normal subgroup `H`. EXAMPLES:: From 71aef7813804d3e051c18aa432e0f029b5099b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 13 Jun 2023 21:20:59 +0200 Subject: [PATCH 174/205] more fixes for superfluous cython imports --- src/sage/algebras/octonion_algebra.pyx | 9 ++++----- src/sage/graphs/hyperbolicity.pyx | 3 +-- src/sage/graphs/strongly_regular_db.pyx | 1 - src/sage/libs/mpmath/ext_libmp.pyx | 2 -- src/sage/matrix/matrix_symbolic_sparse.pyx | 3 +-- src/sage/modular/pollack_stevens/dist.pyx | 16 +++------------- src/sage/numerical/backends/ppl_backend.pyx | 9 +++++---- .../elliptic_curves/descent_two_isogeny.pyx | 2 +- 8 files changed, 15 insertions(+), 30 deletions(-) diff --git a/src/sage/algebras/octonion_algebra.pyx b/src/sage/algebras/octonion_algebra.pyx index 990ee0cd295..562867f0023 100644 --- a/src/sage/algebras/octonion_algebra.pyx +++ b/src/sage/algebras/octonion_algebra.pyx @@ -5,16 +5,15 @@ AUTHORS: - Travis Scrimshaw (2023-05-06): Initial version """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2023 Travis Scrimshaw # # 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.misc.cachefunc import cached_method from sage.misc.functional import sqrt @@ -27,7 +26,7 @@ from sage.modules.free_module import FreeModule from sage.categories.magmatic_algebras import MagmaticAlgebras from sage.categories.rings import Rings from sage.categories.metric_spaces import MetricSpaces -from sage.categories.fields import Fields + cdef class Octonion_generic(AlgebraElement): r""" diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index ff2d20a4d80..fd7a717a2a4 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. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ # **************************************************************************** from libc.string cimport memset @@ -157,7 +157,6 @@ 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.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 diff --git a/src/sage/graphs/strongly_regular_db.pyx b/src/sage/graphs/strongly_regular_db.pyx index 4a72a2da568..3d48b45e58d 100644 --- a/src/sage/graphs/strongly_regular_db.pyx +++ b/src/sage/graphs/strongly_regular_db.pyx @@ -3159,7 +3159,6 @@ def _build_small_srg_database(): from sage.graphs.generators.smallgraphs import M22Graph from sage.graphs.generators.smallgraphs import SimsGewirtzGraph from sage.graphs.generators.smallgraphs import HoffmanSingletonGraph - from sage.graphs.generators.smallgraphs import SchlaefliGraph from sage.graphs.generators.smallgraphs import HigmanSimsGraph from sage.graphs.generators.smallgraphs import IoninKharaghani765Graph from sage.graphs.generators.smallgraphs import JankoKharaghaniGraph diff --git a/src/sage/libs/mpmath/ext_libmp.pyx b/src/sage/libs/mpmath/ext_libmp.pyx index 6f4ab6b2914..5216650e9d3 100644 --- a/src/sage/libs/mpmath/ext_libmp.pyx +++ b/src/sage/libs/mpmath/ext_libmp.pyx @@ -1,10 +1,8 @@ """ 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 diff --git a/src/sage/matrix/matrix_symbolic_sparse.pyx b/src/sage/matrix/matrix_symbolic_sparse.pyx index c03dba4e109..80ba1417285 100644 --- a/src/sage/matrix/matrix_symbolic_sparse.pyx +++ b/src/sage/matrix/matrix_symbolic_sparse.pyx @@ -163,7 +163,6 @@ Check that :issue:`35653` is fixed:: [ 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 @@ -171,7 +170,7 @@ from .constructor import matrix cdef maxima -from sage.calculus.calculus import symbolic_expression_from_maxima_string, maxima +from sage.calculus.calculus import maxima cdef class Matrix_symbolic_sparse(Matrix_generic_sparse): def echelonize(self, **kwds): diff --git a/src/sage/modular/pollack_stevens/dist.pyx b/src/sage/modular/pollack_stevens/dist.pyx index 909d5b4f5cd..f0238bc0f79 100644 --- a/src/sage/modular/pollack_stevens/dist.pyx +++ b/src/sage/modular/pollack_stevens/dist.pyx @@ -18,14 +18,14 @@ REFERENCES: - [PS2011]_ """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012 Robert Pollack # # 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/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.structure.richcmp cimport richcmp_not_equal, rich_to_bool from sage.rings.integer_ring import ZZ @@ -38,20 +38,10 @@ from sage.matrix.constructor import matrix from sage.structure.element cimport Element import operator from sage.rings.padics.padic_generic import pAdicGeneric -from sage.rings.padics.padic_capped_absolute_element cimport pAdicCappedAbsoluteElement -from sage.rings.padics.padic_capped_relative_element cimport pAdicCappedRelativeElement -from sage.rings.padics.padic_fixed_mod_element cimport pAdicFixedModElement from sage.rings.integer cimport Integer from sage.misc.verbose import verbose from sage.rings.infinity import Infinity -from sage.libs.flint.nmod_poly cimport (nmod_poly_init2_preinv, - nmod_poly_set_coeff_ui, - nmod_poly_inv_series, - nmod_poly_mullow, - nmod_poly_pow_trunc, - nmod_poly_get_coeff_ui, nmod_poly_t) - #from sage.libs.flint.ulong_extras cimport * from .sigma0 import Sigma0 diff --git a/src/sage/numerical/backends/ppl_backend.pyx b/src/sage/numerical/backends/ppl_backend.pyx index 1f50c4bdf11..03b54b34359 100644 --- a/src/sage/numerical/backends/ppl_backend.pyx +++ b/src/sage/numerical/backends/ppl_backend.pyx @@ -9,23 +9,24 @@ AUTHORS: constraints and objective function (:trac:`16755`) """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010 Risan # Copyright (C) 2014 Jeroen Demeyer # # 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/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.numerical.mip import MIPSolverException -from ppl import MIP_Problem, Variable, Variables_Set, Linear_Expression, Constraint, Generator +from ppl import MIP_Problem, Variable, Variables_Set, Linear_Expression from sage.rings.integer cimport Integer from sage.rings.rational cimport Rational from .generic_backend cimport GenericBackend from copy import copy + cdef class PPLBackend(GenericBackend): """ diff --git a/src/sage/schemes/elliptic_curves/descent_two_isogeny.pyx b/src/sage/schemes/elliptic_curves/descent_two_isogeny.pyx index 4550db78cbd..59c38c633e8 100644 --- a/src/sage/schemes/elliptic_curves/descent_two_isogeny.pyx +++ b/src/sage/schemes/elliptic_curves/descent_two_isogeny.pyx @@ -13,7 +13,7 @@ Descent on elliptic curves over `\QQ` with a 2-isogeny # *************************************************************************** from cysignals.memory cimport sig_malloc, sig_free -from cysignals.signals cimport sig_on, sig_off +from cysignals.signals cimport sig_on from sage.rings.integer_ring import ZZ from sage.rings.polynomial.polynomial_ring import polygen From 74503097a96b36f5fd0b7794744f9a75e94ab7bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 13 Jun 2023 21:29:36 +0200 Subject: [PATCH 175/205] fixing most E222 warning in py files --- src/sage/algebras/lie_algebras/heisenberg.py | 2 +- src/sage/algebras/splitting_algebra.py | 4 ++-- ...ite_dimensional_lie_algebras_with_basis.py | 2 +- src/sage/coding/punctured_code.py | 2 +- .../orthogonal_arrays_build_recursive.py | 2 +- .../designs/steiner_quadruple_systems.py | 2 +- .../root_system/root_lattice_realizations.py | 4 ++-- src/sage/combinat/root_system/type_D.py | 2 +- src/sage/combinat/sf/llt.py | 2 +- src/sage/combinat/t_sequences.py | 2 +- src/sage/combinat/words/morphic.py | 2 +- src/sage/crypto/cryptosystem.py | 2 +- src/sage/crypto/lwe.py | 4 ++-- src/sage/crypto/mq/rijndael_gf.py | 2 +- src/sage/crypto/mq/sr.py | 6 ++--- src/sage/databases/cremona.py | 2 +- src/sage/databases/knotinfo_db.py | 8 +++---- src/sage/functions/transcendental.py | 2 +- src/sage/geometry/lattice_polytope.py | 2 +- src/sage/geometry/polyhedron/base5.py | 4 ++-- src/sage/geometry/ribbon_graph.py | 2 +- src/sage/graphs/graph_database.py | 6 ++--- .../additive_abelian_group.py | 2 +- src/sage/groups/perm_gps/cubegroup.py | 24 +++++++++---------- src/sage/interfaces/singular.py | 6 ++--- src/sage/interfaces/tides.py | 2 +- src/sage/knots/knotinfo.py | 4 ++-- .../manifolds/differentiable/tensorfield.py | 2 +- src/sage/manifolds/structure.py | 12 +++++----- src/sage/matrix/benchmark.py | 2 +- src/sage/misc/rest_index_of_methods.py | 2 +- .../modular/arithgroup/arithgroup_perm.py | 2 +- src/sage/modular/modform/ring.py | 2 +- .../modular/overconvergent/hecke_series.py | 4 ++-- src/sage/modules/torsion_quadratic_module.py | 2 +- src/sage/quadratic_forms/quadratic_form.py | 4 ++-- .../quadratic_form__siegel_product.py | 2 +- .../quadratic_form__split_local_covering.py | 2 +- src/sage/quadratic_forms/special_values.py | 2 +- src/sage/repl/preparse.py | 2 +- src/sage/rings/function_field/differential.py | 4 ++-- .../rings/number_field/number_field_rel.py | 2 +- .../polynomial/multi_polynomial_ideal.py | 8 +++---- .../polynomial/polynomial_quotient_ring.py | 2 +- src/sage/sat/converters/polybori.py | 2 +- src/sage/symbolic/callable.py | 2 +- src/sage/symbolic/units.py | 2 +- src/sage/tests/benchmark.py | 4 ++-- src/sage/topology/delta_complex.py | 4 ++-- .../topology/simplicial_set_constructions.py | 2 +- 50 files changed, 88 insertions(+), 88 deletions(-) diff --git a/src/sage/algebras/lie_algebras/heisenberg.py b/src/sage/algebras/lie_algebras/heisenberg.py index 4662a3e313f..629fb0a8306 100644 --- a/src/sage/algebras/lie_algebras/heisenberg.py +++ b/src/sage/algebras/lie_algebras/heisenberg.py @@ -261,7 +261,7 @@ def lie_algebra_generators(self): """ if self._n == 0: return Family(['z'], lambda i: self.z()) - k = ['p%s'%i for i in range(1, self._n+1)] + k = ['p%s'%i for i in range(1, self._n+1)] k += ['q%s'%i for i in range(1, self._n+1)] d = {} for i in range(1, self._n+1): diff --git a/src/sage/algebras/splitting_algebra.py b/src/sage/algebras/splitting_algebra.py index 94b3fbc5c24..08a4992d48a 100644 --- a/src/sage/algebras/splitting_algebra.py +++ b/src/sage/algebras/splitting_algebra.py @@ -343,14 +343,14 @@ def __init__(self, monic_polynomial, names='X', iterate=True, warning=True): # ------------------------------------------------------------------ if cf0_inv is not None: deg_cf = len(cf)-1 - pf = P(cf) + pf = P(cf) for root in self._splitting_roots: check = self(pf) if not check.is_zero(): continue root_inv = self.one() for pos in range(deg_cf-1 ): - root_inv = (-1 )**(pos+1 ) * cf[deg_cf-pos-1 ] - root_inv * root + root_inv = (-1 )**(pos+1 ) * cf[deg_cf-pos-1 ] - root_inv * root verbose("inverse %s of root %s" % (root_inv, root)) root_inv = (-1 )**(deg_cf) * cf0_inv * root_inv self._invertible_elements.update({root:root_inv}) diff --git a/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py b/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py index c8ab60cbba1..67181caffa9 100644 --- a/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py @@ -1208,7 +1208,7 @@ def compute_diff(k): zero = [zero] * len(indices) for X in combinations(Ind, k): if not sparse: - ret = list(zero) + ret = list(zero) for i in range(k): Y = list(X) Y.pop(i) diff --git a/src/sage/coding/punctured_code.py b/src/sage/coding/punctured_code.py index 6b99d843f3e..9c5364ab13e 100644 --- a/src/sage/coding/punctured_code.py +++ b/src/sage/coding/punctured_code.py @@ -652,7 +652,7 @@ def decode_to_code(self, y): try: shift = 0 for i in list_pts: - yl[i + shift] = values[shift] + yl[i + shift] = values[shift] shift += 1 y = A(yl) values = next(I) diff --git a/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py b/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py index c5b23da3b91..ff62bae1b8e 100644 --- a/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py +++ b/src/sage/combinat/designs/orthogonal_arrays_build_recursive.py @@ -1404,7 +1404,7 @@ def brouwer_separable_design(k,t,q,x,check=False,verbose=False,explain_construct assert x>=0 assert is_prime_power(q) N2 = q**4+q**2+1 - N1 = q**2+ q +1 + N1 = q**2+ q +1 # A projective plane on (q^2-q+1)*(q^2+q+1)=q^4+q^2+1 points B = difference_family(N2,q**2+1,1)[1][0] diff --git a/src/sage/combinat/designs/steiner_quadruple_systems.py b/src/sage/combinat/designs/steiner_quadruple_systems.py index 8a7ede7af6d..191aa787d1e 100644 --- a/src/sage/combinat/designs/steiner_quadruple_systems.py +++ b/src/sage/combinat/designs/steiner_quadruple_systems.py @@ -718,7 +718,7 @@ def steiner_quadruple_system(n, check=False): elif n == 38: sqs = IncidenceStructure(38, _SQS38(), copy=False, check=False) elif n%12 in [4, 8]: - nn = n // 2 + nn = n // 2 sqs = two_n(steiner_quadruple_system(nn, check=False)) elif n%18 in [4,10]: nn = (n+2) // 3 diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index 84a7b847f43..e2f0757a9ec 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -594,7 +594,7 @@ def roots(self): if not self.cartan_type().is_finite(): from sage.sets.disjoint_union_enumerated_sets \ import DisjointUnionEnumeratedSets - D = DisjointUnionEnumeratedSets([self.positive_roots(), + D = DisjointUnionEnumeratedSets([self.positive_roots(), self.negative_roots()]) D.rename("All roots of type {}".format(self.cartan_type())) return D @@ -1509,7 +1509,7 @@ def simple_reflections(self): sage: s simple reflections """ - res = self.alpha().zip(self.reflection, self.alphacheck()) + res = self.alpha().zip(self.reflection, self.alphacheck()) # Should we use rename to set a nice name for this family? res.rename("simple reflections") return res diff --git a/src/sage/combinat/root_system/type_D.py b/src/sage/combinat/root_system/type_D.py index 94880f6e2c8..4be291b384f 100644 --- a/src/sage/combinat/root_system/type_D.py +++ b/src/sage/combinat/root_system/type_D.py @@ -341,7 +341,7 @@ def ascii_art(self, label=lambda i: i, node=None): if n == 2: ret = "{} {}\n".format(node(label(1)), node(label(2))) return ret + "{!s:4}{!s:4}".format(label(1), label(2)) - ret = (4*(n-3))*" "+"{} {}\n".format(node(label(n)), label(n)) + ret = (4*(n-3))*" "+"{} {}\n".format(node(label(n)), label(n)) ret += ((4*(n-3))*" " +"|\n")*2 ret += "---".join(node(label(i)) for i in range(1, n)) +"\n" ret += "".join("{!s:4}".format(label(i)) for i in range(1,n)) diff --git a/src/sage/combinat/sf/llt.py b/src/sage/combinat/sf/llt.py index 47eca5e9470..7c26b9905cd 100644 --- a/src/sage/combinat/sf/llt.py +++ b/src/sage/combinat/sf/llt.py @@ -256,7 +256,7 @@ def _llt_generic(self, skp, stat): elif isinstance(skp, list) and skp[0] in sage.combinat.skew_partition.SkewPartitions(): #skp is a list of skew partitions - skp2 = [Partition(core=[], quotient=[skp[i][0] for i in range(len(skp))])] + skp2 = [Partition(core=[], quotient=[skp[i][0] for i in range(len(skp))])] skp2 += [Partition(core=[], quotient=[skp[i][1] for i in range(len(skp))])] mu = Partitions(ZZ((skp2[0].size()-skp2[1].size()) / self.level())) skp = skp2 diff --git a/src/sage/combinat/t_sequences.py b/src/sage/combinat/t_sequences.py index 0b967527b8e..8058c1ec548 100644 --- a/src/sage/combinat/t_sequences.py +++ b/src/sage/combinat/t_sequences.py @@ -520,7 +520,7 @@ def T_sequences_smallcases(t, existence=False, check=True): if t in db: if existence: return True - sequences = list(map(Sequence, db[t])) + sequences = list(map(Sequence, db[t])) if check: assert is_T_sequences_set(sequences) return sequences diff --git a/src/sage/combinat/words/morphic.py b/src/sage/combinat/words/morphic.py index 6cca2834ee5..c2f1c525097 100644 --- a/src/sage/combinat/words/morphic.py +++ b/src/sage/combinat/words/morphic.py @@ -207,7 +207,7 @@ def representation(self, n): sage: w.representation(5) [1, 0, 0, 0] """ - letters_to_int = {a:i for (i,a) in enumerate(self._alphabet)} + letters_to_int = {a:i for (i,a) in enumerate(self._alphabet)} position = letters_to_int[self._letter] M = self._morphism.incidence_matrix() vMk = vector([1]*len(self._alphabet)) diff --git a/src/sage/crypto/cryptosystem.py b/src/sage/crypto/cryptosystem.py index b4a1e7c98ea..7ea7884a834 100644 --- a/src/sage/crypto/cryptosystem.py +++ b/src/sage/crypto/cryptosystem.py @@ -207,7 +207,7 @@ def __eq__(self, right): return (type(self) is type(right) and self._cipher_domain == right._cipher_domain and self._cipher_codomain == right._cipher_codomain and - self._key_space == right._key_space and + self._key_space == right._key_space and self._block_length == right._block_length and self._period == right._period) diff --git a/src/sage/crypto/lwe.py b/src/sage/crypto/lwe.py index b15332c84e4..e6928d00213 100644 --- a/src/sage/crypto/lwe.py +++ b/src/sage/crypto/lwe.py @@ -312,7 +312,7 @@ def __init__(self, n, q, D, secret_dist='uniform', m=None): IndexError: Number of available samples exhausted. """ self.n = ZZ(n) - self.m = m + self.m = m self.__i = 0 self.K = IntegerModRing(q) self.FM = FreeModule(self.K, n) @@ -545,7 +545,7 @@ def __init__(self, N, q, D, poly=None, secret_dist='uniform', m=None): """ self.N = ZZ(N) self.n = euler_phi(N) - self.m = m + self.m = m self.__i = 0 self.K = IntegerModRing(q) diff --git a/src/sage/crypto/mq/rijndael_gf.py b/src/sage/crypto/mq/rijndael_gf.py index 6d3ddf988ea..dbf2e0dd5a0 100644 --- a/src/sage/crypto/mq/rijndael_gf.py +++ b/src/sage/crypto/mq/rijndael_gf.py @@ -516,7 +516,7 @@ def __init__(self, Nb, Nk, state_chr='a', key_chr='k'): self._all_PR = PolynomialRing(self._F, len(state_names + subkey_names), state_names + subkey_names) self.state_vrs = matrix(4, self._Nb, self._state_PR.gens()) - fNb = 4 * self._Nb + fNb = 4 * self._Nb self.subkey_vrs_list = list(self._all_PR.gens()[fNb:]) self.subkey_vrs = [matrix(4, self._Nb, self.subkey_vrs_list[fNb * i: fNb * (i + 1)]) diff --git a/src/sage/crypto/mq/sr.py b/src/sage/crypto/mq/sr.py index a79b0868175..f83647f26fc 100644 --- a/src/sage/crypto/mq/sr.py +++ b/src/sage/crypto/mq/sr.py @@ -1804,7 +1804,7 @@ def ring(self, order=None, reverse_variables=None): names += self.varstrs("s", _n, r, e) if reverse_variables: - names += self.varstrs("k", 0, r*c, e) + names += self.varstrs("k", 0, r*c, e) #from sage.rings.polynomial.pbori.pbori import BooleanPolynomialRing @@ -1970,7 +1970,7 @@ def key_schedule_polynomials(self, i): sbox += self.inversion_polynomials( kj[(4*c-3)*e : (4*c-3)*e + e] , si[2*e : 3*e] , e ) sbox += self.inversion_polynomials( kj[(4*c-4)*e : (4*c-4)*e + e] , si[3*e : 4*e] , e ) - si = L * si + d + rc + si = L * si + d + rc Sum = Matrix(R, r*e, 1) lin = [] if c > 1: @@ -3283,7 +3283,7 @@ def inversion_polynomials_single_sbox(self, x=None, w=None, biaffine_only=None, w = P.gens()[:e] S = self.sbox(inversion_only=True) - F = S.polynomials(w, x, degree=e-2, groebner=groebner) + F = S.polynomials(w, x, degree=e-2, groebner=groebner) return F class AllowZeroInversionsContext: diff --git a/src/sage/databases/cremona.py b/src/sage/databases/cremona.py index f6364976dc7..11a081e0ad0 100644 --- a/src/sage/databases/cremona.py +++ b/src/sage/databases/cremona.py @@ -1377,7 +1377,7 @@ def _init_from_ftpdata(self, ftpdata, largest_conductor=0): if largest_conductor: print("largest conductor =", largest_conductor) - self.__largest_conductor__ = largest_conductor + self.__largest_conductor__ = largest_conductor # Since July 2014 the data files have been arranged in # subdirectories (see trac #16903). diff --git a/src/sage/databases/knotinfo_db.py b/src/sage/databases/knotinfo_db.py index 13b83c22be5..91255c564c2 100644 --- a/src/sage/databases/knotinfo_db.py +++ b/src/sage/databases/knotinfo_db.py @@ -45,8 +45,8 @@ class KnotInfoColumnTypes(Enum): , ] """ - OnlyKnots = 'K' # column that is only used in the KnotInfo table - OnlyLinks = 'L' # column that is only used in the LinkInfo table + OnlyKnots = 'K' # column that is only used in the KnotInfo table + OnlyLinks = 'L' # column that is only used in the LinkInfo table KnotsAndLinks = 'B' # column that is only used in both tables @@ -451,7 +451,7 @@ def demo_version(self): num_knots_file = os.path.join(self._sobj_path, self.filename.knots.num_knots(self.version())) from builtins import FileNotFoundError try: - self._num_knots = load(num_knots_file) + self._num_knots = load(num_knots_file) except FileNotFoundError: self.create_filecache() self._demo = False @@ -582,7 +582,7 @@ def _create_data_sobj(self, sobj_path=None): # ---------------------------------------------------------------- # Columns that exist for knots and links # ---------------------------------------------------------------- - column_dict = load('%s/%s' %(sobj_path, self.filename.knots.sobj_column())) + column_dict = load('%s/%s' %(sobj_path, self.filename.knots.sobj_column())) cols = KnotInfoColumns('ColsTemp', column_dict) for col in cols: val_list = [] diff --git a/src/sage/functions/transcendental.py b/src/sage/functions/transcendental.py index 2511d47f13e..63670423fc5 100644 --- a/src/sage/functions/transcendental.py +++ b/src/sage/functions/transcendental.py @@ -444,7 +444,7 @@ def zeta_symmetric(s): if s == 1: # deal with poles, hopefully return R(0.5) - return (s/2 + 1).gamma() * (s-1) * (R.pi()**(-s/2)) * s.zeta() + return (s/2 + 1).gamma() * (s-1) * (R.pi()**(-s/2)) * s.zeta() import math from sage.rings.polynomial.polynomial_real_mpfr_dense import PolynomialRealDense diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index 9ec62336eeb..f7e4e69db63 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -3248,7 +3248,7 @@ def index_of_max(iterable): # This row is smaller than 1st row, so nothing to do del permutations[n_s] continue - permutations[n_s][0] = PGE(S_f, 1, k + 1) * permutations[n_s][0] + permutations[n_s][0] = PGE(S_f, 1, k + 1) * permutations[n_s][0] if d == 0: # This row is the same, so we have a symmetry! n_s += 1 diff --git a/src/sage/geometry/polyhedron/base5.py b/src/sage/geometry/polyhedron/base5.py index decd2fb05a4..906334eda3d 100644 --- a/src/sage/geometry/polyhedron/base5.py +++ b/src/sage/geometry/polyhedron/base5.py @@ -418,7 +418,7 @@ def bipyramid(self): from itertools import chain new_verts = chain(([0] + list(x) for x in self.vertex_generator()), [[1] + list(c), [-1] + list(c)]) - new_rays = ([0] + r for r in self.rays()) + new_rays = ([0] + r for r in self.rays()) new_lines = ([0] + l for l in self.lines()) new_ieqs = chain(([i.b()] + [ c*i.A() + i.b()] + list(i.A()) for i in self.inequalities()), ([i.b()] + [-c*i.A() - i.b()] + list(i.A()) for i in self.inequalities())) @@ -508,7 +508,7 @@ def prism(self): from itertools import chain new_verts = chain(([0] + v for v in self.vertices()), ([1] + v for v in self.vertices())) - new_rays = ([0] + r for r in self.rays()) + new_rays = ([0] + r for r in self.rays()) new_lines = ([0] + l for l in self.lines()) new_eqns = ([e.b()] + [0] + list(e[1:]) for e in self.equations()) new_ieqs = chain(([i.b()] + [0] + list(i[1:]) for i in self.inequalities()), diff --git a/src/sage/geometry/ribbon_graph.py b/src/sage/geometry/ribbon_graph.py index ed41f57f7dd..809d6edba9a 100644 --- a/src/sage/geometry/ribbon_graph.py +++ b/src/sage/geometry/ribbon_graph.py @@ -1221,7 +1221,7 @@ def bipartite_ribbon_graph(p, q): elif (i+1) % q != 0: k = (i+1) % q t = 0 - if (i+1) % q != 0: + if (i+1) % q != 0: t = 1 aux_edge = [i+1, p*q + k*p - ((i+1 + t*q)/q).floor() +1] rho += [aux_edge] diff --git a/src/sage/graphs/graph_database.py b/src/sage/graphs/graph_database.py index 884ad87249c..eb83859c9bc 100644 --- a/src/sage/graphs/graph_database.py +++ b/src/sage/graphs/graph_database.py @@ -180,18 +180,18 @@ def subgraphs_to_query(subgraphs, db): # tables columns input data type sqlite data type # ----------------------------------------------------------------------------- -aut_grp = ['aut_grp_size', # Integer INTEGER +aut_grp = ['aut_grp_size', # Integer INTEGER 'num_orbits', # Integer INTEGER 'num_fixed_points', # Integer INTEGER 'vertex_transitive', # bool BOOLEAN 'edge_transitive'] # bool BOOLEAN -degrees = ['degree_sequence', # list INTEGER (see degseq_to_data module function) +degrees = ['degree_sequence', # list INTEGER (see degseq_to_data module function) 'min_degree', # Integer INTEGER 'max_degree', # Integer INTEGER 'average_degree', # Real REAL 'degrees_sd', # Real REAL 'regular'] # bool BOOLEAN -misc = ['vertex_connectivity', # Integer INTEGER +misc = ['vertex_connectivity', # Integer INTEGER 'edge_connectivity', # Integer INTEGER 'num_components', # Integer INTEGER 'girth', # Integer INTEGER diff --git a/src/sage/groups/additive_abelian/additive_abelian_group.py b/src/sage/groups/additive_abelian/additive_abelian_group.py index 62274a7bfef..de8c4a41656 100644 --- a/src/sage/groups/additive_abelian/additive_abelian_group.py +++ b/src/sage/groups/additive_abelian/additive_abelian_group.py @@ -353,7 +353,7 @@ def exponent(self): if not self.invariants(): return ZZ(1) else: - ann = self.annihilator().gen() + ann = self.annihilator().gen() if ann: return ann return ZZ(0) diff --git a/src/sage/groups/perm_gps/cubegroup.py b/src/sage/groups/perm_gps/cubegroup.py index 3661c2afc10..e23d072de58 100644 --- a/src/sage/groups/perm_gps/cubegroup.py +++ b/src/sage/groups/perm_gps/cubegroup.py @@ -929,15 +929,15 @@ def repr2d(self, mv): """ g = self.parse(mv) lst = self.facets(g) - line1 = " +--------------+\n" - line2 = " |%3d %3d %3d |\n"%(lst[0],lst[1],lst[2]) - line3 = " |%3d top %3d |\n"%(lst[3],lst[4]) - line4 = " |%3d %3d %3d |\n"%(lst[5],lst[6],lst[7]) - line5 = "+------------+--------------+-------------+------------+\n" - line6 = "|%3d %3d %3d |%3d %3d %3d |%3d %3d %3d |%3d %3d %3d |\n"%(lst[8],lst[9],lst[10],lst[16],lst[17],lst[18],lst[24],lst[25],lst[26],lst[32],lst[33],lst[34]) - line7 = "|%3d left%3d |%3d front%3d |%3d right%3d |%3d rear%3d |\n"%(lst[11],lst[12],lst[19],lst[20],lst[27],lst[28],lst[35],lst[36]) - line8 = "|%3d %3d %3d |%3d %3d %3d |%3d %3d %3d |%3d %3d %3d |\n"%(lst[13],lst[14],lst[15],lst[21],lst[22],lst[23],lst[29],lst[30],lst[31],lst[37],lst[38],lst[39]) - line9 = "+------------+--------------+-------------+------------+\n" + line1 = " +--------------+\n" + line2 = " |%3d %3d %3d |\n"%(lst[0],lst[1],lst[2]) + line3 = " |%3d top %3d |\n"%(lst[3],lst[4]) + line4 = " |%3d %3d %3d |\n"%(lst[5],lst[6],lst[7]) + line5 = "+------------+--------------+-------------+------------+\n" + line6 = "|%3d %3d %3d |%3d %3d %3d |%3d %3d %3d |%3d %3d %3d |\n"%(lst[8],lst[9],lst[10],lst[16],lst[17],lst[18],lst[24],lst[25],lst[26],lst[32],lst[33],lst[34]) + line7 = "|%3d left%3d |%3d front%3d |%3d right%3d |%3d rear%3d |\n"%(lst[11],lst[12],lst[19],lst[20],lst[27],lst[28],lst[35],lst[36]) + line8 = "|%3d %3d %3d |%3d %3d %3d |%3d %3d %3d |%3d %3d %3d |\n"%(lst[13],lst[14],lst[15],lst[21],lst[22],lst[23],lst[29],lst[30],lst[31],lst[37],lst[38],lst[39]) + line9 = "+------------+--------------+-------------+------------+\n" line10 = " |%3d %3d %3d |\n"%(lst[40],lst[41],lst[42]) line11 = " |%3d bottom%3d |\n"%(lst[43],lst[44]) line12 = " |%3d %3d %3d |\n"%(lst[45],lst[46],lst[47]) @@ -1002,9 +1002,9 @@ def plot3d_cube(self, mv, title=True): cubeU = sum(cubiesU) cubiesF = [plot3d_cubie(cubie_centers(c),cubie_colors(c,state)) for c in [22,23,24,20,21]] cubeF = sum(cubiesF) - centerR = polygon_plot3d([[1,3,1],[2,3,1],[2,3,2],[1,3,2],[1,3,1]],rgbcolor=green) - centerF = polygon_plot3d([[3,1,1],[3,2,1],[3,2,2],[3,1,2],[3,1,1]],rgbcolor=red) - centerU = polygon_plot3d([[1,1,3],[1,2,3],[2,2,3],[2,1,3],[1,1,3]],rgbcolor=lpurple) + centerR = polygon_plot3d([[1,3,1],[2,3,1],[2,3,2],[1,3,2],[1,3,1]],rgbcolor=green) + centerF = polygon_plot3d([[3,1,1],[3,2,1],[3,2,2],[3,1,2],[3,1,1]],rgbcolor=red) + centerU = polygon_plot3d([[1,1,3],[1,2,3],[2,2,3],[2,1,3],[1,1,3]],rgbcolor=lpurple) centers = centerF+centerR+centerU P = cubeR+cubeF+cubeU+centers P.axes(show=False) diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py index 91a4abd7713..b15cc1c602c 100644 --- a/src/sage/interfaces/singular.py +++ b/src/sage/interfaces/singular.py @@ -1906,7 +1906,7 @@ def sage_poly(self, R=None, kcache=None): exp = int(0) if monomial not in ['1', '(1.000e+00)']: - term = monomial.split("^") + term = monomial.split("^") if len(term)==int(2): exp = int(term[1]) else: @@ -2060,7 +2060,7 @@ def _sage_(self, R=None): elif typ == 'intmat': from sage.matrix.constructor import matrix from sage.rings.integer_ring import ZZ - A = matrix(ZZ, int(self.nrows()), int(self.ncols())) + A = matrix(ZZ, int(self.nrows()), int(self.ncols())) for i in range(A.nrows()): for j in range(A.ncols()): A[i,j] = sage.rings.integer.Integer(str(self[i+1,j+1])) @@ -2496,7 +2496,7 @@ class SingularGBLogPrettyPrinter: cri_hilb = re.compile("h") # used Hilbert series criterion hig_corn = re.compile(r"H\(\d+\)") # found a 'highest corner' of degree d, no need to consider higher degrees num_crit = re.compile(r"\(\d+\)") # n critical pairs are still to be reduced - red_num = re.compile(r"\(S:\d+\)") # doing complete reduction of n elements + red_num = re.compile(r"\(S:\d+\)") # doing complete reduction of n elements deg_lead = re.compile(r"\d+") # the degree of the leading terms is currently d # SlimGB diff --git a/src/sage/interfaces/tides.py b/src/sage/interfaces/tides.py index ff3861dd223..bb48e4a2fd8 100644 --- a/src/sage/interfaces/tides.py +++ b/src/sage/interfaces/tides.py @@ -851,7 +851,7 @@ def genfiles_mpfr(integrator, driver, f, ics, initial, final, delta, VAR = n-1 PAR = len(parameters) - TT = len(code)+1-VAR + TT = len(code)+1-VAR outfile = open(integrator, 'a') diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 19e2589af9d..2b8ddf86ff3 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -2315,7 +2315,7 @@ def list(self, oriented=False, comp=None, det=None, homfly=None): if K.crossing_number() != cross_nr: continue if not is_knot or cross_nr > 10: - if K.is_alternating() != is_alt: + if K.is_alternating() != is_alt: continue if is_knot or oriented: res.append(K) @@ -2475,7 +2475,7 @@ def _name(self): """ is_knot = self._is_knot cross_nr = self._crossing_number - is_alt = self._is_alternating + is_alt = self._is_alternating n_unori = self._name_unoriented alt = 'a' diff --git a/src/sage/manifolds/differentiable/tensorfield.py b/src/sage/manifolds/differentiable/tensorfield.py index 8d42b2994d7..861b05c1d1b 100644 --- a/src/sage/manifolds/differentiable/tensorfield.py +++ b/src/sage/manifolds/differentiable/tensorfield.py @@ -4174,7 +4174,7 @@ def divergence(self, metric=None): metric = self._domain.metric() nabla = metric.connection() if n_cov == 0: - resu = nabla(self).trace(n_con-1, n_con) + resu = nabla(self).trace(n_con-1, n_con) else: tup = self.up(metric, self._tensor_rank-1) resu = nabla(tup).trace(n_con, self._tensor_rank) diff --git a/src/sage/manifolds/structure.py b/src/sage/manifolds/structure.py index 688e4c46833..dd9fc2a3f8a 100644 --- a/src/sage/manifolds/structure.py +++ b/src/sage/manifolds/structure.py @@ -93,7 +93,7 @@ class DifferentialStructure(Singleton): chart = DiffChart name = "differentiable" scalar_field_algebra = DiffScalarFieldAlgebra - homset = DifferentiableManifoldHomset + homset = DifferentiableManifoldHomset def subcategory(self, cat): """ @@ -118,7 +118,7 @@ class RealDifferentialStructure(Singleton): chart = RealDiffChart name = "differentiable" scalar_field_algebra = DiffScalarFieldAlgebra - homset = DifferentiableManifoldHomset + homset = DifferentiableManifoldHomset def subcategory(self, cat): """ @@ -142,7 +142,7 @@ class PseudoRiemannianStructure(Singleton): chart = RealDiffChart name = "pseudo-Riemannian" scalar_field_algebra = DiffScalarFieldAlgebra - homset = DifferentiableManifoldHomset + homset = DifferentiableManifoldHomset def subcategory(self, cat): """ @@ -166,7 +166,7 @@ class RiemannianStructure(Singleton): chart = RealDiffChart name = "Riemannian" scalar_field_algebra = DiffScalarFieldAlgebra - homset = DifferentiableManifoldHomset + homset = DifferentiableManifoldHomset def subcategory(self, cat): """ @@ -190,7 +190,7 @@ class LorentzianStructure(Singleton): chart = RealDiffChart name = "Lorentzian" scalar_field_algebra = DiffScalarFieldAlgebra - homset = DifferentiableManifoldHomset + homset = DifferentiableManifoldHomset def subcategory(self, cat): """ @@ -214,7 +214,7 @@ class DegenerateStructure(Singleton): chart = RealDiffChart name = "degenerate_metric" scalar_field_algebra = DiffScalarFieldAlgebra - homset = DifferentiableManifoldHomset + homset = DifferentiableManifoldHomset def subcategory(self, cat): """ diff --git a/src/sage/matrix/benchmark.py b/src/sage/matrix/benchmark.py index 751b89c5cc3..40675c3f615 100644 --- a/src/sage/matrix/benchmark.py +++ b/src/sage/matrix/benchmark.py @@ -898,7 +898,7 @@ def hilbert_matrix(n): A = Matrix(QQ,n,n) for i in range(A.nrows()): for j in range(A.ncols()): - A[i,j] = QQ(1)/((i+1)+(j+1)-1) + A[i,j] = QQ(1)/((i+1)+(j+1)-1) return A # Reduced row echelon form over QQ diff --git a/src/sage/misc/rest_index_of_methods.py b/src/sage/misc/rest_index_of_methods.py index 5efb863ead3..2ddea66c2db 100644 --- a/src/sage/misc/rest_index_of_methods.py +++ b/src/sage/misc/rest_index_of_methods.py @@ -255,7 +255,7 @@ def local_filter(f,name): else: return inspect.isclass(root) or not (f is gen_rest_table_index) - functions = {getattr(root,name):name for name,f in root.__dict__.items() if + functions = {getattr(root,name):name for name,f in root.__dict__.items() if (not name.startswith('_') and # private functions not hasattr(f,'issue_number') and # deprecated functions not inspect.isclass(f) and # classes diff --git a/src/sage/modular/arithgroup/arithgroup_perm.py b/src/sage/modular/arithgroup/arithgroup_perm.py index 8d2c2f1a19e..4645a2b0716 100644 --- a/src/sage/modular/arithgroup/arithgroup_perm.py +++ b/src/sage/modular/arithgroup/arithgroup_perm.py @@ -395,7 +395,7 @@ def ArithmeticSubgroup_Permutation( S3 = L * ~R elif S2 is not None: # initialize from L,S2 if S3 is None: - S3 = ~S2 * ~L + S3 = ~S2 * ~L if R is None: R = ~S2 * ~L * S2 elif S3 is not None: # initialize from L,S3 diff --git a/src/sage/modular/modform/ring.py b/src/sage/modular/modform/ring.py index f98a0b0adf8..90e149340e4 100644 --- a/src/sage/modular/modform/ring.py +++ b/src/sage/modular/modform/ring.py @@ -1060,7 +1060,7 @@ def cuspidal_ideal_generators(self, maxweight=8, prec=None): # we may need to increase the precision of the cached cusp # generators - G = [] + G = [] for j,f,F in self.__cached_cusp_gens: if f.prec() >= working_prec: f = F.qexp(working_prec).change_ring(self.base_ring()) diff --git a/src/sage/modular/overconvergent/hecke_series.py b/src/sage/modular/overconvergent/hecke_series.py index 2da21b57b77..f9c18c87043 100644 --- a/src/sage/modular/overconvergent/hecke_series.py +++ b/src/sage/modular/overconvergent/hecke_series.py @@ -925,8 +925,8 @@ def katz_expansions(k0, p, ellp, mdash, n): S = Zmod(p ** mdash) Ep1 = eisenstein_series_qexp(p - 1, ellp, K=S, normalization="constant") - E4 = eisenstein_series_qexp(4, ellp, K=S, normalization="constant") - E6 = eisenstein_series_qexp(6, ellp, K=S, normalization="constant") + E4 = eisenstein_series_qexp(4, ellp, K=S, normalization="constant") + E6 = eisenstein_series_qexp(6, ellp, K=S, normalization="constant") delta = delta_qexp(ellp, K=S) h = delta / E6 ** 2 diff --git a/src/sage/modules/torsion_quadratic_module.py b/src/sage/modules/torsion_quadratic_module.py index 0f1a92d8c56..1b9825703f3 100644 --- a/src/sage/modules/torsion_quadratic_module.py +++ b/src/sage/modules/torsion_quadratic_module.py @@ -885,7 +885,7 @@ def orthogonal_group(self, gens=None, check=False): pass # the ambient knows what to do with the generators gens = tuple(ambient(g) for g in gens) - Oq = FqfOrthogonalGroup(ambient, gens, self, check=check) + Oq = FqfOrthogonalGroup(ambient, gens, self, check=check) return Oq def orthogonal_submodule_to(self, S): diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index 4b9380475d8..9dc3c506ee5 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -780,7 +780,7 @@ def __getitem__(self, ij): """ # Unpack the list of indices - i, j = ij + i, j = ij i = int(i) j = int(j) @@ -813,7 +813,7 @@ def __setitem__(self, ij, coeff): """ # Unpack the list of indices - i, j = ij + i, j = ij i = int(i) j = int(j) diff --git a/src/sage/quadratic_forms/quadratic_form__siegel_product.py b/src/sage/quadratic_forms/quadratic_form__siegel_product.py index 1ac027a6331..fd5f539c36b 100644 --- a/src/sage/quadratic_forms/quadratic_form__siegel_product.py +++ b/src/sage/quadratic_forms/quadratic_form__siegel_product.py @@ -111,7 +111,7 @@ def siegel_product(self, u): factor1 *= i genericfactor = factor1 * ((u / f) ** m) \ - * QQ(sqrt((2 ** n) * f) / (u * d)) \ + * QQ(sqrt((2 ** n) * f) / (u * d)) \ * abs(QuadraticBernoulliNumber(m, d1) / bernoulli(2*m)) # DIAGNOSTIC diff --git a/src/sage/quadratic_forms/quadratic_form__split_local_covering.py b/src/sage/quadratic_forms/quadratic_form__split_local_covering.py index 015a96bc09c..65076096db2 100644 --- a/src/sage/quadratic_forms/quadratic_form__split_local_covering.py +++ b/src/sage/quadratic_forms/quadratic_form__split_local_covering.py @@ -236,7 +236,7 @@ def vectors_by_length(self, bound): Q_val = Q_val_double.round() # SANITY CHECK: Roundoff Error is < 0.001 - if abs(Q_val_double - Q_val) > 0.001: + if abs(Q_val_double - Q_val) > 0.001: print(" x = ", x) print(" Float = ", Q_val_double, " Long = ", Q_val) raise RuntimeError("The roundoff error is bigger than 0.001, so we should use more precision somewhere...") diff --git a/src/sage/quadratic_forms/special_values.py b/src/sage/quadratic_forms/special_values.py index 8374ab845dd..99e2152dfcf 100644 --- a/src/sage/quadratic_forms/special_values.py +++ b/src/sage/quadratic_forms/special_values.py @@ -188,7 +188,7 @@ def QuadraticBernoulliNumber(k, d): f = abs(d1) # Make the (usual) k-th Bernoulli polynomial - x = PolynomialRing(QQ, 'x').gen() + x = PolynomialRing(QQ, 'x').gen() bp = bernoulli_polynomial(x, k) # Make the k-th quadratic Bernoulli number diff --git a/src/sage/repl/preparse.py b/src/sage/repl/preparse.py index 24a20be32e2..aa847aca3e8 100644 --- a/src/sage/repl/preparse.py +++ b/src/sage/repl/preparse.py @@ -1079,7 +1079,7 @@ def parse_ellipsis(code, preparse_step=True): if preparse_step: arguments = arguments.replace(';', ', step=') range_or_iter = 'range' if code[start_list]=='[' else 'iter' - code = "%s(ellipsis_%s(%s))%s" % (code[:start_list], + code = "%s(ellipsis_%s(%s))%s" % (code[:start_list], range_or_iter, arguments, code[end_list:]) diff --git a/src/sage/rings/function_field/differential.py b/src/sage/rings/function_field/differential.py index 24ea2371040..be0b4b52104 100644 --- a/src/sage/rings/function_field/differential.py +++ b/src/sage/rings/function_field/differential.py @@ -132,7 +132,7 @@ def _repr_(self): if self._f.is_zero(): # zero differential return '0' - r = 'd({})'.format(self.parent()._gen_base_differential) + r = 'd({})'.format(self.parent()._gen_base_differential) if self._f.is_one(): return r @@ -154,7 +154,7 @@ def _latex_(self): if self._f.is_zero(): # zero differential return '0' - r = 'd{}'.format(self.parent()._gen_base_differential) + r = 'd{}'.format(self.parent()._gen_base_differential) if self._f.is_one(): return r diff --git a/src/sage/rings/number_field/number_field_rel.py b/src/sage/rings/number_field/number_field_rel.py index 838bfd570d7..c81d5ec67f4 100644 --- a/src/sage/rings/number_field/number_field_rel.py +++ b/src/sage/rings/number_field/number_field_rel.py @@ -323,7 +323,7 @@ def __init__(self, base, polynomial, name, embedding=embedding, structure=structure) self._zero_element = self(0) - self._one_element = self(1) + self._one_element = self(1) def change_names(self, names): r""" diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 98171e337cd..7bf29415157 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -817,10 +817,10 @@ def complete_primary_decomposition(self, algorithm="sy"): from sage.libs.singular.function_factory import ff if algorithm == 'sy': - primdecSY = ff.primdec__lib.primdecSY + primdecSY = ff.primdec__lib.primdecSY P = primdecSY(self) elif algorithm == 'gtz': - primdecGTZ = ff.primdec__lib.primdecGTZ + primdecGTZ = ff.primdec__lib.primdecGTZ P = primdecGTZ(self) R = self.ring() @@ -1117,7 +1117,7 @@ def triangular_decomposition(self, algorithm=None, singular=singular_default): # the Singular routines are quite picky about their input. if is_groebner: if Q == P: - I = MPolynomialIdeal(P, self.interreduced_basis()[::-1]) + I = MPolynomialIdeal(P, self.interreduced_basis()[::-1]) else: I = self I = MPolynomialIdeal(P, I.transformed_basis('fglm')[::-1]) # -> 'lex' @@ -1463,7 +1463,7 @@ def _groebner_basis_singular(self, algorithm="groebner", *args, **kwds): R = self.ring() S = self._groebner_basis_singular_raw(algorithm=algorithm, *args, **kwds) - S = PolynomialSequence([R(S[i+1]) for i in range(len(S))], R, immutable=True) + S = PolynomialSequence([R(S[i+1]) for i in range(len(S))], R, immutable=True) return S @cached_method diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index f30f9c58885..85b8d380d8c 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -2017,7 +2017,7 @@ def _isomorphic_ring(self): lambda f: f.lift().map_coefficients(base_to_isomorphic_base)(isomorphic_quotient.gen())) return (from_isomorphic_quotient * isomorphic_ring_to_isomorphic_quotient, - isomorphic_quotient_to_isomorphic_ring * to_isomorphic_quotient, + isomorphic_quotient_to_isomorphic_ring * to_isomorphic_quotient, isomorphic_ring) if self.modulus().degree() == 1: diff --git a/src/sage/sat/converters/polybori.py b/src/sage/sat/converters/polybori.py index a53c4e650e3..ca39def12c1 100644 --- a/src/sage/sat/converters/polybori.py +++ b/src/sage/sat/converters/polybori.py @@ -473,7 +473,7 @@ def split_xor(self, monomial_list, equal_zero): new_variables = [] for j in range(0, nm, step): - m = new_variables + monomial_list[j:j+step] + m = new_variables + monomial_list[j:j+step] if (j + step) < nm: new_variables = [self.var(None)] m += new_variables diff --git a/src/sage/symbolic/callable.py b/src/sage/symbolic/callable.py index 4bd17c0ae4e..787d151b38e 100644 --- a/src/sage/symbolic/callable.py +++ b/src/sage/symbolic/callable.py @@ -429,7 +429,7 @@ def _latex_element_(self, x): from sage.misc.latex import latex args = self.args() args = [latex(arg) for arg in args] - latex_x = SymbolicRing._latex_element_(self, x) + latex_x = SymbolicRing._latex_element_(self, x) if len(args) == 1: return r"%s \ {\mapsto}\ %s" % (args[0], latex_x) else: diff --git a/src/sage/symbolic/units.py b/src/sage/symbolic/units.py index d0a2d84a26a..d01c2a894e3 100644 --- a/src/sage/symbolic/units.py +++ b/src/sage/symbolic/units.py @@ -99,7 +99,7 @@ # Unit conversions dictionary. ############################################################################### -unitdict = { +unitdict = { 'acceleration': {'gal':'1/100', 'galileo':'1/100', diff --git a/src/sage/tests/benchmark.py b/src/sage/tests/benchmark.py index c85e380c530..f6f0ef6fce6 100644 --- a/src/sage/tests/benchmark.py +++ b/src/sage/tests/benchmark.py @@ -410,7 +410,7 @@ def __init__(self, nvars=2, base=QQ, allow_singular=True): self.nvars = nvars self.base = base self.allow_singular = allow_singular - s = 'Compute (x_0 + ... + x_%s) * (x_%s + ... + x_%s) over %s'%( + s = 'Compute (x_0 + ... + x_%s) * (x_%s + ... + x_%s) over %s'%( self.nvars/2 - 1, self.nvars/2, self.nvars, self.base) if self.allow_singular: s += ' (use singular for Sage mult.)' @@ -563,7 +563,7 @@ def __init__(self, nvars=2, base=QQ, allow_singular=True): self.nvars = nvars self.base = base self.allow_singular = allow_singular - s = 'Compute (x_1 + 2*x_2 + 3*x_3 + ... + %s*x_%s) * (%s * x_%s + ... + %s*x_%s) over %s'%( + s = 'Compute (x_1 + 2*x_2 + 3*x_3 + ... + %s*x_%s) * (%s * x_%s + ... + %s*x_%s) over %s'%( self.nvars/2, self.nvars/2, self.nvars/2+1, self.nvars/2+1, self.nvars+1, self.nvars+1, self.base) if self.allow_singular: diff --git a/src/sage/topology/delta_complex.py b/src/sage/topology/delta_complex.py index d4430d074b0..ee8f8678214 100644 --- a/src/sage/topology/delta_complex.py +++ b/src/sage/topology/delta_complex.py @@ -1384,9 +1384,9 @@ def _epi_from_standard_simplex(self, idx=-1, dim=None): for cell in n_cells: if n > 1: faces = [tuple(simplex_cells[n-1][cell[j]]) for j in range(0,n+1)] - one_cell = dict(zip(faces, self_cells[n][n_cells[cell]])) + one_cell = dict(zip(faces, self_cells[n][n_cells[cell]])) else: - temp = dict(zip(cell, self_cells[n][n_cells[cell]])) + temp = dict(zip(cell, self_cells[n][n_cells[cell]])) one_cell = {} for j in temp: one_cell[(j,)] = temp[j] diff --git a/src/sage/topology/simplicial_set_constructions.py b/src/sage/topology/simplicial_set_constructions.py index a4cc87ef3ac..9a378058fc5 100644 --- a/src/sage/topology/simplicial_set_constructions.py +++ b/src/sage/topology/simplicial_set_constructions.py @@ -499,7 +499,7 @@ def __init__(self, maps=None): # the product. translate = {} for simplices in itertools.product(*nondegen): - dims = [_.dimension() for _ in simplices] + dims = [_.dimension() for _ in simplices] dim_max = max(dims) sum_dims = sum(dims) for d in range(dim_max, sum_dims + 1): From 617db3c4e5c1ae71e13eb263db7373c5b78632c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 13 Jun 2023 21:59:08 +0200 Subject: [PATCH 176/205] fixing the 7 last E222 warnings --- src/sage/algebras/cluster_algebra.py | 2 +- src/sage/groups/finitely_presented_named.py | 2 +- src/sage/numerical/interactive_simplex_method.py | 4 ++-- src/sage/structure/factorization.py | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/algebras/cluster_algebra.py b/src/sage/algebras/cluster_algebra.py index eb005168275..b72d2a12976 100644 --- a/src/sage/algebras/cluster_algebra.py +++ b/src/sage/algebras/cluster_algebra.py @@ -613,7 +613,7 @@ def theta_basis_decomposition(self): y_exp = min(f_poly.dict()) coeff = f_poly.dict()[y_exp] g_theta = tuple(g_vect + B*vector(y_exp)) - out[g_theta] = out.get(g_theta, zero_A) + A({zero_t + tuple(y_exp):coeff}) + out[g_theta] = out.get(g_theta, zero_A) + A({zero_t + tuple(y_exp):coeff}) f_poly -= U({y_exp:coeff}) * A.theta_basis_F_polynomial(g_theta) return out diff --git a/src/sage/groups/finitely_presented_named.py b/src/sage/groups/finitely_presented_named.py index 248049fadb7..177f7908895 100644 --- a/src/sage/groups/finitely_presented_named.py +++ b/src/sage/groups/finitely_presented_named.py @@ -381,7 +381,7 @@ def DiCyclicPresentation(n): raise ValueError('input integer must be greater than 1') F = FreeGroup(['a','b']) - rls = F([1])**(2*n), F([2,2])*F([-1])**n, F([-2,1,2,1]) + rls = F([1])**(2*n), F([2,2])*F([-1])**n, F([-2,1,2,1]) return FinitelyPresentedGroup(F, rls) def SymmetricPresentation(n): diff --git a/src/sage/numerical/interactive_simplex_method.py b/src/sage/numerical/interactive_simplex_method.py index 26e332cd8d9..ec8d98853d9 100644 --- a/src/sage/numerical/interactive_simplex_method.py +++ b/src/sage/numerical/interactive_simplex_method.py @@ -4510,7 +4510,7 @@ def __init__(self, problem, basic_variables): "for auxiliary problems") super().__init__() self._problem = problem - R = problem.coordinate_ring() + R = problem.coordinate_ring() self._x_B = vector(R, [variable(R, v) for v in basic_variables]) def __eq__(self, other): @@ -4611,7 +4611,7 @@ def _latex_(self): headers.append("B^{-1} A_{%s}" % latex(entering)) if show_ratios: headers.append(r"\hbox{Ratio}") - lines.append(" & ".join(headers) + r" \\") + lines.append(" & ".join(headers) + r" \\") lines.append(r"\hline") Bi = self.B_inverse() c_B = self.c_B() diff --git a/src/sage/structure/factorization.py b/src/sage/structure/factorization.py index 8fa56d6bf75..8597448373a 100644 --- a/src/sage/structure/factorization.py +++ b/src/sage/structure/factorization.py @@ -815,7 +815,7 @@ def _repr_(self): if len(self) == 0: return repr(self.__unit) s = '' - mul = ' * ' + mul = ' * ' if cr: mul += '\n' x = self.__x[0][0] @@ -846,7 +846,7 @@ def _repr_(self): u = repr(self.__unit) else: u = '(%s)'%self.__unit - s = u + mul + s + s = u + mul + s return s def _latex_(self): @@ -887,7 +887,7 @@ def _latex_(self): u = self.__unit._latex_() else: u = '\\left(%s\\right)'%self.__unit._latex_() - s = u + ' \\cdot ' + s + s = u + ' \\cdot ' + s return s @cached_method From a60b315521e15aa8b1ede351b417fc4f4269b0c3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 13 Jun 2023 17:59:44 -0700 Subject: [PATCH 177/205] sage.matrix.misc*: Fix doctests --- src/sage/matrix/misc.pyx | 28 +++++++++++++++------------- src/sage/matrix/misc_flint.pyx | 11 ++++++----- src/sage/matrix/misc_mpfr.pyx | 16 ++++++++-------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/sage/matrix/misc.pyx b/src/sage/matrix/misc.pyx index 0512ed193b3..2623661c675 100644 --- a/src/sage/matrix/misc.pyx +++ b/src/sage/matrix/misc.pyx @@ -24,10 +24,10 @@ from .matrix_rational_sparse cimport Matrix_rational_sparse matrix_integer_dense_rational_reconstruction = \ LazyImport('sage.matrix.misc_flint', 'matrix_integer_dense_rational_reconstruction', - deprecation=99999) + deprecation=35758) hadamard_row_bound_mpfr = \ LazyImport('sage.matrix.misc_mpfr', 'hadamard_row_bound_mpfr', - deprecation=99999) + deprecation=35758) def matrix_integer_sparse_rational_reconstruction(Matrix_integer_sparse A, Integer N): @@ -39,7 +39,8 @@ def matrix_integer_sparse_rational_reconstruction(Matrix_integer_sparse A, Integ EXAMPLES:: sage: A = matrix(ZZ, 3, 4, [(1/3)%500, 2, 3, (-4)%500, 7, 2, 2, 3, 4, 3, 4, (5/7)%500], sparse=True) - sage: sage.matrix.misc.matrix_integer_sparse_rational_reconstruction(A, 500) + sage: from sage.matrix.misc import matrix_integer_sparse_rational_reconstruction + sage: matrix_integer_sparse_rational_reconstruction(A, 500) [1/3 2 3 -4] [ 7 2 2 3] [ 4 3 4 5/7] @@ -329,29 +330,30 @@ def cmp_pivots(x, y): """ Compare two sequences of pivot columns. - If x is shorter than y, return -1, i.e., x < y, "not as good". - If x is longer than y, then x > y, so "better" and return +1. - If the length is the same, then x is better, i.e., x > y - if the entries of x are correspondingly <= those of y with + If `x` is shorter than `y`, return `-1`, i.e., `x < y`, "not as good". + If `x` is longer than `y`, then `x > y`, so "better" and return `+1`. + If the length is the same, then `x` is better, i.e., `x > y` + if the entries of `x` are correspondingly `\leq` those of `y` with one being strictly less. INPUT: - - x, y -- lists or tuples of integers + - ``x``, ``y`` -- lists or tuples of integers EXAMPLES: We illustrate each of the above comparisons. :: - sage: sage.matrix.misc.cmp_pivots([1,2,3], [4,5,6,7]) + sage: from sage.matrix.misc import cmp_pivots + sage: cmp_pivots([1,2,3], [4,5,6,7]) -1 - sage: sage.matrix.misc.cmp_pivots([1,2,3,5], [4,5,6]) + sage: cmp_pivots([1,2,3,5], [4,5,6]) 1 - sage: sage.matrix.misc.cmp_pivots([1,2,4], [1,2,3]) + sage: cmp_pivots([1,2,4], [1,2,3]) -1 - sage: sage.matrix.misc.cmp_pivots([1,2,3], [1,2,3]) + sage: cmp_pivots([1,2,3], [1,2,3]) 0 - sage: sage.matrix.misc.cmp_pivots([1,2,3], [1,2,4]) + sage: cmp_pivots([1,2,3], [1,2,4]) 1 """ x = tuple(x) diff --git a/src/sage/matrix/misc_flint.pyx b/src/sage/matrix/misc_flint.pyx index bcdace773c2..8b8f7d7c615 100644 --- a/src/sage/matrix/misc_flint.pyx +++ b/src/sage/matrix/misc_flint.pyx @@ -21,18 +21,19 @@ def matrix_integer_dense_rational_reconstruction(Matrix_integer_dense A, Integer """ Given a matrix over the integers and an integer modulus, do rational reconstruction on all entries of the matrix, viewed as - numbers mod N. This is done efficiently by assuming there is a + numbers mod `N`. This is done efficiently by assuming there is a large common factor dividing the denominators. INPUT: - A -- matrix - N -- an integer + - ``A`` -- matrix + - ``N`` -- an integer EXAMPLES:: sage: B = ((matrix(ZZ, 3,4, [1,2,3,-4,7,2,18,3,4,3,4,5])/3)%500).change_ring(ZZ) - sage: sage.matrix.misc.matrix_integer_dense_rational_reconstruction(B, 500) + sage: from sage.matrix.misc import matrix_integer_dense_rational_reconstruction + sage: matrix_integer_dense_rational_reconstruction(B, 500) [ 1/3 2/3 1 -4/3] [ 7/3 2/3 6 1] [ 4/3 1 4/3 5/3] @@ -42,7 +43,7 @@ def matrix_integer_dense_rational_reconstruction(Matrix_integer_dense A, Integer Check that :trac:`9345` is fixed:: sage: A = random_matrix(ZZ, 3) - sage: sage.matrix.misc.matrix_integer_dense_rational_reconstruction(A, 0) + sage: matrix_integer_dense_rational_reconstruction(A, 0) Traceback (most recent call last): ... ZeroDivisionError: The modulus cannot be zero diff --git a/src/sage/matrix/misc_mpfr.pyx b/src/sage/matrix/misc_mpfr.pyx index bcb98868259..40d9b9392e3 100644 --- a/src/sage/matrix/misc_mpfr.pyx +++ b/src/sage/matrix/misc_mpfr.pyx @@ -14,17 +14,17 @@ from .matrix0 cimport Matrix def hadamard_row_bound_mpfr(Matrix A): """ - Given a matrix A with entries that coerce to RR, compute the row + Given a matrix `A` with entries that coerce to ``RR``, compute the row Hadamard bound on the determinant. INPUT: - A -- a matrix over RR + - ``A`` -- a matrix over ``RR`` OUTPUT: - integer -- an integer n such that the absolute value of the - determinant of this matrix is at most $10^n$. + integer -- an integer n such that the absolute value of the + determinant of this matrix is at most `10^n`. EXAMPLES: @@ -32,13 +32,13 @@ def hadamard_row_bound_mpfr(Matrix A): and also compute the row Hadamard bound of the transpose, which happens to be sharp. :: - sage: a = matrix(ZZ, 2, [2^10000,3^10000,2^50,3^19292]) - sage: import sage.matrix.misc - sage: sage.matrix.misc.hadamard_row_bound_mpfr(a.change_ring(RR)) + sage: a = matrix(ZZ, 2, [2^10000, 3^10000, 2^50, 3^19292]) + sage: from sage.matrix.misc import hadamard_row_bound_mpfr + sage: hadamard_row_bound_mpfr(a.change_ring(RR)) 13976 sage: len(str(a.det())) 12215 - sage: sage.matrix.misc.hadamard_row_bound_mpfr(a.transpose().change_ring(RR)) + sage: hadamard_row_bound_mpfr(a.transpose().change_ring(RR)) 12215 Note that in the above example using RDF would overflow:: From 19f38a08215379aa4d84d798dcb9b5ac13357cce Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 13 Jun 2023 18:14:43 -0700 Subject: [PATCH 178/205] Fix up doc --- src/doc/en/reference/matrices/index.rst | 2 ++ src/sage/matrix/misc.pyx | 6 +++--- src/sage/matrix/misc_flint.pyx | 2 +- src/sage/matrix/misc_mpfr.pyx | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/doc/en/reference/matrices/index.rst b/src/doc/en/reference/matrices/index.rst index fb06992c1e1..89453635472 100644 --- a/src/doc/en/reference/matrices/index.rst +++ b/src/doc/en/reference/matrices/index.rst @@ -94,6 +94,8 @@ objects like operation tables (e.g. the multiplication table of a group). sage/matrix/matrix_misc sage/matrix/matrix_window sage/matrix/misc + sage/matrix/misc_mpfr + sage/matrix/misc_flint sage/matrix/symplectic_basis sage/matrix/compute_J_ideal diff --git a/src/sage/matrix/misc.pyx b/src/sage/matrix/misc.pyx index 2623661c675..1819d45591e 100644 --- a/src/sage/matrix/misc.pyx +++ b/src/sage/matrix/misc.pyx @@ -31,10 +31,10 @@ hadamard_row_bound_mpfr = \ def matrix_integer_sparse_rational_reconstruction(Matrix_integer_sparse A, Integer N): - """ + r""" Given a sparse matrix over the integers and an integer modulus, do rational reconstruction on all entries of the matrix, viewed as - numbers mod N. + numbers mod `N`. EXAMPLES:: @@ -327,7 +327,7 @@ def matrix_rational_echelon_form_multimodular(Matrix self, height_guess=None, pr def cmp_pivots(x, y): - """ + r""" Compare two sequences of pivot columns. If `x` is shorter than `y`, return `-1`, i.e., `x < y`, "not as good". diff --git a/src/sage/matrix/misc_flint.pyx b/src/sage/matrix/misc_flint.pyx index 8b8f7d7c615..cf01ba5c048 100644 --- a/src/sage/matrix/misc_flint.pyx +++ b/src/sage/matrix/misc_flint.pyx @@ -18,7 +18,7 @@ from .matrix_rational_dense cimport Matrix_rational_dense def matrix_integer_dense_rational_reconstruction(Matrix_integer_dense A, Integer N): - """ + r""" Given a matrix over the integers and an integer modulus, do rational reconstruction on all entries of the matrix, viewed as numbers mod `N`. This is done efficiently by assuming there is a diff --git a/src/sage/matrix/misc_mpfr.pyx b/src/sage/matrix/misc_mpfr.pyx index 40d9b9392e3..c8cf62abd45 100644 --- a/src/sage/matrix/misc_mpfr.pyx +++ b/src/sage/matrix/misc_mpfr.pyx @@ -13,7 +13,7 @@ from .matrix0 cimport Matrix def hadamard_row_bound_mpfr(Matrix A): - """ + r""" Given a matrix `A` with entries that coerce to ``RR``, compute the row Hadamard bound on the determinant. From 75d0cdcde4617a8c0bfcdffa2f7c3bd6d977ac2e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 13 Jun 2023 20:32:08 -0700 Subject: [PATCH 179/205] Update imports in doctests --- src/sage/matrix/misc_flint.pyx | 2 +- src/sage/matrix/misc_mpfr.pyx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/matrix/misc_flint.pyx b/src/sage/matrix/misc_flint.pyx index cf01ba5c048..37d326c9a74 100644 --- a/src/sage/matrix/misc_flint.pyx +++ b/src/sage/matrix/misc_flint.pyx @@ -32,7 +32,7 @@ def matrix_integer_dense_rational_reconstruction(Matrix_integer_dense A, Integer EXAMPLES:: sage: B = ((matrix(ZZ, 3,4, [1,2,3,-4,7,2,18,3,4,3,4,5])/3)%500).change_ring(ZZ) - sage: from sage.matrix.misc import matrix_integer_dense_rational_reconstruction + sage: from sage.matrix.misc_flint import matrix_integer_dense_rational_reconstruction sage: matrix_integer_dense_rational_reconstruction(B, 500) [ 1/3 2/3 1 -4/3] [ 7/3 2/3 6 1] diff --git a/src/sage/matrix/misc_mpfr.pyx b/src/sage/matrix/misc_mpfr.pyx index c8cf62abd45..48b6ade6379 100644 --- a/src/sage/matrix/misc_mpfr.pyx +++ b/src/sage/matrix/misc_mpfr.pyx @@ -33,7 +33,7 @@ def hadamard_row_bound_mpfr(Matrix A): happens to be sharp. :: sage: a = matrix(ZZ, 2, [2^10000, 3^10000, 2^50, 3^19292]) - sage: from sage.matrix.misc import hadamard_row_bound_mpfr + sage: from sage.matrix.misc_mpfr import hadamard_row_bound_mpfr sage: hadamard_row_bound_mpfr(a.change_ring(RR)) 13976 sage: len(str(a.det())) From e594c31a2e74c75f301c2faec649545d464417ef Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 14 Jun 2023 13:50:59 +0200 Subject: [PATCH 180/205] Fix (maybe) --- src/sage/libs/gap/libgap.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/libs/gap/libgap.pyx b/src/sage/libs/gap/libgap.pyx index 1ac75385071..0c82d297f68 100644 --- a/src/sage/libs/gap/libgap.pyx +++ b/src/sage/libs/gap/libgap.pyx @@ -539,7 +539,7 @@ class Gap(Parent): ... GAPError: Error, VAL_GVAR: No value bound to FooBar """ - return GAP_ValueGlobalVariable(variable) + return make_any_gap_element(GAP_ValueGlobalVariable(variable.value)) def global_context(self, variable, value): """ From 7c8291c178d29713fa8a3d473ff25a7fad4685bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 14 Jun 2023 13:56:07 +0200 Subject: [PATCH 181/205] fix most E301 warnings --- src/sage/algebras/free_algebra.py | 1 + .../finitely_freely_generated_lca.py | 3 ++- src/sage/categories/category_with_axiom.py | 7 +++++++ src/sage/categories/examples/sets_cat.py | 1 + ...nitely_generated_lambda_bracket_algebras.py | 1 + src/sage/categories/lambda_bracket_algebras.py | 1 + src/sage/coding/golay_code.py | 6 +++--- src/sage/coding/goppa_code.py | 4 +++- src/sage/crypto/mq/sr.py | 2 ++ src/sage/databases/findstat.py | 1 + src/sage/groups/perm_gps/permgroup.py | 1 + src/sage/interacts/library.py | 2 ++ src/sage/interfaces/magma_free.py | 2 ++ .../differentiable/vectorfield_module.py | 4 +++- src/sage/modular/abvar/homspace.py | 2 ++ src/sage/modular/quasimodform/ring.py | 1 + src/sage/monoids/free_abelian_monoid.py | 2 ++ src/sage/plot/plot3d/plot3d.py | 3 ++- src/sage/quadratic_forms/quadratic_form.py | 18 +++++++++--------- src/sage/repl/ipython_extension.py | 3 ++- src/sage/rings/multi_power_series_ring.py | 1 + src/sage/rings/padics/padic_base_generic.py | 2 ++ src/sage/rings/quotient_ring.py | 1 + .../elliptic_curves/ell_rational_field.py | 2 ++ src/sage/schemes/generic/point.py | 1 + .../hyperelliptic_padic_field.py | 1 - src/sage/sets/set_from_iterator.py | 3 ++- src/sage/structure/formal_sum.py | 1 + src/sage/symbolic/operators.py | 2 ++ 29 files changed, 60 insertions(+), 19 deletions(-) diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index 3004878a378..52e7471d1bf 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -420,6 +420,7 @@ class FreeAlgebra_generic(CombinatorialFreeModule, Algebra): is a coercion. """ Element = FreeAlgebraElement + def __init__(self, R, n, names): """ The free algebra on `n` generators over a base ring. diff --git a/src/sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py b/src/sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py index 96f6c99defe..9077ef8f6a2 100644 --- a/src/sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py +++ b/src/sage/algebras/lie_conformal_algebras/finitely_freely_generated_lca.py @@ -73,7 +73,8 @@ def _repr_(self): return "Lie conformal algebra generated by {0} over {1}".format( self.gen(0), self.base_ring()) return "Lie conformal algebra with generators {0} over {1}".format( - self.gens(), self.base_ring()) + self.gens(), self.base_ring()) + def _an_element_(self): """ An element of this Lie conformal algebra. diff --git a/src/sage/categories/category_with_axiom.py b/src/sage/categories/category_with_axiom.py index a304ff996cd..2128dac2db9 100644 --- a/src/sage/categories/category_with_axiom.py +++ b/src/sage/categories/category_with_axiom.py @@ -2764,6 +2764,7 @@ def super_categories(self): class FiniteDimensional(CategoryWithAxiom): class Finite(CategoryWithAxiom): pass + class Unital(CategoryWithAxiom): class Commutative(CategoryWithAxiom): pass @@ -2771,14 +2772,17 @@ class Commutative(CategoryWithAxiom): class Commutative(CategoryWithAxiom): class Facade(CategoryWithAxiom): pass + class FiniteDimensional(CategoryWithAxiom): pass + class Finite(CategoryWithAxiom): pass class Unital(CategoryWithAxiom): pass + class TestObjectsOverBaseRing(Category_over_base_ring): r""" A toy singleton category, for testing purposes. @@ -2805,6 +2809,7 @@ def super_categories(self): class FiniteDimensional(CategoryWithAxiom_over_base_ring): class Finite(CategoryWithAxiom_over_base_ring): pass + class Unital(CategoryWithAxiom_over_base_ring): class Commutative(CategoryWithAxiom_over_base_ring): pass @@ -2812,8 +2817,10 @@ class Commutative(CategoryWithAxiom_over_base_ring): class Commutative(CategoryWithAxiom_over_base_ring): class Facade(CategoryWithAxiom_over_base_ring): pass + class FiniteDimensional(CategoryWithAxiom_over_base_ring): pass + class Finite(CategoryWithAxiom_over_base_ring): pass diff --git a/src/sage/categories/examples/sets_cat.py b/src/sage/categories/examples/sets_cat.py index 6f358929a72..fbd7d8b1fc8 100644 --- a/src/sage/categories/examples/sets_cat.py +++ b/src/sage/categories/examples/sets_cat.py @@ -539,6 +539,7 @@ def _from_integer_(self, e): return self.element_class(self, Integer(e)) from sage.structure.element_wrapper import ElementWrapper + class Element (ElementWrapper, PrimeNumbers_Abstract.Element): def _integer_(self, IntRing): """ diff --git a/src/sage/categories/finitely_generated_lambda_bracket_algebras.py b/src/sage/categories/finitely_generated_lambda_bracket_algebras.py index 85315805fad..f8a36053753 100644 --- a/src/sage/categories/finitely_generated_lambda_bracket_algebras.py +++ b/src/sage/categories/finitely_generated_lambda_bracket_algebras.py @@ -31,6 +31,7 @@ class FinitelyGeneratedLambdaBracketAlgebras(CategoryWithAxiom_over_base_ring): Category of finitely generated lambda bracket algebras over Algebraic Field """ _base_category_class_and_axiom = (LambdaBracketAlgebras, "FinitelyGeneratedAsLambdaBracketAlgebra") + class ParentMethods: def ngens(self): r""" diff --git a/src/sage/categories/lambda_bracket_algebras.py b/src/sage/categories/lambda_bracket_algebras.py index 8818c0a918a..c8277ae1f26 100644 --- a/src/sage/categories/lambda_bracket_algebras.py +++ b/src/sage/categories/lambda_bracket_algebras.py @@ -126,6 +126,7 @@ def ideal(self, *gens, **kwds): """ raise NotImplementedError("ideals of Lie Conformal algebras are " "not implemented yet") + class ElementMethods: @coerce_binop diff --git a/src/sage/coding/golay_code.py b/src/sage/coding/golay_code.py index 16d395ffc15..b55cd8a4f4d 100644 --- a/src/sage/coding/golay_code.py +++ b/src/sage/coding/golay_code.py @@ -118,7 +118,7 @@ def __eq__(self, other): """ return isinstance(other, GolayCode) \ and self.base_field() == other.base_field() \ - and self.length() == other.length() \ + and self.length() == other.length() def _repr_(self): r""" @@ -133,8 +133,8 @@ def _repr_(self): ext = "" if n % 2 == 0: ext = "Extended" - return "[%s, %s, %s] %s Golay code over GF(%s)"\ - % (n, self.dimension(), self.minimum_distance(), ext, self.base_field().cardinality()) + return "[%s, %s, %s] %s Golay code over GF(%s)" % (n, self.dimension(), + self.minimum_distance(), ext, self.base_field().cardinality()) def _latex_(self): r""" diff --git a/src/sage/coding/goppa_code.py b/src/sage/coding/goppa_code.py index fbfa74462c4..f4c9b0d5bb8 100644 --- a/src/sage/coding/goppa_code.py +++ b/src/sage/coding/goppa_code.py @@ -139,7 +139,9 @@ def _repr_(self): [8, 2] Goppa code over GF(2) """ return "[{}, {}] Goppa code over GF({})".format( - self.length(), self.dimension(), self.base_field().cardinality()) + self.length(), self.dimension(), + self.base_field().cardinality()) + def _latex_(self): r""" Return a latex representation of ``self``. diff --git a/src/sage/crypto/mq/sr.py b/src/sage/crypto/mq/sr.py index a79b0868175..050c7f44ec5 100644 --- a/src/sage/crypto/mq/sr.py +++ b/src/sage/crypto/mq/sr.py @@ -3301,6 +3301,7 @@ def __init__(self, sr): a^2 + a """ self.sr = sr + def __enter__(self): """ EXAMPLES:: @@ -3318,6 +3319,7 @@ def __enter__(self): """ self.allow_zero_inversions = self.sr._allow_zero_inversions self.sr._allow_zero_inversions = True + def __exit__(self, typ, value, tb): """ EXAMPLES:: diff --git a/src/sage/databases/findstat.py b/src/sage/databases/findstat.py index ecb85b8364e..a668702c9be 100644 --- a/src/sage/databases/findstat.py +++ b/src/sage/databases/findstat.py @@ -4738,6 +4738,7 @@ def __init__(self): # fields = "SageCodeElementToString,SageCodeElementsOnLevel,SageCodeStringToElement" # url = FINDSTAT_API_COLLECTIONS + id + "?fields=" + fields # print(json.load(urlopen(url))["included"]["Collections"][id]) + def position(item): try: return tuple(_SupportedFindStatCollections).index(item[1]["NameWiki"]) diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index fe0bce4e4ea..965076c0a5f 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -4810,6 +4810,7 @@ def upper_central_series(self): return [self.subgroup(gap_group=group) for group in UCS] from sage.groups.generic import structure_description + def sign_representation(self, base_ring=None, side="twosided"): r""" Return the sign representation of ``self`` over ``base_ring``. diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index 582702abe51..ccb8fc6d3c2 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -716,6 +716,7 @@ def special_points( """ import math # Return the intersection point of the bisector of the angle <(A[a],A[c],A[b]) and the unit circle. Angles given in radians. + def half(A, a, b, c): if (A[a] < A[b] and (A[c] < A[a] or A[c] > A[b])) or (A[a] > A[b] and (A[c] > A[a] or A[c] < A[b])): p = A[a] + 0.5 * (A[b] - A[a]) @@ -1300,6 +1301,7 @@ def simpson_integration( interval = interval_s else: interval = interval_g[0] + def parabola(a, b, c): from sage.symbolic.relation import solve A, B, C = SR.var("A, B, C") diff --git a/src/sage/interfaces/magma_free.py b/src/sage/interfaces/magma_free.py index b82b9c4699d..70f196a0fb2 100644 --- a/src/sage/interfaces/magma_free.py +++ b/src/sage/interfaces/magma_free.py @@ -81,7 +81,9 @@ class MagmaFree: """ def eval(self, x, **kwds): return magma_free_eval(x) + def __call__(self, code, strip=True, columns=0): return magma_free_eval(code, strip=strip, columns=columns) + magma_free = MagmaFree() diff --git a/src/sage/manifolds/differentiable/vectorfield_module.py b/src/sage/manifolds/differentiable/vectorfield_module.py index f11a7f0067e..d954b5d4839 100644 --- a/src/sage/manifolds/differentiable/vectorfield_module.py +++ b/src/sage/manifolds/differentiable/vectorfield_module.py @@ -951,7 +951,9 @@ def alternating_contravariant_tensor(self, degree, name=None, return self.element_class(self, name=name, latex_name=latex_name) return self.exterior_power(degree).element_class(self, degree, - name=name, latex_name=latex_name) + name=name, + latex_name=latex_name) + @overload def alternating_form( self, degree: Literal[0], name=None, latex_name=None diff --git a/src/sage/modular/abvar/homspace.py b/src/sage/modular/abvar/homspace.py index adf9889bebe..1b29df45c1b 100644 --- a/src/sage/modular/abvar/homspace.py +++ b/src/sage/modular/abvar/homspace.py @@ -195,11 +195,13 @@ ZZ = sage.rings.integer_ring.ZZ + class Homspace(HomsetWithBase): """ A space of homomorphisms between two modular abelian varieties. """ Element = morphism.Morphism + def __init__(self, domain, codomain, cat): """ Create a homspace. diff --git a/src/sage/modular/quasimodform/ring.py b/src/sage/modular/quasimodform/ring.py index 5579aa621d6..ee939a182df 100644 --- a/src/sage/modular/quasimodform/ring.py +++ b/src/sage/modular/quasimodform/ring.py @@ -216,6 +216,7 @@ class QuasiModularForms(Parent, UniqueRepresentation): NotImplementedError: base ring other than Q are not yet supported for quasimodular forms ring """ Element = QuasiModularFormsElement + def __init__(self, group=1, base_ring=QQ, name='E2'): r""" INPUT: diff --git a/src/sage/monoids/free_abelian_monoid.py b/src/sage/monoids/free_abelian_monoid.py index aa0581c2c0e..9c34e02bed7 100644 --- a/src/sage/monoids/free_abelian_monoid.py +++ b/src/sage/monoids/free_abelian_monoid.py @@ -103,9 +103,11 @@ def create_key(self, n, names): n = int(n) names = normalize_names(n, names) return (n, names) + def create_object(self, version, key): return FreeAbelianMonoid_class(*key) + FreeAbelianMonoid_factory = FreeAbelianMonoidFactory("sage.monoids.free_abelian_monoid.FreeAbelianMonoid_factory") diff --git a/src/sage/plot/plot3d/plot3d.py b/src/sage/plot/plot3d/plot3d.py index 70da180e941..e9bbfaa8370 100644 --- a/src/sage/plot/plot3d/plot3d.py +++ b/src/sage/plot/plot3d/plot3d.py @@ -911,7 +911,8 @@ def triangle(self, a, b, c, color=None): sage: tri [[0, 0, 0], [0, 0, 1], [1, 1, 0]] """ - return [a,b,c] + return [a, b, c] + def smooth_triangle(self, a, b, c, da, db, dc, color=None): """ Function emulating behavior of diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index 4b9380475d8..340d6680c87 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -940,7 +940,6 @@ def sum_by_coefficients_with(self, right): raise TypeError("cannot add these since the quadratic forms do not have the same base rings") return QuadraticForm(self.__base_ring, self.__n, [self.__coeffs[i] + right.__coeffs[i] for i in range(len(self.__coeffs))]) - # ======================== CHANGE THIS TO A TENSOR PRODUCT?!? Even in Characteristic 2?!? ======================= # def __mul__(self, right): # """ @@ -964,19 +963,22 @@ def sum_by_coefficients_with(self, right): # raise TypeError, "Oh no! The multiplier cannot be coerced into the base ring of the quadratic form. =(" # # return QuadraticForm(self.base_ring(), self.dim(), [c * self.__coeffs[i] for i in range(len(self.__coeffs))]) -# ========================================================================================================================= + + # ================================================================= def __call__(self, v): r""" Evaluate this quadratic form `Q` on a vector or matrix of elements - coercible to the base ring of the quadratic form. If a vector + coercible to the base ring of the quadratic form. + + If a vector is given then the output will be the ring element `Q(v)`, but if a matrix is given then the output will be the quadratic form `Q'` which in matrix notation is given by: .. MATH:: - Q' = v^t\cdot Q\cdot v. + Q' = v^t\cdot Q\cdot v. EXAMPLES: @@ -1077,8 +1079,7 @@ def __call__(self, v): else: raise TypeError - -# ===================================================================================================== + # =============================================== def _is_even_symmetric_matrix_(self, A, R=None): """ @@ -1137,13 +1138,12 @@ def _is_even_symmetric_matrix_(self, A, R=None): # Test that the diagonal is even (if 1/2 isn't in R) if not R(2).is_unit(): for i in range(n): - if not is_even(R(A[i,i])): + if not is_even(R(A[i, i])): return False return True - -# ===================================================================================================== + # ===================================================================== def matrix(self): r""" diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index cad6a47ca8b..11cbdde579c 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -197,9 +197,10 @@ def pre_readline(): self.shell.readline_startup_hook(pre_readline) self.shell.pre_readline = pre_readline - print('Interactively loading "%s"'%args) + print('Interactively loading "%s"' % args) _magic_display_status = 'simple' + @line_magic def display(self, args): r""" diff --git a/src/sage/rings/multi_power_series_ring.py b/src/sage/rings/multi_power_series_ring.py index dd374ea0f75..410de0bbff0 100644 --- a/src/sage/rings/multi_power_series_ring.py +++ b/src/sage/rings/multi_power_series_ring.py @@ -281,6 +281,7 @@ class MPowerSeriesRing_generic(PowerSeriesRing_generic, Nonexact): # # sparse setting may not be implemented completely Element = MPowerSeries + @staticmethod def __classcall__(cls, base_ring, num_gens, name_list, order='negdeglex', default_prec=10, sparse=False): diff --git a/src/sage/rings/padics/padic_base_generic.py b/src/sage/rings/padics/padic_base_generic.py index 45730e8b816..6be6bceec0a 100644 --- a/src/sage/rings/padics/padic_base_generic.py +++ b/src/sage/rings/padics/padic_base_generic.py @@ -30,8 +30,10 @@ from sage.rings.padics.padic_fixed_mod_element import pAdicCoercion_ZZ_FM, pAdicConvert_QQ_FM from sage.rings.padics.padic_floating_point_element import pAdicCoercion_ZZ_FP, pAdicCoercion_QQ_FP, pAdicConvert_QQ_FP + class pAdicBaseGeneric(pAdicGeneric): _implementation = 'GMP' + def __init__(self, p, prec, print_mode, names, element_class): """ Initialization diff --git a/src/sage/rings/quotient_ring.py b/src/sage/rings/quotient_ring.py index 11ac5510cf9..178cae67a22 100644 --- a/src/sage/rings/quotient_ring.py +++ b/src/sage/rings/quotient_ring.py @@ -434,6 +434,7 @@ class QuotientRing_nc(ring.Ring, sage.structure.parent_gens.ParentWithGens): (0, d) """ Element = quotient_ring_element.QuotientRingElement + def __init__(self, R, I, names, category=None): """ Create the quotient ring of `R` by the twosided ideal `I`. diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index b5f5de2bd3f..261acb7a67f 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -6643,6 +6643,7 @@ def reduction_at(p): return (H_q) #<------------------------------------------------------------------------- #>------------------------------------------------------------------------- + def S_integral_points_with_bounded_mw_coeffs(): r""" Return the set of S-integers x which are x-coordinates of @@ -6727,6 +6728,7 @@ def test_with_T(R): return xs #<------------------------------------------------------------------------- #>------------------------------------------------------------------------- + def S_integral_x_coords_with_abs_bounded_by(abs_bound): r""" Extra search of points with `|x|< ` abs_bound, assuming diff --git a/src/sage/schemes/generic/point.py b/src/sage/schemes/generic/point.py index 46634c342cb..c3f628159aa 100644 --- a/src/sage/schemes/generic/point.py +++ b/src/sage/schemes/generic/point.py @@ -199,6 +199,7 @@ def _repr_(self): """ return "Point on %s defined by the %s"%(self.scheme(), self.prime_ideal()) + def prime_ideal(self): """ Return the prime ideal that defines this scheme point. diff --git a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py index 030d8dab2e7..5111e08faf1 100644 --- a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py +++ b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_padic_field.py @@ -671,7 +671,6 @@ def coleman_integrals_on_basis(self, P, Q, algorithm=None): coleman_integrals_on_basis_hyperelliptic = coleman_integrals_on_basis - # def invariant_differential(self): # """ # Returns the invariant differential `dx/2y` on self diff --git a/src/sage/sets/set_from_iterator.py b/src/sage/sets/set_from_iterator.py index 1255f903c03..f9e0bccaa14 100644 --- a/src/sage/sets/set_from_iterator.py +++ b/src/sage/sets/set_from_iterator.py @@ -990,7 +990,8 @@ class DummyExampleForPicklingTest: {10, 11, 12, 13, 14, ...} """ start = 10 - stop = 100 + stop = 100 + @set_from_method def f(self): r""" diff --git a/src/sage/structure/formal_sum.py b/src/sage/structure/formal_sum.py index 7a788c3994f..a8414eea037 100644 --- a/src/sage/structure/formal_sum.py +++ b/src/sage/structure/formal_sum.py @@ -322,6 +322,7 @@ class FormalSums(UniqueRepresentation, Module): """ Element = FormalSum + @staticmethod def __classcall__(cls, base_ring=ZZ): """ diff --git a/src/sage/symbolic/operators.py b/src/sage/symbolic/operators.py index 3887583bab9..e89d32f1424 100644 --- a/src/sage/symbolic/operators.py +++ b/src/sage/symbolic/operators.py @@ -229,8 +229,10 @@ class DerivativeOperator(): class DerivativeOperatorWithParameters(): def __init__(self, parameter_set): self._parameter_set = parameter_set + def __call__(self, function): return FDerivativeOperator(function, self._parameter_set) + def __repr__(self): """ Return the string representation of this derivative operator. From a85d250f80f7c671e29766e2bccb7cacb210426e Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 14 Jun 2023 14:09:26 +0200 Subject: [PATCH 182/205] oops --- src/sage/libs/gap/libgap.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/libs/gap/libgap.pyx b/src/sage/libs/gap/libgap.pyx index 0c82d297f68..80b1258042a 100644 --- a/src/sage/libs/gap/libgap.pyx +++ b/src/sage/libs/gap/libgap.pyx @@ -539,7 +539,7 @@ class Gap(Parent): ... GAPError: Error, VAL_GVAR: No value bound to FooBar """ - return make_any_gap_element(GAP_ValueGlobalVariable(variable.value)) + return make_any_gap_element(self, GAP_ValueGlobalVariable(variable.value)) def global_context(self, variable, value): """ From 390cc58f2122dd9e83026e440e98efbf4b1f37d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 14 Jun 2023 17:55:21 +0200 Subject: [PATCH 183/205] cylint: remove some unused variables in rings/ --- src/sage/rings/bernoulli_mod_p.pyx | 2 -- src/sage/rings/complex_arb.pyx | 9 ++--- src/sage/rings/complex_mpc.pyx | 4 +-- src/sage/rings/fast_arith.pyx | 1 - src/sage/rings/finite_rings/element_base.pyx | 10 +++--- src/sage/rings/finite_rings/integer_mod.pyx | 5 --- src/sage/rings/function_field/element.pyx | 8 ++--- .../rings/function_field/element_polymod.pyx | 4 +-- src/sage/rings/integer_ring.pyx | 4 +-- .../rings/laurent_series_ring_element.pyx | 1 - .../number_field/number_field_element.pyx | 13 ++++--- .../number_field_element_quadratic.pyx | 8 ----- src/sage/rings/number_field/totallyreal.pyx | 2 -- .../rings/number_field/totallyreal_data.pyx | 16 ++++----- .../polynomial/laurent_polynomial_mpair.pyx | 2 +- .../multi_polynomial_libsingular.pyx | 36 +++++++++++-------- .../polynomial/multi_polynomial_ring_base.pyx | 3 -- src/sage/rings/polynomial/pbori/pbori.pyx | 10 ++---- src/sage/rings/polynomial/plural.pyx | 7 ++-- src/sage/rings/polynomial/polydict.pyx | 4 +-- .../rings/polynomial/polynomial_compiled.pyx | 7 ++-- .../polynomial_integer_dense_ntl.pyx | 11 +++--- .../polynomial/polynomial_rational_flint.pyx | 1 - .../rings/polynomial/symmetric_reduction.pyx | 4 +-- src/sage/rings/real_arb.pyx | 12 +++---- src/sage/rings/real_mpfr.pyx | 9 +++-- src/sage/rings/sum_of_squares.pyx | 4 +-- 27 files changed, 78 insertions(+), 119 deletions(-) diff --git a/src/sage/rings/bernoulli_mod_p.pyx b/src/sage/rings/bernoulli_mod_p.pyx index 53f1a5fb040..f289a63767d 100644 --- a/src/sage/rings/bernoulli_mod_p.pyx +++ b/src/sage/rings/bernoulli_mod_p.pyx @@ -311,8 +311,6 @@ def bernoulli_mod_p_single(long p, long k): if not sage.arith.all.is_prime(p): raise ValueError("p (=%s) must be a prime" % p) - R = Integers(p) - cdef long x = bernmm_bern_modp(p, k) if x == -1: raise ArithmeticError("B_k is not integral at p") diff --git a/src/sage/rings/complex_arb.pyx b/src/sage/rings/complex_arb.pyx index e8caf2aeb3c..ee74779b208 100644 --- a/src/sage/rings/complex_arb.pyx +++ b/src/sage/rings/complex_arb.pyx @@ -154,7 +154,7 @@ cimport sage.rings.abc cimport sage.rings.rational from cpython.int cimport PyInt_AS_LONG -from cpython.object cimport Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE +from cpython.object cimport Py_EQ, Py_NE from cpython.complex cimport PyComplex_FromDoubles from sage.ext.stdsage cimport PY_NEW @@ -1402,7 +1402,6 @@ cdef class ComplexBall(RingElement): """ cdef fmpz_t tmpz cdef fmpq_t tmpq - cdef long myprec cdef bint cplx = False Element.__init__(self, parent) @@ -2426,17 +2425,15 @@ cdef class ComplexBall(RingElement): False """ cdef ComplexBall lt, rt - cdef acb_t difference lt = left rt = right if op == Py_EQ: return acb_eq(lt.value, rt.value) - elif op == Py_NE: + if op == Py_NE: return acb_ne(lt.value, rt.value) - elif op == Py_GT or op == Py_GE or op == Py_LT or op == Py_LE: - raise TypeError("No order is defined for ComplexBalls.") + raise TypeError("No order is defined for ComplexBalls.") def identical(self, ComplexBall other): """ diff --git a/src/sage/rings/complex_mpc.pyx b/src/sage/rings/complex_mpc.pyx index 403808808c5..388d37a692f 100644 --- a/src/sage/rings/complex_mpc.pyx +++ b/src/sage/rings/complex_mpc.pyx @@ -816,7 +816,6 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): """ # This should not be called except when the number is being created. # Complex Numbers are supposed to be immutable. - cdef RealNumber x cdef mpc_rnd_t rnd rnd =(self._parent).__rnd if y is None: @@ -2338,12 +2337,11 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): sage: u.agm(v, algorithm="optimal") -0.410522769709397 + 4.60061063922097*I """ - if algorithm=="pari": + if algorithm == "pari": t = self._parent(right).__pari__() return self._parent(self.__pari__().agm(t)) cdef MPComplexNumber a, b, d, s, res - cdef mpfr_t sn,dn cdef mp_exp_t rel_prec cdef bint optimal = algorithm == "optimal" diff --git a/src/sage/rings/fast_arith.pyx b/src/sage/rings/fast_arith.pyx index dfaa7782962..06ef980c8be 100644 --- a/src/sage/rings/fast_arith.pyx +++ b/src/sage/rings/fast_arith.pyx @@ -146,7 +146,6 @@ cpdef prime_range(start, stop=None, algorithm=None, bint py_ints=False): - Kevin Stueve (added primes iterator option) 2010-10-16 - Robert Bradshaw (speedup using Pari prime table, py_ints option) """ - cdef Integer z # input to pari.init_primes cannot be greater than 436273290 (hardcoded bound) DEF init_primes_max = 436273290 DEF small_prime_max = 436273009 # a prime < init_primes_max (preferably the largest) diff --git a/src/sage/rings/finite_rings/element_base.pyx b/src/sage/rings/finite_rings/element_base.pyx index db5e5bac5f0..2050cd46256 100755 --- a/src/sage/rings/finite_rings/element_base.pyx +++ b/src/sage/rings/finite_rings/element_base.pyx @@ -81,7 +81,6 @@ cdef class FiniteRingElement(CommutativeRingElement): sage: r = a._nth_root_common(29*283*3539*12345, False, "Johnston", False) sage: r**(29*283*3539*12345) == a True - """ K = self.parent() q = K.order() @@ -96,7 +95,7 @@ cdef class FiniteRingElement(CommutativeRingElement): if gcd == q-1: if all: return [] else: raise ValueError("no nth root") - gcd, alpha, beta = n.xgcd(q-1) # gcd = alpha*n + beta*(q-1), so 1/n = alpha/gcd (mod q-1) + gcd, alpha, _ = n.xgcd(q-1) # gcd = alpha*n + beta*(q-1), so 1/n = alpha/gcd (mod q-1) if gcd == 1: return [self**alpha] if all else self**alpha @@ -406,12 +405,11 @@ cdef class FinitePolyExtElement(FiniteRingElement): sage: e._vector_(reverse=True) (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1) """ - #vector(foo) might pass in ZZ + # vector(foo) might pass in ZZ if isinstance(reverse, Parent): raise TypeError("Base field is fixed to prime subfield.") k = self.parent() - p = self.polynomial() ret = self.polynomial().padded_list(k.degree()) if reverse: @@ -422,7 +420,9 @@ cdef class FinitePolyExtElement(FiniteRingElement): r""" Return the matrix of left multiplication by the element on the power basis `1, x, x^2, \ldots, x^{d-1}` for the field - extension. Thus the \emph{columns} of this matrix give the images + extension. + + Thus the \emph{columns} of this matrix give the images of each of the `x^i`. INPUT: diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index 830f1472a5e..3590fa34eb7 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -147,7 +147,6 @@ def Mod(n, m, parent=None): return n # m is non-zero, so return n mod m - cdef IntegerMod_abstract x if parent is None: from .integer_mod_ring import IntegerModRing parent = IntegerModRing(m) @@ -1524,7 +1523,6 @@ cdef class IntegerMod_abstract(FiniteRingElement): return K(p**(pval // n) * mod(upart, p**(k-pval)).nth_root(n, algorithm=algorithm).lift()) from sage.rings.padics.factory import ZpFM R = ZpFM(p,k) - self_orig = self if p == 2: sign = [1] if self % 4 == 3: @@ -4034,9 +4032,6 @@ cpdef square_root_mod_prime(IntegerMod_abstract a, p=None): cdef double bits = log2(float(p)) cdef long r, m - cdef Integer resZ - - if p_mod_16 % 2 == 0: # p == 2 return a diff --git a/src/sage/rings/function_field/element.pyx b/src/sage/rings/function_field/element.pyx index 3aebcbc3f1a..eac722e8581 100644 --- a/src/sage/rings/function_field/element.pyx +++ b/src/sage/rings/function_field/element.pyx @@ -655,15 +655,15 @@ cdef class FunctionFieldElement(FieldElement): sage: (y/x + 1).evaluate(p) # optional - sage.rings.finite_rings sage.rings.function_field 1 """ - R, fr_R, to_R = place._residue_field() + R, _, to_R = place._residue_field() v = self.valuation(place) if v > 0: return R.zero() - elif v == 0: + if v == 0: return to_R(self) - else: # v < 0 - raise ValueError('has a pole at the place') + # v < 0 + raise ValueError('has a pole at the place') cpdef bint is_nth_power(self, n): r""" diff --git a/src/sage/rings/function_field/element_polymod.pyx b/src/sage/rings/function_field/element_polymod.pyx index 21aa9e36ab3..1e570378a94 100644 --- a/src/sage/rings/function_field/element_polymod.pyx +++ b/src/sage/rings/function_field/element_polymod.pyx @@ -298,7 +298,7 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): # reduce to the separable case poly = self._parent._polynomial if not poly.gcd(poly.derivative()).is_one(): - L, from_L, to_L = self._parent.separable_model(('t', 'w')) + _, from_L, to_L = self._parent.separable_model(('t', 'w')) return from_L(to_L(self).nth_root(n)) constant_base_field = self._parent.constant_base_field() @@ -347,7 +347,7 @@ cdef class FunctionFieldElement_polymod(FunctionFieldElement): # reduce to the separable case poly = self._parent._polynomial if not poly.gcd(poly.derivative()).is_one(): - L, from_L, to_L = self._parent.separable_model(('t', 'w')) + _, _, to_L = self._parent.separable_model(('t', 'w')) return to_L(self).is_nth_power(n) constant_base_field = self._parent.constant_base_field() diff --git a/src/sage/rings/integer_ring.pyx b/src/sage/rings/integer_ring.pyx index b6d6d693b51..8452beaa412 100644 --- a/src/sage/rings/integer_ring.pyx +++ b/src/sage/rings/integer_ring.pyx @@ -413,7 +413,7 @@ cdef class IntegerRing_class(PrincipalIdealDomain): return self if isinstance(x, NumberFieldElement_base): - K, from_K = parent(x).subfield(x) + K, _ = parent(x).subfield(x) return K.order(K.gen()) return PrincipalIdealDomain.__getitem__(self, x) @@ -1651,7 +1651,7 @@ def crt_basis(X, xgcd=None): for i in range(len(X)): p = X[i] others = P // p - g, s, t = p.xgcd(others) + g, _, t = p.xgcd(others) if g != ONE: raise ArithmeticError("the elements of the list X must be coprime in pairs") Y.append(t * others) diff --git a/src/sage/rings/laurent_series_ring_element.pyx b/src/sage/rings/laurent_series_ring_element.pyx index 0ef5b19b2c7..7be60fb4bff 100644 --- a/src/sage/rings/laurent_series_ring_element.pyx +++ b/src/sage/rings/laurent_series_ring_element.pyx @@ -1255,7 +1255,6 @@ cdef class LaurentSeries(AlgebraElement): deg = prec - 1 cdef long i - cdef int c for i in range(val, deg + 1): li = self[i] ri = right[i] diff --git a/src/sage/rings/number_field/number_field_element.pyx b/src/sage/rings/number_field/number_field_element.pyx index 99a79a44821..cc896b641ee 100644 --- a/src/sage/rings/number_field/number_field_element.pyx +++ b/src/sage/rings/number_field/number_field_element.pyx @@ -1514,8 +1514,8 @@ cdef class NumberFieldElement(NumberFieldElement_base): ArithmeticError: vector is not in free module """ K = self.number_field() - V, from_V, to_V = K.absolute_vector_space() - h = K(1) + V, _, to_V = K.absolute_vector_space() + h = K.one() B = [to_V(h)] f = self.absolute_minpoly() for i in range(f.degree()-1): @@ -2041,7 +2041,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): element_fac = [(P.gens_reduced()[0],e) for P,e in fac] # Compute the product of the p^e to figure out the unit from sage.misc.misc_c import prod - element_product = prod([p**e for p,e in element_fac], K(1)) + element_product = prod([p**e for p,e in element_fac], K.one()) from sage.structure.all import Factorization return Factorization(element_fac, unit=self/element_product) @@ -3405,13 +3405,12 @@ cdef class NumberFieldElement(NumberFieldElement_base): 12 sage: z^12==1 and z^6!=1 and z^4!=1 True - """ if self.__multiplicative_order is None: from .number_field import NumberField_cyclotomic if self.is_rational(): if self.is_one(): - self.__multiplicative_order = ZZ(1) + self.__multiplicative_order = ZZ.one() elif (-self).is_one(): self.__multiplicative_order = ZZ(2) else: @@ -4379,7 +4378,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): ## the variable name is irrelevant below, because the ## matrix is over QQ F = K.absolute_field('alpha') - from_f, to_F = F.structure() + _, to_F = F.structure() return to_F(self).matrix() alpha = L.primitive_element() @@ -4392,7 +4391,7 @@ cdef class NumberFieldElement(NumberFieldElement_base): M = K.relativize(beta, (K.variable_name()+'0', L.variable_name()+'0') ) # Carry self over to M. - from_M, to_M = M.structure() + _, to_M = M.structure() try: z = to_M(self) except Exception: diff --git a/src/sage/rings/number_field/number_field_element_quadratic.pyx b/src/sage/rings/number_field/number_field_element_quadratic.pyx index 957c7249846..4b0674e90e6 100644 --- a/src/sage/rings/number_field/number_field_element_quadratic.pyx +++ b/src/sage/rings/number_field/number_field_element_quadratic.pyx @@ -1938,9 +1938,6 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): sage: b._coefficients() [0, 1] """ - # In terms of the generator... - cdef Rational const = Rational.__new__(Rational) - cdef Rational lin = Rational.__new__(Rational) if not self: return [] ad, bd = self.parts() @@ -2429,8 +2426,6 @@ cdef class NumberFieldElement_quadratic_sqrt(NumberFieldElement_quadratic): sage: (3/2*K.one())._coefficients() [3/2] """ - # In terms of the generator... Rational const = Rational.__new__(Rational) - cdef Rational lin = Rational.__new__(Rational) if not self: return [] cdef tuple parts = self.parts() @@ -2852,9 +2847,6 @@ cdef class OrderElement_quadratic(NumberFieldElement_quadratic): sage: aa._coefficients() [0, 1/3] """ - # In terms of the generator... - cdef Rational const = Rational.__new__(Rational) - cdef Rational lin = Rational.__new__(Rational) if not self: return [] ad, bd = self.parts() diff --git a/src/sage/rings/number_field/totallyreal.pyx b/src/sage/rings/number_field/totallyreal.pyx index 6706efc6233..5e2abb154e4 100644 --- a/src/sage/rings/number_field/totallyreal.pyx +++ b/src/sage/rings/number_field/totallyreal.pyx @@ -256,7 +256,6 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False cdef Py_ssize_t k0, lenS cdef tr_data T cdef Integer dB - cdef double db_odlyzko if not isinstance(n, Integer): try: @@ -280,7 +279,6 @@ def enumerate_totallyreal_fields_prim(n, B, a = [], verbose=0, return_seqs=False t2val = B_pari ngt2 = B_pari ng = B_pari - pari_tmp1 = B_pari dB = Integer.__new__(Integer) dB_odlyzko = odlyzko_bound_totallyreal(n_int) diff --git a/src/sage/rings/number_field/totallyreal_data.pyx b/src/sage/rings/number_field/totallyreal_data.pyx index 1eaeeae8343..84e292f79b2 100644 --- a/src/sage/rings/number_field/totallyreal_data.pyx +++ b/src/sage/rings/number_field/totallyreal_data.pyx @@ -120,13 +120,13 @@ cdef double eval_seq_as_poly(int *f, int n, double x): f[n]*x^n + f[n-1]*x^(n-1) + ... + f[0]. """ - cdef double s, xp + cdef double s # Horner's method: With polynomials of small degree, we shouldn't # expect asymptotic methods to be any faster. s = f[n] for i from n > i >= 0: - s = s*x+f[i] + s = s * x + f[i] return s cdef double newton(int *f, int *df, int n, double x0, double eps): @@ -220,13 +220,10 @@ cpdef lagrange_degree_3(int n, int an1, int an2, int an3): sage: sage.rings.number_field.totallyreal_data.lagrange_degree_3(4,12,19,42) [0.0, -1.0] """ - cdef double zmin, zmax, val - cdef double *roots_data cdef long coeffs[7] cdef int r, rsq, rcu cdef int nr, nrsq, nrcu cdef int s1, s1sq, s1cu, s1fo, s2, s2sq, s2cu, s3, s3sq - cdef int found_minmax = 0 RRx = PolynomialRing(RealField(20),'x') @@ -357,11 +354,11 @@ cdef int eval_seq_as_poly_int(int *f, int n, int x): f[n]*x^n + f[n-1]*x^(n-1) + ... + f[0]. """ - cdef int s, xp + cdef int s s = f[n] for i from n > i >= 0: - s = s*x+f[i] + s = s * x + f[i] return s cdef double eps_abs, phi, sqrt2 @@ -374,7 +371,7 @@ cdef int easy_is_irreducible(int *a, int n): Very often, polynomials have roots in {+/-1, +/-2, +/-phi, sqrt2}, so we rule these out quickly. Returns 0 if reducible, 1 if inconclusive. """ - cdef int s, t, st, sgn, i + cdef int s, t, st, i # Check if a has a root in {1,-1,2,-2}. if eval_seq_as_poly_int(a,n,1) == 0 or eval_seq_as_poly_int(a,n,-1) == 0 or eval_seq_as_poly_int(a,n,2) == 0 or eval_seq_as_poly_int(a,n,-2) == 0: @@ -666,8 +663,7 @@ cdef class tr_data: None. The return value is stored in the variable f_out. """ - - cdef int n, np1, k, i, j, nk, kz + cdef int n, np1, k, i, nk, kz cdef int *gnkm cdef int *gnkm1 cdef double *betak diff --git a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx index b442c073250..7f99b0635b5 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx +++ b/src/sage/rings/polynomial/laurent_polynomial_mpair.pyx @@ -1705,7 +1705,7 @@ cdef class LaurentPolynomial_mpair(LaurentPolynomial): cdef dict d, dr cdef ETuple v cdef LaurentPolynomial_mpair ans - cdef list L, mon, exp + cdef list mon, exp cdef Matrix mat = M n = self._parent.ngens() diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 7c9c9813e5e..977989b5978 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -1601,7 +1601,6 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): cdef poly *res cdef ring *r = self._ring cdef number *n - cdef number *denom if self is not f._parent: f = self.coerce(f) @@ -1720,7 +1719,8 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): if g._poly == NULL: raise ArithmeticError("Cannot compute LCM of zero and nonzero element.") - if(self._ring != currRing): rChangeCurrRing(self._ring) + if self._ring != currRing: + rChangeCurrRing(self._ring) pLcm(f._poly, g._poly, m) p_Setm(m, self._ring) @@ -3240,7 +3240,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): 2 """ cdef ring *_ring = self._parent_ring - if(_ring != currRing): rChangeCurrRing(_ring) + if _ring != currRing: + rChangeCurrRing(_ring) if not (p_IsUnit(self._poly,_ring)): raise ArithmeticError("Element is not a unit.") @@ -3271,7 +3272,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): True """ cdef ring *_ring = self._parent_ring - if(_ring != currRing): rChangeCurrRing(_ring) + if _ring != currRing: + rChangeCurrRing(_ring) return bool(p_IsHomogeneous(self._poly,_ring)) cpdef _homogenize(self, int var): @@ -3303,17 +3305,16 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): """ cdef ring *_ring = self._parent_ring cdef MPolynomialRing_libsingular parent = self._parent - cdef MPolynomial_libsingular f if self.is_homogeneous(): return self - if(_ring != currRing): rChangeCurrRing(_ring) + if _ring != currRing: + rChangeCurrRing(_ring) if var < parent._ring.N: - return new_MP(parent, p_Homogen(self._poly, var+1, _ring)) - else: - raise TypeError("var must be < self.parent().ngens()") + return new_MP(parent, p_Homogen(self._poly, var + 1, _ring)) + raise TypeError("var must be < self.parent().ngens()") def is_monomial(self): """ @@ -3344,12 +3345,13 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if self._poly == NULL: return False - if(_ring != currRing): rChangeCurrRing(_ring) + if _ring != currRing: + rChangeCurrRing(_ring) _p = p_Head(self._poly, _ring) _n = p_GetCoeff(_p, _ring) - ret = bool((not self._poly.next) and _ring.cf.cfIsOne(_n,_ring.cf)) + ret = bool((not self._poly.next) and _ring.cf.cfIsOne(_n, _ring.cf)) p_Delete(&_p, _ring) return ret @@ -3672,7 +3674,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): cdef list l = [] cdef MPolynomialRing_libsingular parent = self._parent cdef ring *_ring = parent._ring - if(_ring != currRing): rChangeCurrRing(_ring) + if _ring != currRing: + rChangeCurrRing(_ring) cdef poly *p = p_Copy(self._poly, _ring) cdef poly *t @@ -3771,7 +3774,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): zero = k(0) - if(r != currRing): rChangeCurrRing(r) + if r != currRing: + rChangeCurrRing(r) pTotDegMax = -1 while p2: @@ -3855,7 +3859,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): cdef poly *p cdef poly *v cdef ring *r = self._parent_ring - if(r != currRing): rChangeCurrRing(r) + if r != currRing: + rChangeCurrRing(r) cdef int i l = list() si = set() @@ -3984,7 +3989,8 @@ cdef class MPolynomial_libsingular(MPolynomial_libsingular_base): if self._poly == NULL: return self._parent._base._zero_element - if(_ring != currRing): rChangeCurrRing(_ring) + if _ring != currRing: + rChangeCurrRing(_ring) _p = p_Head(self._poly, _ring) _n = p_GetCoeff(_p, _ring) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 18a0ac6fde6..41b2e4c50ee 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1318,9 +1318,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: R. = QQ[] sage: R.some_elements() [x, y, x + y, x^2 + x*y, 0, 1] - """ - R = self.base_ring() L = list(self.gens()) if L: L.append(L[0] + L[-1]) @@ -1701,7 +1699,6 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): mons_idx = {str(mon): idx for idx, mon in enumerate(mons)} mons_num = len(mons) mons_to_keep = [] - newflist = [] # strip coefficients of the input polynomials: flist = [[f.exponents(), f.coefficients()] for f in flist] numer_matrix = zero_matrix(self.base_ring(), mons_num, sparse=sparse) diff --git a/src/sage/rings/polynomial/pbori/pbori.pyx b/src/sage/rings/polynomial/pbori/pbori.pyx index 06151068427..f7c5807a02c 100644 --- a/src/sage/rings/polynomial/pbori/pbori.pyx +++ b/src/sage/rings/polynomial/pbori/pbori.pyx @@ -2168,8 +2168,6 @@ class BooleanMonomialMonoid(UniqueRepresentation, Monoid_class): var_mapping = get_var_mapping(self, other) except NameError as msg: raise ValueError("cannot convert polynomial %s to %s: %s" % (other, self, msg)) - t = (other)._pbpoly.lead() - m = self._one_element for i in new_BMI_from_BooleanMonomial(other.lm()): m*= var_mapping[i] @@ -2353,7 +2351,6 @@ cdef class BooleanMonomial(MonoidElement): sage: m(x=B(1)) y """ - P = self.parent() if args and kwds: raise ValueError("using keywords and regular arguments not supported") if args: @@ -6440,7 +6437,6 @@ cdef class ReductionStrategy: return deref(self._strat).size() def __getitem__(self, Py_ssize_t i): - cdef PBPoly t if i < 0 or i >= deref(self._strat).size(): raise IndexError return BooleanPolynomialEntry(new_BP_from_PBPoly(self._parent, @@ -6941,7 +6937,6 @@ cdef class GroebnerStrategy: return deref(self._strat).generators.size() def __getitem__(self, Py_ssize_t i): - cdef PBPoly t if i < 0 or i >= deref(self._strat).generators.size(): raise IndexError return new_BP_from_PBPoly(self._parent, deref(self._strat).generators[i].p) @@ -7510,10 +7505,9 @@ def if_then_else(root, a, b): if not isinstance(root, int): raise TypeError("only variables are acceptable as root") - cdef Py_ssize_t* pbind = ring.pbind root = ring.pbind[root] - if (root >= a_set.navigation().value()) or (root >= b_set.navigation().value()): + if root >= a_set.navigation().value() or root >= b_set.navigation().value(): raise IndexError("index of root must be less than " "the values of roots of the branches") @@ -7592,7 +7586,7 @@ cdef BooleanPolynomialRing BooleanPolynomialRing_from_PBRing(PBRing _ring): """ Get BooleanPolynomialRing from C++-implementation """ - cdef int i, j + cdef int i cdef BooleanPolynomialRing self = BooleanPolynomialRing.__new__(BooleanPolynomialRing) cdef int n = _ring.nVariables() diff --git a/src/sage/rings/polynomial/plural.pyx b/src/sage/rings/polynomial/plural.pyx index 9f2b2eb130e..ebc17a01e50 100644 --- a/src/sage/rings/polynomial/plural.pyx +++ b/src/sage/rings/polynomial/plural.pyx @@ -1038,14 +1038,13 @@ cdef class NCPolynomialRing_plural(Ring): .. WARNING:: - Assumes that the head term of f is a multiple of the head - term of g and return the multiplicant m. If this rule is - violated, funny things may happen. + Assumes that the head term of f is a multiple of the head + term of g and return the multiplicant m. If this rule is + violated, funny things may happen. """ cdef poly *res cdef ring *r = self._ring cdef number *n - cdef number *denom if self is not f._parent: f = self.coerce(f) diff --git a/src/sage/rings/polynomial/polydict.pyx b/src/sage/rings/polynomial/polydict.pyx index fb844805fc7..a0040f43e6b 100644 --- a/src/sage/rings/polynomial/polydict.pyx +++ b/src/sage/rings/polynomial/polydict.pyx @@ -787,7 +787,6 @@ cdef class PolyDict: if not self: return "0" - n = len(vars) poly = "" sort_kwargs = {'reverse': True} @@ -886,7 +885,6 @@ cdef class PolyDict: sage: -x - y x + y """ - n = len(vars) poly = "" sort_kwargs = {'reverse': True} if sortkey: @@ -2353,7 +2351,7 @@ cdef class ETuple: """ if not n: raise ZeroDivisionError - cdef size_t i, j + cdef size_t i cdef ETuple result = self._new() result._data = sig_malloc(sizeof(int) * 2 * self._nonzero) result._nonzero = 0 diff --git a/src/sage/rings/polynomial/polynomial_compiled.pyx b/src/sage/rings/polynomial/polynomial_compiled.pyx index 83f33a3a4d2..b84275ef82f 100644 --- a/src/sage/rings/polynomial/polynomial_compiled.pyx +++ b/src/sage/rings/polynomial/polynomial_compiled.pyx @@ -12,7 +12,7 @@ AUTHORS: # # Distributed under the terms of the GNU General Public License (GPL) # -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ ################################################################################ from sage.misc.binary_tree cimport BinaryTree @@ -140,9 +140,8 @@ cdef class CompiledPolynomialFunction: Return the resultant head DAG node, and a binary tree containing the dummy nodes. """ - cdef BinaryTree gaps - cdef int d, i + cdef int d cdef generic_pd s s = univar_pd() @@ -154,7 +153,7 @@ cdef class CompiledPolynomialFunction: s = coeff_pd(d) gap_width = 0 - d-= 1 + d -= 1 while d > 0: gap_width += 1 if self._coeffs[d]: diff --git a/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx index 9cba2eb9e76..e7b708bbc51 100644 --- a/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx @@ -996,15 +996,14 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): sage: f = -30*x; f.factor() (-1) * 2 * 3 * 5 * x """ - cdef int i cdef int deg = ZZX_deg(self.__poly) - # it appears that pari has a window from about degrees 30 and 300 in which it beats NTL. + # it appears that pari has a window from about degrees 30 and 300 + # in which it beats NTL. c = self.content() - g = self//c + g = self // c if deg < 30 or deg > 300: - return c.factor()*g._factor_ntl() - else: - return c.factor()*g._factor_pari() + return c.factor() * g._factor_ntl() + return c.factor() * g._factor_pari() def factor_mod(self, p): """ diff --git a/src/sage/rings/polynomial/polynomial_rational_flint.pyx b/src/sage/rings/polynomial/polynomial_rational_flint.pyx index 8b5af8c4ea1..8dbe789a410 100644 --- a/src/sage/rings/polynomial/polynomial_rational_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_rational_flint.pyx @@ -491,7 +491,6 @@ cdef class Polynomial_rational_flint(Polynomial): """ cdef Polynomial_rational_flint f cdef Rational r - cdef mpz_t tmpz cdef fmpz_t tmpfz cdef fmpq_t tmpfq cdef RealBall arb_a, arb_z diff --git a/src/sage/rings/polynomial/symmetric_reduction.pyx b/src/sage/rings/polynomial/symmetric_reduction.pyx index 68e75475b73..4e5c8b6cf35 100644 --- a/src/sage/rings/polynomial/symmetric_reduction.pyx +++ b/src/sage/rings/polynomial/symmetric_reduction.pyx @@ -583,8 +583,8 @@ cdef class SymmetricReductionStrategy: while True: REDUCTOR = [] for q in lml: - c, P, w = q.symmetric_cancellation_order(p) - if (c is not None) and (c <= 0): + c, P, _ = q.symmetric_cancellation_order(p) + if c is not None and c <= 0: REDUCTOR = [self(q ** P)] break if not REDUCTOR: diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index 6bb650293f2..9eec35e882e 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -1656,7 +1656,6 @@ cdef class RealBall(RingElement): 0.250000000000000 """ cdef RealNumber left, mid, right - cdef long prec = field.precision() cdef int sl, sr if (field.rnd == MPFR_RNDN or field.rnd == MPFR_RNDZ and arb_contains_zero(self.value)): @@ -2428,22 +2427,21 @@ cdef class RealBall(RingElement): False """ cdef RealBall lt, rt - cdef arb_t difference lt = left rt = right if op == Py_EQ: return arb_eq(lt.value, rt.value) - elif op == Py_NE: + if op == Py_NE: return arb_ne(lt.value, rt.value) - elif op == Py_GT: + if op == Py_GT: return arb_gt(lt.value, rt.value) - elif op == Py_LT: + if op == Py_LT: return arb_lt(lt.value, rt.value) - elif op == Py_GE: + if op == Py_GE: return arb_ge(lt.value, rt.value) - elif op == Py_LE: + if op == Py_LE: return arb_le(lt.value, rt.value) def min(self, *others): diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index e2f1b91e3fb..ea7ff07a216 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -5860,21 +5860,20 @@ def create_RealNumber(s, int base=10, int pad=0, rnd="RNDN", int min_prec=53): # Check for a valid base if base < 2 or base > 62: - raise ValueError("base (=%s) must be an integer between 2 and 62"%base) + raise ValueError(f"base (={base}) must be an integer between 2 and 62") if base == 10 and min_prec == 53 and len(s) <= 15 and rnd == "RNDN": R = RR else: # For bases 15 and up, treat 'e' as digit if base <= 14 and ('e' in s or 'E' in s): - #Figure out the exponent - index = max( s.find('e'), s.find('E') ) - exponent = int(s[index+1:]) + # Figure out the exponent + index = max(s.find('e'), s.find('E')) mantissa = s[:index] else: mantissa = s - #Find the first nonzero entry in rest + # Find the first nonzero entry in rest sigfig_mantissa = mantissa.lstrip('-0.') sigfigs = len(sigfig_mantissa) - ('.' in sigfig_mantissa) diff --git a/src/sage/rings/sum_of_squares.pyx b/src/sage/rings/sum_of_squares.pyx index 7e19380441e..8c97f25b0df 100644 --- a/src/sage/rings/sum_of_squares.pyx +++ b/src/sage/rings/sum_of_squares.pyx @@ -307,7 +307,7 @@ def four_squares_pyx(uint32_t n): sage: all(s(four_squares_pyx(n)) == n for n in range(5000,10000)) True """ - cdef uint_fast32_t fac, j, nn + cdef uint_fast32_t fac, j cdef uint_fast32_t i[3] if n == 0: @@ -315,7 +315,7 @@ def four_squares_pyx(uint32_t n): # division by power of 4 fac = 0 - while n%4 == 0: + while n % 4 == 0: n >>= 2 fac += 1 From 40593681d0461a8d65fcbd5982526999fa9863e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 14 Jun 2023 18:15:43 +0200 Subject: [PATCH 184/205] fix details in graphs (indentation) --- src/sage/graphs/graph_database.py | 67 +++++++++++++++---------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/src/sage/graphs/graph_database.py b/src/sage/graphs/graph_database.py index eb83859c9bc..9274ca13452 100644 --- a/src/sage/graphs/graph_database.py +++ b/src/sage/graphs/graph_database.py @@ -73,7 +73,7 @@ def degseq_to_data(degree_sequence): 3221 """ degree_sequence.sort() - return sum(degree_sequence[i]*10**i for i in range(len(degree_sequence))) + return sum(di * 10**i for i, di in enumerate(degree_sequence)) def data_to_degseq(data, graph6=None): @@ -101,9 +101,8 @@ def data_to_degseq(data, graph6=None): if not degseq: # compute number of 0's in list from graph6 string from sage.graphs.generic_graph_pyx import length_and_string_from_graph6 - return length_and_string_from_graph6(str(graph6))[0]*[0] - else: - return degseq + return length_and_string_from_graph6(str(graph6))[0] * [0] + return degseq def graph6_to_plot(graph6): @@ -181,43 +180,43 @@ def subgraphs_to_query(subgraphs, db): # tables columns input data type sqlite data type # ----------------------------------------------------------------------------- aut_grp = ['aut_grp_size', # Integer INTEGER - 'num_orbits', # Integer INTEGER - 'num_fixed_points', # Integer INTEGER - 'vertex_transitive', # bool BOOLEAN - 'edge_transitive'] # bool BOOLEAN + 'num_orbits', # Integer INTEGER + 'num_fixed_points', # Integer INTEGER + 'vertex_transitive', # bool BOOLEAN + 'edge_transitive'] # bool BOOLEAN degrees = ['degree_sequence', # list INTEGER (see degseq_to_data module function) - 'min_degree', # Integer INTEGER - 'max_degree', # Integer INTEGER - 'average_degree', # Real REAL - 'degrees_sd', # Real REAL - 'regular'] # bool BOOLEAN + 'min_degree', # Integer INTEGER + 'max_degree', # Integer INTEGER + 'average_degree', # Real REAL + 'degrees_sd', # Real REAL + 'regular'] # bool BOOLEAN misc = ['vertex_connectivity', # Integer INTEGER - 'edge_connectivity', # Integer INTEGER - 'num_components', # Integer INTEGER - 'girth', # Integer INTEGER - 'radius', # Integer INTEGER - 'diameter', # Integer INTEGER - 'clique_number', # Integer INTEGER - 'independence_number', # Integer INTEGER - 'num_cut_vertices', # Integer INTEGER - 'min_vertex_cover_size', # Integer INTEGER - 'num_spanning_trees', # Integer INTEGER - 'induced_subgraphs'] # String STRING + 'edge_connectivity', # Integer INTEGER + 'num_components', # Integer INTEGER + 'girth', # Integer INTEGER + 'radius', # Integer INTEGER + 'diameter', # Integer INTEGER + 'clique_number', # Integer INTEGER + 'independence_number', # Integer INTEGER + 'num_cut_vertices', # Integer INTEGER + 'min_vertex_cover_size', # Integer INTEGER + 'num_spanning_trees', # Integer INTEGER + 'induced_subgraphs'] # String STRING spectrum = ['spectrum', # String STRING 'min_eigenvalue', # Real REAL 'max_eigenvalue', # Real REAL 'eigenvalues_sd', # Real REAL 'energy'] # Real REAL -graph_data=['complement_graph6', # String STRING - 'eulerian', # bool BOOLEAN - 'graph6', # String STRING - 'lovasz_number', # Real REAL - 'num_cycles', # Integer INTEGER - 'num_edges', # Integer INTEGER - 'num_hamiltonian_cycles', # Integer INTEGER - 'num_vertices', # Integer INTEGER - 'perfect', # bool BOOLEAN - 'planar'] # bool BOOLEAN +graph_data = ['complement_graph6', # String STRING + 'eulerian', # bool BOOLEAN + 'graph6', # String STRING + 'lovasz_number', # Real REAL + 'num_cycles', # Integer INTEGER + 'num_edges', # Integer INTEGER + 'num_hamiltonian_cycles', # Integer INTEGER + 'num_vertices', # Integer INTEGER + 'perfect', # bool BOOLEAN + 'planar'] # bool BOOLEAN valid_kwds = aut_grp + degrees + misc + spectrum + graph_data From dce64d61d19b7c227ea5b749a5f9ff2f283ebca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 14 Jun 2023 20:06:52 +0200 Subject: [PATCH 185/205] a few more details --- src/sage/quadratic_forms/quadratic_form.py | 123 ++++++++---------- .../elliptic_curves/ell_rational_field.py | 24 ++-- 2 files changed, 69 insertions(+), 78 deletions(-) diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index 340d6680c87..1361f2f4aaa 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -125,7 +125,7 @@ def quadratic_form_from_invariants(F, rk, det, P, sminus): """ from sage.arith.misc import hilbert_symbol # normalize input - if F!=QQ: + if F != QQ: raise NotImplementedError('base field must be QQ. If you want this over any field, implement weak approximation.') P = [ZZ(p) for p in P] rk = ZZ(rk) @@ -153,9 +153,9 @@ def quadratic_form_from_invariants(F, rk, det, P, sminus): else: a = ZZ(1) elif rk == 3: - Pprime = [p for p in P if hilbert_symbol(-1, -d, p)==1] - Pprime += [p for p in (2*d).prime_divisors() - if hilbert_symbol(-1, -d, p)==-1 and p not in P] + Pprime = [p for p in P if hilbert_symbol(-1, -d, p) == 1] + Pprime += [p for p in (2 * d).prime_divisors() + if hilbert_symbol(-1, -d, p) == -1 and p not in P] if sminus > 0: a = ZZ(-1) else: @@ -163,23 +163,23 @@ def quadratic_form_from_invariants(F, rk, det, P, sminus): for p in Pprime: if d.valuation(p) % 2 == 0: a *= p - assert all((a*d).valuation(p)%2==1 for p in Pprime) + assert all((a * d).valuation(p) % 2 == 1 for p in Pprime) elif rk == 2: S = P if sminus == 2: S += [-1] - a = QQ.hilbert_symbol_negative_at_S(S,-d) + a = QQ.hilbert_symbol_negative_at_S(S, -d) a = ZZ(a) P = ([p for p in P if hilbert_symbol(a, -d, p) == 1] - +[p for p in (2*a*d).prime_divisors() - if hilbert_symbol(a, -d, p)==-1 and p not in P]) - sminus = max(0, sminus-1) + + [p for p in (2 * a * d).prime_divisors() + if hilbert_symbol(a, -d, p) == -1 and p not in P]) + sminus = max(0, sminus - 1) rk = rk - 1 - d = a*d + d = a * d D.append(a.squarefree_part()) d = d.squarefree_part() D.append(d) - return DiagonalQuadraticForm(QQ,D) + return DiagonalQuadraticForm(QQ, D) class QuadraticForm(SageObject): @@ -606,10 +606,10 @@ def __init__(self, R, n=None, entries=None, unsafe_initialization=False, number_ self.__coeffs = [] for i in range(M.nrows()): for j in range(i, M.nrows()): - if (i == j): - self.__coeffs += [ M_ring(M[i,j] / 2) ] + if i == j: + self.__coeffs += [M_ring(M[i, j] / 2)] else: - self.__coeffs += [ M_ring(M[i,j]) ] + self.__coeffs += [M_ring(M[i, j])] return @@ -649,8 +649,8 @@ def __init__(self, R, n=None, entries=None, unsafe_initialization=False, number_ # Set the number of automorphisms if number_of_automorphisms is not None: self.set_number_of_automorphisms(number_of_automorphisms) - #self.__number_of_automorphisms = number_of_automorphisms - #self.__external_initialization_list.append('number_of_automorphisms') + # self.__number_of_automorphisms = number_of_automorphisms + # self.__external_initialization_list.append('number_of_automorphisms') # Set the determinant if determinant is not None: @@ -827,7 +827,7 @@ def __setitem__(self, ij, coeff): # Set the entry try: - self.__coeffs[i*self.__n - i*(i-1)//2 + j -i] = self.__base_ring(coeff) + self.__coeffs[i*self.__n - i*(i-1)//2 + j - i] = self.__base_ring(coeff) except Exception: raise RuntimeError("this coefficient cannot be coerced to an element of the base ring for the quadratic form") @@ -934,47 +934,42 @@ def sum_by_coefficients_with(self, right): """ if not isinstance(right, QuadraticForm): raise TypeError("cannot add these objects since they are not both quadratic forms") - elif (self.__n != right.__n): + elif self.__n != right.__n: raise TypeError("cannot add these since the quadratic forms do not have the same sizes") - elif (self.__base_ring != right.__base_ring): + elif self.__base_ring != right.__base_ring: raise TypeError("cannot add these since the quadratic forms do not have the same base rings") - return QuadraticForm(self.__base_ring, self.__n, [self.__coeffs[i] + right.__coeffs[i] for i in range(len(self.__coeffs))]) - -# ======================== CHANGE THIS TO A TENSOR PRODUCT?!? Even in Characteristic 2?!? ======================= -# def __mul__(self, right): -# """ -# Multiply (on the right) the quadratic form Q by an element of the ring that Q is defined over. -# -# EXAMPLES:: -# -# sage: Q = QuadraticForm(ZZ, 2, [1,4,10]) -# sage: Q*2 -# Quadratic form in 2 variables over Integer Ring with coefficients: -# [ 2 8 ] -# [ * 20 ] -# -# sage: Q+Q == Q*2 -# True -# -# """ -# try: -# c = self.base_ring()(right) -# except Exception: -# raise TypeError, "Oh no! The multiplier cannot be coerced into the base ring of the quadratic form. =(" -# -# return QuadraticForm(self.base_ring(), self.dim(), [c * self.__coeffs[i] for i in range(len(self.__coeffs))]) - - # ================================================================= + return QuadraticForm(self.__base_ring, self.__n, [self.__coeffs[i] + right.__coeffs[i] for i in range(len(self.__coeffs))]) + + # ======================== CHANGE THIS TO A TENSOR PRODUCT?!? Even in Characteristic 2?!? ======================= + # def __mul__(self, right): + # """ + # Multiply (on the right) the quadratic form Q by an element of the ring that Q is defined over. + # + # EXAMPLES:: + # + # sage: Q = QuadraticForm(ZZ, 2, [1,4,10]) + # sage: Q*2 + # Quadratic form in 2 variables over Integer Ring with coefficients: + # [ 2 8 ] + # [ * 20 ] + # + # sage: Q+Q == Q*2 + # True + # """ + # try: + # c = self.base_ring()(right) + # except Exception: + # raise TypeError("the multiplier cannot be coerced into the base ring of the quadratic form") + # return QuadraticForm(self.base_ring(), self.dim(), [c * self.__coeffs[i] for i in range(len(self.__coeffs))]) def __call__(self, v): r""" Evaluate this quadratic form `Q` on a vector or matrix of elements coercible to the base ring of the quadratic form. - If a vector - is given then the output will be the ring element `Q(v)`, but if a - matrix is given then the output will be the quadratic form `Q'` - which in matrix notation is given by: + If a vector is given then the output will be the ring element + `Q(v)`, but if a matrix is given then the output will be the + quadratic form `Q'` which in matrix notation is given by: .. MATH:: @@ -1116,23 +1111,17 @@ def _is_even_symmetric_matrix_(self, A, R=None): if not isinstance(R, Ring): raise TypeError("R is not a ring.") - if not A.is_square(): + if not (A.is_square() and A.is_symmetric()): return False - # Test that the matrix is symmetric - n = A.nrows() - for i in range(n): - for j in range(i+1, n): - if A[i,j] != A[j,i]: - return False - # Test that all entries coerce to R + n = A.nrows() if not ((A.base_ring() == R) or ring_coerce_test): try: for i in range(n): for j in range(i, n): - R(A[i,j]) - except Exception: + R(A[i, j]) + except (TypeError, ValueError): return False # Test that the diagonal is even (if 1/2 isn't in R) @@ -1180,10 +1169,10 @@ def Hessian_matrix(self): mat_entries = [] for i in range(self.dim()): for j in range(self.dim()): - if (i == j): - mat_entries += [ 2 * self[i,j] ] + if i == j: + mat_entries += [2 * self[i, j]] else: - mat_entries += [ self[i,j] ] + mat_entries += [self[i, j]] return matrix(self.base_ring(), self.dim(), self.dim(), mat_entries) @@ -1384,11 +1373,11 @@ def from_polynomial(poly): if not isinstance(R, MPolynomialRing_base): raise TypeError(f'not a multivariate polynomial ring: {R}') if not all(mon.degree() == 2 for mon in poly.monomials()): - raise ValueError(f'polynomial has monomials of degree != 2') + raise ValueError('polynomial has monomials of degree != 2') base = R.base_ring() vs = R.gens() coeffs = [] - for i,v in enumerate(vs): + for i, v in enumerate(vs): for w in vs[i:]: coeffs.append(poly.monomial_coefficient(v*w)) return QuadraticForm(base, len(vs), coeffs) @@ -1625,7 +1614,7 @@ def level(self): # Warn the user if the form is defined over a field! if self.base_ring().is_field(): warn("Warning -- The level of a quadratic form over a field is always 1. Do you really want to do this?!?") - #raise RuntimeError, "Warning -- The level of a quadratic form over a field is always 1. Do you really want to do this?!?" + # raise RuntimeError("Warning -- The level of a quadratic form over a field is always 1. Do you really want to do this?!?") # Check invertibility and find the inverse try: @@ -1747,7 +1736,7 @@ def bilinear_map(self, v, w): raise TypeError("vectors must have length " + str(self.dim())) if self.base_ring().characteristic() == 2: raise TypeError("not defined for rings of characteristic 2") - return (self(v+w) - self(v) - self(w))/2 + return (self(v + w) - self(v) - self(w)) / 2 def DiagonalQuadraticForm(R, diag): diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 261acb7a67f..c37a33c3bb9 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -6627,22 +6627,23 @@ def reduction_at(p): raise RuntimeError('Unexpected intermediate result. Please try another Mordell-Weil base') d_L_0 = R(b1_norm**2 / c1_LLL) - #Reducing of upper bound + # Reducing of upper bound Q = r * H_q**2 T = (1 + (Z(3)/2*r*H_q))/2 if d_L_0 < R(T**2+Q): d_L_0 = 10*(T**2*Q) low_bound = (R(d_L_0 - Q).sqrt() - T) / c - ##new bound according to low_bound and upper bound - ##[k5*k6 exp(-k7**H_q^2)] + # new bound according to low_bound and upper bound + # [k5*k6 exp(-k7**H_q^2)] if low_bound != 0: H_q_infinity = R(((low_bound/(k6)).log()/(-k7)).sqrt()) - return (H_q_infinity.ceil()) + return H_q_infinity.ceil() else: - return (H_q) - #<------------------------------------------------------------------------- - #>------------------------------------------------------------------------- + return H_q + + # -------------------------------------------------------------------- + # -------------------------------------------------------------------- def S_integral_points_with_bounded_mw_coeffs(): r""" @@ -6726,8 +6727,9 @@ def test_with_T(R): Pi[i] = Pi[i-1] + mw_baseN[i] return xs - #<------------------------------------------------------------------------- - #>------------------------------------------------------------------------- + + # -------------------------------------------------------------------- + # -------------------------------------------------------------------- def S_integral_x_coords_with_abs_bounded_by(abs_bound): r""" @@ -6802,8 +6804,8 @@ def S_integral_x_coords_with_abs_bounded_by(abs_bound): xs += [-tmp] return set(xs) - #<------------------------------------------------------------------------- - #End internal functions ############################################### + # ------------------------------------------------------------------- + # End internal functions ############################################ from sage.misc.mrange import cartesian_product_iterator E = self From 99b44f2d77fb144a6c5802f38709a4dcaa557fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 14 Jun 2023 20:29:53 +0200 Subject: [PATCH 186/205] getting rid of many uses of xrange in pyx files --- src/sage/calculus/interpolators.pyx | 8 +-- src/sage/calculus/riemann.pyx | 68 +++++++++---------- src/sage/coding/binary_code.pyx | 14 ++-- .../coding/codecan/autgroup_can_label.pyx | 24 +++---- src/sage/crypto/boolean_function.pyx | 5 +- src/sage/data_structures/bitset.pyx | 4 +- .../projective_ds_helper.pyx | 10 +-- src/sage/lfunctions/zero_sums.pyx | 4 +- src/sage/libs/coxeter3/coxeter.pyx | 4 +- src/sage/libs/flint/fmpz_poly.pyx | 2 +- src/sage/libs/singular/function.pyx | 22 +++--- src/sage/media/channels.pyx | 2 +- src/sage/misc/binary_tree.pyx | 6 +- src/sage/misc/random_testing.py | 4 +- src/sage/modular/arithgroup/farey_symbol.pyx | 2 +- src/sage/modules/free_module_element.pyx | 4 +- src/sage/modules/vector_integer_dense.pyx | 4 +- src/sage/numerical/gauss_legendre.pyx | 11 +-- src/sage/quadratic_forms/ternary.pyx | 10 +-- src/sage/structure/element.pyx | 4 +- src/sage/symbolic/expression.pyx | 6 +- src/sage/symbolic/getitem_impl.pxi | 3 +- src/sage/symbolic/series_impl.pxi | 26 +++---- 23 files changed, 123 insertions(+), 124 deletions(-) diff --git a/src/sage/calculus/interpolators.pyx b/src/sage/calculus/interpolators.pyx index 662a1fd0ce3..124b9a6f909 100644 --- a/src/sage/calculus/interpolators.pyx +++ b/src/sage/calculus/interpolators.pyx @@ -225,21 +225,21 @@ cdef class CCSpline: cdef int N, i, k N = len(pts) yvec = np.zeros(N, dtype=np.complex128) - for i in xrange(N): + for i in range(N): yvec[i] = 3 * (pts[(i - 1) % N] - 2*pts[i] + pts[(i + 1) % N]) bmat = np.zeros([N, N], dtype=np.complex128) - for i in xrange(N): + for i in range(N): bmat[i, i] = 4 bmat[(i - 1) % N, i] = 1 bmat[(i + 1) % N, i] = 1 bvec = (np.linalg.solve(bmat, yvec)) cvec = np.zeros(N, dtype=np.complex128) - for i in xrange(N): + for i in range(N): cvec[i] = (pts[(i + 1) % N] - pts[i] - 1.0/3.0 * bvec[(i + 1) % N] - 2./3. * bvec[i]) dvec = np.array(pts, dtype=np.complex128) avec = np.zeros(N, dtype=np.complex128) - for i in xrange(N): + for i in range(N): avec[i] = 1.0/3.0 * (bvec[(i + 1) % N] - bvec[i]) self.avec = avec self.bvec = bvec diff --git a/src/sage/calculus/riemann.pyx b/src/sage/calculus/riemann.pyx index 1f038f4ec03..5350f04e707 100644 --- a/src/sage/calculus/riemann.pyx +++ b/src/sage/calculus/riemann.pyx @@ -233,7 +233,7 @@ cdef class Riemann_Map: self.tk = np.array(np.arange(N) * TWOPI / N + 0.001 / N, dtype=FLOAT) self.tk2 = np.zeros(N + 1, dtype=FLOAT) - for i in xrange(N): + for i in range(N): self.tk2[i] = self.tk[i] self.tk2[N] = TWOPI self.B = len(fs) # number of boundaries of the figure @@ -246,14 +246,14 @@ cdef class Riemann_Map: dtype=COMPLEX) # Find the points on the boundaries and their derivatives. if self.exterior: - for k in xrange(self.B): - for i in xrange(N): + for k in range(self.B): + for i in range(N): fk = fs[k](self.tk[N-i-1]) cps[k, i] = complex(1/fk) dps[k, i] = complex(1/fk**2*fprimes[k](self.tk[N-i-1])) else: - for k in xrange(self.B): - for i in xrange(N): + for k in range(self.B): + for i in range(N): cps[k, i] = complex(fs[k](self.tk[i])) dps[k, i] = complex(fprimes[k](self.tk[i])) if self.exterior: @@ -327,7 +327,7 @@ cdef class Riemann_Map: (normalized_dp[t]/(cp-cp[t])).conjugate()) for t in np.arange(NB)], dtype=np.complex128) np.seterr(divide=errdivide,invalid=errinvalid) # resets the error handling - for i in xrange(NB): + for i in range(NB): K[i, i] = 1 # Nystrom Method for solving 2nd kind integrals phi = np.linalg.solve(K, g) / NB * TWOPI @@ -339,22 +339,22 @@ cdef class Riemann_Map: # regions. if B != 1: theta_array = np.zeros([1, NB]) - for i in xrange(NB): + for i in range(NB): theta_array[0, i] = phase(-I * np.power(phi[i], 2) * dp[i]) self.theta_array = np.concatenate( [theta_array.reshape([B, N]), np.zeros([B, 1])], axis=1) - for k in xrange(B): + for k in range(B): self.theta_array[k, N] = self.theta_array[k, 0] + TWOPI # Finding the theta correspondence using abs. Well behaved, but # doesn't work on multiply connected domains. else: phi2 = phi.reshape([self.B, N]) theta_array = np.zeros([B, N + 1], dtype=np.float64) - for k in xrange(B): + for k in range(B): phik = phi2[k] saa = (np.dot(abs(phi), abs(phi))) * TWOPI / NB theta_array[k, 0] = 0 - for i in xrange(1, N): + for i in range(1, N): theta_array[k, i] = ( theta_array[k, i - 1] + ((TWOPI / NB * TWOPI * @@ -368,7 +368,7 @@ cdef class Riemann_Map: t0 = theta_array[k, tmax] + phase(phimax) else: t0 = theta_array[k, tmax] - phase(phimax) - for i in xrange(N): + for i in range(N): theta_array[k, i] = theta_array[k, i] - t0 theta_array[k, N] = TWOPI + theta_array[k, 0] self.theta_array = theta_array @@ -432,7 +432,7 @@ cdef class Riemann_Map: cdef int k, B if boundary < 0: temptk = self.tk - for i in xrange(self.B - 1): + for i in range(self.B - 1): temptk = np.concatenate([temptk, self.tk]) if absolute_value: return np.column_stack( @@ -504,7 +504,7 @@ cdef class Riemann_Map: """ if boundary < 0: temptk = self.tk2 - for i in xrange(self.B - 1): + for i in range(self.B - 1): temptk = np.concatenate([temptk, self.tk2]) return np.column_stack( [temptk, self.theta_array.flatten()]).tolist() @@ -532,8 +532,8 @@ cdef class Riemann_Map: [self.B, N + 1], dtype=np.complex128) cdef int k, i # Lots of setup for Simpson's method of integration. - for k in xrange(self.B): - for i in xrange(N // 3): + for k in range(self.B): + for i in range(N // 3): p_vector[k, 3*i] = (2*coeff * dps[k, 3*i] * exp(I * theta_array[k, 3*i])) p_vector[k, 3*i + 1] = (3*coeff * dps[k, 3*i + 1] * @@ -636,8 +636,8 @@ cdef class Riemann_Map: self.p_vector_inverse = np.zeros([B, N], dtype=np.complex128) # Setup for trapezoid integration because integration points are # not equally spaced. - for k in xrange(B): - for i in xrange(N): + for k in range(B): + for i in range(N): di = theta_array[k, (i + 1) % N] - theta_array[k, (i - 1) % N] if di > PI: di = di - TWOPI @@ -645,12 +645,12 @@ cdef class Riemann_Map: di = di + TWOPI self.p_vector_inverse[k, i] = di / 2 self.sinalpha = np.zeros([B, N], dtype=np.float64) - for k in xrange(B): - for i in xrange(N): + for k in range(B): + for i in range(N): self.sinalpha[k, i] = sin(-theta_array[k, i]) self.cosalpha = np.zeros([B, N], dtype=np.float64) - for k in xrange(B): - for i in xrange(N): + for k in range(B): + for i in range(N): self.cosalpha[k, i] = cos(-theta_array[k, i]) cpdef inverse_riemann_map(self, COMPLEX_T pt): @@ -748,7 +748,7 @@ cdef class Riemann_Map: from sage.plot.all import list_plot plots = list(range(self.B)) - for k in xrange(self.B): + for k in range(self.B): # This conditional should be eliminated when the thickness/pointsize # issue is resolved later. Same for the others in plot_spiderweb(). if plotjoined: @@ -814,13 +814,13 @@ cdef class Riemann_Map: cdef np.ndarray[COMPLEX_T, ndim=2] z_values = np.empty( [y_points, x_points], dtype=np.complex128) if self.exterior: - for i in xrange(x_points): - for j in xrange(y_points): + for i in range(x_points): + for j in range(y_points): pt = 1/(xmin + 0.5*xstep + i*xstep + I*(ymin + 0.5*ystep + j*ystep)) z_values[j, i] = 1/(-np.dot(p_vector,1/(pre_q_vector - pt))) else: - for i in xrange(x_points): - for j in xrange(y_points): + for i in range(x_points): + for j in range(y_points): pt = xmin + 0.5*xstep + i*xstep + I*(ymin + 0.5*ystep + j*ystep) z_values[j, i] = -np.dot(p_vector,1/(pre_q_vector - pt)) return z_values, xmin, xmax, ymin, ymax @@ -949,9 +949,9 @@ cdef class Riemann_Map: s = spline(np.column_stack([self.theta_array[0], self.tk2]).tolist()) tmax = self.theta_array[0, self.N] tmin = self.theta_array[0, 0] - for k in xrange(circles): + for k in range(circles): temp = list(range(pts*2)) - for i in xrange(2*pts): + for i in range(2*pts): temp[i] = self.inverse_riemann_map( (k + 1) / (circles + 1.0) * exp(I*i * TWOPI / (2*pts))) if plotjoined: @@ -961,14 +961,14 @@ cdef class Riemann_Map: circle_list[k] = list_plot(comp_pt(temp, 1), rgbcolor=rgbcolor, pointsize=thickness) line_list = list(range(spokes)) - for k in xrange(spokes): + for k in range(spokes): temp = list(range(pts)) angle = (k*1.0) / spokes * TWOPI if angle >= tmax: angle -= TWOPI elif angle <= tmin: angle += TWOPI - for i in xrange(pts - 1): + for i in range(pts - 1): temp[i] = self.inverse_riemann_map( (i * 1.0) / (pts * 1.0) * exp(I * angle) * linescale) temp[pts - 1] = complex( @@ -1238,8 +1238,8 @@ cpdef complex_to_spiderweb(np.ndarray[COMPLEX_T, ndim = 2] z_values, spoke_angles = srange(-PI,PI+TWOPI/spokes,TWOPI/spokes) else: spoke_angles = [] - for i in xrange(imax-2): # the d arrays are 1 smaller on each side - for j in xrange(jmax-2): + for i in range(imax-2): # the d arrays are 1 smaller on each side + for j in range(jmax-2): z = z_values[i+1,j+1] mag = abs(z) arg = phase(z) @@ -1309,9 +1309,9 @@ cpdef complex_to_rgb(np.ndarray[COMPLEX_T, ndim = 2] z_values): dtype=FLOAT, shape=(imax, jmax, 3)) sig_on() - for i in xrange(imax): + for i in range(imax): row = z_values[i] - for j in xrange(jmax): + for j in range(jmax): z = row[j] mag = abs(z) arg = phase(z) diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index fcd569779f9..0042a5b9594 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -202,10 +202,10 @@ def test_word_perms(t_limit=5.0): raise MemoryError("Error allocating memory.") from sage.misc.prandom import randint from sage.combinat.permutation import Permutations - S = Permutations(list(xrange(n))) + S = Permutations(list(range(n))) t = cputime() while cputime(t) < t_limit: - word = [randint(0, 1) for _ in xrange(n)] + word = [randint(0, 1) for _ in range(n)] cw1 = 0 for j from 0 <= j < n: cw1 += (word[j]) << (j) @@ -298,7 +298,7 @@ cdef WordPermutation *create_word_perm(object list_perm): word_perm.chunk_num = num_chunks words_per_chunk = 1 << chunk_size word_perm.gate = ( (1) << chunk_size ) - 1 - list_perm += list(xrange(len(list_perm), chunk_size*num_chunks)) + list_perm += list(range(len(list_perm), chunk_size*num_chunks)) word_perm.chunk_words = words_per_chunk for i from 0 <= i < num_chunks: images_i = sig_malloc(words_per_chunk * sizeof(codeword)) @@ -661,7 +661,7 @@ cdef codeword *expand_to_ortho_basis(BinaryCode B, int n): for j from i <= j < n: basis[j] = 0 # now basis is length i - perm = list(xrange(B.nrows)) + perm = list(range(B.nrows)) perm_c = [] for j from B.nrows <= j < B.ncols: if (1 << j) & pivots: @@ -669,7 +669,7 @@ cdef codeword *expand_to_ortho_basis(BinaryCode B, int n): else: perm_c.append(j) perm.extend(perm_c) - perm.extend(list(xrange(B.ncols, n))) + perm.extend(list(range(B.ncols, n))) perm_c = [0]*n for j from 0 <= j < n: perm_c[perm[j]] = j @@ -4017,7 +4017,7 @@ cdef class BinaryCodeClassifier: for i from 0 <= i < len(aut_gp_gens): - parent_generators[i] = create_word_perm(aut_gp_gens[i] + list(xrange(B.ncols, n))) + parent_generators[i] = create_word_perm(aut_gp_gens[i] + list(range(B.ncols, n))) word = 0 while ortho_basis[k] & (((1) << B.ncols) - 1): @@ -4116,7 +4116,7 @@ cdef class BinaryCodeClassifier: aut_B_aug = libgap(PermutationGroup([PermutationGroupElement([a+1 for a in g]) for g in aug_aut_gp_gens])) H = libgap(aut_m).Intersection2(aut_B_aug) rt_transversal = [[int(a) - 1 for a in g.ListPerm(n)] for g in aut_B_aug.RightTransversal(H) if not g.IsOne()] - rt_transversal.append(list(xrange(n))) + rt_transversal.append(list(range(n))) bingo2 = 0 for coset_rep in rt_transversal: diff --git a/src/sage/coding/codecan/autgroup_can_label.pyx b/src/sage/coding/codecan/autgroup_can_label.pyx index c83b9264e44..dbb719383d0 100644 --- a/src/sage/coding/codecan/autgroup_can_label.pyx +++ b/src/sage/coding/codecan/autgroup_can_label.pyx @@ -124,8 +124,8 @@ def _cyclic_shift(n, p): sage: p.action(t) [0, 2, 7, 3, 1, 5, 6, 4, 8, 9] """ - x = list(xrange(1, n + 1)) - for i in xrange(1, len(p)): + x = list(range(1, n + 1)) + for i in range(1, len(p)): x[p[i - 1]] = p[i] + 1 x[p[len(p) - 1]] = p[0] + 1 return Permutation(x) @@ -229,17 +229,17 @@ class LinearCodeAutGroupCanLabel: S = SemimonomialTransformationGroup(F, mat.ncols()) if P is None: - P = [list(xrange(mat.ncols()))] + P = [list(range(mat.ncols()))] pos2P = [-1] * mat.ncols() - for i in xrange(len(P)): + for i in range(len(P)): P[i].sort(reverse=True) for x in P[i]: pos2P[x] = i col_list = mat.columns() - nz = [i for i in xrange(mat.ncols()) if not col_list[i].is_zero()] - z = [(pos2P[i], i) for i in xrange(mat.ncols()) if col_list[i].is_zero()] + nz = [i for i in range(mat.ncols()) if not col_list[i].is_zero()] + z = [(pos2P[i], i) for i in range(mat.ncols()) if col_list[i].is_zero()] z.sort() z = [i for (p, i) in z] @@ -259,7 +259,7 @@ class LinearCodeAutGroupCanLabel: col2pos = [] col2P = [] for c in col_set: - X = [(pos2P[y], y) for y in xrange(mat.ncols()) if col_list[y] == c ] + X = [(pos2P[y], y) for y in range(mat.ncols()) if col_list[y] == c ] X.sort() col2pos.append([b for (a, b) in X ]) col2P.append([a for (a, b) in X ]) @@ -272,7 +272,7 @@ class LinearCodeAutGroupCanLabel: P_refined = [] p = [0] act_qty = col2P[0] - for i in xrange(1, len(col_set)): + for i in range(1, len(col_set)): if act_qty == col2P[i]: p.append(i) else: @@ -357,7 +357,7 @@ class LinearCodeAutGroupCanLabel: perm = [-1] * mat.ncols() mult = [F.one()] * mat.ncols() - for i in xrange(len(can_col_set)): + for i in range(len(can_col_set)): img = can_transp.get_perm()(i + 1) for j in col2pos[img - 1]: pos = P[ pos2P[j] ].pop() @@ -378,7 +378,7 @@ class LinearCodeAutGroupCanLabel: self._full_autom_order *= a - for i in xrange(len(col2P)): + for i in range(len(col2P)): if len(col2P[i]) > 1: A, a = self._compute_trivial_automs(normalization, normalization_inverse, col2pos[i], col2P[i]) @@ -508,11 +508,11 @@ class LinearCodeAutGroupCanLabel: n = S.degree() A = [] for g in gens: - perm = list(xrange(1, n + 1)) + perm = list(range(1, n + 1)) mult = [S.base_ring().one()] * n short_perm = g.get_perm() short_mult = g.get_v() - for i in xrange(len(col2pos)): + for i in range(len(col2pos)): c = col2pos[i] img_iter = iter(col2pos[short_perm(i + 1) - 1]) for x in c: diff --git a/src/sage/crypto/boolean_function.pyx b/src/sage/crypto/boolean_function.pyx index adb2405457e..05ec9cfc065 100644 --- a/src/sage/crypto/boolean_function.pyx +++ b/src/sage/crypto/boolean_function.pyx @@ -10,7 +10,7 @@ and also algebraic immunity. EXAMPLES:: - sage: R.=GF(2^8,'a')[] + sage: R. = GF(2^8,'a')[] sage: from sage.crypto.boolean_function import BooleanFunction sage: B = BooleanFunction( x^254 ) # the Boolean function Tr(x^254) sage: B @@ -900,7 +900,8 @@ cdef class BooleanFunction(SageObject): temp[i] = W[i]*W[i] walsh_hadamard(temp, self._nvariables) - self._autocorrelation = tuple([temp[i] >> self._nvariables for i in xrange(n)]) + self._autocorrelation = tuple([temp[i] >> self._nvariables + for i in range(n)]) sig_free(temp) return self._autocorrelation diff --git a/src/sage/data_structures/bitset.pyx b/src/sage/data_structures/bitset.pyx index 29bbeeb0d1c..b49f83f46d6 100644 --- a/src/sage/data_structures/bitset.pyx +++ b/src/sage/data_structures/bitset.pyx @@ -2193,9 +2193,7 @@ def test_bitset(py_a, py_b, long n): print("a.hamming_weight() ", bitset_hamming_weight(a)) - morphism = {} - for i in xrange(a.size): - morphism[i] = a.size - i - 1 + morphism = {i: a.size - i - 1 for i in range(a.size)} bitset_map(r, a, morphism) print("a.map(m) ", bitset_string(r)) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx b/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx index dcb12407b7a..3c547ceb331 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds_helper.pyx @@ -89,7 +89,7 @@ cpdef _fast_possible_periods(self, return_points=False): p = PS.base_ring().order() N = int(PS.dimension_relative()) - point_table = [[0,0] for i in xrange(p**(N + 1))] + point_table = [[0,0] for i in range(p**(N + 1))] index = 1 periods = set() points_periods = [] @@ -173,7 +173,7 @@ def _enum_points(int prime, int dimension): highest_range = prime**dimension while current_range <= highest_range: - for value in xrange(current_range, 2*current_range): + for value in range(current_range, 2*current_range): yield _get_point_from_hash(value, prime, dimension) current_range = current_range * prime @@ -211,7 +211,7 @@ cpdef list _get_point_from_hash(int value, int prime, int dimension): cdef list P = [] cdef int i - for i in xrange(dimension + 1): + for i in range(dimension + 1): P.append(value % prime) value /= prime @@ -258,7 +258,7 @@ cpdef _normalize_coordinates(list point, int prime, int len_points): """ cdef int last_coefficient, coefficient, mod_inverse, val - for coefficient in xrange(len_points): + for coefficient in range(len_points): val = (( point[coefficient]) + prime) % prime point[coefficient] = val if val != 0: @@ -266,7 +266,7 @@ cpdef _normalize_coordinates(list point, int prime, int len_points): mod_inverse = _mod_inv(last_coefficient, prime) - for coefficient in xrange(len_points): + for coefficient in range(len_points): point[coefficient] = (point[coefficient] * mod_inverse) % prime cpdef _all_periodic_points(self): diff --git a/src/sage/lfunctions/zero_sums.pyx b/src/sage/lfunctions/zero_sums.pyx index 251fa0e488f..75ee990b1fc 100644 --- a/src/sage/lfunctions/zero_sums.pyx +++ b/src/sage/lfunctions/zero_sums.pyx @@ -209,8 +209,8 @@ cdef class LFunctionZeroSum_abstract(SageObject): (11, -0.21799047934530644) """ if not python_floats: - return [self.cn(i) for i in xrange(n + 1)] - return [float(self.cn(i)) for i in xrange(n + 1)] + return [self.cn(i) for i in range(n + 1)] + return [float(self.cn(i)) for i in range(n + 1)] def digamma(self, s, include_constant_term=True): r""" diff --git a/src/sage/libs/coxeter3/coxeter.pyx b/src/sage/libs/coxeter3/coxeter.pyx index 9ef1d075be5..61fa617ede1 100644 --- a/src/sage/libs/coxeter3/coxeter.pyx +++ b/src/sage/libs/coxeter3/coxeter.pyx @@ -777,7 +777,7 @@ cdef class CoxGroupElement: """ if isinstance(i, slice): #Get the start, stop, and step from the slice - return [self[ii] for ii in xrange(*i.indices(len(self)))] + return [self[ii] for ii in range(*i.indices(len(self)))] if i < 0: i += len(self) if i >= len(self): @@ -873,7 +873,7 @@ cdef class CoxGroupElement: sage: [a for a in w] # optional - coxeter3 [1, 2, 3] """ - return (self[i] for i in xrange(len(self))) + return (self[i] for i in range(len(self))) def __len__(self): """ diff --git a/src/sage/libs/flint/fmpz_poly.pyx b/src/sage/libs/flint/fmpz_poly.pyx index 38b0e70d143..8811ccf3a51 100644 --- a/src/sage/libs/flint/fmpz_poly.pyx +++ b/src/sage/libs/flint/fmpz_poly.pyx @@ -152,7 +152,7 @@ cdef class Fmpz_poly(SageObject): sage: f.list() [2, 1, 0, -1] """ - return [self[i] for i in xrange(self.degree() + 1)] + return [self[i] for i in range(self.degree() + 1)] def __add__(left, right): """ diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index 411b5eae678..f40346d1fd0 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -686,8 +686,8 @@ cdef class Converter(SageObject): ncols = mat.ncols nrows = mat.nrows result = Matrix(self._sage_ring, nrows, ncols) - for i in xrange(nrows): - for j in xrange(ncols): + for i in range(nrows): + for j in range(ncols): p = new_sage_polynomial(self._sage_ring, mat.m[i*ncols+j]) mat.m[i*ncols+j]=NULL result[i,j] = p @@ -767,8 +767,8 @@ cdef class Converter(SageObject): nrows = mat.rows() result = Matrix(ZZ, nrows, ncols) - for i in xrange(nrows): - for j in xrange(ncols): + for i in range(nrows): + for j in range(ncols): result[i,j] = mat.get(i*ncols+j) return result @@ -828,8 +828,8 @@ cdef class Converter(SageObject): ncols = mat.ncols() nrows = mat.nrows() cdef matrix* _m=mpNew(nrows,ncols) - for i in xrange(nrows): - for j in xrange(ncols): + for i in range(nrows): + for j in range(ncols): #FIXME p = copy_sage_polynomial_into_singular_poly(mat[i,j]) _m.m[ncols*i+j]=p @@ -853,7 +853,7 @@ cdef class Converter(SageObject): cdef lists *singular_list=omAlloc0Bin(slists_bin) singular_list.Init(n) cdef leftv* iv - for i in xrange(n): + for i in range(n): iv=c.pop_front() memcpy(&singular_list.m[i],iv,sizeof(leftv)) omFreeBin(iv, sleftv_bin) @@ -868,7 +868,7 @@ cdef class Converter(SageObject): cdef intvec *iv = new intvec() iv.resize(s) - for i in xrange(s): + for i in range(s): iv.ivGetVec()[i]=a[i] return self._append(iv, INTVEC_CMD) @@ -896,8 +896,8 @@ cdef class Converter(SageObject): cdef int ncols = a.ncols() cdef intvec *iv = new intvec(nrows, ncols, 0) - for i in xrange(nrows): - for j in xrange(ncols): + for i in range(nrows): + for j in range(ncols): iv.ivGetVec()[i*ncols+j]=a[i,j] return self._append(iv, INTMAT_CMD) @@ -971,7 +971,7 @@ cdef class Converter(SageObject): elif rtyp == LIST_CMD: singular_list = to_convert.data ret = [] - for i in xrange(singular_list.nr+1): + for i in range(singular_list.nr+1): ret.append(self.to_python(&(singular_list.m[i]))) return ret elif rtyp == MODUL_CMD: diff --git a/src/sage/media/channels.pyx b/src/sage/media/channels.pyx index d2832abf8ef..266369f3f64 100644 --- a/src/sage/media/channels.pyx +++ b/src/sage/media/channels.pyx @@ -13,7 +13,7 @@ def _separate_channels(_data, _width, _nchannels): cdef int l = len(_data) / (width) - channel_data = [[] for i in xrange(nchannels)] + channel_data = [[] for i in range(nchannels)] if width == 1: # handle the one byte case diff --git a/src/sage/misc/binary_tree.pyx b/src/sage/misc/binary_tree.pyx index c0fe8310c9b..0266699d02b 100644 --- a/src/sage/misc/binary_tree.pyx +++ b/src/sage/misc/binary_tree.pyx @@ -506,9 +506,9 @@ class Test: """ from sage.misc.prandom import randint t = BinaryTree() - for i in xrange(cycles): - r = randint(0,8) - s = randint(0,values) + for i in range(cycles): + r = randint(0, 8) + s = randint(0, values) if r==1: t.insert(s) elif r == 2: diff --git a/src/sage/misc/random_testing.py b/src/sage/misc/random_testing.py index 13ff9be3b57..917d8789b4d 100644 --- a/src/sage/misc/random_testing.py +++ b/src/sage/misc/random_testing.py @@ -54,9 +54,9 @@ def random_testing(fn): fails (raises an exception). If you want a very long-running test using this setup, you should do - something like (in Python 2):: + something like:: - for _ in xrange(10^10): test_foo(100) + for _ in range(10^10): test_foo(100) instead of:: diff --git a/src/sage/modular/arithgroup/farey_symbol.pyx b/src/sage/modular/arithgroup/farey_symbol.pyx index 34b4ebae3f4..863c1d6b654 100644 --- a/src/sage/modular/arithgroup/farey_symbol.pyx +++ b/src/sage/modular/arithgroup/farey_symbol.pyx @@ -609,7 +609,7 @@ cdef class Farey: s = r'\left( -\infty' a = [x._latex_() for x in self.fractions()] + [r'\infty'] b = self.pairings() - for i in xrange(len(a)): + for i in range(len(a)): u = b[i] if u == -3: u = r'\bullet' diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index f4a1ec5c575..8cf65453381 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -2116,9 +2116,9 @@ cdef class FreeModuleElement(Vector): # abstract base class return "()" # compute column widths S = [repr(x) for x in self.list(copy=False)] - #width = max([len(x) for x in S]) + # width = max([len(x) for x in S]) s = "(" - for i in xrange(d): + for i in range(d): if i == d-1: sep = "" else: diff --git a/src/sage/modules/vector_integer_dense.pyx b/src/sage/modules/vector_integer_dense.pyx index 4cdf8eedcc0..22709019993 100644 --- a/src/sage/modules/vector_integer_dense.pyx +++ b/src/sage/modules/vector_integer_dense.pyx @@ -208,8 +208,8 @@ cdef class Vector_integer_dense(free_module_element.FreeModuleElement): (1, 2, 3, 4) """ cdef int i - return [_Integer_from_mpz(self._entries[i]) for i in - xrange(self._degree)] + return [_Integer_from_mpz(self._entries[i]) + for i in range(self._degree)] def __reduce__(self): return (unpickle_v1, (self._parent, self.list(), self._degree, diff --git a/src/sage/numerical/gauss_legendre.pyx b/src/sage/numerical/gauss_legendre.pyx index 7efe3dff724..5325797c7aa 100644 --- a/src/sage/numerical/gauss_legendre.pyx +++ b/src/sage/numerical/gauss_legendre.pyx @@ -132,11 +132,11 @@ def nodes_uncached(degree, prec): else: nodes = [] n = degree - for j in xrange(1, n // 2 + 1): + for j in range(1, n // 2 + 1): r = R(math.cos(math.pi*(j-0.25)/(n+0.5))) while True: t1,t2=ONE,ZERO - for j1 in xrange(1,n+1): + for j1 in range(1,n+1): mpfr_mul(u,r.value,t1.value,rnd) mpfr_mul_si(u,u,2*j1-1,rnd) mpfr_mul_si(v,t2.value,j1-1,rnd) @@ -250,10 +250,11 @@ def estimate_error(results, prec, epsilon): 2.328235...e-10 """ if len(results)==2: - return max((results[0][i]-results[1][i]).abs() for i in xrange(len(results[0]))) + return max((results[0][i]-results[1][i]).abs() + for i in range(len(results[0]))) e = [] - ZERO = 0*epsilon - for i in xrange(len(results[0])): + ZERO = 0 * epsilon + for i in range(len(results[0])): try: if results[-1][i] == results[-2][i] == results[-3][i]: e.append(0*epsilon) diff --git a/src/sage/quadratic_forms/ternary.pyx b/src/sage/quadratic_forms/ternary.pyx index 28db34fd5eb..3fe5ded44dc 100644 --- a/src/sage/quadratic_forms/ternary.pyx +++ b/src/sage/quadratic_forms/ternary.pyx @@ -557,11 +557,11 @@ def _find_zeros_mod_p_odd(long long a, long long b, long long c, long long r, lo cdef long long x0 cdef long long y0 - zeros=[v] - x0=v[0] - y0=v[1] - more=False - for i in xrange(p): + zeros = [v] + x0 = v[0] + y0 = v[1] + more = False + for i in range(p): a_i=(a*x0**2+b*i**2-2*b*i*y0+b*y0**2-t*i*x0+t*x0*y0-2*a*x0+t*i-t*y0+s*x0-r*i+r*y0+a+c-s)%p #b_i=(-2*b*i**2+2*b*i*y0+t*i*x0+2*a*x0-2*t*i+t*y0+r*i-2*a+s)%p if a_i==0: diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index 026991c25d8..36c0d3f0cfa 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -2561,7 +2561,7 @@ cdef class MonoidElement(Element): return [] x = self._parent.one() l = [x] - for i in xrange(n - 1): + for i in range(n - 1): x = x * self l.append(x) return l @@ -2727,7 +2727,7 @@ cdef class RingElement(ModuleElement): return [] x = self._parent.one() l = [x] - for i in xrange(n - 1): + for i in range(n - 1): x = x * self l.append(x) return l diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index bc72df269bc..740975085a0 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -8322,7 +8322,7 @@ cdef class Expression(Expression_abc): else: return new_Expression_from_pyobject(self._parent, y) zero = self._parent.zero() - return zero.add(*(pol[i]*self**i for i in xrange(pol.degree() + 1))) + return zero.add(*(pol[i]*self**i for i in range(pol.degree() + 1))) def collect_common_factors(self): """ @@ -12470,7 +12470,7 @@ cdef class Expression(Expression_abc): ex = self sympy_ex = ex._sympy_() solutions = diophantine(sympy_ex) - if isinstance(solutions, (set)): + if isinstance(solutions, set): solutions = list(solutions) if len(solutions) == 0: @@ -12481,7 +12481,7 @@ cdef class Expression(Expression_abc): solutions = [tuple(SR(s) for s in sol) for sol in solutions] if x is None: wanted_vars = ex.variables() - var_idx = list(xrange(len(ex.variables()))) + var_idx = list(range(len(ex.variables()))) else: if isinstance(x, (list, tuple)): wanted_vars = x diff --git a/src/sage/symbolic/getitem_impl.pxi b/src/sage/symbolic/getitem_impl.pxi index 72bf9d5f0e5..7bbb2dfe852 100644 --- a/src/sage/symbolic/getitem_impl.pxi +++ b/src/sage/symbolic/getitem_impl.pxi @@ -138,8 +138,7 @@ cdef class OperandsWrapper(SageObject): else: step = 1 return [new_Expression_from_GEx(self._expr._parent, - self._expr._gobj.op(ind)) for ind in xrange(bind, eind, step)] - + self._expr._gobj.op(ind)) for ind in range(bind, eind, step)] ind_err_msg = "index should either be a slice object, an integer or a list of integers" if isinstance(arg, (list, tuple)): diff --git a/src/sage/symbolic/series_impl.pxi b/src/sage/symbolic/series_impl.pxi index 4ddea0ffc6f..abac6155572 100644 --- a/src/sage/symbolic/series_impl.pxi +++ b/src/sage/symbolic/series_impl.pxi @@ -240,21 +240,21 @@ cdef class SymbolicSeries(Expression): """ if x is None: x = self.default_variable() - l = [[self.coefficient(x, d), d] for d in xrange(self.degree(x))] + l = [[self.coefficient(x, d), d] for d in range(self.degree(x))] if sparse: return l - else: - from sage.rings.integer_ring import ZZ - if any(not c[1] in ZZ for c in l): - raise ValueError("cannot return dense coefficient list with noninteger exponents") - val = l[0][1] - if val < 0: - raise ValueError("cannot return dense coefficient list with negative valuation") - deg = l[-1][1] - ret = [ZZ(0)] * int(deg+1) - for c in l: - ret[c[1]] = c[0] - return ret + + from sage.rings.integer_ring import ZZ + if any(not c[1] in ZZ for c in l): + raise ValueError("cannot return dense coefficient list with noninteger exponents") + val = l[0][1] + if val < 0: + raise ValueError("cannot return dense coefficient list with negative valuation") + deg = l[-1][1] + ret = [ZZ(0)] * int(deg+1) + for c in l: + ret[c[1]] = c[0] + return ret def power_series(self, base_ring): """ From 7b4046c9afa0b820f238ecdf73c6e0030fd22d7b Mon Sep 17 00:00:00 2001 From: Ewan Davies Date: Wed, 14 Jun 2023 13:25:31 -0600 Subject: [PATCH 187/205] Document that GLPK/exact can be inexact --- src/sage/numerical/backends/glpk_backend.pyx | 12 ++++++++---- src/sage/numerical/backends/glpk_exact_backend.pyx | 10 +++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/sage/numerical/backends/glpk_backend.pyx b/src/sage/numerical/backends/glpk_backend.pyx index fb1ea5845d3..498bc869230 100644 --- a/src/sage/numerical/backends/glpk_backend.pyx +++ b/src/sage/numerical/backends/glpk_backend.pyx @@ -1012,10 +1012,14 @@ cdef class GLPKBackend(GenericBackend): (`get_col_dual` etc.) or tableau data (`get_row_stat` etc.), one needs to switch to "simplex_only" before solving. - GLPK also has an exact rational simplex solver. The only - access to data is via double-precision floats, however. It - reconstructs rationals from doubles and also provides results - as doubles. + GLPK also has an exact rational simplex solver. The only access + to data is via double-precision floats, which means that + rationals in the input data may be rounded before the exact + solver sees them. Thus, it is unreasonable to expect that + arbitrary LPs with rational coefficients are solved exactly. + Once the LP has been read into the backend, it reconstructs + rationals from doubles and does solve exactly over the rationals, + but results are returned as as doubles. EXAMPLES:: diff --git a/src/sage/numerical/backends/glpk_exact_backend.pyx b/src/sage/numerical/backends/glpk_exact_backend.pyx index 0da98460382..3031748eb42 100644 --- a/src/sage/numerical/backends/glpk_exact_backend.pyx +++ b/src/sage/numerical/backends/glpk_exact_backend.pyx @@ -19,9 +19,13 @@ cdef class GLPKExactBackend(GLPKBackend): """ MIP Backend that runs the GLPK solver in exact rational simplex mode. - The only access to data is via double-precision floats, however. It - reconstructs rationals from doubles and also provides results - as doubles. + The only access to data is via double-precision floats, which + means that rationals in the input data may be rounded before + the exact solver sees them. Thus, it is unreasonable to expect + that arbitrary LPs with rational coefficients are solved exactly. + Once the LP has been read into the backend, it reconstructs + rationals from doubles and does solve exactly over the rationals, + but results are returned as as doubles. There is no support for integer variables. """ From 1d061296bc5ce7f8fac7f69cee24cba5b0bed5d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 15 Jun 2023 08:40:54 +0200 Subject: [PATCH 188/205] cylint: no more xrange in matroids --- src/sage/matroids/basis_exchange_matroid.pyx | 50 +++--- src/sage/matroids/basis_matroid.pyx | 28 ++-- src/sage/matroids/extension.pyx | 12 +- src/sage/matroids/lean_matrix.pyx | 40 ++--- src/sage/matroids/linear_matroid.pxd | 1 - src/sage/matroids/linear_matroid.pyx | 155 +++++++++---------- src/sage/matroids/matroid.pyx | 18 +-- src/sage/matroids/set_system.pyx | 42 ++--- src/sage/matroids/unpickling.pyx | 10 +- 9 files changed, 176 insertions(+), 180 deletions(-) diff --git a/src/sage/matroids/basis_exchange_matroid.pyx b/src/sage/matroids/basis_exchange_matroid.pyx index 8555ff67152..b16746da249 100644 --- a/src/sage/matroids/basis_exchange_matroid.pyx +++ b/src/sage/matroids/basis_exchange_matroid.pyx @@ -176,7 +176,7 @@ cdef class BasisExchangeMatroid(Matroid): self._E = groundset self._idx = {} cdef long i - for i in xrange(self._groundset_size): + for i in range(self._groundset_size): self._idx[self._E[i]] = i if basis is not None: @@ -219,7 +219,7 @@ cdef class BasisExchangeMatroid(Matroid): self._groundset = frozenset(E) self._idx = {} - for i in xrange(self._groundset_size): + for i in range(self._groundset_size): self._idx[self._E[i]] = i if self._weak_partition_var: @@ -1090,7 +1090,7 @@ cdef class BasisExchangeMatroid(Matroid): bitset_free(loops) bitset_free(loop) bitset_free(active_rows) - for i in xrange(self.full_rank()): + for i in range(self.full_rank()): bitset_free(comp[i]) sig_free(comp) return res @@ -1267,16 +1267,16 @@ cdef class BasisExchangeMatroid(Matroid): flats = sig_malloc((self.full_rank() + 1) * sizeof(bitset_t)) todo = sig_malloc((self.full_rank() + 1) * sizeof(bitset_t)) - for i in xrange(self.full_rank() + 1): + for i in range(self.full_rank() + 1): bitset_init(flats[i], self._bitset_size) bitset_init(todo[i], self._bitset_size) - f_vec = [0 for i in xrange(self.full_rank() + 1)] + f_vec = [0 for i in range(self.full_rank() + 1)] i = 0 bitset_clear(todo[0]) self.__closure(flats[0], todo[0]) bitset_complement(todo[0], flats[0]) self._f_vector_rec(f_vec, flats, todo, 0, 0) - for i in xrange(self.full_rank() + 1): + for i in range(self.full_rank() + 1): bitset_free(flats[i]) bitset_free(todo[i]) sig_free(flats) @@ -1340,7 +1340,7 @@ cdef class BasisExchangeMatroid(Matroid): flats = sig_malloc((r + 1) * sizeof(bitset_t)) todo = sig_malloc((r + 1) * sizeof(bitset_t)) - for i in xrange(r + 1): + for i in range(r + 1): bitset_init(flats[i], self._bitset_size) bitset_init(todo[i], self._bitset_size) Rflats = SetSystem(self._E) @@ -1349,7 +1349,7 @@ cdef class BasisExchangeMatroid(Matroid): self.__closure(flats[0], todo[0]) bitset_complement(todo[0], flats[0]) self._flats_rec(Rflats, r, flats, todo, 0, 0) - for i in xrange(r + 1): + for i in range(r + 1): bitset_free(flats[i]) bitset_free(todo[i]) sig_free(flats) @@ -1415,7 +1415,7 @@ cdef class BasisExchangeMatroid(Matroid): coflats = sig_malloc((r + 1) * sizeof(bitset_t)) todo = sig_malloc((r + 1) * sizeof(bitset_t)) - for i in xrange(r + 1): + for i in range(r + 1): bitset_init(coflats[i], self._bitset_size) bitset_init(todo[i], self._bitset_size) Rcoflats = SetSystem(self._E) @@ -1424,7 +1424,7 @@ cdef class BasisExchangeMatroid(Matroid): self.__coclosure(coflats[0], todo[0]) bitset_complement(todo[0], coflats[0]) self._coflats_rec(Rcoflats, r, coflats, todo, 0, 0) - for i in xrange(r + 1): + for i in range(r + 1): bitset_free(coflats[i]) bitset_free(todo[i]) sig_free(coflats) @@ -1462,28 +1462,28 @@ cdef class BasisExchangeMatroid(Matroid): flats = sig_malloc((k + 1) * sizeof(bitset_t)) todo = sig_malloc((k + 1) * sizeof(bitset_t)) - for i in xrange(k + 1): + for i in range(k + 1): bitset_init(flats[i], self._bitset_size) bitset_init(todo[i], self._bitset_size) - f_inc = [[0 for e in range(self._groundset_size + 1)] for i in xrange(k + 1)] + f_inc = [[0 for e in range(self._groundset_size + 1)] for i in range(k + 1)] i = 0 bitset_clear(todo[0]) self.__closure(flats[0], todo[0]) bitset_complement(todo[0], flats[0]) self._flat_element_inv_rec(f_inc, k, flats, todo, 0, 0) - for i in xrange(k + 1): + for i in range(k + 1): bitset_free(flats[i]) bitset_free(todo[i]) sig_free(flats) sig_free(todo) fie = {} for e in range(self._groundset_size): - t = tuple([f_inc[i][e] for i in xrange(k + 1)]) + t = tuple([f_inc[i][e] for i in range(k + 1)]) if t in fie: fie[t].add(self._E[e]) else: fie[t] = set([self._E[e]]) - f_vec = tuple([f_inc[i][self._groundset_size] for i in xrange(k + 1)]) + f_vec = tuple([f_inc[i][self._groundset_size] for i in range(k + 1)]) return fie, f_vec cdef _flat_element_inv_rec(self, object f_inc, long R, bitset_t* flats, bitset_t* todo, long elt, long i): @@ -1806,7 +1806,7 @@ cdef class BasisExchangeMatroid(Matroid): if self.__is_independent(self._input): bitset_copy(self._input2, self._current_basis) e = bitset_first(self._current_basis) - for e in xrange(self._groundset_size): + for e in range(self._groundset_size): if not bitset_in(self._current_basis, e): self.__fundamental_circuit(self._output, e) if e > bitset_first(self._output): @@ -1854,7 +1854,7 @@ cdef class BasisExchangeMatroid(Matroid): if self.__is_independent(self._input): bitset_copy(self._input2, self._current_basis) e = bitset_first(self._current_basis) - for e in xrange(self._groundset_size): + for e in range(self._groundset_size): if not bitset_in(self._current_basis, e): self.__fundamental_circuit(self._output, e) if e > bitset_first(self._output): @@ -2162,7 +2162,7 @@ cdef class BasisExchangeMatroid(Matroid): Bitpacked version of ``is_isomorphism``. """ cdef long i - morph = [other._idx[morphism[self._E[i]]] for i in xrange(len(self))] + morph = [other._idx[morphism[self._E[i]]] for i in range(len(self))] bitset_clear(self._input) bitset_set_first_n(self._input, self._matroid_rank) repeat = True @@ -2226,7 +2226,7 @@ cdef class BasisExchangeMatroid(Matroid): if self.full_rank() != other.full_rank(): return None if self.full_rank() == 0 or self.full_corank() == 0: - return {self.groundset_list()[i]: other.groundset_list()[i] for i in xrange(len(self))} + return {self.groundset_list()[i]: other.groundset_list()[i] for i in range(len(self))} if self._weak_invariant() != other._weak_invariant(): return None @@ -2234,7 +2234,7 @@ cdef class BasisExchangeMatroid(Matroid): PO = other._weak_partition() if len(PS) == len(self) and len(PO) == len(other): morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PS[i])] = min(PO[i]) if self.__is_isomorphism(other, morphism): return morphism @@ -2247,7 +2247,7 @@ cdef class BasisExchangeMatroid(Matroid): PO = other._strong_partition() if len(PS) == len(self) and len(PO) == len(other): morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PS[i])] = min(PO[i]) if self.__is_isomorphism(other, morphism): return morphism @@ -2258,7 +2258,7 @@ cdef class BasisExchangeMatroid(Matroid): PHS = self._heuristic_partition() PHO = other._heuristic_partition() morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PHS[i])] = min(PHO[i]) if self.__is_isomorphism(other, morphism): return morphism @@ -2327,7 +2327,7 @@ cdef class BasisExchangeMatroid(Matroid): PO = other._weak_partition() if len(PS) == len(self) and len(PO) == len(other): morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PS[i])] = min(PO[i]) return self.__is_isomorphism(other, morphism) @@ -2337,7 +2337,7 @@ cdef class BasisExchangeMatroid(Matroid): PO = other._strong_partition() if len(PS) == len(self) and len(PO) == len(other): morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PS[i])] = min(PO[i]) return self.__is_isomorphism(other, morphism) @@ -2345,7 +2345,7 @@ cdef class BasisExchangeMatroid(Matroid): PHS = self._heuristic_partition() PHO = other._heuristic_partition() morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PHS[i])] = min(PHO[i]) if self.__is_isomorphism(other, morphism): return True diff --git a/src/sage/matroids/basis_matroid.pyx b/src/sage/matroids/basis_matroid.pyx index 85f09fd8f97..b0b405105af 100644 --- a/src/sage/matroids/basis_matroid.pyx +++ b/src/sage/matroids/basis_matroid.pyx @@ -178,7 +178,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): bitset_init(self._bb, bc) bitset_set_first_n(self._bb, bc) NB = M.nonbases() - for i in xrange(len(NB)): + for i in range(len(NB)): bitset_discard(self._bb, set_to_index(NB._subsets[i])) bitset_init(self._b, (M)._bitset_size) @@ -364,7 +364,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): cdef BasisMatroid D D = BasisMatroid(groundset=self._E, rank=self.full_corank()) N = binom[self._groundset_size][self._matroid_rank] - for i in xrange(N): + for i in range(N): if not bitset_in(self._bb, i): bitset_discard(D._bb, N - i - 1) D.reset_current_basis() @@ -684,8 +684,8 @@ cdef class BasisMatroid(BasisExchangeMatroid): cdef long i, j cdef list bc cdef dict bi - bc = [0 for i in xrange(len(self))] - for i in xrange(binom[self._groundset_size][self._matroid_rank]): + bc = [0 for i in range(len(self))] + for i in range(binom[self._groundset_size][self._matroid_rank]): if not bitset_in(self._bb, i): index_to_set(self._b, i, self._matroid_rank, self._groundset_size) j = bitset_first(self._b) @@ -693,7 +693,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): bc[j] += 1 j = bitset_next(self._b, j + 1) bi = {} - for e in xrange(len(self)): + for e in range(len(self)): if bc[e] in bi: bi[bc[e]].append(e) else: @@ -902,7 +902,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): bitset_complement(bb_comp, self._bb) bitset_init(b2, max(len(self), 1)) - morph = [(other)._idx[morphism[self._E[i]]] for i in xrange(len(self))] + morph = [(other)._idx[morphism[self._E[i]]] for i in range(len(self))] i = bitset_first(bb_comp) while i != -1: index_to_set(self._b, i, self._matroid_rank, self._groundset_size) @@ -993,7 +993,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): if self.full_rank() != other.full_rank(): return None if self.full_rank() == 0: - return {self.groundset_list()[i]: other.groundset_list()[i] for i in xrange(len(self))} + return {self.groundset_list()[i]: other.groundset_list()[i] for i in range(len(self))} if self.bases_count() != other.bases_count(): return None @@ -1003,7 +1003,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): PO = other._bases_partition() if len(PS) == len(self) and len(PO) == len(other): morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PS[i])] = min(PO[i]) if self._is_relaxation(other, morphism): return morphism @@ -1016,7 +1016,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): PO = other._bases_partition2() if len(PS) == len(self) and len(PO) == len(other): morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PS[i])] = min(PO[i]) if self._is_relaxation(other, morphism): return morphism @@ -1027,7 +1027,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): PHS = self._bases_partition3() PHO = other._bases_partition3() morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PHS[i])] = min(PHO[i]) if self._is_relaxation(other, morphism): return morphism @@ -1085,7 +1085,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): PO = other._bases_partition() if len(PS) == len(self) and len(PO) == len(other): morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PS[i])] = min(PO[i]) return self._is_relaxation(other, morphism) @@ -1095,7 +1095,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): PO = other._bases_partition2() if len(PS) == len(self) and len(PO) == len(other): morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PS[i])] = min(PO[i]) return self._is_relaxation(other, morphism) @@ -1103,7 +1103,7 @@ cdef class BasisMatroid(BasisExchangeMatroid): PHS = self._bases_partition3() PHO = other._bases_partition3() morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PHS[i])] = min(PHO[i]) if self._is_relaxation(other, morphism): return True @@ -1246,7 +1246,7 @@ cdef binom_init(long N, long K): if binom[0][0] != 1: binom[0][0] = 1 binom[0][1] = 0 - for n in xrange(1, 2955): + for n in range(1, 2955): bin = 1 k = 0 while bin < 2 ** 32 and k <= 32 and k <= n: diff --git a/src/sage/matroids/extension.pyx b/src/sage/matroids/extension.pyx index d762526d2fa..6043b69077c 100644 --- a/src/sage/matroids/extension.pyx +++ b/src/sage/matroids/extension.pyx @@ -340,8 +340,8 @@ cdef class LinearSubclasses: self._planes_on_line = [[] for l in range(self._hyperlines_count)] self._lines_on_plane = [[] for l in range(self._hyperplanes_count)] - for l in xrange(self._hyperlines_count): - for h in xrange(self._hyperplanes_count): + for l in range(self._hyperlines_count): + for h in range(self._hyperplanes_count): if self._hyperplanes[h] >= self._hyperlines[l]: self._lines_on_plane[h].append(l) self._planes_on_line[l].append(h) @@ -353,10 +353,10 @@ cdef class LinearSubclasses: if line_length is not None: self._line_length = line_length - self._mandatory_lines = [l for l in xrange(self._hyperlines_count) if len(self._planes_on_line[l]) >= line_length] + self._mandatory_lines = [l for l in range(self._hyperlines_count) if len(self._planes_on_line[l]) >= line_length] if subsets is not None: - for p in xrange(self._hyperplanes_count): + for p in range(self._hyperplanes_count): H = self._hyperplanes[p] for S in subsets: if frozenset(S).issubset(H): @@ -370,7 +370,7 @@ cdef class LinearSubclasses: if len(E) != len(E2) or len(F) != 1: raise ValueError("LinearSubclasses: the ground set of the splice matroid is not of the form E + e-f") - for p in xrange(self._hyperplanes_count): + for p in range(self._hyperplanes_count): X = self._hyperplanes[p] - F if splice._rank(X) == splice.full_rank() - 1: if splice._rank(X | F2) == splice.full_rank() - 1: @@ -490,7 +490,7 @@ cdef class MatroidExtensions(LinearSubclasses): BM = BasisMatroid(M) LinearSubclasses.__init__(self, BM, line_length=line_length, subsets=subsets, splice=splice) self._BX = BM._extension(e, []) - self._BH = [BM._extension(e, [self._hyperplanes[i]]) for i in xrange(len(self._hyperplanes))] + self._BH = [BM._extension(e, [self._hyperplanes[i]]) for i in range(len(self._hyperplanes))] if orderly: self._orderly = True diff --git a/src/sage/matroids/lean_matrix.pyx b/src/sage/matroids/lean_matrix.pyx index 145bdd47544..87df80a6f10 100644 --- a/src/sage/matroids/lean_matrix.pyx +++ b/src/sage/matroids/lean_matrix.pyx @@ -339,7 +339,7 @@ cdef class LeanMatrix: """ Get coordinates of nonzero entries of row ``r``. """ - return [i for i in xrange(self._ncols) if self.is_nonzero(r, i)] + return [i for i in range(self._ncols) if self.is_nonzero(r, i)] cdef LeanMatrix transpose(self): """ @@ -545,7 +545,7 @@ cdef class LeanMatrix: - `True, E` -- if there exist a ``m``-separator ``E``. """ - for z in xrange(self.ncols()): + for z in range(self.ncols()): if z in P_cols+Q_cols: continue sol,cert = self.shifting(P_rows,P_cols,Q_rows,Q_cols,z,None,m) @@ -610,22 +610,22 @@ cdef class LeanMatrix: if len(X_1) + len(Y_1) < m: return False, None - cdef set X=set(xrange(self.nrows())) - cdef set Y=set(xrange(self.ncols())) + cdef set X=set(range(self.nrows())) + cdef set Y=set(range(self.ncols())) cdef set X_3 = X-set(X_1+X_2) cdef set Y_3 = Y-set(Y_1+Y_2) cdef list lU_2 = sorted(list(U_2)) cdef list lV_2 = sorted(list(V_2)) - cdef dict rU = dict(zip(lU_2,xrange(len(U_2)))) - cdef dict rV = dict(zip(lV_2,xrange(len(V_2)))) + cdef dict rU = dict(zip(lU_2,range(len(U_2)))) + cdef dict rV = dict(zip(lV_2,range(len(V_2)))) # find a unique representation of every column in U_1xY_3 using columns in U_1xV_2 - B = self.matrix_from_rows_and_columns(list(U_1), xrange(len(Y))) + B = self.matrix_from_rows_and_columns(list(U_1), range(len(Y))) B.gauss_jordan_reduce(lV_2) # find a unique representation of every rows in X_3xV_1 using rows in U_2xV_1 - BT = self.matrix_from_rows_and_columns(xrange(len(X)),list(V_1)).transpose() + BT = self.matrix_from_rows_and_columns(range(len(X)),list(V_1)).transpose() BT.gauss_jordan_reduce(lU_2) cdef set X_p = set(X_1) @@ -1349,17 +1349,17 @@ cdef class BinaryMatrix(LeanMatrix): bitset_complement(mask, mask) # copy relevant part of this matrix into A cdef bitset_t row, row2 - for r in xrange(len(rows)): + for r in range(len(rows)): row = self._M[rows[r]] row2 = A._M[r] bitset_intersection(row2, row, mask) # yes, this is safe - for g in xrange(lg): + for g in range(lg): if bitset_in(row, cols[g]): bitset_add(row2, gaps[g]) # record order of the columns in list `order` - cdef list order = list(xrange(lc)) + cdef list order = list(range(lc)) g = 0 - for g in xrange(lg): + for g in range(lg): order[gaps[g]] = cols[g] # free up the two arrays and the bitset sig_free(gaps) @@ -2026,14 +2026,14 @@ cdef class TernaryMatrix(LeanMatrix): # copy relevant part of this matrix into A cdef bitset_t row0, row1, row0_2, row1_2 cdef mp_bitcnt_t p, q - for r in xrange(len(rows)): + for r in range(len(rows)): row0 = self._M0[rows[r]] row1 = self._M1[rows[r]] row0_2 = A._M0[r] row1_2 = A._M1[r] bitset_intersection(row0_2, row0, mask) # yes, this is safe bitset_intersection(row1_2, row1, mask) # yes, this is safe - for g in xrange(lg): + for g in range(lg): p = cols[g] if bitset_in(row0, p): q = gaps[g] @@ -2041,9 +2041,9 @@ cdef class TernaryMatrix(LeanMatrix): if bitset_in(row1, p): bitset_add(row1_2, q) # record order of the columns in list `order` - cdef list order = list(xrange(lc)) + cdef list order = list(range(lc)) g = 0 - for g in xrange(lg): + for g in range(lg): order[gaps[g]] = cols[g] # free up the two arrays and the bitset sig_free(gaps) @@ -2610,14 +2610,14 @@ cdef class QuaternaryMatrix(LeanMatrix): # copy relevant part of this matrix into A cdef bitset_t row0, row1, row0_2, row1_2 cdef mp_bitcnt_t p, q - for r in xrange(len(rows)): + for r in range(len(rows)): row0 = self._M0[rows[r]] row1 = self._M1[rows[r]] row0_2 = A._M0[r] row1_2 = A._M1[r] bitset_intersection(row0_2, row0, mask) # yes, this is safe bitset_intersection(row1_2, row1, mask) - for g in xrange(lg): + for g in range(lg): p = cols[g] q = gaps[g] if bitset_in(row0, p): @@ -2625,9 +2625,9 @@ cdef class QuaternaryMatrix(LeanMatrix): if bitset_in(row1, p): bitset_add(row1_2, q) # record order of the columns in list `order` - cdef list order = list(xrange(lc)) + cdef list order = list(range(lc)) g = 0 - for g in xrange(lg): + for g in range(lg): order[gaps[g]] = cols[g] # free up the two arrays and the bitset sig_free(gaps) diff --git a/src/sage/matroids/linear_matroid.pxd b/src/sage/matroids/linear_matroid.pxd index 964a00b1808..014c8aef57d 100644 --- a/src/sage/matroids/linear_matroid.pxd +++ b/src/sage/matroids/linear_matroid.pxd @@ -23,7 +23,6 @@ cdef class LinearMatroid(BasisExchangeMatroid): cpdef LeanMatrix _basic_representation(self, B=*) cpdef LeanMatrix _reduced_representation(self, B=*) - cpdef bint _is_field_isomorphism(self, LinearMatroid other, morphism) cpdef is_field_equivalent(self, other) cpdef is_field_isomorphism(self, other, morphism) diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index cd7416c986e..46c1184b9af 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -317,8 +317,8 @@ cdef class LinearMatroid(BasisExchangeMatroid): A = (matrix).copy() # Deprecated Sage matrix operation if keep_initial_representation: self._representation = A.copy() # Deprecated Sage matrix operation - P = gauss_jordan_reduce(A, xrange(A.ncols())) - self._A = A.matrix_from_rows_and_columns(range(len(P)), [c for c in xrange(matrix.ncols()) if c not in P]) + P = gauss_jordan_reduce(A, range(A.ncols())) + self._A = A.matrix_from_rows_and_columns(range(len(P)), [c for c in range(matrix.ncols()) if c not in P]) else: reduced = True if not isinstance(reduced_matrix, LeanMatrix): @@ -328,20 +328,20 @@ cdef class LinearMatroid(BasisExchangeMatroid): self._A = GenericMatrix(reduced_matrix.nrows(), reduced_matrix.ncols(), M=reduced_matrix, ring=ring) else: self._A = (reduced_matrix).copy() # Deprecated Sage matrix operation - P = list(xrange(self._A.nrows())) + P = list(range(self._A.nrows())) self._prow = sig_malloc((self._A.nrows() + self._A.ncols()) * sizeof(long)) if matrix is not None: - for r in xrange(len(P)): + for r in range(len(P)): self._prow[P[r]] = r r = 0 - for c in xrange(A.ncols()): + for c in range(A.ncols()): if c not in P: self._prow[c] = r r += 1 else: - for r from 0 <= r < self._A.nrows(): + for r in range(self._A.nrows()): self._prow[r] = r - for r from 0 <= r < self._A.ncols(): + for r in range(self._A.ncols()): self._prow[self._A.nrows() + r] = r return P @@ -413,7 +413,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): pivi = piv ** (-1) self._A.rescale_row_c(px, pivi, 0) self._A.set_unsafe(px, py, pivi + self._one) # pivoting without column scaling. Add extra so column does not need adjusting - for r in xrange(self._A.nrows()): # if A and A' are the matrices before and after pivoting, then + for r in range(self._A.nrows()): # if A and A' are the matrices before and after pivoting, then a = self._A.get_unsafe(r, py) # ker[I A] equals ker[I A'] except for the labelling of the columns if a and r != px: self._A.add_multiple_of_row_c(r, px, -a, 0) @@ -1175,7 +1175,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): return False if len(PS) == len(self): morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PS[i])] = min(PO[i]) return self._is_field_isomorphism(other, morphism) @@ -1187,7 +1187,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): return False if len(PS) == len(self): morphism = {} - for i in xrange(len(self)): + for i in range(len(self)): morphism[min(PS[i])] = min(PO[i]) return self._is_field_isomorphism(other, morphism) @@ -2094,11 +2094,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): else: M = type(self._A)(self._representation.nrows(), self.size() + 1, self._representation) E = self._E + (element,) - D = {} - for i from 0 <= i < self.size(): - D[E[i]] = i + D = {E[i]: i for i in range(self.size())} for chain in chains: - for i from 0 <= i < M.nrows(): + for i in range(M.nrows()): a = self._zero for e in chain: a += M.get_unsafe(i, D[e]) * chain[e] @@ -2145,11 +2143,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): M = type(self._A)(self._representation.nrows() + 1, self.size() + 1, self._representation) M.set_unsafe(M.nrows() - 1, M.ncols() - 1, self._one) E = self._E + (element,) - D = {} - for i from 0 <= i < self.size(): - D[E[i]] = i + D = {E[i]: i for i in range(self.size())} for cochain in cochains: - for i from 0 <= i < M.ncols() - 1: + for i in range(M.ncols() - 1): M.set_unsafe(M.nrows() - 1, i, 0) for e in cochain: M.set_unsafe(M.nrows() - 1, D[e], -cochain[e]) @@ -2782,9 +2778,9 @@ cdef class LinearMatroid(BasisExchangeMatroid): B[x, y] = 0 # remove row x1 and y1 - Xp = list(xrange(n)) + Xp = list(range(n)) Xp.remove(x1) - Yp = list(xrange(m)) + Yp = list(range(m)) Yp.remove(y1) B = B.matrix_from_rows_and_columns(Xp,Yp) @@ -2864,7 +2860,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): sage: OTG1 is OTG2 True - """ + """ if R is None: R = self.base_ring() @@ -2879,7 +2875,6 @@ cdef class LinearMatroid(BasisExchangeMatroid): else: G, action = G_action, None # the None action is g.__call__ - from sage.algebras.orlik_terao import OrlikTeraoInvariantAlgebra return OrlikTeraoInvariantAlgebra(R, self, G, @@ -3088,17 +3083,17 @@ cdef class BinaryMatroid(LinearMatroid): if keep_initial_representation: self._representation = A.copy() # Deprecated Sage matrix operation if basis is None: - P = gauss_jordan_reduce(A, xrange(A.ncols())) + P = gauss_jordan_reduce(A, range(A.ncols())) A.resize(len(P)) # Not a Sage matrix operation self._A = A else: A = BinaryMatrix(reduced_matrix.nrows(), reduced_matrix.ncols(), M=reduced_matrix) - P = list(xrange(A.nrows())) + P = list(range(A.nrows())) self._A = A.prepend_identity() # Not a Sage matrix operation # Setup groundset, BasisExchangeMatroid data if groundset is None: - groundset = list(xrange(self._A.ncols())) + groundset = list(range(self._A.ncols())) else: if len(groundset) != self._A.ncols(): raise ValueError("size of groundset does not match size of matrix") @@ -3110,17 +3105,17 @@ cdef class BinaryMatroid(LinearMatroid): # Setup index of displayed basis self._prow = sig_malloc((self._A.ncols()) * sizeof(long)) - for c in xrange(self._A.ncols()): + for c in range(self._A.ncols()): self._prow[c] = -1 if matrix is not None: if basis is None: - for r in xrange(len(P)): + for r in range(len(P)): self._prow[P[r]] = r else: - for r in xrange(self._A.nrows()): + for r in range(self._A.nrows()): self._prow[self._idx[basis[r]]] = r else: - for r from 0 <= r < self._A.nrows(): + for r in range(self._A.nrows()): self._prow[r] = r self._zero = GF2_zero @@ -3449,12 +3444,12 @@ cdef class BinaryMatroid(LinearMatroid): i = 0 U = set() while i + d < r: - for j in xrange(i, r - d): + for j in range(i, r - d): if B.row_len(j) % 2 == 1: # Not a Sage matrix operation B.swap_rows_c(i, j) break if B.row_len(i) % 2 == 1: # Not a Sage matrix operation - for j in xrange(i + 1, r - d): + for j in range(i + 1, r - d): if B.row_inner_product(i, j): # Not a Sage matrix operation B.add_multiple_of_row_c(j, i, 1, 0) if B.row_len(i) % 4 == 1: # Not a Sage matrix operation @@ -3464,13 +3459,13 @@ cdef class BinaryMatroid(LinearMatroid): U.add(i) i += 1 else: - for j in xrange(i + 1, r - d): + for j in range(i + 1, r - d): if B.row_inner_product(i, j): # Not a Sage matrix operation B.swap_rows_c(i + 1, j) break if i + 1 < r - d: if B.row_inner_product(i, i + 1): # Not a Sage matrix operation - for j in xrange(i + 2, r): + for j in range(i + 2, r): if B.row_inner_product(i, j): # Not a Sage matrix operation B.add_multiple_of_row_c(j, i + 1, 1, 0) if B.row_inner_product(i + 1, j): # Not a Sage matrix operation @@ -3485,7 +3480,7 @@ cdef class BinaryMatroid(LinearMatroid): d += 1 doubly_even = True - for i in xrange(r - d, r): + for i in range(r - d, r): if B.row_len(i) % 4 == 2: # Not a Sage matrix operation doubly_even = False break @@ -3502,8 +3497,8 @@ cdef class BinaryMatroid(LinearMatroid): self._b_projection = BT._matrix_times_matrix_((B._matrix_times_matrix_(BT))._matrix_times_matrix_(B)) P = [F0, Fp] p = [] - for a in xrange(2): - for b in xrange(a + 1): + for a in range(2): + for b in range(a + 1): x = 0 for i in P[a]: for j in P[b]: @@ -3834,16 +3829,16 @@ cdef class BinaryMatroid(LinearMatroid): c = 1 col = {} - for e in xrange(len(B)): + for e in range(len(B)): for f in range(len(B)): if e is not f: col[e, f] = c c += 1 M = [] r = 0 - for e in xrange(len(B)): - for f in xrange(e): - for g in xrange(f): + for e in range(len(B)): + for f in range(e): + for g in range(f): if not C[e].issuperset(C[f] & C[g]): M.append([col[e,f], col[e,g]]) r += 1 @@ -4154,17 +4149,17 @@ cdef class TernaryMatroid(LinearMatroid): if keep_initial_representation: self._representation = A.copy() # Deprecated Sage matrix operation if basis is None: - P = gauss_jordan_reduce(A, xrange(A.ncols())) + P = gauss_jordan_reduce(A, range(A.ncols())) A.resize(len(P)) # Not a Sage matrix operation self._A = A else: A = TernaryMatrix(reduced_matrix.nrows(), reduced_matrix.ncols(), M=reduced_matrix) - P = list(xrange(A.nrows())) + P = list(range(A.nrows())) self._A = A.prepend_identity() # Not a Sage matrix operation # Setup groundset, BasisExchangeMatroid data if groundset is None: - groundset = list(xrange(self._A.ncols())) + groundset = list(range(self._A.ncols())) else: if len(groundset) != self._A.ncols(): raise ValueError("size of groundset does not match size of matrix") @@ -4176,17 +4171,17 @@ cdef class TernaryMatroid(LinearMatroid): # Setup index of displayed basis self._prow = sig_malloc((self._A.ncols()) * sizeof(long)) - for c in xrange(self._A.ncols()): + for c in range(self._A.ncols()): self._prow[c] = -1 if matrix is not None: if basis is None: - for r in xrange(len(P)): + for r in range(len(P)): self._prow[P[r]] = r else: - for r in xrange(self._A.nrows()): + for r in range(self._A.nrows()): self._prow[self._idx[basis[r]]] = r else: - for r from 0 <= r < self._A.nrows(): + for r in range(self._A.nrows()): self._prow[r] = r self._zero = GF3_zero @@ -4482,7 +4477,7 @@ cdef class TernaryMatroid(LinearMatroid): c = self._one i = 0 while i < r - d: - for j in xrange(i, r - d): + for j in range(i, r - d): if T.row_inner_product(j, j) != 0: # Not a Sage matrix operation if j > i: T.swap_rows_c(i, j) @@ -4497,7 +4492,7 @@ cdef class TernaryMatroid(LinearMatroid): T.swap_rows_c(i, r - d) else: c = c * GF3(x) - for j in xrange(i + 1, r - d): + for j in range(i + 1, r - d): y = T.row_inner_product(i, j) # Not a Sage matrix operation if y == 0: continue @@ -4510,16 +4505,16 @@ cdef class TernaryMatroid(LinearMatroid): TT = T.transpose() self._t_projection = TT._matrix_times_matrix_((T._matrix_times_matrix_(TT))._matrix_times_matrix_(T)) F = frozenset() - for i in xrange(r - d, r): + for i in range(r - d, r): F = F | frozenset(T.nonzero_positions_in_row(i)) - Fa = frozenset([j for j in xrange(len(self)) if self._t_projection.get(j, j) == 0]) - F # Not a Sage matrix operation - Fb = frozenset([j for j in xrange(len(self)) if self._t_projection.get(j, j) == 1]) - F # Not a Sage matrix operation - Fc = frozenset([j for j in xrange(len(self)) if self._t_projection.get(j, j) == -1]) - F # Not a Sage matrix operation + Fa = frozenset([j for j in range(len(self)) if self._t_projection.get(j, j) == 0]) - F # Not a Sage matrix operation + Fb = frozenset([j for j in range(len(self)) if self._t_projection.get(j, j) == 1]) - F # Not a Sage matrix operation + Fc = frozenset([j for j in range(len(self)) if self._t_projection.get(j, j) == -1]) - F # Not a Sage matrix operation P = [Fa, Fb, Fc] p = [] - for a in xrange(3): - for b in xrange(a + 1): + for a in range(3): + for b in range(a + 1): x = 0 for i in P[a]: for j in P[b]: @@ -5053,17 +5048,17 @@ cdef class QuaternaryMatroid(LinearMatroid): if keep_initial_representation: self._representation = A.copy() # Deprecated Sage matrix operation if basis is None: - P = gauss_jordan_reduce(A, xrange(A.ncols())) + P = gauss_jordan_reduce(A, range(A.ncols())) A.resize(len(P)) # Not a Sage matrix operation self._A = A else: A = QuaternaryMatrix(reduced_matrix.nrows(), reduced_matrix.ncols(), M=reduced_matrix, ring=ring) - P = list(xrange(A.nrows())) + P = list(range(A.nrows())) self._A = A.prepend_identity() # Not a Sage matrix operation # Setup groundset, BasisExchangeMatroid data if groundset is None: - groundset = list(xrange(self._A.ncols())) + groundset = list(range(self._A.ncols())) else: if len(groundset) != self._A.ncols(): raise ValueError("size of groundset does not match size of matrix") @@ -5075,17 +5070,17 @@ cdef class QuaternaryMatroid(LinearMatroid): # Setup index of displayed basis self._prow = sig_malloc((self._A.ncols()) * sizeof(long)) - for c in xrange(self._A.ncols()): + for c in range(self._A.ncols()): self._prow[c] = -1 if matrix is not None: if basis is None: - for r in xrange(len(P)): + for r in range(len(P)): self._prow[P[r]] = r else: - for r in xrange(self._A.nrows()): + for r in range(self._A.nrows()): self._prow[self._idx[basis[r]]] = r else: - for r from 0 <= r < self._A.nrows(): + for r in range(self._A.nrows()): self._prow[r] = r self._zero = (self._A)._zero @@ -5336,7 +5331,7 @@ cdef class QuaternaryMatroid(LinearMatroid): d = 0 i = 0 while i < r - d: - for j in xrange(i, r - d): + for j in range(i, r - d): if Q.row_inner_product(j, j) != 0: # Not a Sage matrix operation if j > i: Q.swap_rows_c(i, j) @@ -5351,7 +5346,7 @@ cdef class QuaternaryMatroid(LinearMatroid): d += 1 Q.swap_rows_c(i, r - d) else: - for j in xrange(i + 1, r - d): + for j in range(i + 1, r - d): y = Q.row_inner_product(j, i) # Not a Sage matrix operation if y == 0: continue @@ -5362,15 +5357,15 @@ cdef class QuaternaryMatroid(LinearMatroid): QT.conjugate() # Not a Sage matrix operation self._q_projection = QT._matrix_times_matrix_((Q._matrix_times_matrix_(QT))._matrix_times_matrix_(Q)) F = frozenset() - for i in xrange(r - d, r): + for i in range(r - d, r): F = F | frozenset(Q.nonzero_positions_in_row(i)) - Fa = frozenset([j for j in xrange(len(self)) if self._q_projection.get(j, j) == 0]) - F # Not a Sage matrix operation - Fb = frozenset([j for j in xrange(len(self)) if self._q_projection.get(j, j) == 1]) - F # Not a Sage matrix operation + Fa = frozenset([j for j in range(len(self)) if self._q_projection.get(j, j) == 0]) - F # Not a Sage matrix operation + Fb = frozenset([j for j in range(len(self)) if self._q_projection.get(j, j) == 1]) - F # Not a Sage matrix operation P = [Fa, Fb] p = [] - for a in xrange(2): - for b in xrange(a + 1): + for a in range(2): + for b in range(a + 1): x = 0 for i in P[a]: for j in P[b]: @@ -5782,28 +5777,28 @@ cdef class RegularMatroid(LinearMatroid): A = (matrix).copy() # Deprecated Sage matrix operation if keep_initial_representation: self._representation = A.copy() # Deprecated Sage matrix operation - P = gauss_jordan_reduce(A, xrange(A.ncols())) - self._A = A.matrix_from_rows_and_columns(range(len(P)), [c for c in xrange(matrix.ncols()) if c not in P]) + P = gauss_jordan_reduce(A, range(A.ncols())) + self._A = A.matrix_from_rows_and_columns(range(len(P)), [c for c in range(matrix.ncols()) if c not in P]) else: reduced = True if not isinstance(reduced_matrix, PlusMinusOneMatrix): self._A = PlusMinusOneMatrix(reduced_matrix.nrows(), reduced_matrix.ncols(), M=reduced_matrix) else: self._A = (reduced_matrix).copy() # Deprecated Sage matrix operation - P = list(xrange(self._A.nrows())) + P = list(range(self._A.nrows())) self._prow = sig_malloc((self._A.nrows() + self._A.ncols()) * sizeof(long)) if matrix is not None: - for r in xrange(len(P)): + for r in range(len(P)): self._prow[P[r]] = r r = 0 - for c in xrange(A.ncols()): + for c in range(A.ncols()): if c not in P: self._prow[c] = r r += 1 else: - for r from 0 <= r < self._A.nrows(): + for r in range(self._A.nrows()): self._prow[r] = r - for r from 0 <= r < self._A.ncols(): + for r in range(self._A.ncols()): self._prow[self._A.nrows() + r] = r return P @@ -5855,7 +5850,7 @@ cdef class RegularMatroid(LinearMatroid): pivi = piv # NOTE: 1 and -1 are their own inverses. (self._A).rescale_row_c(px, pivi, 0) (self._A).set(px, py, pivi + 1) # pivoting without column scaling. Add extra so column does not need adjusting # Not a Sage matrix operation - for r in xrange(self._A.nrows()): # if A and A' are the matrices before and after pivoting, then + for r in range(self._A.nrows()): # if A and A' are the matrices before and after pivoting, then a = (self._A).get(r, py) # ker[I A] equals ker[I A'] except for the labelling of the columns # Not a Sage matrix operation if a and r != px: (self._A).add_multiple_of_row_c(r, px, -a, 0) @@ -5981,14 +5976,14 @@ cdef class RegularMatroid(LinearMatroid): A = {} B = {} N = 0 - for i in xrange(P.nrows()): + for i in range(P.nrows()): w = P.get_unsafe(i, i) if w != 0: if w in A: A[w] += 1 else: A[w] = 1 - for j in xrange(i): + for j in range(i): w = abs(P.get_unsafe(i, j)) if w != 0: if w in B: @@ -6047,7 +6042,7 @@ cdef class RegularMatroid(LinearMatroid): else: A[w] = [e] V.append(e) - for j in xrange(i): + for j in range(i): f = self._E[j] w = abs(P.get_unsafe(i, j)) if w != 0: diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 8d641737a8f..111615d5d81 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -2357,7 +2357,7 @@ cdef class Matroid(SageObject): rX = self._rank(XX) if rX > i: return False - for j in xrange(i, len(E) + 1): + for j in range(i, len(E) + 1): for Y in combinations(E, j): YY = frozenset(Y) rY = self._rank(YY) @@ -2510,10 +2510,10 @@ cdef class Matroid(SageObject): sage: [sorted(X) for X in CC[3]] [['a', 'b', 'c', 'd', 'e', 'f', 'g']] """ - CC = [set([]) for r in xrange(self.rank() + 1)] + CC = [set([]) for r in range(self.rank() + 1)] for C in self.circuits(): CC[len(C) - 1].add(self.closure(C)) - return {r: CC[r] for r in xrange(self.rank() + 1) if CC[r]} + return {r: CC[r] for r in range(self.rank() + 1) if CC[r]} cpdef nonspanning_circuit_closures(self): """ @@ -2543,10 +2543,10 @@ cdef class Matroid(SageObject): ... KeyError: 3 """ - CC = [set([]) for r in xrange(self.rank() + 1)] + CC = [set([]) for r in range(self.rank() + 1)] for C in self.nonspanning_circuits(): CC[len(C) - 1].add(self.closure(C)) - return {r: CC[r] for r in xrange(self.rank() + 1) if CC[r]} + return {r: CC[r] for r in range(self.rank() + 1) if CC[r]} cpdef nonbases(self): r""" @@ -2791,7 +2791,7 @@ cdef class Matroid(SageObject): return [] loops = self._closure(set()) flags = [[loops, set(), self.groundset() - loops]] - for r in xrange(r): + for r in range(r): flags = self._extend_flags(flags) return flags @@ -2912,7 +2912,7 @@ cdef class Matroid(SageObject): loops = self._closure(set()) flags = [[loops, set(), self.groundset() - loops]] f_vec = [1] - for r in xrange(self.full_rank()): + for r in range(self.full_rank()): flags = self._extend_flags(flags) f_vec.append(len(flags)) return f_vec @@ -5571,9 +5571,9 @@ cdef class Matroid(SageObject): B[x, y] = 0 # remove row x1 and y1 - Xp = list(xrange(n)) + Xp = list(range(n)) Xp.remove(x1) - Yp = list(xrange(m)) + Yp = list(range(m)) Yp.remove(y1) B = B.matrix_from_rows_and_columns(Xp,Yp) diff --git a/src/sage/matroids/set_system.pyx b/src/sage/matroids/set_system.pyx index d183f6ed5d1..f157b1f9c14 100644 --- a/src/sage/matroids/set_system.pyx +++ b/src/sage/matroids/set_system.pyx @@ -83,7 +83,7 @@ cdef class SetSystem: else: self._groundset = groundset self._idx = {} - for i in xrange(len(groundset)): + for i in range(len(groundset)): self._idx[groundset[i]] = i self._groundset_size = len(groundset) @@ -125,7 +125,7 @@ cdef class SetSystem: def __dealloc__(self): cdef long i - for i in xrange(self._len): + for i in range(self._len): bitset_free(self._subsets[i]) sig_free(self._subsets) bitset_free(self._temp) @@ -205,7 +205,7 @@ cdef class SetSystem: cdef copy(self): cdef SetSystem S S = SetSystem(self._groundset, capacity=len(self)) - for i in xrange(len(self)): + for i in range(len(self)): S._append(self._subsets[i]) return S @@ -232,7 +232,7 @@ cdef class SetSystem: E.append(self._E[i]) self._groundset = E self._idx = {} - for i in xrange(self._groundset_size): + for i in range(self._groundset_size): self._idx[self._groundset[i]] = i cpdef _complements(self): @@ -255,7 +255,7 @@ cdef class SetSystem: if self._groundset_size == 0: return self S = SetSystem(self._groundset, capacity=len(self)) - for i in xrange(len(self)): + for i in range(len(self)): bitset_complement(self._temp, self._subsets[i]) S._append(self._temp) return S @@ -266,7 +266,7 @@ cdef class SetSystem: """ if k is None: k = self._len - for i in xrange(k, self._len): + for i in range(k, self._len): bitset_free(self._subsets[i]) self._len = min(self._len, k) k2 = max(k, 1) @@ -357,7 +357,7 @@ cdef class SetSystem: bitset_complement(active, active) # We compute the union of all sets containing 0, and deactivate them. - for i in xrange(self._len): + for i in range(self._len): if bitset_in(self._subsets[i], 0): bitset_union(self._temp, self._subsets[i], self._temp) bitset_discard(active, i) @@ -388,7 +388,7 @@ cdef class SetSystem: """ cdef long i, e cdef list cnt - cnt = [0 for v in xrange(self._groundset_size)] + cnt = [0 for v in range(self._groundset_size)] for e in E: i = bitset_first(self._subsets[e]) while i >= 0: @@ -405,7 +405,7 @@ cdef class SetSystem: cdef bint split C = {} - for i in xrange(len(P)): + for i in range(len(P)): v = bitset_first(P._subsets[i]) if v < 0: continue @@ -443,7 +443,7 @@ cdef class SetSystem: """ cdef long c c = 0 - for p in xrange(len(P)): + for p in range(len(P)): c <<= bitset_len(P._subsets[p]) bitset_intersection(self._temp, P._subsets[p], self._subsets[e]) c += bitset_len(self._temp) @@ -456,7 +456,7 @@ cdef class SetSystem: if P is None: P = self.groundset_partition() if E is None: - E = xrange(self._len) + E = range(self._len) if len(E) == 0: return [E] @@ -486,7 +486,7 @@ cdef class SetSystem: S = SetSystem(self._groundset, capacity=len(self) + 1) bitset_clear(self._temp) bitset_add(self._temp, v) - for i in xrange(len(self)): + for i in range(len(self)): bitset_difference(S._temp, self._subsets[i], self._temp) S._append(S._temp) S._append(self._temp) @@ -498,7 +498,7 @@ cdef class SetSystem: Helper method for partition methods below. """ if E is None: - E = xrange(self._len) + E = range(self._len) if P is None: if self._groundset: P = SetSystem(self._groundset, [self._groundset], capacity=self._groundset_size) @@ -632,7 +632,7 @@ cdef class SetSystem: [3] """ P, EP, h = self._equitable_partition(P, EP) - for i in xrange(len(P)): + for i in range(len(P)): if bitset_len(P._subsets[i]) > 1: return self._heuristic_partition(P._distinguish(bitset_first(P._subsets[i])), EP) return P, EP, h @@ -675,13 +675,13 @@ cdef class SetSystem: if len(SP) != len(OP): return None p = SP._groundset_size + 1 - for i in xrange(len(SP)): + for i in range(len(SP)): l = bitset_len(SP._subsets[i]) if l != bitset_len(OP._subsets[i]): return None if l != 1 and l < p: p = l - for i in xrange(len(SP)): + for i in range(len(SP)): if bitset_len(SP._subsets[i]) == p: SP2, SEP, sh = self._equitable_partition(SP._distinguish(bitset_first(SP._subsets[i]))) v = bitset_first(OP._subsets[i]) @@ -693,9 +693,9 @@ cdef class SetSystem: return m v = bitset_next(OP._subsets[i], v + 1) return None - if sorted([self.subset_characteristic(SP, i) for i in xrange(len(self))]) != sorted([other.subset_characteristic(OP, i) for i in xrange(len(other))]): + if sorted([self.subset_characteristic(SP, i) for i in range(len(self))]) != sorted([other.subset_characteristic(OP, i) for i in range(len(other))]): return None - return dict([(self._groundset[bitset_first(SP._subsets[i])], other._groundset[bitset_first(OP._subsets[i])]) for i in xrange(len(SP))]) + return dict([(self._groundset[bitset_first(SP._subsets[i])], other._groundset[bitset_first(OP._subsets[i])]) for i in range(len(SP))]) cpdef _equivalence(self, is_equiv, SetSystem other, SetSystem SP=None, SetSystem OP=None): """ @@ -744,10 +744,10 @@ cdef class SetSystem: return None if len(SP) != len(OP): return None - for i in xrange(len(SP)): + for i in range(len(SP)): if bitset_len(SP._subsets[i]) != bitset_len(OP._subsets[i]): return None - for i in xrange(len(SP)): + for i in range(len(SP)): if bitset_len(SP._subsets[i]) > 1: SP2, SEP, sh = self._equitable_partition(SP._distinguish(bitset_first(SP._subsets[i]))) v = bitset_first(OP._subsets[i]) @@ -759,7 +759,7 @@ cdef class SetSystem: return m v = bitset_next(OP._subsets[i], v + 1) return None - morph = dict([(self._groundset[bitset_first(SP._subsets[i])], other._groundset[bitset_first(OP._subsets[i])]) for i in xrange(len(SP))]) + morph = dict([(self._groundset[bitset_first(SP._subsets[i])], other._groundset[bitset_first(OP._subsets[i])]) for i in range(len(SP))]) if is_equiv(self, other, morph): return morph diff --git a/src/sage/matroids/unpickling.pyx b/src/sage/matroids/unpickling.pyx index b37ae49a37f..6f25f5d8883 100644 --- a/src/sage/matroids/unpickling.pyx +++ b/src/sage/matroids/unpickling.pyx @@ -39,6 +39,7 @@ from .graphic_matroid import GraphicMatroid from sage.rings.rational cimport Rational from sage.libs.gmp.mpq cimport mpq_set + ############################################################################# # BasisMatroid ############################################################################# @@ -224,7 +225,7 @@ def unpickle_binary_matrix(version, data): raise TypeError("object was created with newer version of Sage. Please upgrade.") nrows, ncols, versionB, size, limbs, longsize, M = data A = BinaryMatrix(nrows, ncols) - for i from 0 <= i < nrows: + for i in range(nrows): bitset_unpickle(A._M[i], (versionB, size, limbs, longsize, M[i])) return A @@ -253,7 +254,7 @@ def unpickle_ternary_matrix(version, data): raise TypeError("object was created with newer version of Sage. Please upgrade.") nrows, ncols, versionB, size, limbs, longsize, M0, M1 = data A = TernaryMatrix(nrows, ncols) - for i from 0 <= i < nrows: + for i in range(nrows): bitset_unpickle(A._M0[i], (versionB, size, limbs, longsize, M0[i])) bitset_unpickle(A._M1[i], (versionB, size, limbs, longsize, M1[i])) return A @@ -283,7 +284,7 @@ def unpickle_quaternary_matrix(version, data): raise TypeError("object was created with newer version of Sage. Please upgrade.") nrows, ncols, ring, versionB, size, limbs, longsize, M0, M1 = data A = QuaternaryMatrix(nrows, ncols, ring=ring) - for i from 0 <= i < nrows: + for i in range(nrows): bitset_unpickle(A._M0[i], (versionB, size, limbs, longsize, M0[i])) bitset_unpickle(A._M1[i], (versionB, size, limbs, longsize, M1[i])) return A @@ -324,7 +325,7 @@ def unpickle_plus_minus_one_matrix(version, data): raise TypeError("object was created with newer version of Sage. Please upgrade.") cdef PlusMinusOneMatrix A = PlusMinusOneMatrix(data[0], data[1]) cdef long i - for i from 0 <= i < A._nrows * A._ncols: + for i in range(A._nrows * A._ncols): A._entries[i] = data[2][i] return A @@ -332,6 +333,7 @@ def unpickle_plus_minus_one_matrix(version, data): from sage.misc.persist import register_unpickle_override register_unpickle_override("sage.matroids.unpickling", "unpickle_integer_matrix", unpickle_plus_minus_one_matrix) + def unpickle_rational_matrix(version, data): """ Reconstruct a :class:`sage.matroids.lean_matrix.RationalMatrix` object From a5928fd75c65f2653283a11d10d410313460634b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 16 Jun 2023 10:43:18 +0200 Subject: [PATCH 189/205] Update libgap.pyx trying without .value --- src/sage/libs/gap/libgap.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/libs/gap/libgap.pyx b/src/sage/libs/gap/libgap.pyx index 80b1258042a..cb140760a0b 100644 --- a/src/sage/libs/gap/libgap.pyx +++ b/src/sage/libs/gap/libgap.pyx @@ -539,7 +539,7 @@ class Gap(Parent): ... GAPError: Error, VAL_GVAR: No value bound to FooBar """ - return make_any_gap_element(self, GAP_ValueGlobalVariable(variable.value)) + return make_any_gap_element(self, GAP_ValueGlobalVariable(variable)) def global_context(self, variable, value): """ From 4da6cccafabfa715c8449501bf1778ab57ec2029 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Fri, 16 Jun 2023 14:50:27 +0200 Subject: [PATCH 190/205] reduce dependency to rainbow in sage.graphs.graph_coloring --- src/sage/graphs/graph_coloring.pyx | 194 ++++++++++++++++------------- 1 file changed, 110 insertions(+), 84 deletions(-) diff --git a/src/sage/graphs/graph_coloring.pyx b/src/sage/graphs/graph_coloring.pyx index f04f1e382e8..5ad756a3104 100644 --- a/src/sage/graphs/graph_coloring.pyx +++ b/src/sage/graphs/graph_coloring.pyx @@ -46,7 +46,6 @@ do : :meth:`acyclic_edge_coloring` | Compute an acyclic edge coloring of the current graph - AUTHORS: - Tom Boothby (2008-02-21): Initial version @@ -75,7 +74,69 @@ 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): +def format_coloring(data, value_only=False, hex_colors=False, vertex_color_dict=False): + r""" + Helper method for vertex and edge coloring methods. + + INPUT: + + - ``data`` -- either a number when ``value_only`` is ``True`` or a list of + color classes + + - ``value_only`` -- boolean (default: ``False``); when set to ``True``, it + simply returns ``data`` + + - ``hex_colors`` -- boolean (default: ``False``); when set to ``False``, + colors are labeled [0, 1, ..., `n - 1`], otherwise the RGB Hex labeling + is used + + - ``vertex_color_dict`` -- boolean (default: ``False``); when set to + ``True``, it returns a dictionary ``{vertex: color}``, otherwise it + returns a dictionary ``{color: [list of vertices]}`` + + EXAMPLES:: + + sage: from sage.graphs.graph_coloring import format_coloring + sage: color_classes = [['a', 'b'], ['c'], ['d']] + sage: format_coloring(color_classes, value_only=True) + [['a', 'b'], ['c'], ['d']] + sage: format_coloring(len(color_classes), value_only=True) + 3 + sage: format_coloring(color_classes, value_only=False) + {0: ['a', 'b'], 1: ['c'], 2: ['d']} + sage: format_coloring(color_classes, value_only=False, hex_colors=True) + {'#0000ff': ['d'], '#00ff00': ['c'], '#ff0000': ['a', 'b']} + sage: format_coloring(color_classes, value_only=False, hex_colors=False, vertex_color_dict=True) + {'a': 0, 'b': 0, 'c': 1, 'd': 2} + sage: format_coloring(color_classes, value_only=False, hex_colors=True, vertex_color_dict=True) + {'a': '#ff0000', 'b': '#ff0000', 'c': '#00ff00', 'd': '#0000ff'} + + TESTS:: + + sage: from sage.graphs.graph_coloring import format_coloring + sage: format_coloring([], value_only=True) + [] + sage: format_coloring([], value_only=False, hex_colors=True) + {} + sage: format_coloring([], value_only=False, hex_colors=True, vertex_color_dict=True) + {} + sage: format_coloring([], value_only=False, hex_colors=False, vertex_color_dict=True) + {} + """ + if value_only: + return data + if hex_colors: + from sage.plot.colors import rainbow + colors = rainbow(len(data)) + else: + colors = list(range(len(data))) + if vertex_color_dict: + return {u: col for col, C in zip(colors, data) for u in C} + return {col: C for col, C in zip(colors, data) if C} + + +def all_graph_colorings(G, n, count_only=False, hex_colors=False, + vertex_color_dict=False, color_classes=False): r""" Compute all `n`-colorings of a graph. @@ -90,7 +151,7 @@ def all_graph_colorings(G, n, count_only=False, hex_colors=False, vertex_color_d * ``n`` -- a positive integer; the number of colors * ``count_only`` -- boolean (default: ``False``); when set to ``True``, it - returns 1 for each coloring + returns 1 for each coloring and ignores other parameters * ``hex_colors`` -- boolean (default: ``False``); when set to ``False``, colors are labeled [0, 1, ..., `n - 1`], otherwise the RGB Hex labeling @@ -100,6 +161,10 @@ def all_graph_colorings(G, n, count_only=False, hex_colors=False, vertex_color_d ``True``, it returns a dictionary ``{vertex: color}``, otherwise it returns a dictionary ``{color: [list of vertices]}`` + * ``color_classes`` -- boolean (default: ``False``); when set to ``True``, + the method returns only the color classes and ignores parameters + ``hex_colors`` and ``vertex_color_dict`` + .. WARNING:: This method considers only colorings using exactly `n` colors, even if a @@ -170,27 +235,29 @@ def all_graph_colorings(G, n, count_only=False, hex_colors=False, vertex_color_d sage: G = Graph({0: [1], 1: [2]}) sage: for c in all_graph_colorings(G, 2, vertex_color_dict=True): ....: print(c) - {0: 0, 1: 1, 2: 0} - {0: 1, 1: 0, 2: 1} + {0: 0, 2: 0, 1: 1} + {1: 0, 0: 1, 2: 1} sage: for c in all_graph_colorings(G, 2, hex_colors=True): ....: print(sorted(c.items())) [('#00ffff', [1]), ('#ff0000', [0, 2])] [('#00ffff', [0, 2]), ('#ff0000', [1])] sage: for c in all_graph_colorings(G, 2, hex_colors=True, vertex_color_dict=True): ....: print(c) - {0: '#ff0000', 1: '#00ffff', 2: '#ff0000'} - {0: '#00ffff', 1: '#ff0000', 2: '#00ffff'} + {0: '#ff0000', 2: '#ff0000', 1: '#00ffff'} + {1: '#ff0000', 0: '#00ffff', 2: '#00ffff'} sage: for c in all_graph_colorings(G, 2, vertex_color_dict=True): ....: print(c) - {0: 0, 1: 1, 2: 0} - {0: 1, 1: 0, 2: 1} + {0: 0, 2: 0, 1: 1} + {1: 0, 0: 1, 2: 1} sage: for c in all_graph_colorings(G, 2, count_only=True, vertex_color_dict=True): ....: print(c) 1 1 + sage: for c in all_graph_colorings(G, 2, color_classes=True): + ....: print(c) + [[0, 2], [1]] + [[1], [0, 2]] """ - from sage.plot.colors import rainbow - G._scream_if_not_simple(allow_multiple_edges=True) if not n or n > G.order(): @@ -230,48 +297,29 @@ def all_graph_colorings(G, n, count_only=False, hex_colors=False, vertex_color_d for i in range(n * nE): ones.push_back((k + i, [nV + i])) - cdef list colors = rainbow(n) - cdef dict color_dict = {col: i for i, col in enumerate(colors)} - cdef list ones_second = [ones[i].second for i in range(len(ones))] - cdef dict coloring + cdef list coloring cdef set used_colors try: for a in DLXCPP(ones_second): - coloring = {} + coloring = [[] for _ in range(n)] used_colors = set() if count_only: used_colors = set(colormap[x][1] for x in a if x in colormap) - elif vertex_color_dict: - for x in a: - if x in colormap: - v, c = colormap[x] - used_colors.add(c) - if hex_colors: - coloring[v] = colors[c] - else: - coloring[v] = color_dict[colors[c]] else: for x in a: if x in colormap: v, c = colormap[x] used_colors.add(c) - if hex_colors: - if colors[c] in coloring: - coloring[colors[c]].append(v) - else: - coloring[colors[c]] = [v] - else: - if color_dict[colors[c]] in coloring: - coloring[color_dict[colors[c]]].append(v) - else: - coloring[color_dict[colors[c]]] = [v] + coloring[c].append(v) if len(used_colors) == n: if count_only: yield 1 else: - yield coloring + yield format_coloring(coloring, value_only=color_classes, + hex_colors=hex_colors, + vertex_color_dict=vertex_color_dict) except RuntimeError: raise RuntimeError("too much recursion, Graph coloring failed") @@ -310,11 +358,8 @@ cpdef first_coloring(G, n=0, hex_colors=False): G._scream_if_not_simple(allow_multiple_edges=True) cdef int o = G.order() for m in range(n, o + 1): - for C in all_graph_colorings(G, m, hex_colors=True): - if hex_colors: - return C - else: - return list(C.values()) + for C in all_graph_colorings(G, m, hex_colors=hex_colors, color_classes=not hex_colors): + return C cpdef number_of_n_colorings(G, n): @@ -402,7 +447,7 @@ cpdef chromatic_number(G): # don't waste our time coloring. return m for n in range(m, o + 1): - for C in all_graph_colorings(G, n): + for C in all_graph_colorings(G, n, count_only=True): return n @@ -491,7 +536,6 @@ def vertex_coloring(g, k=None, value_only=False, hex_colors=False, solver=None, 4 """ g._scream_if_not_simple(allow_multiple_edges=True) - from sage.plot.colors import rainbow cdef list colorings cdef set vertices cdef list deg @@ -514,18 +558,15 @@ def vertex_coloring(g, k=None, value_only=False, hex_colors=False, solver=None, if not g.size(): if value_only: return 1 - elif hex_colors: - return {rainbow(1)[0]: list(g)} - else: - return [list(g)] + return format_coloring([list(g)], value_only=not hex_colors, + hex_colors=hex_colors) # - Bipartite set if g.is_bipartite(): if value_only: return 2 - elif hex_colors: - return dict(zip(rainbow(2), g.bipartite_sets())) - else: - return g.bipartite_sets() + return format_coloring(g.bipartite_sets(), + value_only=not hex_colors, + hex_colors=hex_colors) # - No need to try any k smaller than the maximum clique in the graph # - No need to try k less than |G|/alpha(G), as each color @@ -553,10 +594,9 @@ def vertex_coloring(g, k=None, value_only=False, hex_colors=False, solver=None, if not g.order(): if value_only: return True - elif hex_colors: - return {color: [] for color in rainbow(k)} - else: - return [[] for i in range(k)] + return format_coloring([[] for i in range(k)], + value_only=not hex_colors, + hex_colors=hex_colors) # Is the graph connected? # This is not so stupid, as the graph could be disconnected # by the test of degeneracy (as previously). @@ -585,10 +625,9 @@ def vertex_coloring(g, k=None, value_only=False, hex_colors=False, solver=None, for color in range(k): for component in colorings: value[color].extend(component[color]) - if hex_colors: - return dict(zip(rainbow(k), value)) - else: - return value + + return format_coloring(value, value_only=not hex_colors, + hex_colors=hex_colors) # Degeneracy # Vertices whose degree is less than k are of no importance in @@ -623,10 +662,9 @@ def vertex_coloring(g, k=None, value_only=False, hex_colors=False, solver=None, classe.append(deg[-1]) deg.pop(-1) break - if hex_colors: - return dict(zip(rainbow(k), value)) - else: - return value + + return format_coloring(value, value_only=not hex_colors, + hex_colors=hex_colors) p = MixedIntegerLinearProgram(maximization=True, solver=solver) color = p.new_variable(binary=True) @@ -664,10 +702,8 @@ def vertex_coloring(g, k=None, value_only=False, hex_colors=False, solver=None, classes[i].append(v) break - if hex_colors: - return dict(zip(rainbow(len(classes)), classes)) - else: - return classes + return format_coloring(classes, value_only=not hex_colors, + hex_colors=hex_colors) # Fractional relaxations @@ -1385,7 +1421,6 @@ def edge_coloring(g, value_only=False, vizing=False, hex_colors=False, solver=No {} """ g._scream_if_not_simple() - from sage.plot.colors import rainbow if not g.order() or not g.size(): if value_only: @@ -1492,10 +1527,7 @@ def edge_coloring(g, value_only=False, vizing=False, hex_colors=False, solver=No return chi # if needed, builds a dictionary from the color classes adding colors - if hex_colors: - return dict(zip(rainbow(len(classes)), classes)) - else: - return classes + return format_coloring(classes, value_only=not hex_colors, hex_colors=hex_colors) def _vizing_edge_coloring(g): @@ -1861,8 +1893,6 @@ def linear_arboricity(g, plus_one=None, hex_colors=False, value_only=False, else: raise ValueError("plus_one must be equal to 0,1, or to None!") - from sage.plot.colors import rainbow - p = MixedIntegerLinearProgram(solver=solver) # c is a boolean value such that c[i,(u,v)] = 1 if and only if (u,v) is @@ -1928,10 +1958,7 @@ def linear_arboricity(g, plus_one=None, hex_colors=False, value_only=False, if c[i, frozenset((u, v))]: add((u, v), i) - if hex_colors: - return dict(zip(rainbow(len(answer)), answer)) - else: - return answer + return format_coloring(answer, value_only=not hex_colors, hex_colors=hex_colors) def acyclic_edge_coloring(g, hex_colors=False, value_only=False, k=0, @@ -2079,7 +2106,6 @@ def acyclic_edge_coloring(g, hex_colors=False, value_only=False, k=0, from sage.rings.integer import Integer from sage.combinat.subset import Subsets - from sage.plot.colors import rainbow if not g.order() or not g.size(): if k == 0: @@ -2089,7 +2115,10 @@ def acyclic_edge_coloring(g, hex_colors=False, value_only=False, k=0, else: if k is None: return {} if hex_colors else [] - return {c: [] for c in rainbow(k)} if hex_colors else [copy(g) for _ in range(k)] + if hex_colors: + return format_coloring([[] for _ in range(k)], hex_colors=True) + else: + return [copy(g) for _ in range(k)] if k is None: k = max(g.degree()) @@ -2181,10 +2210,7 @@ def acyclic_edge_coloring(g, hex_colors=False, value_only=False, k=0, if c[i, E(u, v)]: add((u, v), i) - if hex_colors: - return dict(zip(rainbow(len(answer)), answer)) - else: - return answer + return format_coloring(answer, value_only=not hex_colors, hex_colors=hex_colors) cdef class Test: From 2697eed63deae7757bf44e6d15a66d21f6d3796f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 16 Jun 2023 16:00:13 +0200 Subject: [PATCH 191/205] Update libgap.pyx adding str_to_bytes --- src/sage/libs/gap/libgap.pyx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/libs/gap/libgap.pyx b/src/sage/libs/gap/libgap.pyx index cb140760a0b..e34b7f9f1cb 100644 --- a/src/sage/libs/gap/libgap.pyx +++ b/src/sage/libs/gap/libgap.pyx @@ -217,6 +217,7 @@ from .gap_includes cimport * from .util cimport * from .element cimport * +from sage.cpython.string cimport str_to_bytes from sage.structure.parent cimport Parent from sage.structure.element cimport Vector from sage.rings.integer_ring import ZZ @@ -539,7 +540,7 @@ class Gap(Parent): ... GAPError: Error, VAL_GVAR: No value bound to FooBar """ - return make_any_gap_element(self, GAP_ValueGlobalVariable(variable)) + return make_any_gap_element(self, GAP_ValueGlobalVariable(str_to_bytes(variable))) def global_context(self, variable, value): """ From 6ef2b63023186a8af056502d981b8f3f17870987 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Fri, 16 Jun 2023 18:00:31 +0200 Subject: [PATCH 192/205] PR #35780: better description --- src/sage/graphs/graph_coloring.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/graph_coloring.pyx b/src/sage/graphs/graph_coloring.pyx index 5ad756a3104..9828cdf5585 100644 --- a/src/sage/graphs/graph_coloring.pyx +++ b/src/sage/graphs/graph_coloring.pyx @@ -162,8 +162,8 @@ def all_graph_colorings(G, n, count_only=False, hex_colors=False, returns a dictionary ``{color: [list of vertices]}`` * ``color_classes`` -- boolean (default: ``False``); when set to ``True``, - the method returns only the color classes and ignores parameters - ``hex_colors`` and ``vertex_color_dict`` + the method returns only a list of the the color classes and ignores + parameters ``hex_colors`` and ``vertex_color_dict`` .. WARNING:: From 7d97f68a29ede00f169fc31862036600687820c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 16 Jun 2023 20:10:53 +0200 Subject: [PATCH 193/205] Update libgap.pyx now returning NULL for undefined GAP variables, instead of raising GapError --- src/sage/libs/gap/libgap.pyx | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/sage/libs/gap/libgap.pyx b/src/sage/libs/gap/libgap.pyx index e34b7f9f1cb..c16de9104fb 100644 --- a/src/sage/libs/gap/libgap.pyx +++ b/src/sage/libs/gap/libgap.pyx @@ -479,9 +479,7 @@ class Gap(Parent): 1 sage: libgap.unset_global('FooBar') sage: libgap.get_global('FooBar') - Traceback (most recent call last): - ... - GAPError: Error, VAL_GVAR: No value bound to FooBar + NULL """ is_bound = self.function_factory('IsBoundGlobal') bind_global = self.function_factory('BindGlobal') @@ -504,9 +502,7 @@ class Gap(Parent): 1 sage: libgap.unset_global('FooBar') sage: libgap.get_global('FooBar') - Traceback (most recent call last): - ... - GAPError: Error, VAL_GVAR: No value bound to FooBar + NULL """ is_readonlyglobal = self.function_factory('IsReadOnlyGlobal') make_readwrite = self.function_factory('MakeReadWriteGlobal') @@ -536,9 +532,7 @@ class Gap(Parent): 1 sage: libgap.unset_global('FooBar') sage: libgap.get_global('FooBar') - Traceback (most recent call last): - ... - GAPError: Error, VAL_GVAR: No value bound to FooBar + NULL """ return make_any_gap_element(self, GAP_ValueGlobalVariable(str_to_bytes(variable))) From e6be1da89d126787626e4217e77ab5d3888654ff Mon Sep 17 00:00:00 2001 From: dcoudert Date: Fri, 16 Jun 2023 20:44:30 +0200 Subject: [PATCH 194/205] PR #35780: fix typo --- src/sage/graphs/graph_coloring.pyx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/graph_coloring.pyx b/src/sage/graphs/graph_coloring.pyx index 9828cdf5585..0b34088ef9c 100644 --- a/src/sage/graphs/graph_coloring.pyx +++ b/src/sage/graphs/graph_coloring.pyx @@ -162,8 +162,8 @@ def all_graph_colorings(G, n, count_only=False, hex_colors=False, returns a dictionary ``{color: [list of vertices]}`` * ``color_classes`` -- boolean (default: ``False``); when set to ``True``, - the method returns only a list of the the color classes and ignores - parameters ``hex_colors`` and ``vertex_color_dict`` + the method returns only a list of the color classes and ignores parameters + ``hex_colors`` and ``vertex_color_dict`` .. WARNING:: @@ -1124,9 +1124,9 @@ def b_coloring(g, k, value_only=True, solver=None, verbose=0, proper coloring where each color class has a b-vertex. In the worst case, after successive applications of the above procedure, one - get a proper coloring that uses a number of colors equal to the the - b-chromatic number of `G` (denoted `\chi_b(G)`): the maximum `k` such that - `G` admits a b-coloring with `k` colors. + get a proper coloring that uses a number of colors equal to the b-chromatic + number of `G` (denoted `\chi_b(G)`): the maximum `k` such that `G` admits a + b-coloring with `k` colors. A useful upper bound for calculating the b-chromatic number is the following. If `G` admits a b-coloring with `k` colors, then there are `k` From 840df5c034a325e492ba9f7863a90dfecb541bcc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 16 Jun 2023 16:30:04 -0700 Subject: [PATCH 195/205] src/sage/dynamics/arithmetic_dynamics/projective_ds.py: Wrap long lines --- .../arithmetic_dynamics/projective_ds.py | 53 +++++++++++-------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 2e40776fb9d..534cca093af 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -1869,9 +1869,13 @@ def conjugate(self, M, adjugate=False, normalize=False): - ``M`` -- a square invertible matrix - - ``adjugate`` -- (default: ``False``) boolean, also classically called adjoint, takes a square matrix ``M`` and finds the transpose of its cofactor matrix. Used for conjugation in place of inverse when specified ``True``. Functionality is the same in projective space. + - ``adjugate`` -- (default: ``False``) boolean, also classically called + adjoint, takes a square matrix ``M`` and finds the transpose of its + cofactor matrix. Used for conjugation in place of inverse when + specified ``True``. Functionality is the same in projective space. - - ``normalize`` -- (default: ``False``) boolean, if normalize is ``'True'``, then the function ``normalize_coordinates`` is called. + - ``normalize`` -- (default: ``False``) boolean, if ``normalize`` is + ``True``, then the method ``normalize_coordinates`` is called. OUTPUT: a dynamical system @@ -2720,34 +2724,41 @@ def nth_preimage_tree(self, Q, n, **kwds): kwds: - - ``return_points`` -- (default: ``False``) boolean; if ``True``, return a list of lists - where the index ``i`` is the level of the tree and the elements of the list at that - index are the ``i``-th preimage points as an algebraic element of the splitting field - of the polynomial ``f^n - Q = 0`` + - ``return_points`` -- (default: ``False``) boolean; if ``True``, + return a list of lists where the index `i` is the level of the tree + and the elements of the list at that index are the `i`-th preimage + points as an algebraic element of the splitting field of the + polynomial `f^n - Q = 0` - - ``numerical`` -- (default: ``False``) boolean; calculate pre-images numerically. Note if this - is set to ``True``, preimage points are displayed as complex numbers + - ``numerical`` -- (default: ``False``) boolean; calculate pre-images + numerically. Note if this is set to ``True``, preimage points are + displayed as complex numbers - - ``prec`` -- (default: 100) positive integer; the precision of the ``ComplexField`` if - we compute the preimage points numerically + - ``prec`` -- (default: 100) positive integer; the precision of the + ``ComplexField`` if we compute the preimage points numerically - - ``display_labels`` -- (default: ``True``) boolean; whether to display vertex labels. Since labels - can be very cluttered, can set ``display_labels`` to ``False`` and use ``return_points`` to get a + - ``display_labels`` -- (default: ``True``) boolean; whether to display + vertex labels. Since labels can be very cluttered, can set + ``display_labels`` to ``False`` and use ``return_points`` to get a hold of the points themselves, either as algebraic or complex numbers - - ``display_complex`` -- (default: ``False``) boolean; display vertex labels as - complex numbers. Note if this option is chosen that we must choose an embedding - from the splitting field ``field_def`` of the nth-preimage equation into C. We make - the choice of the first embedding returned by ``field_def.embeddings(ComplexField())`` + - ``display_complex`` -- (default: ``False``) boolean; display vertex + labels as complex numbers. Note if this option is chosen that we must + choose an embedding from the splitting field ``field_def`` of the + `n`-th-preimage equation into `\CC`. We make the choice of the first + embedding returned by ``field_def.embeddings(ComplexField())`` - - ``digits`` -- a positive integer, the number of decimal digits to display for complex - numbers. This only applies if ``display_complex`` is set to ``True`` + - ``digits`` -- a positive integer, the number of decimal digits to + display for complex numbers. This only applies if ``display_complex`` + is set to ``True`` OUTPUT: - If ``return_points`` is ``False``, a ``GraphPlot`` object representing the ``n``-th pre-image tree. - If ``return_points`` is ``True``, a tuple ``(GP, points)``, where ``GP`` is a ``GraphPlot`` object, - and ``points`` is a list of lists as described above under ``return_points``. + If ``return_points`` is ``False``, a :class:`GraphPlot` object representing + the `n`-th pre-image tree. If ``return_points`` is ``True``, a tuple + ``(GP, points)``, where ``GP`` is a :class:`GraphPlot` object, and + ``points`` is a list of lists as described above under + ``return_points``. EXAMPLES:: From 4d507c7f35b8ea135d3c8a978c0c4c78d486c924 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 16 Jun 2023 16:35:36 -0700 Subject: [PATCH 196/205] Reformat adjacent annotations as '# indirect doctest, optional...' --- src/sage/matroids/linear_matroid.pyx | 2 +- src/sage/matroids/minor_matroid.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index 7a8b945ee3e..baa8aae6f15 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -5042,7 +5042,7 @@ cdef class QuaternaryMatroid(LinearMatroid): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: QuaternaryMatroid(matrix=Matrix(GF(4, 'x'), # indirect doctest # optional - sage.rings.finite_rings + sage: QuaternaryMatroid(matrix=Matrix(GF(4, 'x'), # indirect doctest, optional - sage.rings.finite_rings ....: [[1, 0, 1, 1, 1], ....: [0, 1, 1, 1, 1]])) Quaternary matroid of rank 2 on 5 elements diff --git a/src/sage/matroids/minor_matroid.py b/src/sage/matroids/minor_matroid.py index 1c27166d4f8..21122fcb59b 100644 --- a/src/sage/matroids/minor_matroid.py +++ b/src/sage/matroids/minor_matroid.py @@ -132,7 +132,7 @@ def __init__(self, matroid, contractions=None, deletions=None): EXAMPLES:: sage: from sage.matroids.advanced import * - sage: M = MinorMatroid(matroids.named_matroids.Fano(), # indirect doctest # optional - sage.rings.finite_rings + sage: M = MinorMatroid(matroids.named_matroids.Fano(), # indirect doctest, optional - sage.rings.finite_rings ....: contractions=set(), deletions=set(['g'])) sage: M.is_isomorphic(matroids.Wheel(3)) # optional - sage.rings.finite_rings True From 3395892c6c5e279ba71f700f65c35ae66871f9cf Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 16 Jun 2023 23:16:59 -0700 Subject: [PATCH 197/205] Markup fixes --- src/sage/features/kenzo.py | 2 +- src/sage/features/latte.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/features/kenzo.py b/src/sage/features/kenzo.py index b9ccd8537fe..0060e6deb03 100644 --- a/src/sage/features/kenzo.py +++ b/src/sage/features/kenzo.py @@ -19,7 +19,7 @@ class Kenzo(Feature): r""" - A :class:`~sage.features.Feature` describing the presence of :class:`Kenzo `. + A :class:`~sage.features.Feature` describing the presence of :ref:`Kenzo `. EXAMPLES:: diff --git a/src/sage/features/latte.py b/src/sage/features/latte.py index 9c043d8d016..4df8b1cd586 100644 --- a/src/sage/features/latte.py +++ b/src/sage/features/latte.py @@ -58,7 +58,8 @@ def __init__(self): class Latte(JoinFeature): r""" - A :class:`~sage.features.Feature` describing the presence of excecutables from :ref:`LattE integrale `. + A :class:`~sage.features.Feature` describing the presence of excecutables + from :ref:`LattE integrale `. EXAMPLES:: From 99739d3bbe1c892abb4b6082347f250b67ed7d39 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 16 Jun 2023 23:25:45 -0700 Subject: [PATCH 198/205] bootstrap: Use 'distribution packages' --- src/doc/bootstrap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/bootstrap b/src/doc/bootstrap index 11bbc5510a5..a700428f135 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -105,8 +105,8 @@ for PKG_BASE in $(sage-package list --has-file SPKG.rst :standard: | grep -v '^s done >> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" < Date: Fri, 16 Jun 2023 23:33:50 -0700 Subject: [PATCH 199/205] bootstrap: Shorten section title --- src/doc/bootstrap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/bootstrap b/src/doc/bootstrap index a700428f135..8b4c3477cca 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -139,8 +139,8 @@ for PKG_BASE in $(sage-package list --has-file SPKG.rst :experimental: | grep -v done >> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" < Date: Fri, 16 Jun 2023 23:35:31 -0700 Subject: [PATCH 200/205] Move join_feature, all back to the front --- src/doc/bootstrap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/bootstrap b/src/doc/bootstrap index 8b4c3477cca..121b450e7cb 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -146,6 +146,8 @@ Features :maxdepth: 1 sage/features + sage/features/join_feature + sage/features/all sage/features/sagemath sage/features/pkg_systems sage/features/bliss @@ -173,8 +175,6 @@ Features sage/features/polymake sage/features/rubiks sage/features/tdlib - sage/features/join_feature - sage/features/all All External Packages --------------------- From 3995d71c79013e7d51f05f458e06d22c9c35f339 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 16 Jun 2023 23:45:41 -0700 Subject: [PATCH 201/205] Shorten section title, move experimental packages to the end --- src/doc/bootstrap | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/doc/bootstrap b/src/doc/bootstrap index 121b450e7cb..7aa458c336b 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -89,8 +89,8 @@ fi OUTPUT_INDEX="$OUTPUT_DIR"/index.rst cat > "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" -cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" OUTPUT_INDEX="$OUTPUT_DIR"/index_alph.rst cat >> "$OUTPUT_INDEX" < Date: Fri, 16 Jun 2023 23:46:46 -0700 Subject: [PATCH 202/205] Move distributions after optional packages --- src/doc/bootstrap | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/doc/bootstrap b/src/doc/bootstrap index 7aa458c336b..9e680ce85d2 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -105,15 +105,6 @@ for PKG_BASE in $(sage-package list --has-file SPKG.rst :standard: | grep -v '^s done >> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" -cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" +cat >> "$OUTPUT_INDEX" < Date: Sat, 17 Jun 2023 05:55:20 -0700 Subject: [PATCH 203/205] src/doc/bootstrap: Fixup --- src/doc/bootstrap | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/doc/bootstrap b/src/doc/bootstrap index 9e680ce85d2..be2168af064 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -153,15 +153,6 @@ Features sage/features/polymake sage/features/rubiks sage/features/tdlib - -All External Packages ---------------------- - -.. toctree:: - :maxdepth: 1 - - index_alph - EOF cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" +cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" < Date: Sat, 17 Jun 2023 15:20:02 +0100 Subject: [PATCH 204/205] adjust random tests for generators of elliptic curves --- .../elliptic_curves/ell_rational_field.py | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index b5f5de2bd3f..1066e76ec25 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -2319,6 +2319,22 @@ def gens(self, proof=None, **kwds): sage: E1.gens(algorithm="pari") #random [(-400 : 8000 : 1), (0 : -8000 : 1)] + TESTS:: + + sage: E = EllipticCurve('389a') + sage: len(E.gens()) + 2 + sage: E.saturation(E.gens())[1] + 1 + sage: len(E.gens(algorithm="pari")) + 2 + sage: E.saturation(E.gens(algorithm="pari"))[1] + 1 + sage: E = EllipticCurve([-3/8,-2/3]) + sage: P = E.lift_x(10/9) + sage: set(E.gens()) <= set([P,-P]) + True + """ if proof is None: from sage.structure.proof.proof import get_flag @@ -2370,23 +2386,29 @@ def _compute_gens(self, proof, 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) + sage: E.gens(use_database=False, algorithm="pari",pari_effort=4) # random [(611429153205013185025/9492121848205441 : 15118836457596902442737698070880/924793900700594415341761 : 1)] + TESTS:: + + sage: P = E.lift_x(611429153205013185025/9492121848205441) + sage: set(E.gens(use_database=False, algorithm="pari",pari_effort=4)) <= set([P+T for T + ....: in E.torsion_points()] + [-P+T for T in E.torsion_points()]) + True + 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) # long time + sage: ge = E.gens(use_database=False, algorithm="pari",pari_effort=10) + sage: ge #random [(-166136231668185267540804/2825630694251145858025 : 167661624456834335404812111469782006/150201095200135518108761470235125 : 1)] + sage: P = E.lift_x(-166136231668185267540804/2825630694251145858025) + sage: set(E.gens(use_database=False, algorithm="pari",pari_effort=4)) <= set([P+T for T + ....: in E.torsion_points()] + [-P+T for T in E.torsion_points()]) + True """ # If the optional extended database is installed and an @@ -2532,6 +2554,11 @@ def gens_certain(self): TESTS:: + sage: E = EllipticCurve('37a1') + sage: P = E([0,-1]) + sage: set(E.gens()) <= set([P,-P]) + True + sage: E = EllipticCurve([2, 4, 6, 8, 10]) sage: E.gens_certain() Traceback (most recent call last): From 3230f00aeb49802f99b0a3b76e770fa9d628c4e1 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Wed, 21 Jun 2023 23:07:52 +0200 Subject: [PATCH 205/205] Updated SageMath version to 10.1.beta4 --- 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 29721b280a3..1e4a3f7e84b 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.1.beta3 +version: 10.1.beta4 doi: 10.5281/zenodo.593563 -date-released: 2023-06-11 +date-released: 2023-06-21 repository-code: "https://github.com/sagemath/sage" url: "https://www.sagemath.org/" diff --git a/VERSION.txt b/VERSION.txt index 22e57381881..d91304debdc 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 10.1.beta3, Release Date: 2023-06-11 +SageMath version 10.1.beta4, Release Date: 2023-06-21 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index ce6cbceb5f5..433aaa94679 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=310e1602a96449fc1da190278048e89f63c71ef2 -md5=20faa4d933ea72b0fc3ab323c8d5cc97 -cksum=2486899926 +sha1=b3604052037bc57fb64fcbe347b289dcd959366c +md5=603842fccbd68e1125d32fed8d81ca86 +cksum=2053680048 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 46b933f0b15..4ccd147a316 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -a198b0e946fab4b5ff3b0a2bdc1dbad86f24d24c +4fa9c1c33b69fc6c3b948e9df3f7688b61b70589 diff --git a/build/pkgs/sage_conf/install-requires.txt b/build/pkgs/sage_conf/install-requires.txt index 89c7f89092e..dc86a0083d1 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.1b3 +sage-conf ~= 10.1b4 diff --git a/build/pkgs/sage_docbuild/install-requires.txt b/build/pkgs/sage_docbuild/install-requires.txt index 3853df189b7..09fa2357f61 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.1b3 +sage-docbuild ~= 10.1b4 diff --git a/build/pkgs/sage_setup/install-requires.txt b/build/pkgs/sage_setup/install-requires.txt index cbe875cbadf..feb29568e37 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.1b3 +sage-setup ~= 10.1b4 diff --git a/build/pkgs/sage_sws2rst/install-requires.txt b/build/pkgs/sage_sws2rst/install-requires.txt index 15283c90e87..499c62fc0a0 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.1b3 +sage-sws2rst ~= 10.1b4 diff --git a/build/pkgs/sagelib/install-requires.txt b/build/pkgs/sagelib/install-requires.txt index 26f47a8cfe0..128dfc286e3 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.1b3 +sagelib ~= 10.1b4 diff --git a/build/pkgs/sagemath_categories/install-requires.txt b/build/pkgs/sagemath_categories/install-requires.txt index 5b009ccfdcb..f84b868badb 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.1b3 +sagemath-categories ~= 10.1b4 diff --git a/build/pkgs/sagemath_environment/install-requires.txt b/build/pkgs/sagemath_environment/install-requires.txt index 0d2a87143f3..7bc9628f15a 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.1b3 +sagemath-environment ~= 10.1b4 diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index 3f15a34d3aa..351d5cbe6f7 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.1b3 +sagemath-objects ~= 10.1b4 diff --git a/build/pkgs/sagemath_repl/install-requires.txt b/build/pkgs/sagemath_repl/install-requires.txt index bc8bda08722..9b633de75f0 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.1b3 +sagemath-repl ~= 10.1b4 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 134573c319a..8dc27b1ee06 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -10.1.beta3 +10.1.beta4 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 134573c319a..8dc27b1ee06 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -10.1.beta3 +10.1.beta4 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 134573c319a..8dc27b1ee06 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -10.1.beta3 +10.1.beta4 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 134573c319a..8dc27b1ee06 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -10.1.beta3 +10.1.beta4 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 134573c319a..8dc27b1ee06 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -10.1.beta3 +10.1.beta4 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 134573c319a..8dc27b1ee06 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -10.1.beta3 +10.1.beta4 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 134573c319a..8dc27b1ee06 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -10.1.beta3 +10.1.beta4 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index 134573c319a..8dc27b1ee06 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -10.1.beta3 +10.1.beta4 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 134573c319a..8dc27b1ee06 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -10.1.beta3 +10.1.beta4 diff --git a/src/VERSION.txt b/src/VERSION.txt index 134573c319a..8dc27b1ee06 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -10.1.beta3 +10.1.beta4 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 00fd83ccd47..6555188b84c 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.beta3' -SAGE_RELEASE_DATE='2023-06-11' -SAGE_VERSION_BANNER='SageMath version 10.1.beta3, Release Date: 2023-06-11' +SAGE_VERSION='10.1.beta4' +SAGE_RELEASE_DATE='2023-06-21' +SAGE_VERSION_BANNER='SageMath version 10.1.beta4, Release Date: 2023-06-21' diff --git a/src/sage/version.py b/src/sage/version.py index 5119b7def49..8b362f1de6a 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.beta3' -date = '2023-06-11' -banner = 'SageMath version 10.1.beta3, Release Date: 2023-06-11' +version = '10.1.beta4' +date = '2023-06-21' +banner = 'SageMath version 10.1.beta4, Release Date: 2023-06-21'